-
-
Save martinklepsch/0a146f46dfc7a304eaec0f348e5a5d36 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns icebreaker.util.sentry | |
{:clj-kondo/config '{:linters | |
{:unresolved-symbol {:exclude [sentry]} | |
:unresolved-namespace {:exclude [sentry]}}}} | |
(:require #?(:node ["@sentry/node" :as sentry] | |
:browser ["@sentry/browser" :as sentry]) | |
#?@(:cljs [[promesa.core :as p] | |
[icebreaker.config :as config] | |
[icebreaker.model :as model]]))) | |
#?(:cljs | |
(do | |
(defn dsn | |
[] | |
(when-let [{:keys [public-key | |
host | |
project-id]} config/sentry-config] | |
(str "https://" public-key "@" host "/" project-id))) | |
(defn init | |
[] | |
(when-let [d (dsn)] | |
(println "[init] sentry" config/ENV config/RELEASE (:project-name config/sentry-config)) | |
(sentry/init #js {:dsn d | |
:release config/RELEASE | |
:environment config/ENV}) | |
true)) | |
(defn set-user! | |
[user] | |
(some-> ^js sentry | |
(.configureScope (fn [^js scope] | |
(.setUser scope (clj->js user)))))) | |
(defn set-event! | |
[event-id event] | |
(some-> ^js sentry | |
(.configureScope (fn [^js scope] | |
(.setTag scope "event.id" event-id))))) | |
(defn set-ex-data! | |
"When passed an instance of `ExceptionInfo` this will add the data | |
attached to the exception object as additional context on the error. | |
If the exception data contains a `:name` key that will be used as the | |
exception class that is visible most prominently in Sentry." | |
;; This could eventually replace things like `set-event!` above by | |
;; supporting a `:tags` key which sets the appropriate tags w/ setTag. | |
[e] | |
(when (instance? ExceptionInfo e) | |
(some->> e ex-data :name (set! (.-name e))) | |
(.configureScope ^js sentry (fn [^js scope] | |
(.setExtra scope "ex-data" (pr-str (dissoc (ex-data e) :name))))))) | |
(defn capture-message! [msg] | |
(.captureMessage ^js sentry msg) | |
nil) | |
(defn capture! | |
[e] | |
(if-not (.. ^js sentry (getCurrentHub) (getClient)) | |
(js/console.log "No client: Sentry not initialized for error:" e) | |
(do | |
(js/console.log "Reporting error to Sentry:" (.-message e)) | |
(set-ex-data! e) | |
(.captureException ^js sentry e) | |
;; .flush will ensure errors are written to sentry before exiting | |
;; https://docs.sentry.io/error-reporting/configuration/draining/?platform=javascript | |
;; TODO investigate not rethrowing to improve function performance | |
;; NOTE would probably require a refactor of how we do middleware | |
;; https://cloud.google.com/functions/docs/monitoring/error-reporting | |
(-> (.flush ^js sentry 10000) | |
(.then #(throw e)))))) | |
(defn wrap-capture! | |
[f] | |
(fn [& args] | |
(try | |
(let [ret (apply f args)] | |
(if (p/promise? ret) | |
(.catch ret capture!) | |
ret)) | |
(catch js/Error e (capture! e))))) | |
(def log-level | |
{:critical "critical" | |
:fatal "fatal" | |
:error "error" | |
:warn "warning" | |
:info "info" | |
:debug "debug" | |
:log "log"}) | |
(defn breadcrumb! | |
[{:keys [category | |
level | |
message | |
data] | |
:or {category "log" | |
level :info}}] | |
(let [slevel (get log-level level)] | |
(assert slevel (str "invalid sentry log level" level)) | |
(some-> ^js sentry | |
(.addBreadcrumb #js {:category category | |
:level slevel | |
:message message | |
:data data})))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment