https://github.com/ninjakoala/bjorr
Timbre appender which sends messages to Logz.io
https://github.com/ninjakoala/bjorr
appender clojure logging logzio timbre
Last synced: 1 day ago
JSON representation
Timbre appender which sends messages to Logz.io
- Host: GitHub
- URL: https://github.com/ninjakoala/bjorr
- Owner: ninjakoala
- License: epl-1.0
- Created: 2019-01-11T21:12:52.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-04-01T10:10:19.000Z (about 7 years ago)
- Last Synced: 2025-02-25T14:39:02.814Z (over 1 year ago)
- Topics: appender, clojure, logging, logzio, timbre
- Language: Clojure
- Size: 12.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://clojars.org/com.ninjakoala/bjorr) [](https://travis-ci.org/ninjakoala/bjorr)
# bjorr
[](dependency)
```clojure
[com.ninjakoala/bjorr "0.1.0-SNAPSHOT"] ;; latest release
```
[](/dependency)
A [Timbre](https://github.com/ptaoussanis/timbre) appender for [Logz.io](https://logz.io) which uses their [Java sender](https://github.com/logzio/logzio-java-sender) and is based on their [Logback appender](https://github.com/logzio/logzio-logback-appender).
## Usage
Just to demonstrate the steps required to get up and running in a simple app:
```clojure
(ns your.app
(:require [ninjakoala.bjorr :as bjorr]
[taoensso.timbre :as log])
(:import [java.util.concurrent Executors]))
(defn -main
[]
;; I'd recommend blacklisting these two patterns in Timbre unless you desperately want them.
;; They're both only really useful if you're having trouble getting the sender or appender
;; up and running. It's also a good idea to blacklist them _before_ starting the sender.
(log/merge-config! {:ns-blacklist ["io.logz.sender.*" "ninjakoala.bjorr"]})
(let [threadpool (Executors/newScheduledThreadPool 3)
sender (bjorr/create-logzio-sender "" threadpool)
appender (bjorr/create-logzio-appender sender)]
(.start sender)
(log/merge-config! {:appenders {:bjorr appender}})
(log/with-context {:some "context"
:look-numbers 123}
(log/warn "Hello from Bjorr"))
(.stop sender)
(.shutdown threadpool)))
```
This will result in the following JSON being sent to Logz.io (with the default type of `java`):
```json
{
"@timestamp": "2019-01-11T16:51:34.396Z",
"logger": "your.app",
"loglevel": "warn",
"look-numbers": 123,
"message": "Hello from Bjorr",
"some": "context",
"thread": "main",
}
```
Of course, you can use [Claypoole](https://github.com/TheClimateCorporation/claypoole) for your threadpools. It'll just slot in as `threadpool` in the above example.
Using [Integrant](https://github.com/weavejester/integrant) you might start things up like this:
```clojure
(ns your.app
(:require [integrant.core :as ig]
[ninjakoala.bjorr :as bjorr]
[taoensso.timbre :as log])
(:import [java.util.concurrent Executors]))
(def config
{::logzio-threadpool {:thread-count 3}
::logzio-sender {:threadpool (ig/ref ::logzio-threadpool)
:token ""}
::logzio-appender {:sender (ig/ref ::logzio-sender)}
::logging-config {:appenders {:bjorr (ig/ref ::logzio-appender)}}})
(defmethod ig/init-key ::logzio-threadpool
[_ {:keys [thread-count]}]
(Executors/newScheduledThreadPool thread-count))
(defmethod ig/halt-key! ::logzio-threadpool
[_ threadpool]
(when threadpool
(.shutdown threadpool)))
(defmethod ig/init-key ::logzio-sender
[_ {:keys [threadpool token]}]
(let [sender (bjorr/create-logzio-sender token threadpool)]
(.start sender)
sender))
(defmethod ig/halt-key! ::logzio-sender
[_ sender]
(when sender
(.stop sender)))
(defmethod ig/init-key ::logzio-appender
[_ {:keys [sender]}]
(bjorr/create-logzio-appender sender))
(defmethod ig/init-key ::logging-config
[_ config]
(log/merge-config! config))
(defn -main
[]
(log/merge-config! {:ns-blacklist ["io.logz.sender.*" "ninjakoala.bjorr"]})
(when-let [system (ig/init config)]
(log/with-context {:some "context"
:look-numbers 123}
(log/warn "Hello from Bjorr"))
(ig/halt! system)))
```
Or using [Mount](https://github.com/tolitius/mount):
```clojure
(ns your.app
(:require [mount.core :as mount :refer [defstate]]
[ninjakoala.bjorr :as bjorr]
[taoensso.timbre :as log])
(:import [java.util.concurrent Executors]))
(defstate logzio-threadpool
:start (Executors/newScheduledThreadPool 3)
:stop (when logzio-threadpool
(.shutdown logzio-threadpool)))
(defstate logzio-sender
:start (let [sender (bjorr/create-logzio-sender "" logzio-threadpool)]
(.start sender)
sender)
:stop (when logzio-sender
(.stop logzio-sender)))
(defstate logzio-appender
:start (bjorr/create-logzio-appender logzio-sender))
(defstate logging
:start (log/merge-config! {:appenders {:bjorr logzio-appender}})
:stop (log/swap-config! update-in [:appenders] #(dissoc % :bjorr)))
(defn -main
[]
(log/merge-config! {:ns-blacklist ["io.logz.sender.*" "ninjakoala.bjorr"]})
(mount/start)
(log/with-context {:some "context"
:look-numbers 123}
(log/warn "Hello from Bjorr"))
(mount/stop))
```
### Configuration
#### Sender
The defaults used by the Logback appender are in place in this library but you can customise the following settings to suit your needs. For descriptions of the settings it's probably best to head over to the [Parameters](https://github.com/logzio/logzio-java-sender#parameters) section of the original sender's README.
Key | Default value
--- | ---
`:check-disk-space-interval-millis` | `1000`
`:compress-requests?` | `false`
`:connect-timeout-millis` | `10000`
`:debug?` | `false`
`:drain-timeout-seconds` | `5`
`:file-system-full-percent-threshold` | `98`
`:gc-persisted-queue-files-interval-seconds` | `30`
`:in-memory-queue-capacity-bytes` | `104857600`
`:in-memory-queue-logs-count-limit` | `nil`
`:initial-wait-before-retry-millis` | `2000`
`:listener-url` | `https://listener.logz.io:8071`
`:log-type` | `java`
`:max-retries-attempts` | `3`
`:queue-directory` | `nil`
`:request-method` | `POST`
`:socket-timeout-millis` | `10000`
`:use-in-memory-queue?` | `false`
These options are specified as the optional third argument to `ninjakoala.bjorr/create-logzio-sender`. So to use an in-memory queue you would make the following call:
```clojure
(bjorr/create-logzio-sender "" threadpool {:use-in-memory-queue? true})
```
#### Appender
Finally there are a number of options you can use to configure the appender itself.
Key | Default value | Description
--- | --- | ---
`:add-file?` | `false` | Whether to add the filename of the log message.
`:add-hostname?` | `false` | Whether to add the hostname of the machine hosting this JVM.
`:add-line-number?` | `false` | Whether to add the line number of the log statement.
`:add-thread-name?` | `true` | Whether to add the name of the calling thread.
`:additional-fields` | `nil` | A map containing a number of static fields which will be merged into the context of every log message (therefore appearing as top-level fields in the JSON object sent to Logz.io). For example, you might want to log the service name, datacenter or availability zone.
| `:field-mappings` | `default-field-mappings` | See the [Field mappings](#field-mappings) section in the table below.
These options are specified as the optional second argument to `ninjakoala.bjorr/create-logzio-appender`. So to stop adding the thread name to each log message you would make the following call:
```clojure
(bjorr/create-logzio-appender sender {:add-thread-name? false})
```
#### Field mappings
The original Logback appender defines some field names which have been adopted by this library as defaults. However, it's all configurable so you can name things what you want.
Timbre field | Logz.io field
--- | ---
`:?err` | `:exception`
`:?file` | `:file`
`:hostname_` | `:hostname`
`:?line` | `:line`
`:level` | `:loglevel`
`:?ns-str` | `:logger`
`:msg_` | `:message`
`:thread_` | `:thread`
`:instant` | `"@timestamp"`
These are specified as the `:field-mappings` key in the configuration of the appender. So, to change the `:hostname_` field to be called `:pod-name` you would create the appender with the following call:
```clojure
(bjorr/create-logzio-appender sender {:field-mappings {:hostname_ :pod-name}})
```
## License
Copyright © 2019 Neil Prosser
Distributed under the Eclipse Public License either version 1.0 or (at
your option) any later version.