如何抑制 ANSI 着色 ring.middleware.logger 放入我的日志?

How do I suppress the ANSI coloring ring.middleware.logger is putting in my logs?

我继承了一个项目,该项目通过 project.clj 中的 [ring.middleware.logger "0.5.0" :exclusions [org.slf4j/slf4j-log4j12]] 获得了一些日志记录魔法。随着中间件的设置 ring.middleware.logger/wrap-with-logger 进来,这让我对每个请求都有一些很好的记录,比如...

2016-03-25 15:46:03,787 a939 level=INFO [qtp509784188-34] core:288 - Starting :delete /v4/events/c.c.t.p.v4.api-a9c6d846-1da5-4593-a711-18d90aa8490f/test-layer/2015-05-31T00:00:00.000Z for 127.0.0.1 {"host" "localhost:50654", "user-agent" "Apache-HttpClient/4.3.6 (java 1.5)", "accept-encoding" "gzip, deflate", "connection" "close"}
2016-03-25 15:46:03,788 a939 level=INFO [qtp509784188-34] core:288 -   \ - - - -  Params: {}
2016-03-25 15:46:03,794 a939 level=INFO [qtp509784188-34] core:288 - Finished :delete /v4/events/c.c.t.p.v4.api-a9c6d846-1da5-4593-a711-18d90aa8490f/test-layer/2015-05-31T00:00:00.000Z for 127.0.0.1 in (6 ms) Status: 404

...问题是此日志记录中的某些字段显示为 ANSI 彩色。在 "a939" 字段上方有一个类似请求 ID 的东西,以及 "Starting"、"Finished" 和 "Status" 代码,这些代码以 ANSI 颜色显示。这有一个令人不快的副作用,即对 Splunk 中的日志进行 RegEx 挑战,因为现在有控制字符,现在显示为 ascii 数字,破坏了工作。

2016-03-25 15:46:03,794 [0m[35m[44ma939[0m level=INFO [qtp509784188-34] onelog.core - [36mFinished...Status: [39m200[0m

如何通过 ring.middleware.logger 东西抑制日志输出的 ANSI 着色?

似乎 ring.middleware.logger 默认实现了 ANSI 着色,并且没有配置选项可以在不提供您自己的 pre-loggerpost-logger 等的情况下轻松禁用它

但是您可以创建一个解决方法:ring.middleware.logger 使用 clansi for applying ANSI colors. clansi provides without-ansi 宏来禁用着色。

你可以自己编写需要包装的中间件ring.middleware.logger:

(defn wrap-no-ansi-colors [handler]
  (fn [rq]
    (without-ansi
      (handler rq))))

(def app
  (-> handler
    (wrap-with-logger)
    (wrap-no-ansi-colors)))

另一种方法是迁移到 [ring-logger-onelog "0.7.6"]。我将它作为 ring.middleware.logger 的一个分支开始,目的是使其更加灵活。例如,它包含一个选项 :printer :no-color,您可以使用它来避免所有 ANSI 着色。

迁移路径很顺利,如图in the README:

  • Replace dependency in project.clj from [ring.middleware.logger "0.5.0"] to [ring-logger-onelog "0.7.6"]
  • Replace the require from [ring.middleware.logger :as logger] to [ring.logger.onelog :as logger]
  • Pass options to logger/wrap-with-logger using a proper map instead of keyword arguments.

有一个 example app,您可以 运行 查看将记录的内容。

还有核心 ring-logger library that works with different logging backends (as opposed to ring-logger-onelog which relies on onelog, which ultimately goes through log4j... or slf4j, not sure). ring-logger doesn't have request-id built-in, but there's an example in the README 展示了如何自己实现它。