For why we need it, we would get the information of how many clients would
consume a particular server, at the first request. Based on that we would
create all the necessary route objects with key name as client's name (as a
lookup for routes). When a particular client requests, based on the client
name we would populate the key which is required for the router to map to,
and also dynamic hostname and port for that client through the
ThreadContext object.

Yes, I had tried the XML approach itself for the reference to the
programmatic approach
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Routing name="Routing">
<Routes pattern="$${ctx:module}">
<Route ref="SYSLOG1" key="Module1">
</Route>
<Route key="Module2">
<Syslog name="SYSLOG" format="RFC5424" host="${ctx:hostname}" port="
${ctx:port}" protocol="UDP" appName="myApp" includeMDC="true">
</Syslog>
</Route>
<Route key="$${ctx:module}">
<Syslog name="SYSLOG" format="RFC5424" host="${ctx:hostname}" port="
${ctx:port}" protocol="UDP" appName="myApp" includeMDC="true">
</Syslog>
</Route>
</Routes>
</Routing>
<Syslog name="SYSLOG1" format="RFC5424" host="${ctx:hostname}" port="
${ctx:port}" protocol="UDP" appName="myApp" includeMDC="true">
</Syslog>
</Appenders>

<Loggers>
<Logger name="RoutingLogger" level="debug" additivity="false">
<appender-ref ref="Routing" level="debug"/>
</Logger>
<Root level="debug">
<appender-ref ref="Routing" level="debug"/>
</Root>
</Loggers>
</Configuration>

Based on that itself I have configured the programmatic approach

LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
    Configuration config = ctx.getConfiguration();

    SyslogAppender syslogAppender =
SyslogAppender.newSyslogAppenderBuilder()
    .setName("syslog")
    .setProtocol(Protocol.UDP)
        .setHost(hostname)
        .setPort(port)
        .setAppName("service_name")
        .setId("service_name")
        .setFacility(Facility.LOCAL0)
        .setNewLine(true)
        .setFormat("RFC5424")
        .setIgnoreExceptions(false)
        .build();

    syslogAppender.start();
    config.addAppender(syslogAppender);

    RoutingAppender.Builder routingBuilder = RoutingAppender.newBuilder();
    routingBuilder.setConfiguration(config);
         routingBuilder.setName("RoutingConfig");

         Node node = null;
         Route[] routeList = new Route[1];
         routeList[0] = Route.createRoute("syslog", "domain#client", node);

         routingBuilder.withRoutes(
                 Routes.newBuilder().withPattern("$${ctx:module}")
                 .withRoutes(routeList)
                 .build());

         RoutingAppender routingAppender = routingBuilder.build();
         routingAppender.start();
         config.addAppender(routingAppender);

         AppenderRef ref = AppenderRef.createAppenderRef("RoutingConfig",
Level.DEBUG, null);
         AppenderRef[] refs = new AppenderRef[] { ref };

         LoggerConfig loggerConfig = LoggerConfig.newBuilder()
              .withAdditivity(false)
            .withLevel(Level.DEBUG)
            .withLoggerName("RoutingLogger")
            .withIncludeLocation("true")
            .withRefs(refs)
            .withConfig(config)
            .build();
         LoggerConfig rootLoggerConfig = LoggerConfig.newBuilder()
            .withLevel(Level.DEBUG)
            .withLoggerName(LogManager.ROOT_LOGGER_NAME)
            .withIncludeLocation("true")
            .withRefs(refs)
            .withConfig(config)
            .build();

         loggerConfig.addAppender(routingAppender, Level.DEBUG, null);
         rootLoggerConfig.addAppender(routingAppender, Level.DEBUG, null);
         config.addLogger("RoutingLogger", loggerConfig);
         config.addLogger(LogManager.ROOT_LOGGER_NAME, loggerConfig);
         ctx.updateLoggers();

         Logger logger = LogManager.getLogger("RoutingLogger");

         ThreadContext.put("module", "domain#client");
         ThreadContext.put("hostname", "somehost")
         ThreadContext.put("port", "someport")
         logger.info("message from domain client");
         logger.error("message form domain client error");
         ThreadContext.remove("module");
         ThreadContext.remove("hostname");
         ThreadContext.remove("port");

