Configuring a Timbre appender

An appender's configuration is managed by a single function, timbre/set-config!, which accepts a list of keys identifying the type of appender, and the appender map, which is the actual configuration for the appender.

Taking a look at the init function in hipstr.handler, the first thing we see is a call to configure Timbre:

(timbre/set-config!
  [:appenders :rotor]
  {:min-level :info
    :enabled? true
    :async? false ; should be always false for rotor
    :max-message-per-msecs nil
    :fn rotor/appender-fn})

The preceding snippet configures the rotor appender, a type of file appender that creates a new log file after the current log file exceeds a specific size. Timbre's set-config! has a similar signature and behavior to Clojure's assoc-in (https://clojuredocs.org/clojure.core/assoc-in) function, but without having to define the target map to mutate.

Note

To see all the different appenders that Timbre ships with and to see how to configure each of them, take a look at the appenders' source at https://github.com/ptaoussanis/timbre/tree/master/src/taoensso/timbre/appenders.

Timbre log levels

A log level is the severity of a log message. In order, from lowest to highest, the seven Timbre log levels are :trace, :debug, :info, :warn, :error, :fatal, and :report. We can configure which appenders listen to which log levels by either setting a global log level using Timbre's set-level!, or on a case-by-case basis when configuring an appender using :min-level, as we did in our preceding example snippet.

Note

There are other ways to set global or thread-level minimum log levels, but they're not as convenient or useful. You can read more about those in the configuration section of the Timbre documentation. To see all the different appenders that Timbre ships with, take a look at the appenders' source at https://github.com/ptaoussanis/timbre/tree/master/src/taoensso/timbre/appenders.

We can configure multiple appenders with multiple calls to set-config!, and each appender can respond to a different minimum logging level. For example, perhaps you'll want to use a file appender for the :info level and above, but for anything fatal, you'll want to also use an email appender (also included as part of the Timbre library, called a postal appender). This can be done by either explicitly setting :min-level on each appender's configuration, or by setting the global minimum log level to be :info using Timbre's set-level! setting and overriding it on any appender that requires a different minimum level. Take a look at the following code sample:

(require ‘[taoensso.timbre :as timbre]
         ‘[taoensso.timbre.appenders.postal :as postal])
(timbre/set-level! :info)
(timbre/set-config! [:appenders :postal] 
        (postal/make-postal-appender
          {:minlevel :fatal}
          ;...snipped for brevity...
        ))

In the preceding snippet, we set a global minimum log level of :info using set-level!. However, we override the global level in our :postal appender such that the appender only fires off emails for any log statements that are at least :fatal.

Appender configuration keys

As timbre/set-config! is modeled after Clojure's assoc-in call, the keys we pass must map to Timbre's internal, nested configuration map. The appender's configuration keys typically match the name of the appender's namespace, so the configuration of the taoensso.timbre.appenders.rotor key is [:appenders :rotor], the configuration of the taoensso.timbre.appenders.mongo key is [:appenders :mongo], and so on. However, it's always best to take a quick peek at the code on GitHub to ensure that you're using the correct keys.

Appender map

The appender map, like the appender configuration keys, is specific to the appender you're configuring. Each appender will have its own set of options defining it how it should behave (such as :path for the rotor appender). However, there is a set of configuration keys that are common to all appenders:

  • :min-level: This is an optional key and the minimum emitted log level required to actually append to the target. By default it is set to all levels.
  • :enabled?: This is an optional key and it has a true/false value, which enables/disables the appender. By default it is set to false.
  • :async?: This is an optional key and it also has a true/false value, which when true, will call the appender asynchronously (good for slower appenders, such as a database appender or a socket appender). By default it is set to false.
  • :rate-limit: This is an optional key and limits the number of appender calls per millisecond. By default it is set to no limit.
  • :fn: This is a required key and the function for the appender in question.

There are a few other more advanced options but you'll rarely, if ever, need to use them. You can read the full list of available appender configuration options at https://github.com/ptaoussanis/timbre#configuration.

Shared appender configuration

The next thing we notice in the hipstr.handler namespace, after the configuration of the rotor appender, is the shared configuration.

  (timbre/set-config!
    [:shared-appender-config :rotor]
    {:path "hipstr.log" :max-size (* 512 1024) :backlog 10})

The :shared-appender-config is a configuration shared across all appenders, despite each appender having its own section within the shared configuration. It's shared in the sense that it's blindly sent to each appender at runtime, and each appender knows which section to interrogate to get its settings. It's like having a shared cheese plate that you pass around to dinner guests, but each piece of cheese is different and is labeled with a specific guest's name. It's that kind of "share".

The rotor appender uses [:shared-appender-config :rotor] for some of its values. We know this by checking the docstring in the taoensso.timbre.appenders.rotor namespace, as follows:

(def rotor-appender
  {:doc (str "Simple Rotating File Appender.
"
             "Needs :rotor config map in :shared-appender-config, 	    e.g.:
             {:path "logs/app.log"
              :max-size (* 512 1024)
              :backlog 5}")

You will often need to add an additional configuration to :shared-appender-config for the appender you want to use. This is one of those weird idiosyncratic "gotchas!" that often appear when it comes to logging.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.85.181