-
Notifications
You must be signed in to change notification settings - Fork 0
/
gcp.clj
81 lines (72 loc) 路 2.57 KB
/
gcp.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
(ns gcp-ser-clj.gcp
"Clojure wrapper utility around the Google Cloud Error Reporting Java library.
Consider all functions in this namespace private and subject to change."
(:require [clojure.tools.logging :as log])
(:import [com.google.api.gax.rpc
ApiException]
[com.google.auth.oauth2
ServiceAccountCredentials]
[com.google.devtools.clouderrorreporting.v1beta1
ErrorContext
ReportedErrorEvent
ReportErrorsServiceClient
ServiceContext
SourceLocation]))
(defn ^ServiceContext svc-ctx
[{:keys [service-name service-version]}]
(let [builder (ServiceContext/newBuilder)]
(when service-name
(.setService builder service-name))
(when service-version
(.setVersion builder service-version))
(.build builder)))
(defn string-trace
[^Throwable ex]
(with-open [str-w (java.io.StringWriter.)
prn-w (java.io.PrintWriter. str-w)]
(.printStackTrace ex prn-w)
(.toString str-w)))
(defn ^SourceLocation ex->loc
[^Throwable exception]
(let [^StackTraceElement frame (-> exception (.getStackTrace) (nth 0))]
(-> (SourceLocation/newBuilder)
(.setFilePath (.getFileName frame))
(.setLineNumber (.getLineNumber frame))
(.setFunctionName (.getMethodName frame))
(.build))))
(defn ex->error-ctx
[^Throwable exception]
(let [loc (ex->loc exception)]
(-> (ErrorContext/newBuilder)
(.setReportLocation loc)
(.build))))
(defn ^ReportedErrorEvent ex->event
[exception opts]
(-> (ReportedErrorEvent/newBuilder)
(.setServiceContext (svc-ctx opts))
(.setMessage (string-trace exception))
(.build)))
(defn project-from-config
[]
(let [^ServiceAccountCredentials creds
(ServiceAccountCredentials/getApplicationDefault)]
(.getProjectId creds)))
(defn api-call
[^ReportErrorsServiceClient client
^String project-id
^ReportedErrorEvent event-obj]
(try
(.reportErrorEvent client project-id event-obj)
(catch ApiException e
(log/error "Failed to report error to GCP" e))))
(defn report
([exception]
(report exception {}))
([exception {:keys [project-name client] :as opts}]
(let [project-id (format "projects/%s" (name (or project-name
(project-from-config))))
event-obj (ex->event exception opts)]
(if client
(api-call client project-id event-obj)
(with-open [ephemeral-client (ReportErrorsServiceClient/create)]
(api-call ephemeral-client project-id event-obj))))))