Search code examples
clojurering

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


I've inherited a project that gets some logging magic through [ring.middleware.logger "0.5.0" :exclusions [org.slf4j/slf4j-log4j12]] in the project.clj. As the middlewares get set up ring.middleware.logger/wrap-with-logger comes in and that gets me some nice logging on each request like...

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

...the problem is that some of the fields in this logging come out ANSI colorized. There is a request id like thing, above its the "a939" field, as well as the "Starting", "Finished", and the "Status" code which are presented with ANSI colors. This has the unpleasant side effect of making it challenging to RegEx the logs in Splunk, as there are now control characters, which appear as ascii digits now, mucking up the works.

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

How can I suppress the ANSI colorization of the logging output through the ring.middleware.logger thing?


Solution

  • An alternative is to migrate to [ring-logger-onelog "0.7.6"]. I started it as a fork of ring.middleware.logger with the goal of making it more flexible. For example it includes an option :printer :no-color with which you can avoid all the ANSI colorization.

    The migration path is very smooth, as shown 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.

    There's an example app that you can run to see what would be logged.

    There's also the core 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 that shows how you can implement it yourself.