• Stars
    star
    149
  • Rank 241,364 (Top 5 %)
  • Language
    Clojure
  • License
    Other
  • Created over 9 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

easy logging setup in clojure

unilog: logging should be easy!

cljdoc badge

clojure.tools.logging is a great library to perform logging. It walks through several available options such as slf4j, commons-logging, log4j, and logback.

While the logging itself is simple and straightforward, navigating the many ways to configure logging can be a bit daunting. The above logging frameworks which clojure.tools.logging relies on expect logging configuration to happen in separate configuration file.

Unilog provides an extendable data format for configuration the logback framework.

Unilog also provides facilities to attach metadata to logs.

Coordinates

Clojars Project

Usage

Let's pretend you have an application, which reads its initial configuration in a YAML file:

other-config:
  foo: bar
logging:
  level: info
  console: true
  files:
    - "/var/log/program.log"
    - file: "/var/log/program-json.log"
      encoder: json
  overrides:
    some.namespace: debug

You would supply configuration by parsing the YAML and then calling start-logging!

(require '[clj-yaml.core  :refer [parse-string]]
         '[unilog.config  :refer [start-logging!]])

(let [default-logging  {:level "info" :console true}
      config           (parse-string (slurp "my-config.yml"))]
  (start-logging! (merge default-logging (:logging config)))
  ;; rest of program startup)

Configuration details

The configuration, given as a map to start-logging! understands a number of keys.

Global Options

  • :level: Default logging level
    • any of :all, :trace, :debug, :info, :warn, :error, :off
  • :external
    • If it is true, do not try to configure logging. An external configuration is supplied.
  • :overrides
    • Provide a map of namespace to level, overriding the provided default level.

Console

If the :console key is present in the configuration map, it may be any of:

  • false
    • Do not log to the console.
  • true
    • Log to the console, using a pattern encoder and the default pattern.
  • A string
    • Log to the console, using a pattern encoder and the supplied pattern string.
  • A map
    • Log to the console, other attributes are taken from the map.
    • For instance: {:console {:encoder :json}}.

File

If the :file key is present in the configuration map, it may be any of:

  • A string: Log to the provided file, using a pattern encoder and the default pattern.
  • A map: Log to a file, taking configuration attributes from the map.
    • For instance: {:file {:file "/var/log/foo.log" :encoder :json}}

Files

Expects a sequence of valid configurations for File.

Appenders

As for Files, but do not assume a specific appender, expect it to be supplied in the configuration map.

Example configuration map

{:level   :info
 :console false
 :files ["/var/log/standard.log"
         {:file "/var/log/standard-json.log" :encoder :json}]
 :file {:file "/var/log/file.log" :encoder :json}
 :appenders [{:appender :file
              :encoder  :json
              :file     "/var/log/other-json.log"}

             {:appender :file
              :encoder  :pattern
              :pattern  "%p [%d] %t - %c %m%n"
              :file     "/var/log/other-pattern.log"}

             {:appender :rolling-file
              :file     "/var/log/rolling-file.log"}

             {:appender :rolling-file
              :rolling-policy :fixed-window
              :triggering-policy :size-based
              :file     "/var/log/rolling-file.log"}

             {:appender :rolling-file
              :rolling-policy {:type :fixed-window
                               :max-index 5}
              :triggering-policy {:type :size-based
                                  :max-size 5120}
              :file     "/var/log/rolling-file.log"}]
 :overrides  {"org.apache.http"      :debug
              "org.apache.http.wire" :error}}

Encoders

You could specify encoder arguments in some appenders. Not every appender supports encoders. The following encoders are currently supported in :appenders.

PatternLayoutEncoder uses a default pattern of "%p [%d] %t - %c %m%n".

{:appender :file
 :file     "/var/log/file.log"
 ;; PatternLayoutEncoder
 ;; Without :pattern argument in an appender config, the default pattern is used.
 :encoder  :pattern}

{:appender :file
 :file     "/var/log/file2.log"
 :encoder  :pattern
 :pattern  "%p [%d] %t - %c %m%n"}

LogstashEncoder formats messages for logstash.

{:appender :file
 :file     "/var/log/file3.log"
 ;; LogstashEncoder
 :encoder  :json}

Appenders

The following appenders are currently supported:

:console appender

  • Optional Arguments
    • :encoder
    • :pattern
{:appender :console}

{:appender :console
 :encoder  :pattern}

{:appender :console
 :encoder  :pattern
 :pattern  "%p [%d] %t - %c %m%n"}

{:appender :console
 :encoder  :json}

:file appender

  • Mandatory Arguments
    • :file
  • Optional Arguments
    • :encoder
    • :pattern
{:appender :file
 :file     "/var/log/file.log"}

{:appender :file
 :file     "/var/log/file.log"
 :encoder  :pattern}

{:appender :file
 :file     "/var/log/file.log"
 :encoder  :pattern
 :pattern  "%p [%d] %t - %c %m%n"}

{:appender :file
 :file     "/var/log/file.log"
 :encoder  :json}

:rolling-file appender

  • Mandatory Arguments
    • :file
  • Optional Arguments
    • :rolling-policy
    • :triggering-policy
    • :encoder
    • :pattern

There are two rolling policies.

  • :fixed-window
    • Renames files according to a fixed window algorithm.
  • :time-based
    • Defines a rollover based on time.

Don't use a triggering policy with :time-based rolling policy since :time-based rolling policy is its own triggering policy as well. You can specify a rolling policy by the keyword.

{:appender       :rolling-file
 :rolling-policy :fixed-window
 :file           "/var/log/rolling-file.log"
 :encoder        :pattern}

{:appender :rolling-file
 :rolling-policy :time-based
 :file           "/var/log/rolling-file2.log"
 :encoder        :pattern
 :pattern        "%p [%d] %t - %c %m%n"}

If you want to specify arguments for a rolling policy, you can pass a map to :rolling-policy as below. every argument to a rolling policy except :type is optional.

{:appender :rolling-file
 :file           "rolling-file.log"
 :rolling-policy {:type      :fixed-window
                  :min-index 1
                  :max-index 5
                  ;; :pattern combines with :file to make the name of a rolled log file.
                  ;; For example, "rolling-file.log.%i.gz"
                  ;; %i is index.
                  :pattern  ".%i.gz"}
 :encoder        :json}

{:appender :rolling-file
 :file "rolling-file2.log"
 ;; If you use this rolling policy, don't use a triggering policy
 :rolling-policy {:type        :time-based
                  ;; log files are kept for :max-history periods.
                  ;; periods can be hours, days, months, and so on.
                  :max-history 5
                  ;; Before a period ends, if a log file reaches :max-size, it is rolled.
                  ;; :max-size adds %i to :pattern. Without :max-size, you shouldn't
                  ;; specify %i in :pattern.
                  ;; Refer to http://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedFNATP
                  ;; for elaborate description of :max-size
                  :max-size    51200 ; bytes
                  ;; :pattern combines with :file
                  ;; The rolling period is defined by :pattern.
                  ;; Refer to http://logback.qos.ch/manual/appenders.html#tbrpFileNamePattern
                  :pattern    ".%d{yyyy-MM-dd}.%i"}
 :encoder :pattern
 :pattern "%p [%d] %t - %c %m%n"}

There is only one triggering policy, :size-based.

{:appender :rolling-file
 :rolling-policy :fixed-window
 ;; If you don't pass any argument to :size-based triggering policy, it triggers a rollover
 ;; when a log file grow beyond SizeBasedTriggeringPolicy/DEFAULT_MAX_FILE_SIZE.
 :triggering-policy :size-based
 :file          "rolling-file.log"}

{:appender :rolling-file
 :rolling-policy :fixed-window
 :triggering-policy {:type     :size-based
                     ;; Refer to
                     ;; http://logback.qos.ch/manual/appenders.html#SizeBasedTriggeringPolicy
                     :max-size 51200}} ; 51200 bytes

:socket appender

  • Optional Arguments
    • :remote-host
    • :port
    • :queue-size
    • :reconnection-delay
    • :event-delay-limit
{:appender            :socket
 :remote-host        "localhost"
 :port                2004
 :queue-size          500
 :reconnection-delay "10 seconds"
 :event-delay-limit  "10 seconds"}

:syslog appender

  • Optional Arguments
    • :host
    • :port
{:appender :syslog
 :host    "localhost"
 :port     514}

Extending

If you wish to supply your own configuration functions for appenders or encoders, you may do so by adding multi-methods for build-appender and build-encoder. build-appender dispatches on the :appender key in a configuration map while build-encoder dispatches on the :encoder key.

These functions receive the provided configuration map and may thus expect specific keys to be present to perform their configuration.

You may need to add a multimethod for start-appender! if your appender needs a specialized initialization procedure.

API documentation

Full API documentation is available at http://pyr.github.io/unilog

Releases

0.7.29

0.7.28

0.7.26

  • Dependency upgrades
  • Unilog now depends on Clojure 1.10.1

0.7.24

  • Introduce mdc-fn and mdc-fn* which preserve MDC context across threads

0.7.22

  • Dependency upgrades
  • Switch to clojure 1.9, paving the way for specs

0.7.21

  • Dependency upgrades

0.7.20

  • Upgrade to logback 1.2.0

0.7.19

  • Add tests to ensure base functionality is preserved.
  • Hold-off on upgrading to logback 1.2.0 until logstash-encoder is compatible.

0.7.17

0.7.15

License

Copyright © 2014 Pierre-Yves Ritschard [email protected] MIT/ISC License, See LICENSE file.

More Repositories

1

cyanite

cyanite stores your metrics
Clojure
446
star
2

kinsky

Kafka Clojure client library
Clojure
193
star
3

signal

system signal handler for clojure
Clojure
81
star
4

recordbus

recordbus: mysql binlog to apache kafka
Clojure
80
star
5

net

the netty clojure companion
Clojure
64
star
6

check-graphite

nagios check for graphite metrics
Ruby
64
star
7

url-shortener

demo url shortening app in flask
Python
59
star
8

apotiki

a faster debian repository
Haskell
56
star
9

clj-statsd

simple client library to interface with statsd
Clojure
46
star
10

riemann-kafka

kafka producer and consumer support in riemann
Clojure
41
star
11

riemann-extra

Additional facilities for riemann
Clojure
40
star
12

himpy

snmp polling for riemann
Haskell
29
star
13

warp

simple controller for parallel script execution
Clojure
28
star
14

hublo

hublo: the world needed another site generator
Emacs Lisp
23
star
15

dot.emacs

my emacs config
Emacs Lisp
17
star
16

unklog

kafka log consumer
C
15
star
17

ipcalc

simple ipv4 calculator
C
13
star
18

kmodel

making use of kafka log compaction
Clojure
12
star
19

watchman

easy directory watches in clojure
Clojure
11
star
20

tree

ascii tree of directory structures
C
11
star
21

tron

TRON: Task Run ON
Clojure
10
star
22

brainfuck

clojure brainfuck interpreter
Clojure
10
star
23

nginxpipe

small nginx wrapper with syslog logging
Haskell
10
star
24

pickler

just enough pickle for graphite
Clojure
7
star
25

progress

sequence progress bars
Clojure
7
star
26

mdcat

terminal markdown cat
Go
7
star
27

collectd-dsl

Simple Collectd DSL in ruby
Ruby
7
star
28

stevedore

An embedding of shell script in clojure.
Clojure
7
star
29

jcipher

Jasypt compatible encryption and decryption CLI
Clojure
6
star
30

constance

constant time comparison
Clojure
4
star
31

uncaught

handle uncaught exceptions with ease
Clojure
4
star
32

sterm

simple term, based on vbeterm
C
3
star
33

warp-agent

simple agent for parallel script execution
Haskell
3
star
34

maniflow

lightweight interceptor type library for manifold
Clojure
3
star
35

ruby-storm-pointless

randomly generate names for things like operation codenames
Ruby
2
star
36

emenv

dependency handling for emacs
Go
2
star
37

commons

it's dangerous to go alone, take this
Clojure
2
star
38

blog

personal site, driven by hugo
HTML
2
star
39

jlog

small helper for JSON logs
Go
1
star
40

pyr.github.com

CSS
1
star
41

better-website

Chrome extension which provides a minimal viable layout for excessively simple website
CSS
1
star