Skip to content

Commit 9e80a4c

Browse files
authored
Fix MeterService NPE as not initialized in so11y plugin. (#755)
1 parent f971bcf commit 9e80a4c

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ Release Notes.
88
* Add the virtual thread executor plugin
99
* Fix Conflicts apm-jdk-threadpool-plugin conflicts with apm-jdk-forkjoinpool-plugin
1010
* Fix NPE in hikaricp-plugin if JDBC URL is not set
11+
* Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent transfer
12+
initialization. Delay so11y metrics#build when the services are not ready to avoid MeterService status is not
13+
initialized.
1114

1215
All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/236?closed=1)
1316

apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/ServiceManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.List;
2626
import java.util.Map;
2727
import java.util.ServiceLoader;
28+
import lombok.Getter;
2829
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
2930
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
3031
import org.apache.skywalking.apm.agent.core.plugin.loader.AgentClassLoader;
@@ -37,6 +38,8 @@ public enum ServiceManager {
3738

3839
private static final ILog LOGGER = LogManager.getLogger(ServiceManager.class);
3940
private Map<Class, BootService> bootedServices = Collections.emptyMap();
41+
@Getter
42+
private volatile boolean isBooted = false;
4043

4144
public void boot() {
4245
bootedServices = loadAllServices();
@@ -127,6 +130,7 @@ private void onComplete() {
127130
LOGGER.error(e, "Service [{}] AfterBoot process fails.", service.getClass().getName());
128131
}
129132
}
133+
isBooted = true;
130134
}
131135

132136
/**

apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/so11y/AgentSo11y.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.List;
2323
import java.util.Map;
2424
import java.util.concurrent.ConcurrentHashMap;
25+
import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
2526
import org.apache.skywalking.apm.agent.core.meter.Counter;
2627
import org.apache.skywalking.apm.agent.core.meter.Histogram;
2728
import org.apache.skywalking.apm.agent.core.meter.MeterFactory;
@@ -58,6 +59,12 @@ public class AgentSo11y {
5859
private static Histogram INTERCEPTOR_TIME_COST;
5960

6061
public static void measureTracingContextCreation(boolean forceSampling, boolean ignoredTracingContext) {
62+
if (!ServiceManager.INSTANCE.isBooted()) {
63+
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
64+
// transfer initialization.
65+
// Skip when the services are not ready to avoid MeterService status is not initialized.
66+
return;
67+
}
6168
if (forceSampling) {
6269
if (ignoredTracingContext) {
6370
if (PROPAGATED_IGNORE_CONTEXT_COUNTER == null) {
@@ -98,6 +105,12 @@ public static void measureTracingContextCreation(boolean forceSampling, boolean
98105
}
99106

100107
public static void measureTracingContextCompletion(boolean ignoredTracingContext) {
108+
if (!ServiceManager.INSTANCE.isBooted()) {
109+
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
110+
// transfer initialization.
111+
// Skip when the services are not ready to avoid MeterService status is not initialized.
112+
return;
113+
}
101114
if (ignoredTracingContext) {
102115
if (FINISH_IGNORE_CONTEXT_COUNTER == null) {
103116
FINISH_IGNORE_CONTEXT_COUNTER = MeterFactory.counter("finished_ignored_context_counter").build();
@@ -112,6 +125,12 @@ public static void measureTracingContextCompletion(boolean ignoredTracingContext
112125
}
113126

114127
public static void measureLeakedTracingContext(boolean ignoredTracingContext) {
128+
if (!ServiceManager.INSTANCE.isBooted()) {
129+
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
130+
// transfer initialization.
131+
// Skip when the services are not ready to avoid MeterService status is not initialized.
132+
return;
133+
}
115134
if (ignoredTracingContext) {
116135
if (LEAKED_IGNORE_CONTEXT_COUNTER == null) {
117136
LEAKED_IGNORE_CONTEXT_COUNTER = MeterFactory
@@ -132,6 +151,12 @@ public static void measureLeakedTracingContext(boolean ignoredTracingContext) {
132151
}
133152

134153
public static void durationOfInterceptor(double timeCostInNanos) {
154+
if (!ServiceManager.INSTANCE.isBooted()) {
155+
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
156+
// transfer initialization.
157+
// Skip when the services are not ready to avoid MeterService status is not initialized.
158+
return;
159+
}
135160
if (INTERCEPTOR_TIME_COST == null) {
136161
INTERCEPTOR_TIME_COST = MeterFactory
137162
.histogram("tracing_context_performance")
@@ -142,6 +167,12 @@ public static void durationOfInterceptor(double timeCostInNanos) {
142167
}
143168

144169
public static void errorOfPlugin(String pluginName, String interType) {
170+
if (!ServiceManager.INSTANCE.isBooted()) {
171+
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
172+
// transfer initialization.
173+
// Skip when the services are not ready to avoid MeterService status is not initialized.
174+
return;
175+
}
145176
Counter counter = ERROR_COUNTER_CACHE.computeIfAbsent(pluginName + interType, key -> MeterFactory
146177
.counter("interceptor_error_counter")
147178
.tag("plugin_name", pluginName)

0 commit comments

Comments
 (0)