This is an automated email from the ASF dual-hosted git repository. wusheng pushed a commit to branch refactor/lal-output-builder-module-manager in repository https://gitbox.apache.org/repos/asf/skywalking.git
commit 9cdc0e6a1749237ac868900992ebf47fbee28541 Author: Wu Sheng <[email protected]> AuthorDate: Thu Mar 12 14:25:57 2026 +0800 Refactor LALOutputBuilder.init() to take ModuleManager instead of NamingControl Move service resolution (NamingControl, searchableTagKeys) from RecordSinkListener into each LALOutputBuilder implementation. Each builder caches resolved services in static fields so ModuleManager lookups only happen once. RecordSinkListener no longer needs to know about Log-specific concerns like searchableTagKeys. --- .../listener/DatabaseSlowStatementBuilder.java | 22 ++++++++--- .../trace/parser/listener/SampledTraceBuilder.java | 24 +++++++++--- oap-server/analyzer/log-analyzer/CLAUDE.md | 7 +++- .../provider/log/listener/RecordSinkListener.java | 33 ++++------------- .../oap/server/core/source/LALOutputBuilder.java | 11 +++--- .../oap/server/core/source/LogBuilder.java | 39 ++++++++++++++------ .../envoy/persistence/EnvoyAccessLogBuilder.java | 6 +-- .../persistence/EnvoyAccessLogBuilderTest.java | 43 +++++++++++++++++++--- .../envoy/persistence/EnvoyAlsLalTest.java | 40 +++++++++++++++++--- 9 files changed, 154 insertions(+), 71 deletions(-) diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/DatabaseSlowStatementBuilder.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/DatabaseSlowStatementBuilder.java index 1ab9d17204..db33d33e2f 100644 --- a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/DatabaseSlowStatementBuilder.java +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/DatabaseSlowStatementBuilder.java @@ -23,6 +23,7 @@ import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.apm.network.logging.v3.LogData; +import org.apache.skywalking.oap.server.core.CoreModule; import org.apache.skywalking.oap.server.core.analysis.DownSampling; import org.apache.skywalking.oap.server.core.analysis.IDManager; import org.apache.skywalking.oap.server.core.analysis.Layer; @@ -31,12 +32,14 @@ import org.apache.skywalking.oap.server.core.config.NamingControl; import org.apache.skywalking.oap.server.core.source.DatabaseSlowStatement; import org.apache.skywalking.oap.server.core.source.LALOutputBuilder; import org.apache.skywalking.oap.server.core.source.SourceReceiver; +import org.apache.skywalking.oap.server.library.module.ModuleManager; @Slf4j public class DatabaseSlowStatementBuilder implements LALOutputBuilder { public static final String NAME = "SlowSQL"; - private NamingControl namingControl; + private static NamingControl NAMING_CONTROL; + private static boolean INITIALIZED; @Getter @Setter @@ -66,8 +69,12 @@ public class DatabaseSlowStatementBuilder implements LALOutputBuilder { public DatabaseSlowStatementBuilder() { } + /** + * Constructor for v1 (Groovy) path which doesn't use {@link #init}. + */ public DatabaseSlowStatementBuilder(final NamingControl namingControl) { - this.namingControl = namingControl; + NAMING_CONTROL = namingControl; + INITIALIZED = true; } @Override @@ -77,8 +84,13 @@ public class DatabaseSlowStatementBuilder implements LALOutputBuilder { @Override public void init(final LogData logData, final Optional<Object> extraLog, - final NamingControl namingControl) { - this.namingControl = namingControl; + final ModuleManager moduleManager) { + if (!INITIALIZED) { + NAMING_CONTROL = moduleManager.find(CoreModule.NAME) + .provider() + .getService(NamingControl.class); + INITIALIZED = true; + } // Only populate fields not already set by the LAL extractor. if (this.serviceName == null) { this.serviceName = logData.getService(); @@ -114,7 +126,7 @@ public class DatabaseSlowStatementBuilder implements LALOutputBuilder { } public void prepare() { - this.serviceName = namingControl.formatServiceName(serviceName); + this.serviceName = NAMING_CONTROL.formatServiceName(serviceName); } public DatabaseSlowStatement toDatabaseSlowStatement() { diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/SampledTraceBuilder.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/SampledTraceBuilder.java index 88997b63cb..1605a7ca10 100644 --- a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/SampledTraceBuilder.java +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/SampledTraceBuilder.java @@ -34,6 +34,7 @@ import org.apache.skywalking.oap.server.core.analysis.manual.trace.SampledStatus import org.apache.skywalking.oap.server.core.analysis.manual.trace.SampledStatus5xxTraceRecord; import org.apache.skywalking.oap.server.core.analysis.record.Record; import org.apache.skywalking.oap.server.core.analysis.worker.RecordStreamProcessor; +import org.apache.skywalking.oap.server.core.CoreModule; import org.apache.skywalking.oap.server.core.config.NamingControl; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; import org.apache.skywalking.oap.server.core.source.DetectPoint; @@ -41,12 +42,14 @@ import org.apache.skywalking.oap.server.core.source.ISource; import org.apache.skywalking.oap.server.core.source.LALOutputBuilder; import org.apache.skywalking.oap.server.core.source.ProcessRelation; import org.apache.skywalking.oap.server.core.source.SourceReceiver; +import org.apache.skywalking.oap.server.library.module.ModuleManager; @Slf4j public class SampledTraceBuilder implements LALOutputBuilder { public static final String NAME = "SampledTrace"; - private NamingControl namingControl; + private static NamingControl NAMING_CONTROL; + private static boolean INITIALIZED; @Setter @Getter @@ -90,8 +93,12 @@ public class SampledTraceBuilder implements LALOutputBuilder { public SampledTraceBuilder() { } + /** + * Constructor for v1 (Groovy) path which doesn't use {@link #init}. + */ public SampledTraceBuilder(final NamingControl namingControl) { - this.namingControl = namingControl; + NAMING_CONTROL = namingControl; + INITIALIZED = true; } @Override @@ -101,8 +108,13 @@ public class SampledTraceBuilder implements LALOutputBuilder { @Override public void init(final LogData logData, final Optional<Object> extraLog, - final NamingControl namingControl) { - this.namingControl = namingControl; + final ModuleManager moduleManager) { + if (!INITIALIZED) { + NAMING_CONTROL = moduleManager.find(CoreModule.NAME) + .provider() + .getService(NamingControl.class); + INITIALIZED = true; + } // Only populate fields not already set by the LAL extractor. if (this.traceId == null) { this.traceId = logData.getTraceContext().getTraceId(); @@ -203,9 +215,9 @@ public class SampledTraceBuilder implements LALOutputBuilder { public ISource toEntity() { final ProcessRelation processRelation = new ProcessRelation(); - final String serviceId = IDManager.ServiceID.buildId(namingControl.formatServiceName(serviceName), + final String serviceId = IDManager.ServiceID.buildId(NAMING_CONTROL.formatServiceName(serviceName), Layer.nameOf(layer).isNormal()); - final String instanceId = IDManager.ServiceInstanceID.buildId(serviceId, namingControl.formatInstanceName(serviceInstanceName)); + final String instanceId = IDManager.ServiceInstanceID.buildId(serviceId, NAMING_CONTROL.formatInstanceName(serviceInstanceName)); processRelation.setInstanceId(instanceId); processRelation.setSourceProcessId(processId); processRelation.setDestProcessId(destProcessId); diff --git a/oap-server/analyzer/log-analyzer/CLAUDE.md b/oap-server/analyzer/log-analyzer/CLAUDE.md index a7adcee94d..3a0f6b0d13 100644 --- a/oap-server/analyzer/log-analyzer/CLAUDE.md +++ b/oap-server/analyzer/log-analyzer/CLAUDE.md @@ -237,8 +237,11 @@ validates that a matching setter exists on the output type class (e.g., `setStat If no setter is found, compilation fails with an `IllegalArgumentException` at boot. **Runtime dispatch**: `RecordSinkListener.parse()` reads the output object from -`ExecutionContext.output()` (already populated by generated code), calls `init()` for -builder mode, then `build()` dispatches via `complete()` or `sourceReceiver.receive()`. +`ExecutionContext.output()` (already populated by generated code), calls +`init(logData, extraLog, moduleManager)` to populate standard fields and resolve +services (e.g., `NamingControl`, `ConfigService`) from `ModuleManager`, then `build()` +dispatches via `complete(sourceReceiver)`. Each builder caches resolved services in +static fields so `ModuleManager` lookups only happen once. Note: `slowSql {}` and `sampledTrace {}` sub-DSLs were removed. Custom output types use the `outputType` + output field mechanism instead of dedicated DSL blocks. diff --git a/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/log/listener/RecordSinkListener.java b/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/log/listener/RecordSinkListener.java index 2f7c16cb91..11e741db7d 100644 --- a/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/log/listener/RecordSinkListener.java +++ b/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/log/listener/RecordSinkListener.java @@ -17,20 +17,14 @@ package org.apache.skywalking.oap.log.analyzer.v2.provider.log.listener; -import java.util.Arrays; -import java.util.List; import java.util.Optional; import lombok.SneakyThrows; import org.apache.skywalking.apm.network.logging.v3.LogData; import org.apache.skywalking.oap.log.analyzer.v2.dsl.ExecutionContext; import org.apache.skywalking.oap.log.analyzer.v2.provider.LogAnalyzerModuleConfig; -import org.apache.skywalking.oap.server.core.Const; import org.apache.skywalking.oap.server.core.CoreModule; -import org.apache.skywalking.oap.server.core.config.ConfigService; -import org.apache.skywalking.oap.server.core.config.NamingControl; import org.apache.skywalking.oap.server.core.source.LALOutputBuilder; -import org.apache.skywalking.oap.server.core.source.LogBuilder; import org.apache.skywalking.oap.server.core.source.SourceReceiver; import org.apache.skywalking.oap.server.library.module.ModuleManager; import org.slf4j.Logger; @@ -46,17 +40,14 @@ import org.slf4j.LoggerFactory; public class RecordSinkListener implements LogSinkListener { private static final Logger LOGGER = LoggerFactory.getLogger(RecordSinkListener.class); private final SourceReceiver sourceReceiver; - private final NamingControl namingControl; - private final List<String> searchableTagKeys; + private final ModuleManager moduleManager; private LALOutputBuilder builder; RecordSinkListener(final SourceReceiver sourceReceiver, - final NamingControl namingControl, - final List<String> searchableTagKeys) { + final ModuleManager moduleManager) { this.sourceReceiver = sourceReceiver; - this.namingControl = namingControl; - this.searchableTagKeys = searchableTagKeys; + this.moduleManager = moduleManager; } @Override @@ -87,12 +78,9 @@ public class RecordSinkListener implements LogSinkListener { return this; } builder = ctx.outputAsBuilder(); - if (builder instanceof LogBuilder) { - ((LogBuilder) builder).setSearchableTagKeys(searchableTagKeys); - } // Pass the input data matching the declared inputType: // extraLog (e.g., HTTPAccessLogEntry) when present, otherwise LogData. - builder.init(logData.build(), extraLog, namingControl); + builder.init(logData.build(), extraLog, moduleManager); return this; } @@ -102,25 +90,18 @@ public class RecordSinkListener implements LogSinkListener { public static class Factory implements LogSinkListenerFactory { private final SourceReceiver sourceReceiver; - private final NamingControl namingControl; - private final List<String> searchableTagKeys; + private final ModuleManager moduleManager; public Factory(ModuleManager moduleManager, LogAnalyzerModuleConfig moduleConfig) { this.sourceReceiver = moduleManager.find(CoreModule.NAME) .provider() .getService(SourceReceiver.class); - this.namingControl = moduleManager.find(CoreModule.NAME) - .provider() - .getService(NamingControl.class); - ConfigService configService = moduleManager.find(CoreModule.NAME) - .provider() - .getService(ConfigService.class); - this.searchableTagKeys = Arrays.asList(configService.getSearchableLogsTags().split(Const.COMMA)); + this.moduleManager = moduleManager; } @Override public RecordSinkListener create() { - return new RecordSinkListener(sourceReceiver, namingControl, searchableTagKeys); + return new RecordSinkListener(sourceReceiver, moduleManager); } } } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/LALOutputBuilder.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/LALOutputBuilder.java index 94c4ed4886..fad33dd9a8 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/LALOutputBuilder.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/LALOutputBuilder.java @@ -20,7 +20,7 @@ package org.apache.skywalking.oap.server.core.source; import java.util.Optional; import org.apache.skywalking.apm.network.logging.v3.LogData; -import org.apache.skywalking.oap.server.core.config.NamingControl; +import org.apache.skywalking.oap.server.library.module.ModuleManager; /** * Interface for LAL output builders that produce {@link Source} objects from @@ -54,11 +54,12 @@ public interface LALOutputBuilder { * Called once per log entry. * * @param logData log metadata (service, layer, timestamp, trace context, etc.) - * @param extraLog optional extra input whose type matches - * {@code LALSourceTypeProvider#inputType()} for the layer - * (e.g., {@code HTTPAccessLogEntry} for envoy access logs) + * @param extraLog optional extra input whose type matches + * {@code LALSourceTypeProvider#inputType()} for the layer + * (e.g., {@code HTTPAccessLogEntry} for envoy access logs) + * @param moduleManager module manager for resolving services (e.g., NamingControl) */ - void init(LogData logData, Optional<Object> extraLog, NamingControl namingControl); + void init(LogData logData, Optional<Object> extraLog, ModuleManager moduleManager); /** * Validate the builder state and dispatch the final output source(s). diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/LogBuilder.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/LogBuilder.java index a7d2cbdcbf..96f7f7a294 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/LogBuilder.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/LogBuilder.java @@ -19,6 +19,7 @@ package org.apache.skywalking.oap.server.core.source; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -31,12 +32,16 @@ import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.apm.network.logging.v3.LogData; import org.apache.skywalking.apm.network.logging.v3.LogDataBody; import org.apache.skywalking.apm.network.logging.v3.TraceContext; +import org.apache.skywalking.oap.server.core.Const; +import org.apache.skywalking.oap.server.core.CoreModule; import org.apache.skywalking.oap.server.core.analysis.IDManager; import org.apache.skywalking.oap.server.core.analysis.TimeBucket; import org.apache.skywalking.oap.server.core.analysis.manual.searchtag.Tag; import org.apache.skywalking.oap.server.core.analysis.manual.searchtag.TagType; +import org.apache.skywalking.oap.server.core.config.ConfigService; import org.apache.skywalking.oap.server.core.config.NamingControl; import org.apache.skywalking.oap.server.core.query.type.ContentType; +import org.apache.skywalking.oap.server.library.module.ModuleManager; import org.apache.skywalking.oap.server.library.util.StringUtil; /** @@ -47,11 +52,11 @@ import org.apache.skywalking.oap.server.library.util.StringUtil; public class LogBuilder implements LALOutputBuilder { public static final String NAME = "Log"; - private NamingControl namingControl; - private LogData logData; + private static NamingControl NAMING_CONTROL; + private static List<String> SEARCHABLE_TAG_KEYS; + private static boolean INITIALIZED; - @Setter - private List<String> searchableTagKeys; + private LogData logData; @Setter private String service; @@ -91,8 +96,18 @@ public class LogBuilder implements LALOutputBuilder { @Override public void init(final LogData logData, final Optional<Object> extraLog, - final NamingControl namingControl) { - this.namingControl = namingControl; + final ModuleManager moduleManager) { + if (!INITIALIZED) { + NAMING_CONTROL = moduleManager.find(CoreModule.NAME) + .provider() + .getService(NamingControl.class); + final ConfigService configService = moduleManager.find(CoreModule.NAME) + .provider() + .getService(ConfigService.class); + SEARCHABLE_TAG_KEYS = Arrays.asList( + configService.getSearchableLogsTags().split(Const.COMMA)); + INITIALIZED = true; + } this.logData = logData; // Only populate fields that were NOT already set by the LAL extractor. // The extractor runs before init(), so extractor values take priority. @@ -139,19 +154,19 @@ public class LogBuilder implements LALOutputBuilder { log.setTimeBucket(TimeBucket.getRecordTimeBucket(timestamp)); // service - final String serviceName = namingControl.formatServiceName(service); + final String serviceName = NAMING_CONTROL.formatServiceName(service); final String serviceId = IDManager.ServiceID.buildId(serviceName, true); log.setServiceId(serviceId); // service instance if (StringUtil.isNotEmpty(serviceInstance)) { log.setServiceInstanceId(IDManager.ServiceInstanceID.buildId( serviceId, - namingControl.formatInstanceName(serviceInstance) + NAMING_CONTROL.formatInstanceName(serviceInstance) )); } // endpoint if (StringUtil.isNotEmpty(endpoint)) { - final String endpointName = namingControl.formatEndpointName(serviceName, endpoint); + final String endpointName = NAMING_CONTROL.formatEndpointName(serviceName, endpoint); log.setEndpointId(IDManager.EndpointID.buildId(serviceId, endpointName)); } // trace @@ -188,16 +203,16 @@ public class LogBuilder implements LALOutputBuilder { private Collection<Tag> collectSearchableTags() { final HashSet<Tag> result = new HashSet<>(); - if (searchableTagKeys != null) { + if (SEARCHABLE_TAG_KEYS != null) { // Tags from original LogData logData.getTags().getDataList().forEach(kv -> { - if (searchableTagKeys.contains(kv.getKey())) { + if (SEARCHABLE_TAG_KEYS.contains(kv.getKey())) { addSearchableTag(result, kv.getKey(), kv.getValue()); } }); // Tags added by LAL extractor for (final String[] kv : lalTags) { - if (searchableTagKeys.contains(kv[0])) { + if (SEARCHABLE_TAG_KEYS.contains(kv[0])) { addSearchableTag(result, kv[0], kv[1]); } } diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAccessLogBuilder.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAccessLogBuilder.java index 69b0df6de7..60ba08618c 100644 --- a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAccessLogBuilder.java +++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAccessLogBuilder.java @@ -22,10 +22,10 @@ import com.google.protobuf.Message; import java.util.Optional; import lombok.SneakyThrows; import org.apache.skywalking.apm.network.logging.v3.LogData; -import org.apache.skywalking.oap.server.core.config.NamingControl; import org.apache.skywalking.oap.server.core.query.type.ContentType; import org.apache.skywalking.oap.server.core.source.Log; import org.apache.skywalking.oap.server.core.source.LogBuilder; +import org.apache.skywalking.oap.server.library.module.ModuleManager; import org.apache.skywalking.oap.server.library.util.ProtoBufJsonUtils; /** @@ -51,9 +51,9 @@ public class EnvoyAccessLogBuilder extends LogBuilder { @Override public void init(final LogData logData, final Optional<Object> extraLog, - final NamingControl namingControl) { + final ModuleManager moduleManager) { extraLog.ifPresent(entry -> this.accessLogEntry = entry); - super.init(logData, extraLog, namingControl); + super.init(logData, extraLog, moduleManager); } @Override diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAccessLogBuilderTest.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAccessLogBuilderTest.java index 9e257fd376..7bc3b0f89d 100644 --- a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAccessLogBuilderTest.java +++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAccessLogBuilderTest.java @@ -53,11 +53,26 @@ import static org.mockito.Mockito.when; class EnvoyAccessLogBuilderTest { - private NamingControl namingControl; + private ModuleManager moduleManager; @BeforeEach void setUp() { - namingControl = new NamingControl(512, 512, 512, new EndpointNameGrouping()); + resetLogBuilderState(); + moduleManager = buildModuleManager(); + } + + private static ModuleManager buildModuleManager() { + final ModuleManager manager = mock(ModuleManager.class); + final ModuleProviderHolder coreHolder = mock(ModuleProviderHolder.class); + final ModuleServiceHolder coreServices = mock(ModuleServiceHolder.class); + when(coreHolder.provider()).thenReturn(coreServices); + when(manager.find(CoreModule.NAME)).thenReturn(coreHolder); + when(coreServices.getService(NamingControl.class)) + .thenReturn(new NamingControl(512, 512, 512, new EndpointNameGrouping())); + final ConfigService configService = mock(ConfigService.class); + when(configService.getSearchableLogsTags()).thenReturn(""); + when(coreServices.getService(ConfigService.class)).thenReturn(configService); + return manager; } @Test @@ -76,7 +91,7 @@ class EnvoyAccessLogBuilderTest { .setService("test-svc") .setTimestamp(1609459200000L) .build(); - builder.init(logData, Optional.of(entry), namingControl); + builder.init(logData, Optional.of(entry), moduleManager); final Log log = builder.toLog(); @@ -99,7 +114,7 @@ class EnvoyAccessLogBuilderTest { .setTimestamp(1609459200000L) .build(); // Pass a default (empty) entry — no response code, so toLog() serializes empty JSON - builder.init(logData, Optional.of(HTTPAccessLogEntry.getDefaultInstance()), namingControl); + builder.init(logData, Optional.of(HTTPAccessLogEntry.getDefaultInstance()), moduleManager); final Log log = builder.toLog(); @@ -175,8 +190,13 @@ class EnvoyAccessLogBuilderTest { // Tags are stored in the output builder (via addTag), not in LogData. // To verify, call init + toLog and check the Log's searchable tags. final EnvoyAccessLogBuilder output = (EnvoyAccessLogBuilder) ctx.output(); - output.setSearchableTagKeys(java.util.Arrays.asList("status.code", "svc")); - output.init(logData.build(), Optional.of(entry), namingControl); + // Build a moduleManager with searchable tag keys for this test + final ModuleManager testMm = buildModuleManager(); + final ConfigService cs = testMm.find(CoreModule.NAME).provider().getService(ConfigService.class); + when(cs.getSearchableLogsTags()).thenReturn("status.code,svc"); + // Reset static initialized flag so the new config takes effect + resetLogBuilderState(); + output.init(logData.build(), Optional.of(entry), testMm); final Log log = output.toLog(); assertTrue(log.getTags().stream().anyMatch( @@ -225,6 +245,17 @@ class EnvoyAccessLogBuilderTest { return filterSpec; } + private static void resetLogBuilderState() { + try { + final java.lang.reflect.Field f = org.apache.skywalking.oap.server.core.source.LogBuilder.class + .getDeclaredField("INITIALIZED"); + f.setAccessible(true); + f.set(null, false); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + private static void assertTrue(final boolean condition, final String message) { org.junit.jupiter.api.Assertions.assertTrue(condition, message); } diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAlsLalTest.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAlsLalTest.java index 974f4ff42b..9a9cb6a96e 100644 --- a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAlsLalTest.java +++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/persistence/EnvoyAlsLalTest.java @@ -70,10 +70,11 @@ import static org.mockito.Mockito.when; class EnvoyAlsLalTest { private LALClassGenerator generator; - private NamingControl namingControl; + private ModuleManager moduleManager; @BeforeEach void setUp(final TestInfo testInfo) { + resetLogBuilderState(); generator = new LALClassGenerator(new ClassPool(true)); generator.setInputType(HTTPAccessLogEntry.class); generator.setOutputType(EnvoyAccessLogBuilder.class); @@ -81,8 +82,32 @@ class EnvoyAlsLalTest { final String methodName = testInfo.getTestMethod() .map(m -> m.getName()).orElse("unknown"); generator.setClassNameHint("EnvoyAlsLalTest_" + methodName); - namingControl = new NamingControl( - 512, 512, 512, new EndpointNameGrouping()); + moduleManager = buildCoreModuleManager(""); + } + + private static ModuleManager buildCoreModuleManager(final String searchableTags) { + final ModuleManager manager = mock(ModuleManager.class); + final ModuleProviderHolder coreHolder = mock(ModuleProviderHolder.class); + final ModuleServiceHolder coreServices = mock(ModuleServiceHolder.class); + when(coreHolder.provider()).thenReturn(coreServices); + when(manager.find(CoreModule.NAME)).thenReturn(coreHolder); + when(coreServices.getService(NamingControl.class)) + .thenReturn(new NamingControl(512, 512, 512, new EndpointNameGrouping())); + final ConfigService configService = mock(ConfigService.class); + when(configService.getSearchableLogsTags()).thenReturn(searchableTags); + when(coreServices.getService(ConfigService.class)).thenReturn(configService); + return manager; + } + + private static void resetLogBuilderState() { + try { + final Field f = org.apache.skywalking.oap.server.core.source.LogBuilder.class + .getDeclaredField("INITIALIZED"); + f.setAccessible(true); + f.set(null, false); + } catch (Exception e) { + throw new RuntimeException(e); + } } // ==================== def + toJson: JWT from filter_metadata =========== @@ -303,8 +328,11 @@ class EnvoyAlsLalTest { assertNotNull(ctx.output()); final EnvoyAccessLogBuilder output = (EnvoyAccessLogBuilder) ctx.output(); - output.setSearchableTagKeys(java.util.Arrays.asList(searchableTagKeys)); - output.init(ctx.log().build(), Optional.of(entry), namingControl); + // Reset and rebuild with the desired searchable tag keys + resetLogBuilderState(); + final ModuleManager tagMm = buildCoreModuleManager( + String.join(",", searchableTagKeys)); + output.init(ctx.log().build(), Optional.of(entry), tagMm); return output.toLog(); } @@ -347,7 +375,7 @@ class EnvoyAlsLalTest { when(coreServices.getService(SourceReceiver.class)) .thenReturn(mock(SourceReceiver.class)); when(coreServices.getService(NamingControl.class)) - .thenReturn(namingControl); + .thenReturn(new NamingControl(512, 512, 512, new EndpointNameGrouping())); final ConfigService configService = mock(ConfigService.class); when(configService.getSearchableLogsTags()).thenReturn(""); when(coreServices.getService(ConfigService.class))
