I want to add another appender (Syslog, but any can do as an illustration) to my log4j2 logger progr...
s
I want to add another appender (Syslog, but any can do as an illustration) to my log4j2 logger programmatically, anybody got a snippet?
a
Logging is something that should be configured by the environment the application is running in. Not by the application itself.
šŸ‘Ž 1
āž• 1
s
Bold statement šŸ˜‰ Logging is something that should be configured as the developer chooses. Anyway, here is the snippet for whoever wishes to follow this path:
Copy code
data class LoggerConfig(
    var syslogHost: String = "127.0.0.1",
    var syslogPort: Int = 514,
    var syslogProtocol: String = "udp",
    var rootLevel: String = "info",
    var consoleLevel: String = "info",
    var syslogLevel: String? = null,
    var consolePattern: String = "%d{HH:mm:ss.SSS} %-5level %logger{36} %F(%L) - %msg%n")

fun configureLogger() {
    val loggerConfig = LoggerConfig()
    val builder = ConfigurationBuilderFactory.newConfigurationBuilder()
    val syslog = builder
        .newAppender("app_syslog", "Syslog")
        .addAttribute("host", loggerConfig.syslogHost)
        .addAttribute("port", loggerConfig.syslogPort)
        .addAttribute("protocol", loggerConfig.syslogProtocol)
        .add(
            builder.newLayout("RFC5424Layout")
                .addAttribute("appName", "my_app")
                .addAttribute("mdcId", "mdc")
                .addAttribute("facility", "LOCAL0")
                .addAttribute("exceptionPattern", "%throwable{full}")
                .addAttribute("newLine", true)
        )
    if (loggerConfig.syslogLevel != null) {
        syslog.add(builder
            .newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.DENY)
            .addAttribute("level", loggerConfig.syslogLevel))
    }
    val console = builder
        .newAppender("app_console", "Console")
        .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT)
        .add(
            builder
                .newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.DENY)
                .addAttribute("level", loggerConfig.consoleLevel)
        )
        .add(
            builder
                .newLayout("PatternLayout")
                .addAttribute("pattern", loggerConfig.consolePattern)
        )
    val config = builder
        .add(console)
        .add(syslog)
        .add(
            builder
                .newRootLogger(loggerConfig.rootLevel)
                .add(builder.newAppenderRef("app_syslog"))
                .add(builder.newAppenderRef("app_console"))
        )
        .build()
    (LogManager.getContext(false) as LoggerContext).configuration = config
    logger.warn("LOGGER INITIALIZED - $loggerConfig")
}
a
It’s not really a bold statement but literally one of the first guidelines 12 factor app. How would you deploy to different environments with different logging requirements without recompiling? You have now created hard coded configuration which is a big code smell. Logging is something that should be configurable as the deployment environment requires and not as the developer chooses.
s
Why do you think the config above has var’s not val’s. I’m deploying to multiple environments and not only the parameters are different, I can send syslog to a different server without even restarting the instance. Of course
Copy code
val loggerConfig = LoggerConfig()
Is just for an illustration, in real app you’ll get the config object from somewhere else.
That line ^^^
Copy code
(LogManager.getContext(false) as LoggerContext).configuration = config
Initializes or re-initializes the logging system. If you just love the xml, it is your problem, but in the real life the configuration parameters can be get from anywhere (f.e. database etc.)
a
I had a whole story, but to be honest I don’t like your hostile way of communicating. Things like thumbs down on things you don’t like, ā€œit’s your problemā€ and ā€œin the real lifeā€ don’t contribute to an honest discussion and are a far cry of the normal tone of discussion on the Kotlin Slack. I suggest you reevaluate your discussion skills
s
I’m sorry if I have offended you, just feel pretty strongly about prescribing solutions to people. IMO thumbs down are normal to express disagreement, it is a pity most of the social networks don’t have them. On the topic, I’d love to hear the argument on why we can’t have an option to configure either in config or code. F.e. Ktor has both…