On Jul 23, 2014, at 7:11 PM, Jonah Benton <jo...@jonah.com> wrote: > Sean Corfield has a great example of writing a log4j logging backend in > clojure: > > http://corfield.org/blog/post.cfm/real-world-clojure-logging
Thanx for the referral. That made me go back and look at what that code has evolved into today... Despite the copyright date, we haven't actually touched this code for well over a year now! One thing we decided to do was move just the dbappender.clj to a separate file and AOT that, minimizing the code that the compiler might transitively drag in. Then we lein install the logging appender and depend on it from our main project. The delay / require / resolve construct seems a bit of a nasty hack so feedback on how to achieve that more elegantly is welcome. We also isolated the hooks into that main project as two logging calls: one which writes structured data to MongoDB and one which writes flat data to MySQL: ;; copyright (c) 2012-2014 world singles llc ;; ;; custom log appender that writes (non-DEBUG) log data to the log table (ns worldsingles.logging.dbappender (:import org.apache.log4j.Level org.apache.log4j.spi.LoggingEvent) (:gen-class :name worldsingles.logging.DBLogger :extends org.apache.log4j.AppenderSkeleton)) (def ^:private resolve-log-structured-data "Dynamically resolve worldsingles.logging.core/log-structured-data. We use delay to ensure we only require / resolve once." (delay (do (require 'worldsingles.logging.core) (resolve (symbol "worldsingles.logging.core/log-structured-data"))))) (def ^:private resolve-log-table-data "Dynamically resolve worldsingles.logging.core/log-table-data. We use delay to ensure we only require / resolve once." (delay (do (require 'worldsingles.logging.core) (resolve (symbol "worldsingles.logging.core/log-table-data"))))) ;; implement void AppenderSkeleton.append(LoggingEvent event) (defn -append "Append non-DEBUG events to MySQL and/or MongoDB as appropriate." [_ ^LoggingEvent event] (when (.isGreaterOrEqual (.getLevel event) Level/INFO) (let [msg (.getMessage event)] (@resolve-log-structured-data msg) (when (and (map? msg) (= (:logtype msg) "action")) (@resolve-log-table-data msg))))) ;; implement void Appender.close() (defn -close [_]) ;; implement boolean Appender.requiresLayout() (defn -requiresLayout [_] false) Sean Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ "Perfection is the enemy of the good." -- Gustave Flaubert, French realist novelist (1821-1880)
signature.asc
Description: Message signed with OpenPGP using GPGMail