zalando / friboo

Utility library for writing microservices in Clojure, with support for Swagger and OAuth
Apache License 2.0
118 stars 16 forks source link

Logging configuration #109

Open dryewo opened 7 years ago

dryewo commented 7 years ago

Use https://github.com/malcolmsparks/clj-logging-config instead of providing resources/log4j.xml. This should allow to configure logging in runtime.

dryewo commented 7 years ago

Also consider using Timbre intead of log4j.

PetrGlad commented 7 years ago

Timbre is convenient but it does not work with existing loggers. For one of projects that used Timbre I had to write adapter to have unified logging from Timbre, Jetty and other libraries https://github.com/PetrGlad/timbre-over-slf4j If this solves what you want o achieve, then go on. In my java projects I normally had logging adapters to slf4j and then plugged in some slf4j implementation (however Log4j has several direct adapters to it's API).

Also you can change logging levels right now (Log4j 2.x) see https://logging.apache.org/log4j/2.x/faq.html#reconfig_level_from_code

(require '[org.zalando.stups.friboo.log :as log]) 
(import org.apache.logging.log4j.core.config.Configurator)
(import  org.apache.logging.log4j.Level)
(Configurator/setLevel "user" Level/TRACE) ;
(log/trace "Hello")
(Configurator/setLevel "user" Level/INFO) ;
(log/trace "Hello")
sebastianpoeplau commented 7 years ago

@PetrGlad wouldn't slf4j-timbre solve the problem with existing dependencies on (most) other logging frameworks?

dryewo commented 7 years ago

@PetrGlad that's interesting, because we already have set-log-level! code function that does more or less the same. The current problem is that calling it from system/run did not work for me and I had to call.

In a nutshell, my problem is:

I want to set DEBUG level for org.zalando.stups and com.example.foo, but for everything else I'd like to have INFO. No combination of :stups-log-level and :log-level made system/run to work as expected, I ended up calling set-log-level! separately before trying to start the system, right from dev/user.clj.

I'd like to have more intuitive way of configuring logging, and also including a resource in the library isn't a very good practice, because some apps might want to include their own log4j.xml and it would override the library's one.

PetrGlad commented 7 years ago

@sebastianpoeplau there are multiple adapters of logging frameworks' APIs (at least for all usual suspects JUL, Log4j and JCL) on one hand and logging implementations for slf4j on the other.

Since Friboo already contains several adapters directly to Log4j v2 logger

  [org.apache.logging.log4j/log4j-api "2.7"]
  [org.apache.logging.log4j/log4j-slf4j-impl "2.7"]  ;; <<<<<<<<<<<
  [org.apache.logging.log4j/log4j-jcl "2.7"]
  [org.apache.logging.log4j/log4j-1.2-api "2.7"]
  [org.apache.logging.log4j/log4j-jul "2.7"]

no need to change that: with an adapter Timbre will log to slf4j which would log to log4j. One also can implement own adapter to log4j directly of course.

For my projects I'd prefer to stay with clojure.tools.logging though.

PetrGlad commented 7 years ago

@dryewo Friboo template could provide some default configuration file. Also one can enable refresh in configuration see "Automatic Reconfiguration" in https://logging.apache.org/log4j/2.x/manual/configuration.html and this is probably sufficient for debugging/interactive work.

If org.zalando.stups.friboo.system/set-log-level! does not work as expected it's a bug to be fixed. Looking at the code, did you pass level as (run {:system {:log-level "DEBUG"}})?

The use case I care about is application deployed in a container. The configuration there is normally passed via environment variables. With log4j one can put placeholders in configuration file that will be filled from environment (see section "Property Substitution"). But this does not allow to configure levels for arbitrary loggers (e.g. 3rd party libraries).

PetrGlad commented 7 years ago

@sebastianpoeplau I probably misunderstood the question. Timbre is logging implementation that has own logger and is completely oblivious to the java ecosystem out there. That's the problem. No choice of logging framework inside Friboo would change the fact that 3rd party libraries already use loggers. Citing Timbre readme:

Java logging is a Kafkaesque mess of complexity that buys you nothing. It can be comically hard to get even the simplest logging working, and it just gets worse at scale.

Actually it buys you Jetty, for example :)

PetrGlad commented 7 years ago

I just checked Timbre again, now they have implemented a slf4j appender.

sebastianpoeplau commented 7 years ago

@PetrGlad my understanding is that we actually want to use Timbre at the base, rather than deferring to some Java logger. That's why I mentioned that there are bindings to redirect to Timbre whatever third parties log to some of the well-known Java frameworks.

PetrGlad commented 7 years ago

OK. What problem do you want to solve by using Timbre?

dixel commented 7 years ago

The only valid point I see here in Timbre is zero-configuration in case of stdout logging. Apart from that don't have a definite opinion, because I'm not sure how timbre handles heavy load and other "sensitive" logging topics.

Otann commented 7 years ago

I would love to have the freedom of choosing a logging implementation, which would mean choosing the way of configuring it as well. So I think benefits of using Timbre is a separate discussion.

Existing libraries, from my experience, use slf4j mostly, so there should be no problem with that.

Also I would prefer to log objects instead of strings and send them to Reimann for monitoring and to ELK for analysis.

p.s. this setup works fine with friboo 2.0:

[com.taoensso/timbre "4.4.0"]              ; clojure[script] logging
[org.slf4j/slf4j-api "1.7.14"]             ; for other libs that use it
[com.fzakaria/slf4j-timbre "0.3.2"]        ; delegate slf4j to timbre