Fix MeterService NPE as not initialized in so11y plugin. (#755)

This commit is contained in:
吴晟 Wu Sheng 2025-05-13 14:33:52 +08:00 committed by GitHub
parent f971bcf0fd
commit 9e80a4c85b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 38 additions and 0 deletions

View File

@ -8,6 +8,9 @@ Release Notes.
* Add the virtual thread executor plugin
* Fix Conflicts apm-jdk-threadpool-plugin conflicts with apm-jdk-forkjoinpool-plugin
* Fix NPE in hikaricp-plugin if JDBC URL is not set
* Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent transfer
initialization. Delay so11y metrics#build when the services are not ready to avoid MeterService status is not
initialized.
All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/236?closed=1)

View File

@ -25,6 +25,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import lombok.Getter;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
import org.apache.skywalking.apm.agent.core.plugin.loader.AgentClassLoader;
@ -37,6 +38,8 @@ public enum ServiceManager {
private static final ILog LOGGER = LogManager.getLogger(ServiceManager.class);
private Map<Class, BootService> bootedServices = Collections.emptyMap();
@Getter
private volatile boolean isBooted = false;
public void boot() {
bootedServices = loadAllServices();
@ -127,6 +130,7 @@ public enum ServiceManager {
LOGGER.error(e, "Service [{}] AfterBoot process fails.", service.getClass().getName());
}
}
isBooted = true;
}
/**

View File

@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
import org.apache.skywalking.apm.agent.core.meter.Counter;
import org.apache.skywalking.apm.agent.core.meter.Histogram;
import org.apache.skywalking.apm.agent.core.meter.MeterFactory;
@ -58,6 +59,12 @@ public class AgentSo11y {
private static Histogram INTERCEPTOR_TIME_COST;
public static void measureTracingContextCreation(boolean forceSampling, boolean ignoredTracingContext) {
if (!ServiceManager.INSTANCE.isBooted()) {
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
// transfer initialization.
// Skip when the services are not ready to avoid MeterService status is not initialized.
return;
}
if (forceSampling) {
if (ignoredTracingContext) {
if (PROPAGATED_IGNORE_CONTEXT_COUNTER == null) {
@ -98,6 +105,12 @@ public class AgentSo11y {
}
public static void measureTracingContextCompletion(boolean ignoredTracingContext) {
if (!ServiceManager.INSTANCE.isBooted()) {
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
// transfer initialization.
// Skip when the services are not ready to avoid MeterService status is not initialized.
return;
}
if (ignoredTracingContext) {
if (FINISH_IGNORE_CONTEXT_COUNTER == null) {
FINISH_IGNORE_CONTEXT_COUNTER = MeterFactory.counter("finished_ignored_context_counter").build();
@ -112,6 +125,12 @@ public class AgentSo11y {
}
public static void measureLeakedTracingContext(boolean ignoredTracingContext) {
if (!ServiceManager.INSTANCE.isBooted()) {
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
// transfer initialization.
// Skip when the services are not ready to avoid MeterService status is not initialized.
return;
}
if (ignoredTracingContext) {
if (LEAKED_IGNORE_CONTEXT_COUNTER == null) {
LEAKED_IGNORE_CONTEXT_COUNTER = MeterFactory
@ -132,6 +151,12 @@ public class AgentSo11y {
}
public static void durationOfInterceptor(double timeCostInNanos) {
if (!ServiceManager.INSTANCE.isBooted()) {
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
// transfer initialization.
// Skip when the services are not ready to avoid MeterService status is not initialized.
return;
}
if (INTERCEPTOR_TIME_COST == null) {
INTERCEPTOR_TIME_COST = MeterFactory
.histogram("tracing_context_performance")
@ -142,6 +167,12 @@ public class AgentSo11y {
}
public static void errorOfPlugin(String pluginName, String interType) {
if (!ServiceManager.INSTANCE.isBooted()) {
// Agent kernel services could be not-booted-yet as ServiceManager#INSTANCE#boot executed after agent
// transfer initialization.
// Skip when the services are not ready to avoid MeterService status is not initialized.
return;
}
Counter counter = ERROR_COUNTER_CACHE.computeIfAbsent(pluginName + interType, key -> MeterFactory
.counter("interceptor_error_counter")
.tag("plugin_name", pluginName)