🎉 Add unified logging api.

This commit is contained in:
Andrey Antukh 2021-09-29 16:39:25 +02:00 committed by Alonso Torres
parent 2eccf77986
commit b64d5ef357
54 changed files with 361 additions and 413 deletions

View file

@ -17,6 +17,7 @@
{:exclude-files {:exclude-files
["data_readers.clj" ["data_readers.clj"
"app/util/perf.cljs" "app/util/perf.cljs"
"app/common/logging.cljc"
"app/common/exceptions.cljc"]} "app/common/exceptions.cljc"]}
:linters :linters

View file

@ -7,13 +7,13 @@
(ns app.cli.fixtures (ns app.cli.fixtures
"A initial fixtures." "A initial fixtures."
(:require (:require
[app.common.logging :as l]
[app.common.pages :as cp] [app.common.pages :as cp]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.db :as db] [app.db :as db]
[app.main :as main] [app.main :as main]
[app.rpc.mutations.profile :as profile] [app.rpc.mutations.profile :as profile]
[app.util.blob :as blob] [app.util.blob :as blob]
[app.util.logging :as l]
[buddy.hashers :as hashers] [buddy.hashers :as hashers]
[integrant.core :as ig])) [integrant.core :as ig]))

View file

@ -7,11 +7,11 @@
(ns app.cli.manage (ns app.cli.manage
"A manage cli api." "A manage cli api."
(:require (:require
[app.common.logging :as l]
[app.db :as db] [app.db :as db]
[app.main :as main] [app.main :as main]
[app.rpc.mutations.profile :as profile] [app.rpc.mutations.profile :as profile]
[app.rpc.queries.profile :refer [retrieve-profile-data-by-email]] [app.rpc.queries.profile :refer [retrieve-profile-data-by-email]]
[app.util.logging :as l]
[clojure.string :as str] [clojure.string :as str]
[clojure.tools.cli :refer [parse-opts]] [clojure.tools.cli :refer [parse-opts]]
[integrant.core :as ig]) [integrant.core :as ig])

View file

@ -6,12 +6,12 @@
(ns app.cli.migrate-media (ns app.cli.migrate-media
(:require (:require
[app.common.logging :as l]
[app.common.media :as cm] [app.common.media :as cm]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
[app.main :as main] [app.main :as main]
[app.storage :as sto] [app.storage :as sto]
[app.util.logging :as l]
[cuerdas.core :as str] [cuerdas.core :as str]
[datoteka.core :as fs] [datoteka.core :as fs]
[integrant.core :as ig])) [integrant.core :as ig]))

View file

@ -9,13 +9,13 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.transit :as t] [app.common.transit :as t]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.db.sql :as sql] [app.db.sql :as sql]
[app.metrics :as mtx] [app.metrics :as mtx]
[app.util.json :as json] [app.util.json :as json]
[app.util.logging :as l]
[app.util.migrations :as mg] [app.util.migrations :as mg]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.java.io :as io] [clojure.java.io :as io]

View file

@ -7,12 +7,12 @@
(ns app.emails (ns app.emails
"Main api for send emails." "Main api for send emails."
(:require (:require
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
[app.db.sql :as sql] [app.db.sql :as sql]
[app.util.emails :as emails] [app.util.emails :as emails]
[app.util.logging :as l]
[app.worker :as wrk] [app.worker :as wrk]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[integrant.core :as ig])) [integrant.core :as ig]))

View file

@ -8,11 +8,11 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.http.errors :as errors] [app.http.errors :as errors]
[app.http.middleware :as middleware] [app.http.middleware :as middleware]
[app.metrics :as mtx] [app.metrics :as mtx]
[app.util.logging :as l]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[integrant.core :as ig] [integrant.core :as ig]
[reitit.ring :as rr] [reitit.ring :as rr]

View file

@ -8,10 +8,10 @@
"AWS SNS webhook handler for bounces." "AWS SNS webhook handler for bounces."
(:require (:require
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.db :as db] [app.db :as db]
[app.db.sql :as sql] [app.db.sql :as sql]
[app.util.http :as http] [app.util.http :as http]
[app.util.logging :as l]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[cuerdas.core :as str] [cuerdas.core :as str]
[integrant.core :as ig] [integrant.core :as ig]

View file

@ -9,8 +9,8 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.util.logging :as l]
[clojure.pprint] [clojure.pprint]
[cuerdas.core :as str])) [cuerdas.core :as str]))

View file

@ -6,10 +6,10 @@
(ns app.http.middleware (ns app.http.middleware
(:require (:require
[app.common.logging :as l]
[app.common.transit :as t] [app.common.transit :as t]
[app.metrics :as mtx] [app.metrics :as mtx]
[app.util.json :as json] [app.util.json :as json]
[app.util.logging :as l]
[buddy.core.codecs :as bc] [buddy.core.codecs :as bc]
[buddy.core.hash :as bh] [buddy.core.hash :as bh]
[clojure.java.io :as io] [clojure.java.io :as io]

View file

@ -8,6 +8,7 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.uri :as u] [app.common.uri :as u]
[app.config :as cf] [app.config :as cf]
@ -15,7 +16,6 @@
[app.loggers.audit :as audit] [app.loggers.audit :as audit]
[app.rpc.queries.profile :as profile] [app.rpc.queries.profile :as profile]
[app.util.http :as http] [app.util.http :as http]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.data.json :as json] [clojure.data.json :as json]
[clojure.set :as set] [clojure.set :as set]

View file

@ -8,11 +8,11 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.config :as cfg] [app.config :as cfg]
[app.db :as db] [app.db :as db]
[app.metrics :as mtx] [app.metrics :as mtx]
[app.util.async :as aa] [app.util.async :as aa]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[app.worker :as wrk] [app.worker :as wrk]
[clojure.core.async :as a] [clojure.core.async :as a]

View file

@ -9,6 +9,7 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.transit :as t] [app.common.transit :as t]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
@ -16,7 +17,6 @@
[app.db :as db] [app.db :as db]
[app.util.async :as aa] [app.util.async :as aa]
[app.util.http :as http] [app.util.http :as http]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[app.worker :as wrk] [app.worker :as wrk]
[clojure.core.async :as a] [clojure.core.async :as a]

