|
4 | 4 | [steffan-westcott.clj-otel.api.logs.log-record :as log-record] |
5 | 5 | [steffan-westcott.clj-otel.api.trace.span :as span] |
6 | 6 | [steffan-westcott.clj-otel.context :as context] |
7 | | - [steffan-westcott.clj-otel.instrumentation.api.config :as inst-config]) |
| 7 | + [steffan-westcott.clj-otel.instrumentation.api.config :as inst-config] |
| 8 | + [steffan-westcott.clj-otel.instrumentation.api.config.logging :as config-logging] |
| 9 | + [steffan-westcott.clj-otel.util :as util]) |
8 | 10 | (:import (io.opentelemetry.api.baggage BaggageEntry) |
9 | 11 | (io.opentelemetry.api.logs Severity) |
10 | 12 | (io.opentelemetry.api.trace Span SpanContext TraceFlags TraceState) |
11 | 13 | (io.opentelemetry.semconv.incubating ThreadIncubatingAttributes) |
12 | 14 | (java.util.concurrent TimeUnit) |
13 | | - (org.apache.logging.log4j Level) |
14 | 15 | (org.apache.logging.log4j.core LogEvent) |
15 | 16 | (org.apache.logging.log4j.core.time Instant) |
16 | 17 | (org.apache.logging.log4j.message MapMessage Message) |
|
24 | 25 | StandardLevel/INFO Severity/INFO |
25 | 26 | StandardLevel/WARN Severity/WARN |
26 | 27 | StandardLevel/ERROR Severity/ERROR |
27 | | - StandardLevel/FATAL Severity/FATAL |
28 | | - StandardLevel/OFF Severity/UNDEFINED_SEVERITY_NUMBER}) |
29 | | - |
30 | | -(defn- trace-id-key |
31 | | - [] |
32 | | - (inst-config/get-string "otel.instrumentation.common.logging.trace-id" "trace_id")) |
33 | | - |
34 | | -(defn- span-id-key |
35 | | - [] |
36 | | - (inst-config/get-string "otel.instrumentation.common.logging.span-id" "span_id")) |
37 | | - |
38 | | -(defn- trace-flags-key |
39 | | - [] |
40 | | - (inst-config/get-string "otel.instrumentation.common.logging.trace-flags" "trace_flags")) |
| 28 | + StandardLevel/FATAL Severity/FATAL}) |
41 | 29 |
|
42 | 30 | (defn- add-baggage? |
43 | 31 | [] |
44 | 32 | (inst-config/get-boolean "otel.instrumentation.log4j-context-data.add-baggage" false)) |
45 | 33 |
|
46 | | -(defn- assoc-all! |
47 | | - [m kvs] |
48 | | - (reduce (fn [m [k v]] |
49 | | - (assoc! m k v)) |
50 | | - m |
51 | | - kvs)) |
52 | | - |
53 | 34 | (defn context-data |
54 | 35 | "Returns a string map to add to Log4j context data. This includes trace id, |
55 | 36 | span id, trace flags and baggage (if enabled). The data is taken from the |
56 | 37 | span in the bound or current context." |
57 | 38 | [] |
58 | 39 | (let [span-context (span/get-span-context)] |
59 | | - (if (.isValid span-context) |
60 | | - (let [cdata (transient {(trace-id-key) (.getTraceId span-context) |
61 | | - (span-id-key) (.getSpanId span-context) |
62 | | - (trace-flags-key) (.asHex (.getTraceFlags span-context))}) |
63 | | - cdata (reduce (fn [m [k ^BaggageEntry v]] |
64 | | - (assoc! m |
65 | | - (str "baggage." k) |
66 | | - (.getValue v))) |
67 | | - cdata |
68 | | - (when (add-baggage?) |
69 | | - (.asMap (baggage/get-baggage))))] |
70 | | - (persistent! cdata)) |
71 | | - {}))) |
| 40 | + (persistent! (cond-> (transient {}) |
| 41 | + (add-baggage?) (util/into! (map (fn [[k v]] [(str "baggage." k) |
| 42 | + (.getValue ^BaggageEntry v)])) |
| 43 | + (.asMap (baggage/get-baggage))) |
| 44 | + (.isValid span-context) (assoc! (config-logging/trace-id-key) |
| 45 | + (.getTraceId span-context) |
| 46 | + (config-logging/span-id-key) |
| 47 | + (.getSpanId span-context) |
| 48 | + (config-logging/trace-flags-key) |
| 49 | + (.asHex (.getTraceFlags span-context))))))) |
72 | 50 |
|
73 | 51 | (defn- context-from-cdata |
74 | 52 | "Returns a context containing a span with span context data stored in cdata. |
75 | 53 | This is used in cases where `emit` may be evaluated in a different context |
76 | 54 | to where the log record occurred i.e. asynchronously." |
77 | 55 | [cdata] |
78 | | - (let [trace-id (get cdata (trace-id-key)) |
79 | | - span-id (get cdata (span-id-key)) |
80 | | - trace-flags (get cdata (trace-flags-key))] |
| 56 | + (let [trace-id (get cdata (config-logging/trace-id-key)) |
| 57 | + span-id (get cdata (config-logging/span-id-key)) |
| 58 | + trace-flags (get cdata (config-logging/trace-flags-key))] |
81 | 59 | (and trace-id |
82 | 60 | span-id |
83 | 61 | trace-flags |
|
94 | 72 | logger-name |
95 | 73 | "ROOT"))) |
96 | 74 |
|
| 75 | +(defn- get-timestamp |
| 76 | + [^LogEvent event] |
| 77 | + (when-some [^Instant instant (.getInstant event)] |
| 78 | + (let [nanos (+ (.toNanos TimeUnit/MILLISECONDS (.getEpochMillisecond instant)) |
| 79 | + (.getNanoOfMillisecond instant))] |
| 80 | + [nanos TimeUnit/NANOSECONDS]))) |
| 81 | + |
97 | 82 | (defn- get-source |
98 | 83 | [^LogEvent event] |
99 | 84 | (when-some [elem (.getSource event)] |
|
103 | 88 | :line (when (> line 0) |
104 | 89 | line)}))) |
105 | 90 |
|
106 | | -(defn- get-timestamp |
107 | | - [^LogEvent event] |
108 | | - (when-some [^Instant instant (.getInstant event)] |
109 | | - (let [nanos (+ (.toNanos TimeUnit/MILLISECONDS (.getEpochMillisecond instant)) |
110 | | - (.getNanoOfMillisecond instant))] |
111 | | - [nanos TimeUnit/NANOSECONDS]))) |
112 | | - |
113 | 91 | (defn- ->log-record |
114 | 92 | [^CljOtelAppender appender ^LogEvent event] |
115 | | - (let [logger-name (get-logger-name event) |
116 | | - cdata (.toMap (.getContextData event)) |
| 93 | + (let [cdata (.toMap (.getContextData event)) |
117 | 94 | context (context/dyn) |
118 | 95 | context (if (identical? (context/root) context) |
119 | 96 | (context-from-cdata cdata) ; cover asynchronous case |
120 | 97 | context) |
| 98 | + level (.getLevel event) |
121 | 99 | ^Message message (.getMessage event) |
122 | 100 | map-message? (and message (instance? MapMessage message)) |
123 | 101 | body (when message |
|
128 | 106 | body (if check-msg-attr? |
129 | 107 | (.get ^MapMessage message "message") |
130 | 108 | body) |
131 | | - ^Level level (.getLevel event) |
132 | 109 | attributes (persistent! |
133 | | - (cond-> (transient {}) |
134 | | - (.-experimentalAttrs appender) (assoc! |
135 | | - ThreadIncubatingAttributes/THREAD_NAME |
136 | | - (.getThreadName event) |
137 | | - ThreadIncubatingAttributes/THREAD_ID |
138 | | - (.getThreadId event)) |
139 | | - (and map-message? (.-mapMessageAttrs appender)) |
140 | | - (assoc-all! (->> (.getData ^MapMessage message) |
141 | | - (remove (fn [[k _]] |
142 | | - (and check-msg-attr? (= k "message")))) |
143 | | - (map (fn [[k v]] [(str "log4j.map_message." k) |
144 | | - (str v)])))) |
145 | | - |
146 | | - (.-markerAttr appender) (assoc! "log4j.marker" |
147 | | - (.getName (.getMarker event))) |
148 | | - :always (assoc-all! (filter |
149 | | - (fn [[k _]] |
150 | | - (and (not (and (.-eventName appender) |
151 | | - (= k "event.name"))) |
152 | | - (or (.-allCdataAttrs appender) |
153 | | - (contains? (.-cdataAttrs appender) k)))) |
154 | | - cdata))))] |
155 | | - {:logger-name logger-name |
| 110 | + (cond-> (util/into! |
| 111 | + (transient {}) |
| 112 | + (filter |
| 113 | + (fn [[k _]] |
| 114 | + (or (.-captureAllContextDataAttributes appender) |
| 115 | + (contains? (.-captureContextDataAttributes appender) k)))) |
| 116 | + cdata) |
| 117 | + (.-captureExperimentalAttributes appender) |
| 118 | + (assoc! ThreadIncubatingAttributes/THREAD_NAME |
| 119 | + (.getThreadName event) |
| 120 | + ThreadIncubatingAttributes/THREAD_ID |
| 121 | + (.getThreadId event)) |
| 122 | + |
| 123 | + (and map-message? (.-captureMapMessageAttributes appender)) |
| 124 | + (util/into! (comp (remove (fn [[k _]] |
| 125 | + (and check-msg-attr? (= k "message")))) |
| 126 | + (map (fn [[k v]] [(str "log4j.map_message." k) |
| 127 | + (str v)]))) |
| 128 | + (.getData ^MapMessage message)) |
| 129 | + |
| 130 | + (.-captureMarkerAttribute appender) |
| 131 | + (assoc! "log4j.marker" (.getName (.getMarker event))))) |
| 132 | + event-name (when (.-captureEventName appender) |
| 133 | + (get attributes "event.name")) |
| 134 | + attributes (cond-> attributes |
| 135 | + event-name (dissoc "event.name"))] |
| 136 | + {:logger-name (get-logger-name event) |
156 | 137 | :context context |
157 | | - :severity (and level (StandardLevel->Severity (.getStandardLevel level))) |
| 138 | + :severity (and level |
| 139 | + (get StandardLevel->Severity |
| 140 | + (.getStandardLevel level) |
| 141 | + Severity/UNDEFINED_SEVERITY_NUMBER)) |
158 | 142 | :severity-text (and level (.name level)) |
159 | 143 | :body body |
160 | 144 | :attributes attributes |
161 | 145 | :exception (.getThrown event) |
162 | 146 | :thread nil ; thread added as attributes instead |
163 | 147 | :timestamp (get-timestamp event) |
164 | | - :source (when (.-codeAttrs appender) |
| 148 | + :source (when (.-captureCodeAttributes appender) |
165 | 149 | (get-source event)) |
166 | | - :event-name (when (.-eventName appender) |
167 | | - (get cdata "event.name"))})) |
| 150 | + :event-name event-name})) |
168 | 151 |
|
169 | 152 | (defn- emit |
170 | 153 | [record] |
|
0 commit comments