@@ -18,6 +18,7 @@ package spp.probe.services.instrument
18
18
19
19
import net.bytebuddy.pool.TypePool
20
20
import org.apache.skywalking.apm.agent.core.context.util.ThrowableTransformer
21
+ import org.apache.skywalking.apm.agent.core.logging.api.LogManager
21
22
import org.springframework.expression.ParseException
22
23
import org.springframework.expression.spel.SpelCompilerMode
23
24
import org.springframework.expression.spel.SpelParserConfiguration
@@ -39,6 +40,7 @@ import java.util.stream.Collectors
39
40
40
41
object LiveInstrumentService {
41
42
43
+ private val log = LogManager .getLogger(LiveInstrumentService ::class .java)
42
44
private val instruments: MutableMap <String ?, ActiveLiveInstrument > = ConcurrentHashMap ()
43
45
private val applyingInstruments: MutableMap <String ?, ActiveLiveInstrument > = ConcurrentHashMap ()
44
46
private val parser = SpelExpressionParser (
@@ -52,6 +54,7 @@ object LiveInstrumentService {
52
54
init {
53
55
timer.schedule(object : TimerTask () {
54
56
override fun run () {
57
+ if (log.isDebugEnable) log.debug(" Running LiveInstrumentScheduler" )
55
58
val removeInstruments: MutableList <ActiveLiveInstrument > = ArrayList ()
56
59
instruments.values.forEach {
57
60
if (it.instrument.expiresAt != null
@@ -67,13 +70,23 @@ object LiveInstrumentService {
67
70
removeInstruments.add(it)
68
71
}
69
72
}
73
+
74
+ if (log.isDebugEnable) log.debug(" Found {} expired instruments" , removeInstruments.size)
70
75
removeInstruments.forEach { _removeInstrument (it.instrument, null ) }
71
76
}
72
77
}, 5000 , 5000 )
73
78
}
74
79
75
80
var liveInstrumentApplier = object : LiveInstrumentApplier {
76
81
override fun apply (inst : Instrumentation , instrument : ActiveLiveInstrument ) {
82
+ if (log.isInfoEnable) {
83
+ if (instrument.isRemoval) {
84
+ log.info(" Attempting to remove live instrument: {}" , instrument.instrument)
85
+ } else {
86
+ log.info(" Attempting to apply live instrument: {}" , instrument.instrument)
87
+ }
88
+ }
89
+
77
90
val className = if (instrument.instrument.location.source.contains(" (" )) {
78
91
instrument.instrument.location.source.substringBefore(" (" ).substringBeforeLast(" ." )
79
92
} else {
@@ -83,17 +96,24 @@ object LiveInstrumentService {
83
96
for (classLoader in poolMap.keys) {
84
97
try {
85
98
clazz = Class .forName(className, true , classLoader)
99
+ if (log.isInfoEnable) log.info(" Found {} in class loader {}" , clazz, classLoader)
86
100
} catch (ignored: ClassNotFoundException ) {
87
101
}
88
102
}
89
103
if (poolMap.isEmpty()) {
90
104
try {
91
105
clazz = Class .forName(className)
106
+ if (log.isInfoEnable) log.info(" Found {} in system class loader" , clazz)
92
107
} catch (ignored: ClassNotFoundException ) {
93
108
}
94
109
}
95
110
if (clazz == null ) {
111
+ if (log.isDebugEnable) log.debug(" {} not found" , className)
96
112
if (instrument.instrument.applyImmediately) {
113
+ log.warn(
114
+ " Unable to find {}. Live instrument {} cannot be applied immediately" ,
115
+ className, instrument.instrument
116
+ )
97
117
throw LiveInstrumentException (LiveInstrumentException .ErrorType .CLASS_NOT_FOUND , className)
98
118
.toEventBusException()
99
119
} else if (! instrument.isRemoval) {
@@ -114,20 +134,27 @@ object LiveInstrumentService {
114
134
inst.addTransformer(transformer, true )
115
135
inst.retransformClasses(clazz)
116
136
instrument.isLive = true
117
- if (! instrument.isRemoval) {
137
+
138
+ if (instrument.isRemoval) {
139
+ if (log.isInfoEnable) log.info(" Successfully removed live instrument: {}" , instrument.instrument)
140
+ } else {
141
+ if (log.isInfoEnable) log.info(" Successfully applied live instrument {}" , instrument.instrument)
118
142
instrumentEventConsumer!! .accept(
119
143
ProcessorAddress .LIVE_INSTRUMENT_APPLIED ,
120
144
ModelSerializer .INSTANCE .toJson(instrument.instrument)
121
145
)
122
146
}
123
147
} catch (ex: Throwable ) {
148
+ log.warn(ex, " Failed to apply live instrument: {}" , instrument)
149
+
124
150
// remove and re-transform
125
151
_removeInstrument (instrument.instrument, ex)
126
152
applyingInstruments.remove(instrument.instrument.id)
127
153
inst.addTransformer(transformer, true )
128
154
try {
129
155
inst.retransformClasses(clazz)
130
156
} catch (e: UnmodifiableClassException ) {
157
+ log.warn(e, " Failed to re-transform class: {}" , clazz)
131
158
throw RuntimeException (e)
132
159
}
133
160
} finally {
@@ -176,6 +203,7 @@ object LiveInstrumentService {
176
203
val expression = parser.parseExpression(liveInstrument.condition!! )
177
204
ActiveLiveInstrument (liveInstrument, expression)
178
205
} catch (ex: ParseException ) {
206
+ log.warn(ex, " Failed to parse condition: {}" , liveInstrument.condition)
179
207
throw LiveInstrumentException (LiveInstrumentException .ErrorType .CONDITIONAL_FAILED , ex.message)
180
208
.toEventBusException()
181
209
}
@@ -217,6 +245,12 @@ object LiveInstrumentService {
217
245
}
218
246
219
247
fun _removeInstrument (instrument : LiveInstrument , ex : Throwable ? ) {
248
+ if (ex != null ) {
249
+ log.warn(ex, " Removing erroneous live instrument: {}" , instrument)
250
+ } else {
251
+ log.info(" Removing live instrument: {}" , instrument)
252
+ }
253
+
220
254
removeInstrument(instrument.location.source, instrument.location.line, instrument.id)
221
255
val map: MutableMap <String , Any ?> = HashMap ()
222
256
map[" instrument" ] = ModelSerializer .INSTANCE .toJson(instrument)
@@ -287,6 +321,7 @@ object LiveInstrumentService {
287
321
false
288
322
}
289
323
} catch (e: Throwable ) {
324
+ log.warn(e, " Failed to evaluate condition: {}" , instrument.instrument.condition)
290
325
ContextReceiver .clear(instrumentId)
291
326
_removeInstrument (instrument.instrument, e)
292
327
false
0 commit comments