In the above programmatic approach I have used the Appender reference
approach in route object
because if we want to directly add appenders inside route object we need to
construct Node
<https://www.javadoc.io/static/org.apache.logging.log4j/log4j-core/2.8.2/org/apache/logging/log4j/core/config/Node.html#Node-org.apache.logging.log4j.core.config.Node-java.lang.String-org.apache.logging.log4j.core.config.plugins.util.PluginType->
object
along with PluginType
<https://www.javadoc.io/static/org.apache.logging.log4j/log4j-core/2.8.2/org/apache/logging/log4j/core/config/plugins/util/PluginType.html#PluginType-org.apache.logging.log4j.core.config.plugins.processor.PluginEntry-java.lang.Class-java.lang.String->
 and PluginEntry
<https://www.javadoc.io/static/org.apache.logging.log4j/log4j-core/2.8.2/org/apache/logging/log4j/core/config/plugins/processor/PluginEntry.html>
for
which there is no proper documentation to how to create and what does each
method means and relation between XML or JSON tag with java object's
properties in javadoc.io.

1. The problem is, this appender reference route approach programmatically
is not pushing the logs to the remote server, but the same XML approach
does.

2. And I would like to move from appender reference approach in route
object to directly adding the appenders inside the route object, for which
I need some documentation or examples for Node object, PluginType object
and PluginEnty object creation (creating from scratch not by getting the
existing node object from existing route object with route.getNode()). This
is because we could more efficiently purge the unused dynamically created
appenders automatically by the routing appender based on IdlePurgePolicy

For the first problem please can anyone look into the programmatic approach
that I had done, and figure out where the issue could be, since it is not
pushing the message to the specified host, but the same is working in the
XML approach.

For the second problem, please let me know how to configure the Node object
which is required for creation of the appender and putting them inside the
route object.


Thanks,
Ganesh S


On Fri, Oct 20, 2023 at 11:19 AM Ralph Goers <ralph.go...@dslextreme.com>
wrote:

