Skip to content


Mulog is library that defines log events as data, with a wide range of publisher for 🌐 popular log aggregation services, e.g. Elastic Search, Cloudwatch, Kinesis, Prometheus, etc.)

Creating a custom publisher, all mulog events can be sent to portal data inspector.

Portal - mulog event messages tap>

Mulog eventλ︎

mulog/log function is used to define an event message. The first argument is a unique event name, followed by key/value pairs that define the contents of the message.

Simple Mulog Event

mulog/log ::dev-user-ns :message "Example event message" :ns (ns-publics *ns*))

Mulog configurationλ︎

mulog/set-global-context! defines key/value pairs included in every mulog event allowing a separate context to be used for logs, e.g. :env :dev indicating development time events.

TapPublisher defines a custom Mulog publisher which wraps tap> around every mulog event created, sending each mulog event to Portal.

tap-publisher is a var that starts the custom mulog publisher, providing a reference to the publisher so it can be shut down.

stop function is provided as a convienient way to stop the publisher via the REPL.

Mulog events publisher

;; ---------------------------------------------------------
;; Mulog Global Context and Custom Publisher
;; - set event log global context
;; - tap publisher for use with Portal and other tap sources
;; - publish all mulog events to Portal tap source
;; ---------------------------------------------------------

(ns mulog-events
   [com.brunobonacci.mulog        :as mulog]
   [com.brunobonacci.mulog.buffer :as mulog-buffer]))

;; ---------------------------------------------------------
;; Set event global context
;; - information added to every event for REPL workflow
(mulog/set-global-context! {:service-name "todo-tracker Service",
                            :version "0.1.0", :env "dev"})
;; ---------------------------------------------------------

;; ---------------------------------------------------------
;; Mulog event publishing

(deftype TapPublisher
         [buffer transform]
  (agent-buffer [_] buffer)
  (publish-delay [_] 200)
  (publish [_ buffer]
    (doseq [item (transform (map second (mulog-buffer/items buffer)))]
      (tap> item))
    (mulog-buffer/clear buffer)))

#_{:clj-kondo/ignore [:unused-private-var]}
(defn ^:private tap-events
  [{:keys [transform] :as _config}]
  (TapPublisher. (mulog-buffer/agent-buffer 10000) (or transform identity)))

(def tap-publisher
  "Start mulog custom tap publisher to send all events to Portal
  and other tap sources
  `mulog-tap-publisher` to stop publisher"
   {:type :custom, :fqn-function "mulog-events/tap-events"}))

#_{:clj-kondo/ignore [:unused-public-var]}
(defn stop
  "Stop mulog tap publisher to ensure multiple publishers are not started
 Recommended before using `(restart)` or evaluating the `user` namespace"

;; ---------------------------------------------------------