Here's some code to implement a simple otplike logging system:
(ns otplike-log.log
(:require [clj-time.core :as t]
[clj-time.local :as l]
[otplike.process :as process :refer [!]]))
(defn pad0
[field-width n]
(let [s (pr-str n)
pad-count (- field-width (count s))
pad-string (apply str (repeat pad-count "0"))]
(str pad-string s)))
(def pad00 (partial pad0 2))
(def pad000 (partial pad0 3))
(defn get-now-str
[]
(let [now (l/local-now)]
(str
(pad00 (t/year now)) "-" (pad00 (t/month now)) "-" (pad00 (t/day now))
" "
(pad00 (t/hour now)) ":" (pad00 (t/minute now)) ":" (pad00 (t/second now))
"." (pad000 (t/milli now)))))
(defn get-space-delimited-values-string
[values]
(apply str (interpose " " values)))
(defn get-log-line
[values]
(str (get-now-str) ": " (get-space-delimited-values-string values) "\n"))
(process/proc-defn
log-proc
[log-line-fn]
(process/receive!
msg (do (log-line-fn msg)
(recur log-line-fn))))
(defn create-log
[log-fn]
(let [log (process/spawn log-proc [(comp log-fn get-log-line)])]
(fn
[& values]
(! log values))))
and here's a demo of using it:
(ns otplike-log.core
(:require [otplike-log.log :as l])
(:gen-class))
(defn doit
[this-many-times moniker sleep-ms log]
(doall (for [n (range this-many-times)]
(do
(log moniker n)
(Thread/sleep sleep-ms)))))
(def doit-slow (partial doit 10 "slow" 1000))
(def doit-fast (partial doit 20 "fast" 500))
(defn log-to-file
[log-file-spec]
(fn
[log-line]
(spit log-file-spec log-line :append true)))
(defn example-1
[log]
(log
"one"
(+ 1 2)
(apply str (interpose "," "three")))
(doseq [log-message (range 10)]
(log log-message)))
(defn example-2
[log]
(future (doit-fast log))
(doit-slow log))
(defn -main
[& args]
(let [log (l/create-log (log-to-file "log.txt"))]
(example-1 log)
(example-2 log)))
Running "-main" produces something like:
2017-09-08 15:18:15.799: one 3 t,h,r,e,e
2017-09-08 15:18:15.801: 0
2017-09-08 15:18:15.801: 1
2017-09-08 15:18:15.802: 2
2017-09-08 15:18:15.803: 3
2017-09-08 15:18:15.803: 4
2017-09-08 15:18:15.804: 5
2017-09-08 15:18:15.804: 6
2017-09-08 15:18:15.805: 7
2017-09-08 15:18:15.806: 8
2017-09-08 15:18:15.806: 9
2017-09-08 15:18:15.807: fast 0
2017-09-08 15:18:15.807: slow 0
2017-09-08 15:18:16.301: fast 1
2017-09-08 15:18:16.801: slow 1
2017-09-08 15:18:16.802: fast 2
2017-09-08 15:18:17.302: fast 3
2017-09-08 15:18:17.801: slow 2
2017-09-08 15:18:17.803: fast 4
2017-09-08 15:18:18.303: fast 5
2017-09-08 15:18:18.802: slow 3
2017-09-08 15:18:18.803: fast 6
2017-09-08 15:18:19.304: fast 7
2017-09-08 15:18:19.803: slow 4
2017-09-08 15:18:19.804: fast 8
2017-09-08 15:18:20.305: fast 9
2017-09-08 15:18:20.803: slow 5
2017-09-08 15:18:20.805: fast 10
2017-09-08 15:18:21.305: fast 11
2017-09-08 15:18:21.804: slow 6
2017-09-08 15:18:21.806: fast 12
2017-09-08 15:18:22.307: fast 13
2017-09-08 15:18:22.804: slow 7
2017-09-08 15:18:22.807: fast 14
2017-09-08 15:18:23.307: fast 15
2017-09-08 15:18:23.805: slow 8
2017-09-08 15:18:23.808: fast 16
2017-09-08 15:18:24.308: fast 17
2017-09-08 15:18:24.805: slow 9
2017-09-08 15:18:24.809: fast 18
2017-09-08 15:18:25.309: fast 19
Here's some code to implement a simple otplike logging system:
and here's a demo of using it:
Running "-main" produces something like: