{"action":"created","issue":{"url":"https://api.github.com/repos/ptaoussanis/timbre/issues/188","repository_url":"https://api.github.com/repos/ptaoussanis/timbre","labels_url":"https://api.github.com/repos/ptaoussanis/timbre/issues/188/labels{/name}","comments_url":"https://api.github.com/repos/ptaoussanis/timbre/issues/188/comments","events_url":"https://api.github.com/repos/ptaoussanis/timbre/issues/188/events","html_url":"https://github.com/ptaoussanis/timbre/issues/188","id":171057748,"number":188,"title":"Thread safety on println-appender","user":{"login":"azyr","id":3604830,"avatar_url":"https://avatars.githubusercontent.com/u/3604830?v=3","gravatar_id":"","url":"https://api.github.com/users/azyr","html_url":"https://github.com/azyr","followers_url":"https://api.github.com/users/azyr/followers","following_url":"https://api.github.com/users/azyr/following{/other_user}","gists_url":"https://api.github.com/users/azyr/gists{/gist_id}","starred_url":"https://api.github.com/users/azyr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/azyr/subscriptions","organizations_url":"https://api.github.com/users/azyr/orgs","repos_url":"https://api.github.com/users/azyr/repos","events_url":"https://api.github.com/users/azyr/events{/privacy}","received_events_url":"https://api.github.com/users/azyr/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-08-14T13:07:48Z","updated_at":"2016-08-14T13:33:26Z","closed_at":null,"body":"It seems that there are no guarantees that `println` commands are thread safe (no interleaved lines) on `println-appender`. Is there some configuration switch that will assure thread safety or do I need to write a custom appender?"},"comment":{"url":"https://api.github.com/repos/ptaoussanis/timbre/issues/comments/239673812","html_url":"https://github.com/ptaoussanis/timbre/issues/188#issuecomment-239673812","issue_url":"https://api.github.com/repos/ptaoussanis/timbre/issues/188","id":239673812,"user":{"login":"azyr","id":3604830,"avatar_url":"https://avatars.githubusercontent.com/u/3604830?v=3","gravatar_id":"","url":"https://api.github.com/users/azyr","html_url":"https://github.com/azyr","followers_url":"https://api.github.com/users/azyr/followers","following_url":"https://api.github.com/users/azyr/following{/other_user}","gists_url":"https://api.github.com/users/azyr/gists{/gist_id}","starred_url":"https://api.github.com/users/azyr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/azyr/subscriptions","organizations_url":"https://api.github.com/users/azyr/orgs","repos_url":"https://api.github.com/users/azyr/repos","events_url":"https://api.github.com/users/azyr/events{/privacy}","received_events_url":"https://api.github.com/users/azyr/received_events","type":"User","site_admin":false},"created_at":"2016-08-14T13:33:26Z","updated_at":"2016-08-14T13:33:26Z","body":"I created a quick and dirty fix using `locking`. New appender:\r\n\r\n``` clojure\r\n(defn println-appender\r\n  \"Returns a simple `println` appender for Clojure/Script.\r\n  Use with ClojureScript requires that `cljs.core/*print-fn*` be set.\r\n\r\n  :stream (clj only) - e/o #{:auto :*out* :*err* :std-err :std-out <io-stream>}.\"\r\n\r\n  ;; Unfortunately no easy way to check if *print-fn* is set. Metadata on the\r\n  ;; default throwing fn would be nice...\r\n\r\n  [& [{:keys [stream] :or {stream :auto}}]]\r\n  (let [stream (case stream\r\n                 :std-err timbre/default-err\r\n                 :std-out timbre/default-out\r\n                 stream)\r\n        locker (Object.)]\r\n    {:enabled?   true\r\n     :async?     false\r\n     :min-level  nil\r\n     :rate-limit nil\r\n     :output-fn  :inherit\r\n     :fn\r\n     (fn [data]\r\n       (let [{:keys [output_]} data]\r\n         (let [stream (case stream\r\n                        :auto  (if (:error? data) *err* *out*)\r\n                        :*out* *out*\r\n                        :*err* *err*\r\n                        stream)]\r\n           (locking locker (binding [*out* stream] (println (force output_)))))))}))\r\n```"}}
{"actor":{"display_login":"azyr"}}