> Why do you need to do it through code? I would recommend getting it
> working using a configuration (XML or JSON) and then, if you still need to,
> use that as your guide for how to create the RoutingAppender.
>
> Ralph
>
> > On Oct 19, 2023, at 11:53 AM, Ganesh S <ganesh123.g...@gmail.com> wrote:
> >
> > I have made some modification in the previous code that I had sent and
> > there is no error or warning while configuration initialization, but logs
> > are not going to the destination server
> > But if I try the same thing using log4j2.xml it is working fine.
> >
> > Below is my updated code:
> >
> > LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
> >    Configuration config = ctx.getConfiguration();
> >
> >    SyslogAppender syslogAppender =
> > SyslogAppender.newSyslogAppenderBuilder()
> >    .setName("syslog")
> >    .setProtocol(Protocol.UDP)
> >        .setHost(hostname)
> >        .setPort(port)
> >        .setAppName("service_name")
> >        .setId("service_name")
> >        .setFacility(Facility.LOCAL0)
> >        .setNewLine(true)
> >        .setFormat("RFC5424")
> >        .setIgnoreExceptions(false)
> >        .build();
> >
> >    syslogAppender.start();
> >    config.addAppender(syslogAppender);
> >
> >    RoutingAppender.Builder routingBuilder = RoutingAppender.newBuilder();
> >    routingBuilder.setConfiguration(config);
> >         routingBuilder.setName("RoutingConfig");
> >
> >         Node node = null;
> >         Route[] routeList = new Route[1];
> >         routeList[0] = Route.createRoute("syslog", "domain#client",
> node);
> >
> >         routingBuilder.withRoutes(
> >                 Routes.newBuilder().withPattern("$${ctx:module}")
> >                 .withRoutes(routeList)
> >                 .build());
> >
> >         RoutingAppender routingAppender = routingBuilder.build();
> >         routingAppender.start();
> >         config.addAppender(routingAppender);
> >
> >         AppenderRef ref = AppenderRef.createAppenderRef("RoutingConfig",
> > Level.DEBUG, null);
> >         AppenderRef[] refs = new AppenderRef[] { ref };
> >
> >         LoggerConfig loggerConfig = LoggerConfig.newBuilder()
> >              .withAdditivity(false)
> >            .withLevel(Level.DEBUG)
> >            .withLoggerName("RoutingLogger")
> >            .withIncludeLocation("true")
> >            .withRefs(refs)
> >            .withConfig(config)
> >            .build();
> >         LoggerConfig rootLoggerConfig = LoggerConfig.newBuilder()
> >            .withLevel(Level.DEBUG)
> >            .withLoggerName(LogManager.ROOT_LOGGER_NAME)
> >            .withIncludeLocation("true")
> >            .withRefs(refs)
> >            .withConfig(config)
> >            .build();
> >
> >         loggerConfig.addAppender(routingAppender, Level.DEBUG, null);
> >         rootLoggerConfig.addAppender(routingAppender, Level.DEBUG, null);
> >         config.addLogger("RoutingLogger", loggerConfig);
> >         config.addLogger(LogManager.ROOT_LOGGER_NAME, loggerConfig);
> >         ctx.updateLoggers();
> >
> >         Logger logger = LogManager.getLogger("RoutingLogger");
> >
> >         ThreadContext.put("module", "domain#client");
> >         logger.info("message from domain client");
> >         logger.error("message form domain client error");
> >         ThreadContext.remove("module");
> >
> > Please can any one tell me what am I missing in the above programmatic
> > approach
> >
> > On Thu, Oct 19, 2023 at 6:59 PM Ganesh S <ganesh123.g...@gmail.com>
> wrote:
> >
> >> Trying to configure routing appender programmatically
> >> Unable to figure out completely.
> >> The current code for this is as below, which is not currently working.
> >> Need help to complete this code.
> >>
> >> ConfigurationBuilder<BuiltConfiguration> builder =
> >> ConfigurationBuilderFactory.newConfigurationBuilder();
> >> AppenderComponentBuilder syslogAppender = builder.newAppender("syslog",
> >> "Syslog")
> >>        .addAttribute("protocol", "UDP")
> >>        .addAttribute("host", hostname)
> >>        .addAttribute("port", port)
> >>        .addAttribute("appName", "serviceName")
> >>        .addAttribute("id", "serviceName")
> >>        .addAttribute("facility", "LOCAL0")
> >>        .addAttribute("newLine", true)
> >>        .addAttribute("format", "RFC5424")
> >>        .addAttribute("ignoreExceptions", false);
> >>
> >> syslogAppender.add(builder.newFilter("ThresholdFilter",
> >> Filter.Result.ACCEPT, Filter.Result.DENY)
> >>        .addAttribute("level", Level.DEBUG));
> >>
> >> builder.add(syslogAppender);
> >>
> >> Configuration config = builder.build();
> >>    RoutingAppender.Builder routingBuilder =
> RoutingAppender.newBuilder();
> >>    routingBuilder.setConfiguration(config);
> >>         routingBuilder.setName("RoutingConfig");
> >>
> >>         Node node = null;
> >>         Route[] routeList = new Route[1];
> >>         routeList[0] = Route.createRoute("syslog", "client1", node);
> >>
> >>         routingBuilder.withRoutes(
> >>                 Routes.newBuilder().withPattern("$${ctx:module}")
> >>                 .withRoutes(routeList)
> >>                 .build());
> >>
> >>         RoutingAppender routingAppender = routingBuilder.build();
> >>         routingAppender.start();
> >>         config.addAppender(routingAppender);
> >>         builder.add(builder.newLogger("RoutingLogger", Level.DEBUG)
> >>               .add(builder.newAppenderRef("RoutingConfig"))
> >>               .addAttribute("additivity", false));
> >>         config = builder.build();
> >>         config.addLogger("RoutingLogger",
> >> config.getLoggerConfig("RoutingLogger"));
> >>         Configurator.reconfigure(config);
> >>         LoggerContext ctx = (LoggerContext)
> LogManager.getContext(false);
> >>         ctx.updateLoggers();
> >>
> >>         Logger logger = LogManager.getLogger("RoutingLogger");
> >>
> >>         ThreadContext.put("module", "client1");
> >>         logger.info("message from client");
> >>         logger.error("message form client error");
> >>         ThreadContext.remove("module");
> >>
> >> On Thu, Oct 19, 2023 at 2:27 PM Ganesh S <ganesh123.g...@gmail.com>
> wrote:
> >>
> >>> Is there any reference for creating routing appender programmatically ?
> >>>
> >>> On Thu, Oct 19, 2023, 9:35 AM Ralph Goers <ralph.go...@dslextreme.com>
> >>> wrote:
> >>>
> >>>> Why are you doing it this way? Can you not just use the
> RoutingAppender?
> >>>>
> https://logging.apache.org/log4j/2.x/manual/appenders.html#RoutingAppender
> >>>>
> >>>> Ralph
> >>>>
> >>>>> On Oct 18, 2023, at 8:50 PM, Ganesh S <ganesh123.g...@gmail.com>
> >>>> wrote:
> >>>>>
> >>>>> Hello,
> >>>>> I'm trying to create different logger with different hostname and
> port
> >>>> for
> >>>>> different client requests to the server.
> >>>>> If a new client request comes, I will store the information in the
> >>>> thread
> >>>>> local object and based on the information I need to append a new
> logger
> >>>>> object to the existing configuration object using
> >>>> CompositeConfiguration
> >>>>> and update loggers in the logger context.
> >>>>> I'm using the name of the logger object not to have a package level
> >>>>> hierarchy but just as a named (client name) logger.
> >>>>>
> >>>>> Currently I'm getting the below error when I try to append new syslog
> >>>> using
> >>>>> CompositeConfiguration
> >>>>> at the line
> >>>>> logContext.reconfigure(compositeConfiguration);
> >>>>>
> >>>>> ERROR StatusConsoleListener Appender references must contain a
> >>>> reference
> >>>>> ERROR StatusConsoleListener Null object returned for AppenderRef in
> >>>> Logger.
> >>>>> ERROR StatusConsoleListener No appender name provided
> >>>>> ERROR StatusConsoleListener Could not create plugin of type class
> >>>>> org.apache.logging.log4j.core.appender.SyslogAppender for element
> >>>> Syslog
> >>>>> org.apache.logging.log4j.core.config.ConfigurationException:
> Arguments
> >>>>> given for element Syslog are invalid: field 'name' has invalid value
> >>>> 'null'
> >>>>> at
> >>>>>
> >>>>
> org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.injectFields(PluginBuilder.java:199)
> >>>>> .....
> >>>>> at
> >>>>>
> >>>>
> org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:621)
> >>>>> at
> >>>>>
> >>>>
> org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:715)
> >>>>> ERROR StatusConsoleListener Null object returned for Syslog in
> >>>> Appenders.
> >>>>>
> >>>>>
> >>>>> Below is my implementation
> >>>>>
> >>>>> ConfigurationBuilder<BuiltConfiguration> builder1 =
> >>>>> ConfigurationBuilderFactory.newConfigurationBuilder();
> >>>>>   AppenderComponentBuilder syslogAppender1 =
> >>>>> builder1.newAppender("syslog", "Syslog")
> >>>>>       .addAttribute("protocol", "UDP")
> >>>>>       .addAttribute("host", hostname)
> >>>>>       .addAttribute("port", port1)
> >>>>>       .addAttribute("appName", "serviceName")
> >>>>>       .addAttribute("id", "serviceName")
> >>>>>       .addAttribute("facility", "LOCAL0")
> >>>>>       .addAttribute("newLine", true)
> >>>>>       .addAttribute("format", "RFC5424")
> >>>>>       .addAttribute("ignoreExceptions", false);
> >>>>> syslogAppender1.add(builder1.newFilter("ThresholdFilter",
> >>>>> Filter.Result.ACCEPT, Filter.Result.DENY)
> >>>>> .addAttribute("level", Level.DEBUG));
> >>>>> builder1.add(syslogAppender1);
> >>>>>
> >>>>> builder1.add(builder1.newLogger("client1", Level.DEBUG)
> >>>>>              .add(builder1.newAppenderRef("syslog"))
> >>>>>              .addAttribute("additivity", false));
> >>>>> Configurator.reconfigure(builder1.build());
> >>>>>
> >>>>> Logger logger = LogManager.getLogger("client1");
> >>>>> logger.info("client1 message1");
> >>>>>
> >>>>> ConfigurationBuilder<BuiltConfiguration> builder =
> >>>>> ConfigurationBuilderFactory.newConfigurationBuilder();
> >>>>> AppenderComponentBuilder syslogAppender =
> >>>> builder.newAppender("syslog1",
> >>>>> "Syslog")
> >>>>>       .addAttribute("protocol", "UDP")
> >>>>>       .addAttribute("host", hostname)
> >>>>>       .addAttribute("port", port2)
> >>>>>       .addAttribute("appName", "serviceName")
> >>>>>       .addAttribute("id", "serviceName")
> >>>>>       .addAttribute("facility", "LOCAL0")
> >>>>>       .addAttribute("newLine", true)
> >>>>>       .addAttribute("format", "RFC5424")
> >>>>>       .addAttribute("ignoreExceptions", false);
> >>>>>
> >>>>> syslogAppender.add(builder.newFilter("ThresholdFilter",
> >>>>> Filter.Result.ACCEPT, Filter.Result.DENY)
> >>>>>       .addAttribute("level", Level.DEBUG));
> >>>>> builder.add(syslogAppender);
> >>>>>
> >>>>> builder.add(builder.newLogger("client2", Level.DEBUG)
> >>>>>              .add(builder.newAppenderRef("syslog1"))
> >>>>>              .addAttribute("additivity", false));
> >>>>>
> >>>>> LoggerContext logContext = LoggerContext.getContext(false);
> >>>>> org.apache.logging.log4j.core.config.Configuration configurationcore
> =
> >>>>> logContext.getConfiguration();
> >>>>> List<AbstractConfiguration> configurationList = new ArrayList<>();
> >>>>> if (configurationcore != null)
> >>>>> configurationList.add((AbstractConfiguration) configurationcore);
> >>>>> org.apache.logging.log4j.core.config.Configuration newconfig =
> >>>>> builder.build();
> >>>>> configurationList.add((AbstractConfiguration) newconfig);
> >>>>> CompositeConfiguration compositeConfiguration = new
> >>>>> CompositeConfiguration(configurationList);
> >>>>> logContext.reconfigure(compositeConfiguration);
> >>>>> logContext.updateLoggers();
> >>>>>
> >>>>> Logger logger1 = LogManager.getLogger("client2");
> >>>>> logger1.info("client2 message1");
> >>>>> logger1.info("client2 message2");
> >>>>> logger.info("client1 message2");
> >>>>> logger1.info("client2 message3");
> >>>>> logger.info("client1 message3");
> >>>>>
> >>>>>
> >>>>> Thank you,
> >>>>> Ganesh S
> >>>>
> >>>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>
>

Reply via email to