Skip to the content.

Home | About | Documentation | Discuss

Cambium requires Clojure 1.6 or higher, Java 6 or higher.

SECURITY-FIX: Upgrade cambium.logback.* to version 0.4.6 for CVE-2021-42550 fix. SECURITY-FIX: Upgrade cambium.logback.* to version 0.4.5 for LOGBACK-1591 fix. See more details.

Latest release

API

Module Description Clojars artifact Dependencies
cambium.core SLF4j based core API implementation [cambium/cambium.core "1.1.1"] SLF4j
cambium.codec-simple Simple, non-nested codec [cambium/cambium.codec-simple "1.0.0"]  
cambium.codec-cheshire Cheshire based nesting-capable codec [cambium/cambium.codec-cheshire "1.0.0"] Cheshire

Backend: Logback

Module Description Clojars artifact Dependencies
cambium.logback.core Core Logback backend [cambium/cambium.logback.core "0.4.6"] Logback
cambium.logback.json JSON Logback backend [cambium/cambium.logback.json "0.4.6"] Jackson
cambium.logback.rabbitmq RabbitMQ appender for Logback [cambium/cambium.logback.rabbitmq "0.4.6"] RabbitMQ client

Quickstart

Configure application for only Text logs

Include the following dependencies in your project:

[cambium/cambium.core         "1.1.1"]
[cambium/cambium.codec-simple "1.0.0"]
[cambium/cambium.logback.core "0.4.6"]

Then, create a file resources/logback.xml with the following content:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg { %mdc }%n</pattern>
    </encoder>
  </appender>
  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

In your application, log events as data:

(ns myapp.main
  (:require
    [cambium.core  :as log]))

(defn -main
  [& args]
  (log/info "Application started")
  (log/info {:args (vec args) :argc (count args)} "Arguments received")
  ;; load rest of the application
  )

Text log output

The log output comes to the console when we run the app:

$ lein run foo 10
18:56:42.054 [main] INFO  myapp.main - Application started { ns=myapp.main, line=8, column=3 }
18:56:42.060 [main] INFO  myapp.main - Arguments received { args=["foo" "10"], argc=2, ns=myapp.main, line=9, column=3 }

When you run the same command without creating the resources/logback.xml file:

$ lein run foo 10
18:57:48.836 [main] INFO myapp.main - Application started
18:57:48.842 [main] INFO myapp.main - Arguments received

Configure application for JSON (and Text) logs

Include the following dependencies in your project:

[cambium/cambium.core           "1.1.1"]
[cambium/cambium.codec-cheshire "1.0.0"]
[cambium/cambium.logback.json   "0.4.6"]

Create resources/logback.xml file in your project with the following content:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
          <layout class="cambium.logback.json.FlatJsonLayout">
            <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
              <!-- prettyPrint is probably ok in dev, but usually not ideal in production: -->
              <prettyPrint>true</prettyPrint>
            </jsonFormatter>
            <!-- <context>api</context> -->
            <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSS'Z'</timestampFormat>
            <timestampFormatTimezoneId>UTC</timestampFormatTimezoneId>
            <appendLineSeparator>true</appendLineSeparator>
          </layout>
        </encoder>
    </appender>
    <root level="debug">
      <appender-ref ref="STDOUT" />
    </root>
</configuration>

Now before your application logs any event, configure the SLF4j backend to use the codec:

(ns myapp.main
  (:require
    [cambium.codec :as codec]
    [cambium.core  :as log]
    [cambium.logback.json.flat-layout :as flat]))

(defn -main
  [& args]
  (flat/set-decoder! codec/destringify-val)  ; configure backend with the codec
  (log/info "Application started")
  (log/info {:args (vec args) :argc (count args)} "Arguments received")
  ;; start rest of the app
  )

JSON log output

The log output comes to the console:

$ lein run foo 10
{
  "timestamp" : "2017-12-01T13:31:42.265Z",
  "level" : "INFO",
  "thread" : "main",
  "ns" : "myapp.main",
  "line" : 12,
  "column" : 3,
  "logger" : "myapp.main",
  "message" : "Application started",
  "context" : "default"
}
{
  "timestamp" : "2017-12-01T13:31:42.323Z",
  "level" : "INFO",
  "thread" : "main",
  "args" : [ "foo", "10" ],
  "argc" : 2,
  "ns" : "myapp.main",
  "line" : 13,
  "column" : 3,
  "logger" : "myapp.main",
  "message" : "Arguments received",
  "context" : "default"
}

License

Copyright © 2017-2023 Shantanu Kumar

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Fork me on GitHub