5
5
6
6
package io .opentelemetry .instrumentation .spring .autoconfigure .instrumentation .logging ;
7
7
8
- import ch .qos .logback .classic .LoggerContext ;
9
- import ch .qos .logback .classic .spi .ILoggingEvent ;
10
- import ch .qos .logback .core .Appender ;
11
- import io .opentelemetry .instrumentation .logback .appender .v1_0 .OpenTelemetryAppender ;
12
- import java .util .Iterator ;
13
- import java .util .Optional ;
14
- import org .slf4j .ILoggerFactory ;
15
- import org .slf4j .Logger ;
16
- import org .slf4j .LoggerFactory ;
17
8
import org .springframework .boot .SpringApplication ;
18
9
import org .springframework .boot .context .event .ApplicationEnvironmentPreparedEvent ;
19
10
import org .springframework .boot .context .logging .LoggingApplicationListener ;
@@ -27,8 +18,8 @@ public class LogbackAppenderApplicationListener implements GenericApplicationLis
27
18
private static final Class <?>[] SOURCE_TYPES = {
28
19
SpringApplication .class , ApplicationContext .class
29
20
};
30
-
31
21
private static final Class <?>[] EVENT_TYPES = {ApplicationEnvironmentPreparedEvent .class };
22
+ private static final boolean LOGBACK_PRESENT = isLogbackPresent ();
32
23
33
24
@ Override
34
25
public boolean supportsSourceType (Class <?> sourceType ) {
@@ -53,149 +44,29 @@ private static boolean isAssignableFrom(Class<?> type, Class<?>... supportedType
53
44
54
45
@ Override
55
46
public void onApplicationEvent (ApplicationEvent event ) {
56
- if (event instanceof ApplicationEnvironmentPreparedEvent // Event for which
57
- // org.springframework.boot.context.logging.LoggingApplicationListener
58
- // initializes logging
59
- ) {
60
- Optional <OpenTelemetryAppender > existingOpenTelemetryAppender = findOpenTelemetryAppender ();
61
- ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent =
62
- (ApplicationEnvironmentPreparedEvent ) event ;
63
- if (existingOpenTelemetryAppender .isPresent ()) {
64
- reInitializeOpenTelemetryAppender (
65
- existingOpenTelemetryAppender , applicationEnvironmentPreparedEvent );
66
- } else if (isLogbackAppenderAddable (applicationEnvironmentPreparedEvent )) {
67
- addOpenTelemetryAppender (applicationEnvironmentPreparedEvent );
68
- }
69
- }
70
- }
71
-
72
- private static boolean isLogbackAppenderAddable (
73
- ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent ) {
74
- Boolean otelSdkDisableProperty =
75
- evaluateBooleanProperty (applicationEnvironmentPreparedEvent , "otel.sdk.disabled" );
76
- Boolean logbackInstrumentationEnabledProperty =
77
- evaluateBooleanProperty (
78
- applicationEnvironmentPreparedEvent , "otel.instrumentation.logback-appender.enabled" );
79
- return otelSdkDisableProperty == null
80
- || !otelSdkDisableProperty .booleanValue ()
81
- || logbackInstrumentationEnabledProperty == null
82
- || logbackInstrumentationEnabledProperty .booleanValue ();
83
- }
84
-
85
- private static void reInitializeOpenTelemetryAppender (
86
- Optional <OpenTelemetryAppender > existingOpenTelemetryAppender ,
87
- ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent ) {
88
- OpenTelemetryAppender openTelemetryAppender = existingOpenTelemetryAppender .get ();
89
- // The OpenTelemetry appender is stopped and restarted from the
90
- // org.springframework.boot.context.logging.LoggingApplicationListener.initialize
91
- // method.
92
- // The OpenTelemetryAppender initializes the LoggingEventMapper in the start() method. So, here
93
- // we stop the OpenTelemetry appender before its re-initialization and its restart.
94
- openTelemetryAppender .stop ();
95
- initializeOpenTelemetryAppenderFromProperties (
96
- applicationEnvironmentPreparedEvent , openTelemetryAppender );
97
- openTelemetryAppender .start ();
98
- }
99
-
100
- private static void addOpenTelemetryAppender (
101
- ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent ) {
102
- ch .qos .logback .classic .Logger logger =
103
- (ch .qos .logback .classic .Logger )
104
- LoggerFactory .getILoggerFactory ().getLogger (Logger .ROOT_LOGGER_NAME );
105
- OpenTelemetryAppender openTelemetryAppender = new OpenTelemetryAppender ();
106
- initializeOpenTelemetryAppenderFromProperties (
107
- applicationEnvironmentPreparedEvent , openTelemetryAppender );
108
- openTelemetryAppender .start ();
109
- logger .addAppender (openTelemetryAppender );
110
- }
111
-
112
- private static void initializeOpenTelemetryAppenderFromProperties (
113
- ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent ,
114
- OpenTelemetryAppender openTelemetryAppender ) {
115
-
116
- // Implemented in the same way as the
117
- // org.springframework.boot.context.logging.LoggingApplicationListener, config properties not
118
- // available
119
- Boolean codeAttribute =
120
- evaluateBooleanProperty (
121
- applicationEnvironmentPreparedEvent ,
122
- "otel.instrumentation.logback-appender.experimental.capture-code-attributes" );
123
- if (codeAttribute != null ) {
124
- openTelemetryAppender .setCaptureCodeAttributes (codeAttribute .booleanValue ());
125
- }
126
-
127
- Boolean markerAttribute =
128
- evaluateBooleanProperty (
129
- applicationEnvironmentPreparedEvent ,
130
- "otel.instrumentation.logback-appender.experimental.capture-marker-attribute" );
131
- if (markerAttribute != null ) {
132
- openTelemetryAppender .setCaptureMarkerAttribute (markerAttribute .booleanValue ());
133
- }
134
-
135
- Boolean keyValuePairAttributes =
136
- evaluateBooleanProperty (
137
- applicationEnvironmentPreparedEvent ,
138
- "otel.instrumentation.logback-appender.experimental.capture-key-value-pair-attributes" );
139
- if (keyValuePairAttributes != null ) {
140
- openTelemetryAppender .setCaptureKeyValuePairAttributes (keyValuePairAttributes .booleanValue ());
141
- }
142
-
143
- Boolean logAttributes =
144
- evaluateBooleanProperty (
145
- applicationEnvironmentPreparedEvent ,
146
- "otel.instrumentation.logback-appender.experimental-log-attributes" );
147
- if (logAttributes != null ) {
148
- openTelemetryAppender .setCaptureExperimentalAttributes (logAttributes .booleanValue ());
149
- }
150
-
151
- Boolean loggerContextAttributes =
152
- evaluateBooleanProperty (
153
- applicationEnvironmentPreparedEvent ,
154
- "otel.instrumentation.logback-appender.experimental.capture-logger-context-attributes" );
155
- if (loggerContextAttributes != null ) {
156
- openTelemetryAppender .setCaptureLoggerContext (loggerContextAttributes .booleanValue ());
47
+ if (!LOGBACK_PRESENT ) {
48
+ return ;
157
49
}
158
50
159
- String mdcAttributeProperty =
160
- applicationEnvironmentPreparedEvent
161
- .getEnvironment ()
162
- .getProperty (
163
- "otel.instrumentation.logback-appender.experimental.capture-mdc-attributes" ,
164
- String .class );
165
- if (mdcAttributeProperty != null ) {
166
- openTelemetryAppender .setCaptureMdcAttributes (mdcAttributeProperty );
167
- }
168
- }
169
-
170
- private static Boolean evaluateBooleanProperty (
171
- ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent , String property ) {
172
- return applicationEnvironmentPreparedEvent
173
- .getEnvironment ()
174
- .getProperty (property , Boolean .class );
175
- }
176
-
177
- private static Optional <OpenTelemetryAppender > findOpenTelemetryAppender () {
178
- ILoggerFactory loggerFactorySpi = LoggerFactory .getILoggerFactory ();
179
- if (!(loggerFactorySpi instanceof LoggerContext )) {
180
- return Optional .empty ();
181
- }
182
- LoggerContext loggerContext = (LoggerContext ) loggerFactorySpi ;
183
- for (ch .qos .logback .classic .Logger logger : loggerContext .getLoggerList ()) {
184
- Iterator <Appender <ILoggingEvent >> appenderIterator = logger .iteratorForAppenders ();
185
- while (appenderIterator .hasNext ()) {
186
- Appender <ILoggingEvent > appender = appenderIterator .next ();
187
- if (appender instanceof OpenTelemetryAppender ) {
188
- OpenTelemetryAppender openTelemetryAppender = (OpenTelemetryAppender ) appender ;
189
- return Optional .of (openTelemetryAppender );
190
- }
191
- }
51
+ // Event for which org.springframework.boot.context.logging.LoggingApplicationListener
52
+ // initializes logging
53
+ if (event instanceof ApplicationEnvironmentPreparedEvent ) {
54
+ LogbackAppenderInstaller .install ((ApplicationEnvironmentPreparedEvent ) event );
192
55
}
193
- return Optional .empty ();
194
56
}
195
57
196
58
@ Override
197
59
public int getOrder () {
198
60
return LoggingApplicationListener .DEFAULT_ORDER + 1 ; // To execute this listener just after
199
61
// org.springframework.boot.context.logging.LoggingApplicationListener
200
62
}
63
+
64
+ private static boolean isLogbackPresent () {
65
+ try {
66
+ Class .forName ("ch.qos.logback.core.Appender" );
67
+ return true ;
68
+ } catch (ClassNotFoundException exception ) {
69
+ return false ;
70
+ }
71
+ }
201
72
}
0 commit comments