참조 : https://shybovycha.github.io/2015/10/05/custom-logging-with-timbre.html

Timbre란? Timbre는 로그 라이브러리이다. 꽤 많은 기능들을 제공하고 있다.
예로, 로그 파일 사이즈 제한, 복사본 만들기, 로그 파일 롤링, JSON 형식으로 로그 남기기

기타 등등이 있을 수 있다.

 장점                                                                                                                    단점  
 1. Objects 출력이 가능하다.                                                                                             없다. 

1 시작하기

Leiningen 프로젝트를 사용한다는 가정하에 시작한다.

2 프로젝트 생성하기

$ lein new app your-app-name

3 라이브러리 추가하기

(defproject your-app-name
    :dependencies [[org.clojure/clojure "1.8.0"]
                 [com.taoensso/timbre "4.10.0"]
                 [org.clojure/data.json "0.2.6"]]
)

4 의존성 라이브러리 가져오기

의존성 라이브러리 다운로드 하기 위해 아래와 같이 입력해주자.

$ lein deps

5 커스텀 JSON 로그로 설정하기

Timbre설명에서도 나와 있듯이, timbre는 기본설정을 가지고있다. 예를 들어, 로그를 파일에 저장하기 위해 spit appender가 있다.

또한 기본적 timbre appender는 로그를 stdout으로 출력 할 수 있다.

각 Timbre의 appender는 type이 아닌 id기반으로 설정되어야 한다. 그래서 두가지의 spit appender를 가질수도 있다. 예로, 두개의 파일에 저장할 수 있다.

Timbre 설정을 위해,두가지의 설정 방법을 제공한다.

  • merge : 기본설정에서의 몇가지 옵션만 덮어 씌어 설정 할 수 있다.
  • setting : 한번에 모든 설정을 덮어 씌어 설정 할 수 있다.

우리는 첫번째 방식을 사용할 것이다. 만약 우리가 완벽하게 설정하지 않을 경우, 우리는 제대로 된 로그를 출력 할 수 없을 것이다. 그리고 우리는 최소한으로 설정할 것이다.

첫번째로, 우리는 JSON으로 화면에 출력할 수 있도록 간단하게 설정했다.

(ns timbre-test1.core
  (:require [taoensso.timbre :as timbre :refer (log info warn debug error)]
            [clojure.data.json :as json]))

(defn json-output-fn
  [{:keys [vargs_ hostname_ timestamp_ level] :as args}]
  (let [
        messages (map (fn [msg] { :timestamp @timestamp_
                                  :level     level
                                  :hostname  @hostname_
                                  :message   msg })
                   @vargs_)
        json-messages (map #(json/write-str %) messages)]
    (clojure.string/join "\n" json-messages)))

(defn -main [& args]
  (timbre/merge-config!
    {:appenders {
                 :println {
                    :output-fn json-output-fn
                 }}})
  (info {:moo -3.14} {:foo :bar})
)

위 코드는 println appender에 output-fn 을 오버라이드 했다. output-fn함수는 각 다른 키값을 가지는 map 파라미터를 가진다.

가장 중요한 한가지는 vargs_, hostname_, timestamp_, 그리고 level이다.

아마 이정보들은 여러분이 원하는 포멧, 그리고 메시지 로 충분할 것이다.

vargs_ 변수는 모든 arguments를 포함한다. timbre에서 제공되는 (info, warn, error 기타 함수)에 파라미터로 전달한다. 그리고 clojure.data.json/write-str함수는 문자열 json 스트링으로 변환하여 반환한다.

level 은 매크로에 의해 설정된다. 예를들어 timbre/info “info”로 level로, timbre/error는 “error”로 설정될 것이다.

hostname timestamp 헬퍼 arguments이다. 아마도 앞의 두 파라미터는 필요 없을 수 도 있다. 하지만 timestamp_ 는 언제나 정말 많은 도움이 된다.

우리는 기본 설정에 file appender(json-output-fn)를 덮어씌었다.

(ns timbre-test1.core
  (:require [taoensso.timbre :as timbre :refer (log info warn debug error)]
            [taoensso.timbre.appenders.core :as appenders]
            [clojure.data.json :as json]))


(defn json-output-fn
  [{:keys [vargs_ hostname_ timestamp_ level] :as args}]
  (let [
        messages (map (fn [msg] {:timestamp @timestamp_
                                  :level     level
                                  :hostname  @hostname_
                                  :message   msg})
                   @vargs_)
        json-messages (map #(json/write-str %) messages)]
    (clojure.string/join "\n" json-messages)))


(defn -main [& args]
  (timbre/merge-config!
    {:appenders {
                 :spit (merge (appenders/spit-appender {:fname "timbre.log"}) {:output-fn json-output-fn})
                 }})
  (info {:moo -3.14} {:foo :bar})
)

여기에서는 크게 추가 할 것은 없고, 화면과 파일 두곳에 출력되도록 해보겠다. stdout에 로그 출력을 막기 위해, 우리는 println appender를 disabled 햇다.

여기서 우리는 json파일로 출력되는 우리만의 로그 설정을 완료하였다.

(defn -main [& args]
  (timbre/merge-config!
    {:appenders {
                 :println {:enabled? true}
                 :spit (merge (appenders/spit-appender {:fname "timbre.log"}) {:output-fn json-output-fn})
                 }})
  (info {:moo -3.14} {:foo :bar})
)