This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new d8b97f8e5b LAL: move service resolution into LALOutputBuilder, fix tag
assignment restriction (#13741)
d8b97f8e5b is described below
commit d8b97f8e5b5e0766217490915f2871167491b8fb
Author: 吴晟 Wu Sheng <[email protected]>
AuthorDate: Thu Mar 12 15:48:44 2026 +0800
LAL: move service resolution into LALOutputBuilder, fix tag assignment
restriction (#13741)
1. Refactor LALOutputBuilder.init() to take ModuleManager instead of
NamingControl. Each builder (LogBuilder, DatabaseSlowStatementBuilder,
SampledTraceBuilder, EnvoyAccessLogBuilder) now resolves its own
services and caches them in static fields. RecordSinkListener no
longer holds NamingControl, searchableTagKeys, or instanceof checks.
2. Fix bug where LAL tag assignments were incorrectly restricted to
LogBuilder via isAssignableFrom check, blocking any other output
builder from defining addTag(String, String).
---
.../listener/DatabaseSlowStatementBuilder.java | 22 ++++++++---
.../trace/parser/listener/SampledTraceBuilder.java | 24 +++++++++---
oap-server/analyzer/log-analyzer/CLAUDE.md | 7 +++-
.../log/analyzer/v2/compiler/LALBlockCodegen.java | 12 ------
.../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 +++++++++++++++++---
10 files changed, 154 insertions(+), 83 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/compiler/LALBlockCodegen.java
b/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/compiler/LALBlockCodegen.java
index d3f2647150..629edf7f4e 100644
---
a/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/compiler/LALBlockCodegen.java
+++
b/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/compiler/LALBlockCodegen.java
@@ -288,18 +288,6 @@ final class LALBlockCodegen {
static void generateTagAssignment(final StringBuilder sb,
final LALScriptModel.TagAssignment tag,
final LALClassGenerator.GenCtx genCtx) {
- // tag assignments are only supported on LogBuilder (the default
output type).
- // Other output types (e.g. SampledTraceBuilder,
DatabaseSlowStatementBuilder)
- // do not carry tags — fail at compile time instead of silently
dropping them.
- if (genCtx.outputType != null
- &&
!org.apache.skywalking.oap.server.core.source.LogBuilder.class
- .isAssignableFrom(genCtx.outputType)) {
- throw new IllegalArgumentException(
- "LAL 'tag' assignments are only supported when outputType is
LogBuilder"
- + " (or default), but the resolved outputType is "
- + genCtx.outputType.getName()
- + ". Remove the 'tag' statements or change the
outputType.");
- }
for (final Map.Entry<String, LALScriptModel.TagValue> entry
: tag.getTags().entrySet()) {
sb.append(" _o.addTag(\"")
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))