View file

@ -8,12 +8,12 @@
"A specific logger impl that persists errors on the database." "A specific logger impl that persists errors on the database."
(:require (:require
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
[app.util.async :as aa] [app.util.async :as aa]
[app.util.logging :as l]
[app.util.template :as tmpl] [app.util.template :as tmpl]
[app.worker :as wrk] [app.worker :as wrk]
[clojure.core.async :as a] [clojure.core.async :as a]

View file

@ -7,12 +7,12 @@
(ns app.loggers.loki (ns app.loggers.loki
"A Loki integration." "A Loki integration."
(:require (:require
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.config :as cfg] [app.config :as cfg]
[app.util.async :as aa] [app.util.async :as aa]
[app.util.http :as http] [app.util.http :as http]
[app.util.json :as json] [app.util.json :as json]
[app.util.logging :as l]
[app.worker :as wrk] [app.worker :as wrk]
[clojure.core.async :as a] [clojure.core.async :as a]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]

View file

@ -7,13 +7,13 @@
(ns app.loggers.mattermost (ns app.loggers.mattermost
"A mattermost integration for error reporting." "A mattermost integration for error reporting."
(:require (:require
[app.common.logging :as l]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
[app.loggers.database :as ldb] [app.loggers.database :as ldb]
[app.util.async :as aa] [app.util.async :as aa]
[app.util.http :as http] [app.util.http :as http]
[app.util.json :as json] [app.util.json :as json]
[app.util.logging :as l]
[app.worker :as wrk] [app.worker :as wrk]
[clojure.core.async :as a] [clojure.core.async :as a]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]

View file

@ -7,11 +7,11 @@
(ns app.loggers.sentry (ns app.loggers.sentry
"A mattermost integration for error reporting." "A mattermost integration for error reporting."
(:require (:require
[app.common.logging :as l]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
[app.util.async :as aa] [app.util.async :as aa]
[app.util.logging :as l]
[app.worker :as wrk] [app.worker :as wrk]
[clojure.core.async :as a] [clojure.core.async :as a]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]

View file

@ -7,9 +7,9 @@
(ns app.loggers.zmq (ns app.loggers.zmq
"A generic ZMQ listener." "A generic ZMQ listener."
(:require (:require
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.util.json :as json] [app.util.json :as json]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.core.async :as a] [clojure.core.async :as a]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]

View file

@ -6,8 +6,8 @@
(ns app.main (ns app.main
(:require (:require
[app.common.logging :as l]
[app.config :as cf] [app.config :as cf]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[integrant.core :as ig])) [integrant.core :as ig]))

View file

@ -7,7 +7,7 @@
(ns app.metrics (ns app.metrics
(:require (:require
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.util.logging :as l] [app.common.logging :as l]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[integrant.core :as ig]) [integrant.core :as ig])
(:import (:import

View file

@ -8,10 +8,10 @@
"The msgbus abstraction implemented using redis as underlying backend." "The msgbus abstraction implemented using redis as underlying backend."
(:require (:require
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.config :as cfg] [app.config :as cfg]
[app.util.blob :as blob] [app.util.blob :as blob]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.core.async :as a] [clojure.core.async :as a]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]

View file

@ -7,12 +7,12 @@
(ns app.notifications (ns app.notifications
"A websocket based notifications mechanism." "A websocket based notifications mechanism."
(:require (:require
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.transit :as t] [app.common.transit :as t]
[app.db :as db] [app.db :as db]
[app.metrics :as mtx] [app.metrics :as mtx]
[app.util.async :as aa] [app.util.async :as aa]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[app.worker :as wrk] [app.worker :as wrk]
[clojure.core.async :as a] [clojure.core.async :as a]

View file

@ -8,12 +8,12 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.db :as db] [app.db :as db]
[app.loggers.audit :as audit] [app.loggers.audit :as audit]
[app.metrics :as mtx] [app.metrics :as mtx]
[app.rlimits :as rlm] [app.rlimits :as rlm]
[app.util.logging :as l]
[app.util.services :as sv] [app.util.services :as sv]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[cuerdas.core :as str] [cuerdas.core :as str]

View file

@ -7,13 +7,13 @@
(ns app.rpc.mutations.ldap (ns app.rpc.mutations.ldap
(:require (:require
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.config :as cfg] [app.config :as cfg]
[app.db :as db] [app.db :as db]
[app.loggers.audit :as audit] [app.loggers.audit :as audit]
[app.rpc.mutations.profile :as profile-m] [app.rpc.mutations.profile :as profile-m]
[app.rpc.queries.profile :as profile-q] [app.rpc.queries.profile :as profile-q]
[app.util.logging :as l]
[app.util.services :as sv] [app.util.services :as sv]
[clj-ldap.client :as ldap] [clj-ldap.client :as ldap]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]

View file

@ -7,9 +7,9 @@
(ns app.srepl (ns app.srepl
"Server Repl." "Server Repl."
(:require (:require
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.srepl.main] [app.srepl.main]
[app.util.logging :as l]
[clojure.core.server :as ccs] [clojure.core.server :as ccs]
[clojure.main :as cm] [clojure.main :as cm]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]

View file

@ -9,6 +9,7 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.db :as db] [app.db :as db]
@ -16,7 +17,6 @@
[app.storage.fs :as sfs] [app.storage.fs :as sfs]
[app.storage.impl :as impl] [app.storage.impl :as impl]
[app.storage.s3 :as ss3] [app.storage.s3 :as ss3]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[app.worker :as wrk] [app.worker :as wrk]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]

View file

@ -9,10 +9,10 @@
objects from files. A file is ellegible to be garbage collected objects from files. A file is ellegible to be garbage collected
after some period of inactivity (the default threshold is 72h)." after some period of inactivity (the default threshold is 72h)."
(:require (:require
[app.common.logging :as l]
[app.common.pages.migrations :as pmg] [app.common.pages.migrations :as pmg]
[app.db :as db] [app.db :as db]
[app.util.blob :as blob] [app.util.blob :as blob]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[integrant.core :as ig])) [integrant.core :as ig]))

View file

@ -7,11 +7,11 @@
(ns app.tasks.file-offload (ns app.tasks.file-offload
"A maintenance task that offloads file data to an external storage (S3)." "A maintenance task that offloads file data to an external storage (S3)."
(:require (:require
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.db :as db] [app.db :as db]
[app.storage :as sto] [app.storage :as sto]
[app.storage.impl :as simpl] [app.storage.impl :as simpl]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[integrant.core :as ig])) [integrant.core :as ig]))

View file

@ -8,8 +8,8 @@
"A maintenance task that performs a garbage collection of the file "A maintenance task that performs a garbage collection of the file
change (transaction) log." change (transaction) log."
(:require (:require
[app.common.logging :as l]
[app.db :as db] [app.db :as db]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[integrant.core :as ig])) [integrant.core :as ig]))

View file

@ -8,11 +8,11 @@
"A maintenance task that performs a general purpose garbage collection "A maintenance task that performs a general purpose garbage collection
of deleted objects." of deleted objects."
(:require (:require
[app.common.logging :as l]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
[app.storage :as sto] [app.storage :as sto]
[app.storage.impl :as simpl] [app.storage.impl :as simpl]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[cuerdas.core :as str] [cuerdas.core :as str]

View file

@ -8,8 +8,8 @@
"A maintenance task that performs a cleanup of already executed tasks "A maintenance task that performs a cleanup of already executed tasks
from the database table." from the database table."
(:require (:require
[app.common.logging :as l]
[app.db :as db] [app.db :as db]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[integrant.core :as ig])) [integrant.core :as ig]))

View file

@ -1,110 +0,0 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) UXBOX Labs SL
(ns app.util.logging
(:require
[clojure.pprint :refer [pprint]])
(:import
org.apache.logging.log4j.Level
org.apache.logging.log4j.LogManager
org.apache.logging.log4j.Logger
org.apache.logging.log4j.ThreadContext
org.apache.logging.log4j.message.MapMessage
org.apache.logging.log4j.spi.LoggerContext))
(defn build-map-message
[m]
(let [message (MapMessage. (count m))]
(reduce-kv #(.with ^MapMessage %1 (name %2) %3) message m)))
(defprotocol ILogger
(-enabled? [logger level])
(-write! [logger level throwable message]))
(def logger-context
(LogManager/getContext false))
(def logging-agent
(agent nil :error-mode :continue))
(defn get-logger
[lname]
(.getLogger ^LoggerContext logger-context ^String lname))
(defn get-level
[level]
(case level
:trace Level/TRACE
:debug Level/DEBUG
:info Level/INFO
:warn Level/WARN
:error Level/ERROR
:fatal Level/FATAL))
(defn enabled?
[logger level]
(.isEnabled ^Logger logger ^Level level))
(defn write-log!
[logger level e msg]
(if e
(.log ^Logger logger
^Level level
^Object msg
^Throwable e)
(.log ^Logger logger
^Level level
^Object msg)))
(defmacro log
[& {:keys [level cause ::logger ::async ::raw] :as props}]
(let [props (dissoc props :level :cause ::logger ::async ::raw)
logger (or logger (str *ns*))
logger-sym (gensym "log")
level-sym (gensym "log")]
`(let [~logger-sym (get-logger ~logger)
~level-sym (get-level ~level)]
(if (enabled? ~logger-sym ~level-sym)
~(if async
`(send-off logging-agent
(fn [_#]
(let [message# (or ~raw (build-map-message ~props))]
(write-log! ~logger-sym ~level-sym ~cause message#))))
`(let [message# (or ~raw (build-map-message ~props))]
(write-log! ~logger-sym ~level-sym ~cause message#)))))))
(defmacro info
[& params]
`(log :level :info ~@params))
(defmacro error
[& params]
`(log :level :error ~@params))
(defmacro warn
[& params]
`(log :level :warn ~@params))
(defmacro debug
[& params]
`(log :level :debug ~@params))
(defmacro trace
[& params]
`(log :level :trace ~@params))
(defn update-thread-context!
[data]
(run! (fn [[key val]]
(ThreadContext/put
(name key)
(cond
(coll? val)
(binding [clojure.pprint/*print-right-margin* 120]
(with-out-str (pprint val)))
(instance? clojure.lang.Named val) (name val)
:else (str val))))
data))

View file

@ -6,7 +6,7 @@
(ns app.util.migrations (ns app.util.migrations
(:require (:require
[app.util.logging :as l] [app.common.logging :as l]
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[next.jdbc :as jdbc])) [next.jdbc :as jdbc]))

View file

@ -9,12 +9,12 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.db :as db] [app.db :as db]
[app.metrics :as mtx] [app.metrics :as mtx]
[app.util.async :as aa] [app.util.async :as aa]
[app.util.logging :as l]
[app.util.time :as dt] [app.util.time :as dt]
[clojure.core.async :as a] [clojure.core.async :as a]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]

View file

@ -0,0 +1,297 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) UXBOX Labs SL
(ns app.common.logging
(:require
[app.common.exceptions :as ex]
[clojure.pprint :refer [pprint]]
[cuerdas.core :as str]
#?(:cljs [goog.log :as glog]))
#?(:cljs (:require-macros [app.common.logging]))
#?(:clj
(:import
org.apache.logging.log4j.Level
org.apache.logging.log4j.LogManager
org.apache.logging.log4j.Logger
org.apache.logging.log4j.ThreadContext
org.apache.logging.log4j.message.MapMessage
org.apache.logging.log4j.spi.LoggerContext)))
#?(:clj
(defn build-map-message
[m]
(let [message (MapMessage. (count m))]
(reduce-kv #(.with ^MapMessage %1 (name %2) %3) message m))))
#?(:clj
(def logger-context
(LogManager/getContext false)))
#?(:clj
(def logging-agent
(agent nil :error-mode :continue)))
(defn get-logger
[lname]
#?(:clj (.getLogger ^LoggerContext logger-context ^String lname)
:cljs
(glog/getLogger
(cond
(string? lname) lname
(= lname :root) ""
(simple-ident? lname) (name lname)
(qualified-ident? lname) (str (namespace lname) "." (name lname))
:else (str lname)))))
(defn get-level
[level]
#?(:clj
(case level
:trace Level/TRACE
:debug Level/DEBUG
:info Level/INFO
:warn Level/WARN
:error Level/ERROR
:fatal Level/FATAL)
:cljs
(case level
:off (.-OFF ^js glog/Level)
:shout (.-SHOUT ^js glog/Level)
:error (.-SEVERE ^js glog/Level)
:severe (.-SEVERE ^js glog/Level)
:warning (.-WARNING ^js glog/Level)
:warn (.-WARNING ^js glog/Level)
:info (.-INFO ^js glog/Level)
:config (.-CONFIG ^js glog/Level)
:debug (.-FINE ^js glog/Level)
:fine (.-FINE ^js glog/Level)
:finer (.-FINER ^js glog/Level)
:trace (.-FINER ^js glog/Level)
:finest (.-FINEST ^js glog/Level)
:all (.-ALL ^js glog/Level))))
(defn write-log!
[logger level exception message]
#?(:clj
(if exception
(.log ^Logger logger
^Level level
^Object message
^Throwable exception)
(.log ^Logger logger
^Level level
^Object message))
:cljs
(when glog/ENABLED
(when-let [l (get-logger logger)]
(let [level (get-level level)
record (glog/LogRecord. level message (.getName ^js l))]
(when exception (.setException record exception))
(glog/publishLogRecord l record))))))
#?(:clj
(defn enabled?
[logger level]
(.isEnabled ^Logger logger ^Level level)))
(defmacro log
[& {:keys [level cause ::logger ::async ::raw] :as props}]
(if (:ns &env) ; CLJS
`(write-log! ~(or logger (str *ns*))
~level
~cause
~(dissoc props :level :cause ::logger ::raw))
(let [props (dissoc props :level :cause ::logger ::async ::raw)
logger (or logger (str *ns*))
logger-sym (gensym "log")
level-sym (gensym "log")]
`(let [~logger-sym (get-logger ~logger)
~level-sym (get-level ~level)]
(if (enabled? ~logger-sym ~level-sym)
~(if async
`(send-off logging-agent
(fn [_#]
(let [message# (or ~raw (build-map-message ~props))]
(write-log! ~logger-sym ~level-sym ~cause message#))))
`(let [message# (or ~raw (build-map-message ~props))]
(write-log! ~logger-sym ~level-sym ~cause message#))))))))
(defmacro info
[& params]
`(log :level :info ~@params))
(defmacro error
[& params]
`(log :level :error ~@params))
(defmacro warn
[& params]
`(log :level :warn ~@params))
(defmacro debug
[& params]
`(log :level :debug ~@params))
(defmacro trace
[& params]
`(log :level :trace ~@params))
(defmacro set-level!
([level]
(when (:ns &env)
`(set-level* ~(str *ns*) ~level)))
([n level]
(when (:ns &env)
`(set-level* ~n ~level))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; CLJ Specific
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#?(:clj
(defn update-thread-context!
[data]
(run! (fn [[key val]]
(ThreadContext/put
(name key)
(cond
(coll? val)
(binding [clojure.pprint/*print-right-margin* 120]
(with-out-str (pprint val)))
(instance? clojure.lang.Named val) (name val)
:else (str val))))
data)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; CLJS Specific
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#?(:cljs
(def ^:private colors
{:gray3 "#8e908c"
:gray4 "#969896"
:gray5 "#4d4d4c"
:gray6 "#282a2e"
:black "#1d1f21"
:red "#c82829"
:blue "#4271ae"
:orange "#f5871f"}))
#?(:cljs
(defn- level->color
[level]
(letfn [(get-level-value [l] (.-value ^js (get-level l)))]
(condp <= (get-level-value level)
(get-level-value :error) (get colors :red)
(get-level-value :warn) (get colors :orange)
(get-level-value :info) (get colors :blue)
(get-level-value :debug) (get colors :gray4)
(get-level-value :trace) (get colors :gray3)
(get colors :gray2)))))
#?(:cljs
(defn- level->short-name
[l]
(case l
:fine "DBG"
:debug "DBG"
:finer "TRC"
:trace "TRC"
:info "INF"
:warn "WRN"
:warning "WRN"
:error "ERR"
(subs (.-name ^js (get-level l)) 0 3))))
#?(:cljs
(defn set-level*
"Set the level (a keyword) of the given logger, identified by name."
[name lvl]
(some-> (get-logger name)
(glog/setLevel (get-level lvl)))))
#?(:cljs
(defn set-levels!
[lvls]
(doseq [[logger level] lvls
:let [level (if (string? level) (keyword level) level)]]
(set-level* logger level))))
#?(:cljs
(defn- prepare-message
[message]
(loop [kvpairs (seq message)
message (array-map)
specials []]
(if (nil? kvpairs)
[message specials]
(let [[k v] (first kvpairs)]
(cond
(= k :err)
(recur (next kvpairs)
message
(conj specials [:error nil v]))
(and (qualified-ident? k)
(= "js" (namespace k)))
(recur (next kvpairs)
message
(conj specials [:js (name k) (if (object? v) v (clj->js v))]))
:else
(recur (next kvpairs)
(assoc message k v)
specials)))))))
#?(:cljs
(defn default-handler
[{:keys [message level logger-name]}]
(let [header-styles (str "font-weight: 600; color: " (level->color level))
normal-styles (str "font-weight: 300; color: " (get colors :gray6))
level-name (level->short-name level)
header (str "%c" level-name " [" logger-name "] ")]
(if (string? message)
(let [message (str header "%c" message)]
(js/console.log message header-styles normal-styles))
(let [[message specials] (prepare-message message)]
(if (seq specials)
(let [message (str header "%c" (pr-str message))]
(js/console.group message header-styles normal-styles)
(doseq [[type n v] specials]
(case type
:js (js/console.log n v)
:error (if (ex/ex-info? v)
(js/console.error (pr-str v))
(js/console.error v))))
(js/console.groupEnd message))
(let [message (str header "%c" (pr-str message))]
(js/console.log message header-styles normal-styles))))))))
#?(:cljs
(defn record->map
[^js record]
{:seqn (.-sequenceNumber_ record)
:time (.-time_ record)
:level (keyword (str/lower (.-name (.-level_ record))))
:message (.-msg_ record)
:logger-name (.-loggerName_ record)
:exception (.-exception_ record)}))
#?(:cljs
(defonce default-console-handler
(comp default-handler record->map)))
#?(:cljs
(defn initialize!
[]
(let [l (get-logger :root)]
(glog/removeHandler l default-console-handler)
(glog/addHandler l default-console-handler)
nil)))

View file

@ -10,6 +10,7 @@
[app.common.spec :as us] [app.common.spec :as us]
[app.common.uri :as u] [app.common.uri :as u]
[app.common.version :as v] [app.common.version :as v]
[app.common.logging :as log]
[app.util.avatars :as avatars] [app.util.avatars :as avatars]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.globals :refer [global location]] [app.util.globals :refer [global location]]
@ -102,10 +103,6 @@
(not (str/ends-with? (:path uri) "/")) (not (str/ends-with? (:path uri) "/"))
(update :path #(str % "/"))))) (update :path #(str % "/")))))
(when (= :browser @target)
(js/console.log
(str/format "Welcome to penpot! version='%s' base-uri='%s'." (:full @version) (str public-uri))))
;; --- Helper Functions ;; --- Helper Functions
(defn ^boolean check-browser? [candidate] (defn ^boolean check-browser? [candidate]

View file

@ -6,9 +6,10 @@
(ns app.main (ns app.main
(:require (:require
[app.common.logging :as log]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cfg] [app.config :as cf]
[app.main.data.events :as ev] [app.main.data.events :as ev]
[app.main.data.messages :as dm] [app.main.data.messages :as dm]
[app.main.data.users :as du] [app.main.data.users :as du]
@ -20,7 +21,6 @@
[app.main.worker] [app.main.worker]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n] [app.util.i18n :as i18n]
[app.util.logging :as log]
[app.util.router :as rt] [app.util.router :as rt]
[app.util.storage :refer [storage]] [app.util.storage :refer [storage]]
[app.util.theme :as theme] [app.util.theme :as theme]
@ -33,6 +33,11 @@
(log/set-level! :root :warn) (log/set-level! :root :warn)
(log/set-level! :app :info) (log/set-level! :app :info)
(when (= :browser @cf/target)
(log/info :message "wecome to penpot" :version (:full @cf/version) :public-uri (str cf/public-uri)))
(declare reinit) (declare reinit)
(s/def ::any any?) (s/def ::any any?)
@ -105,8 +110,8 @@
(defn ^:export init (defn ^:export init
[] []
(sentry/init!) (sentry/init!)
(i18n/init! cfg/translations) (i18n/init! cf/translations)
(theme/init! cfg/themes) (theme/init! cf/themes)
(init-ui) (init-ui)
(st/emit! (initialize))) (st/emit! (initialize)))

View file

@ -8,12 +8,12 @@
(:require (:require
["opentype.js" :as ot] ["opentype.js" :as ot]
[app.common.data :as d] [app.common.data :as d]
[app.common.logging :as log]
[app.common.media :as cm] [app.common.media :as cm]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.main.fonts :as fonts] [app.main.fonts :as fonts]
[app.main.repo :as rp] [app.main.repo :as rp]
[app.util.logging :as log]
[app.util.webapi :as wa] [app.util.webapi :as wa]
[beicon.core :as rx] [beicon.core :as rx]
[cuerdas.core :as str] [cuerdas.core :as str]

View file

@ -8,9 +8,9 @@
(:refer-clojure :exclude [meta reset!]) (:refer-clojure :exclude [meta reset!])
(:require (:require
["mousetrap" :as mousetrap] ["mousetrap" :as mousetrap]
[app.common.logging :as log]
[app.common.spec :as us] [app.common.spec :as us]
[app.config :as cfg] [app.config :as cf]
[app.util.logging :as log]
[cljs.spec.alpha :as s] [cljs.spec.alpha :as s]
[potok.core :as ptk])) [potok.core :as ptk]))
@ -37,7 +37,7 @@
"Adds the control/command modifier to a shortcuts depending on the "Adds the control/command modifier to a shortcuts depending on the
operating system for the user" operating system for the user"
[shortcut] [shortcut]
(if (cfg/check-platform? :macos) (if (cf/check-platform? :macos)
(str "command+" shortcut) (str "command+" shortcut)
(str "ctrl+" shortcut))) (str "ctrl+" shortcut)))
@ -55,12 +55,12 @@
[key] [key]
;; If the key is "+" we need to surround with quotes ;; If the key is "+" we need to surround with quotes
;; otherwise will not be very readable ;; otherwise will not be very readable
(let [key (if (and (not (cfg/check-platform? :macos)) (let [key (if (and (not (cf/check-platform? :macos))
(= key "+")) (= key "+"))
"\"+\"" "\"+\""
key)] key)]
(str (str
(if (cfg/check-platform? :macos) (if (cf/check-platform? :macos)
mac-command mac-command
"Ctrl+") "Ctrl+")
key))) key)))
@ -68,7 +68,7 @@
(defn shift (defn shift
[key] [key]
(str (str
(if (cfg/check-platform? :macos) (if (cf/check-platform? :macos)
mac-shift mac-shift
"Shift+") "Shift+")
key)) key))
@ -76,7 +76,7 @@
(defn alt (defn alt
[key] [key]
(str (str
(if (cfg/check-platform? :macos) (if (cf/check-platform? :macos)
mac-option mac-option
"Alt+") "Alt+")
key)) key))
@ -91,19 +91,19 @@
(defn supr (defn supr
[] []
(if (cfg/check-platform? :macos) (if (cf/check-platform? :macos)
mac-delete mac-delete
"Supr")) "Supr"))
(defn esc (defn esc
[] []
(if (cfg/check-platform? :macos) (if (cf/check-platform? :macos)
mac-esc mac-esc
"Escape")) "Escape"))
(defn enter (defn enter
[] []
(if (cfg/check-platform? :macos) (if (cf/check-platform? :macos)
mac-enter mac-enter
"Enter")) "Enter"))

View file

@ -7,6 +7,7 @@
(ns app.main.data.workspace.changes (ns app.main.data.workspace.changes
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.logging :as log]
[app.common.pages :as cp] [app.common.pages :as cp]
[app.common.pages.spec :as spec] [app.common.pages.spec :as spec]
[app.common.spec :as us] [app.common.spec :as us]
@ -14,7 +15,6 @@
[app.main.data.workspace.undo :as dwu] [app.main.data.workspace.undo :as dwu]
[app.main.store :as st] [app.main.store :as st]
[app.main.worker :as uw] [app.main.worker :as uw]
[app.util.logging :as log]
[beicon.core :as rx] [beicon.core :as rx]
[cljs.spec.alpha :as s] [cljs.spec.alpha :as s]
[potok.core :as ptk])) [potok.core :as ptk]))

View file

@ -7,6 +7,7 @@
(ns app.main.data.workspace.common (ns app.main.data.workspace.common
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.logging :as log]
[app.common.geom.proportions :as gpr] [app.common.geom.proportions :as gpr]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.pages :as cp] [app.common.pages :as cp]
@ -17,7 +18,6 @@
[app.main.data.workspace.undo :as dwu] [app.main.data.workspace.undo :as dwu]
[app.main.streams :as ms] [app.main.streams :as ms]
[app.main.worker :as uw] [app.main.worker :as uw]
[app.util.logging :as log]
[beicon.core :as rx] [beicon.core :as rx]
[cljs.spec.alpha :as s] [cljs.spec.alpha :as s]
[potok.core :as ptk])) [potok.core :as ptk]))

View file

@ -7,6 +7,7 @@
(ns app.main.data.workspace.libraries (ns app.main.data.workspace.libraries
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.logging :as log]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom] [app.common.geom.shapes :as geom]
[app.common.pages :as cp] [app.common.pages :as cp]
@ -21,7 +22,6 @@
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.store :as st] [app.main.store :as st]
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[app.util.logging :as log]
[app.util.router :as rt] [app.util.router :as rt]
[app.util.time :as dt] [app.util.time :as dt]
[beicon.core :as rx] [beicon.core :as rx]

View file

@ -7,13 +7,13 @@
(ns app.main.data.workspace.libraries-helpers (ns app.main.data.workspace.libraries-helpers
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.logging :as log]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom] [app.common.geom.shapes :as geom]
[app.common.pages :as cp] [app.common.pages :as cp]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.text :as txt] [app.common.text :as txt]
[app.main.data.workspace.groups :as dwg] [app.main.data.workspace.groups :as dwg]
[app.util.logging :as log]
[cljs.spec.alpha :as s] [cljs.spec.alpha :as s]
[clojure.set :as set])) [clojure.set :as set]))

View file

@ -9,11 +9,11 @@
(:require-macros [app.main.fonts :refer [preload-gfonts]]) (:require-macros [app.main.fonts :refer [preload-gfonts]])
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.logging :as log]
[app.common.text :as txt] [app.common.text :as txt]
[app.config :as cf] [app.config :as cf]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.http :as http] [app.util.http :as http]
[app.util.logging :as log]
[app.util.object :as obj] [app.util.object :as obj]
[beicon.core :as rx] [beicon.core :as rx]
[clojure.set :as set] [clojure.set :as set]

View file

@ -10,6 +10,7 @@
["@sentry/browser" :as sentry] ["@sentry/browser" :as sentry]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.common.logging :as log]
[app.config :as cf] [app.config :as cf]
[app.main.refs :as refs])) [app.main.refs :as refs]))

View file

@ -18,13 +18,10 @@
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd] [app.util.keyboard :as kbd]
[app.util.logging :as log]
[beicon.core :as rx] [beicon.core :as rx]
[cuerdas.core :as str] [cuerdas.core :as str]
[rumext.alpha :as mf])) [rumext.alpha :as mf]))
(log/set-level! :trace)
(defn- use-set-page-title (defn- use-set-page-title
[team section] [team section]
(mf/use-effect (mf/use-effect

View file

@ -7,6 +7,7 @@
(ns app.main.ui.dashboard.import (ns app.main.ui.dashboard.import
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.logging :as log]
[app.main.data.events :as ev] [app.main.data.events :as ev]
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.store :as st] [app.main.store :as st]
@ -16,7 +17,6 @@
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd] [app.util.keyboard :as kbd]
[app.util.logging :as log]
[beicon.core :as rx] [beicon.core :as rx]
[potok.core :as ptk] [potok.core :as ptk]
[rumext.alpha :as mf])) [rumext.alpha :as mf]))

View file

@ -11,13 +11,10 @@
[app.main.store :as st] [app.main.store :as st]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.dom.dnd :as dnd] [app.util.dom.dnd :as dnd]
[app.util.logging :as log]
[app.util.timers :as ts] [app.util.timers :as ts]
[beicon.core :as rx] [beicon.core :as rx]
[rumext.alpha :as mf])) [rumext.alpha :as mf]))
(log/set-level! :warn)
(defn use-rxsub (defn use-rxsub
[ob] [ob]
(let [[state reset-state!] (mf/useState @ob)] (let [[state reset-state!] (mf/useState @ob)]
@ -101,7 +98,6 @@
subscribe-to-drag-end subscribe-to-drag-end
(fn [] (fn []
(when (nil? (:subscr @state)) (when (nil? (:subscr @state))
;; (js/console.log "subscribing" (:name data))
(swap! state (swap! state
#(assoc % :subscr (rx/sub! global-drag-end cleanup))))) #(assoc % :subscr (rx/sub! global-drag-end cleanup)))))

View file

@ -7,6 +7,7 @@
(ns app.main.ui.share-link (ns app.main.ui.share-link
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.logging :as log]
[app.config :as cf] [app.config :as cf]
[app.main.data.common :as dc] [app.main.data.common :as dc]
[app.main.data.messages :as dm] [app.main.data.messages :as dm]
@ -16,7 +17,6 @@
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.logging :as log]
[app.util.router :as rt] [app.util.router :as rt]
[app.util.webapi :as wapi] [app.util.webapi :as wapi]
[rumext.alpha :as mf])) [rumext.alpha :as mf]))

View file

@ -121,7 +121,6 @@
(fn [] (fn []
(st/emit! (dw/setup-layout layout-name)))) (st/emit! (dw/setup-layout layout-name))))
(mf/use-effect (mf/use-effect
(mf/deps project-id file-id) (mf/deps project-id file-id)
(fn [] (fn []

View file

@ -6,6 +6,7 @@
(ns app.main.ui.workspace.shapes.text (ns app.main.ui.workspace.shapes.text
(:require (:require
[app.common.logging :as log]
[app.common.math :as mth] [app.common.math :as mth]
[app.main.data.workspace.texts :as dwt] [app.main.data.workspace.texts :as dwt]
[app.main.refs :as refs] [app.main.refs :as refs]
@ -13,7 +14,6 @@
[app.main.ui.shapes.shape :refer [shape-container]] [app.main.ui.shapes.shape :refer [shape-container]]
[app.main.ui.shapes.text :as text] [app.main.ui.shapes.text :as text]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.logging :as log]
[app.util.object :as obj] [app.util.object :as obj]
[app.util.text-editor :as ted] [app.util.text-editor :as ted]
[app.util.timers :as timers] [app.util.timers :as timers]

View file

@ -1,46 +0,0 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) UXBOX Labs SL
(ns app.util.logging)
(defn- log-expr [_form level keyvals]
(let [keyvals-map (apply array-map keyvals)
;;formatter (::formatter keyvals-map 'identity)
]
`(log ~(::logger keyvals-map (str *ns*))
~level
~(-> keyvals-map
(dissoc ::logger)
#_(assoc :line (:line (meta form))))
~(:err keyvals-map))))
(defmacro set-level!
([level]
`(set-level* ~(str *ns*) ~level))
([n level]
`(set-level* ~n ~level)))
(defmacro error [& keyvals]
(log-expr &form :error keyvals))
(defmacro warn [& keyvals]
(log-expr &form :warn keyvals))
(defmacro info [& keyvals]
(log-expr &form :info keyvals))
(defmacro debug [& keyvals]
(log-expr &form :debug keyvals))
(defmacro trace [& keyvals]
(log-expr &form :trace keyvals))
(defmacro spy [form]
(let [res (gensym)]
`(let [~res ~form]
~(log-expr &form :debug [:spy `'~form
:=> res])
~res)))

View file

@ -1,189 +0,0 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) UXBOX Labs SL
;;
;; This code is highly inspired on the lambdaisland/glogi library but
;; adapted and simplified to our needs. The adapted code shares the
;; same license. You can found the origianl source code here:
;; https://github.com/lambdaisland/glogi
(ns app.util.logging
(:require
[app.common.exceptions :as ex]
[cuerdas.core :as str]
[goog.log :as glog])
(:require-macros [app.util.logging]))
(defn- logger-name
[s]
(cond
(string? s) s
(= s :root) ""
(simple-ident? s) (name s)
(qualified-ident? s) (str (namespace s) "." (name s))
:else (str s)))
(defn get-logger
[n]
(glog/getLogger (logger-name n)))
(def levels
{:off (.-OFF ^js glog/Level)
:shout (.-SHOUT ^js glog/Level)
:error (.-SEVERE ^js glog/Level)
:severe (.-SEVERE ^js glog/Level)
:warning (.-WARNING ^js glog/Level)
:warn (.-WARNING ^js glog/Level)
:info (.-INFO ^js glog/Level)
:config (.-CONFIG ^js glog/Level)
:debug (.-FINE ^js glog/Level)
:fine (.-FINE ^js glog/Level)
:finer (.-FINER ^js glog/Level)
:trace (.-FINER ^js glog/Level)
:finest (.-FINEST ^js glog/Level)
:all (.-ALL ^js glog/Level)})
(def colors
{:gray3 "#8e908c"
:gray4 "#969896"
:gray5 "#4d4d4c"
:gray6 "#282a2e"
:black "#1d1f21"
:red "#c82829"
:blue "#4271ae"
:orange "#f5871f"})
(defn- get-level-value
[level]
(if (instance? glog/Level level)
(.-value ^js level)
(.-value ^js (get levels level))))
(defn- level->color
[level]
(condp <= (get-level-value level)
(get-level-value :error) (get colors :red)
(get-level-value :warn) (get colors :orange)
(get-level-value :info) (get colors :blue)
(get-level-value :debug) (get colors :gray4)
(get-level-value :trace) (get colors :gray3)
(get colors :gray2)))
(defn- level->short-name
[l]
(case l
:fine "DBG"
:debug "DBG"
:finer "TRC"
:trace "TRC"
:info "INF"
:warn "WRN"
:warning "WRN"
:error "ERR"
(subs (.-name ^js (get levels l)) 0 3)))
(defn- make-log-record
[level message name exception]
(let [record (glog/LogRecord. level message name)]
(when exception (.setException record exception))
record))
(defn log
"Output a log message to the given logger, optionally with an exception to be
logged."
([name lvl message]
(log name lvl message nil))
([name lvl message exception]
(when glog/ENABLED
(when-let [l (get-logger name)]
(glog/publishLogRecord l (make-log-record (get levels lvl) message name exception))))))
(defn set-level*
"Set the level (a keyword) of the given logger, identified by name."
[name lvl]
(assert (contains? levels lvl))
(some-> (get-logger name)
(glog/setLevel (get levels lvl))))
(defn set-levels!
[lvls]
(doseq [[logger level] lvls
:let [level (if (string? level) (keyword level) level)]]
(set-level* logger level)))
(defn record->map
[^js record]
{:seqn (.-sequenceNumber_ record)
:time (.-time_ record)
:level (keyword (str/lower (.-name (.-level_ record))))
:message (.-msg_ record)
:logger-name (.-loggerName_ record)
:exception (.-exception_ record)})
(defn add-handler!
([handler-fn]
(add-handler! :root handler-fn))
([logger-or-name handler-fn]
(when-let [l (get-logger logger-or-name)]
(glog/removeHandler l handler-fn)
(glog/addHandler l handler-fn))))
(defn- prepare-message
[message]
(loop [kvpairs (seq message)
message (array-map)
specials []]
(if (nil? kvpairs)
[message specials]
(let [[k v] (first kvpairs)]
(cond
(= k :err)
(recur (next kvpairs)
message
(conj specials [:error nil v]))
(and (qualified-ident? k)
(= "js" (namespace k)))
(recur (next kvpairs)
message
(conj specials [:js (name k) (if (object? v) v (clj->js v))]))
:else
(recur (next kvpairs)
(assoc message k v)
specials))))))
(defn default-handler
[{:keys [message level logger-name]}]
(let [header-styles (str "font-weight: 600; color: " (level->color level))
normal-styles (str "font-weight: 300; color: " (get colors :gray6))
level-name (level->short-name level)
header (str "%c" level-name " [" logger-name "] ")]
(if (string? message)
(let [message (str header "%c" message)]
(js/console.log message header-styles normal-styles))
(let [[message specials] (prepare-message message)]
(if (seq specials)
(let [message (str header "%c" (pr-str message))]
(js/console.group message header-styles normal-styles)
(doseq [[type n v] specials]
(case type
:js (js/console.log n v)
:error (if (ex/ex-info? v)
(js/console.error (pr-str v))
(js/console.error v))))
(js/console.groupEnd message))
(let [message (str header "%c" (pr-str message))]
(js/console.log message header-styles normal-styles)))))))
(defonce default-console-handler
#(default-handler (record->map %)))
(defn initialize!
[]
(add-handler! :root default-console-handler)
nil)

View file

@ -8,6 +8,7 @@
(:refer-clojure :exclude [resolve]) (:refer-clojure :exclude [resolve])
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.logging :as log]
[app.common.file-builder :as fb] [app.common.file-builder :as fb]
[app.common.pages :as cp] [app.common.pages :as cp]
[app.common.text :as ct] [app.common.text :as ct]
@ -17,7 +18,6 @@
[app.util.http :as http] [app.util.http :as http]
[app.util.import.parser :as cip] [app.util.import.parser :as cip]
[app.util.json :as json] [app.util.json :as json]
[app.util.logging :as log]
[app.util.zip :as uz] [app.util.zip :as uz]
[app.worker.impl :as impl] [app.worker.impl :as impl]
[beicon.core :as rx] [beicon.core :as rx]