diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md index 530894769270..5ca2ad79efe9 100644 --- a/docs/en/changes/changes.md +++ b/docs/en/changes/changes.md @@ -36,6 +36,7 @@ * Fix LAL `layer: auto` mode dropping logs after extractor set the layer. Codegen now propagates `layer "..."` assignments to `LogMetadata.layer` so `FilterSpec.doSink()` sees the script-decided layer. * Fix MetricKit histogram percentile metrics being reported at 1000× their true value — the listener now marks its `SampleFamily` with `defaultHistogramBucketUnit(MILLISECONDS)` so MAL's default SECONDS→MS rescale of `le` labels is not applied. * Add WeChat and Alipay Mini Program monitoring via the SkyAPM mini-program-monitor SDK (SWIP-12). Two new layers (`WECHAT_MINI_PROGRAM`, `ALIPAY_MINI_PROGRAM`); two new JavaScript componentIds (`WeChat-MiniProgram: 10002`, `AliPay-MiniProgram: 10003`). Service / instance / endpoint entities are produced by MAL + LAL, not trace analysis — mini-programs are client-side (exit-only) so `RPCAnalysisListener` stays unchanged (same pattern as browser and iOS). MAL rules per platform × scope under `otel-rules/miniprogram/` with explicit `.service(...)` / `.endpoint(...)` chains (empty `expSuffix` so endpoint-scope rules aren't overridden), histogram percentile via `.histogram("le", TimeUnit.MILLISECONDS)` to keep ms bucket bounds intact, and request-cpm derived from the histogram `_count` family. LAL `layer: auto` rule produces both layers via `miniprogram.platform` dispatch and emits error-count samples consumed by per-platform log-MAL rules. Per-layer menu entries and service / instance / endpoint dashboards with Trace and Log sub-tabs. +* Fix: remove `VirtualServiceAnalysisListener`'s dependency on `GenAIAnalyzerModule` if it is disabled. * MAL: register `TimeUnit` in `MALCodegenHelper.ENUM_FQCN` so rule YAML can write `.histogram("le", TimeUnit.MILLISECONDS)` for SDKs that emit histogram bucket bounds in ms (default `SECONDS` unit applies a ×1000 rescale that would otherwise inflate stored `le` labels 1000×). #### UI diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/VirtualServiceAnalysisListener.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/VirtualServiceAnalysisListener.java index 1d48dd2a386b..74ef7986fd49 100644 --- a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/VirtualServiceAnalysisListener.java +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/VirtualServiceAnalysisListener.java @@ -18,7 +18,7 @@ package org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener; -import java.util.Arrays; +import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; @@ -82,22 +82,25 @@ public Factory(ModuleManager moduleManager) { this.namingControl = moduleManager.find(CoreModule.NAME) .provider() .getService(NamingControl.class); - this.genAIMeterAnalyzerService = moduleManager.find(GenAIAnalyzerModule.NAME) - .provider() - .getService(IGenAIMeterAnalyzerService.class); + if (moduleManager.has(GenAIAnalyzerModule.NAME)) { + this.genAIMeterAnalyzerService = moduleManager.find(GenAIAnalyzerModule.NAME) + .provider() + .getService(IGenAIMeterAnalyzerService.class); + } else { + this.genAIMeterAnalyzerService = null; + } } @Override public AnalysisListener create(ModuleManager moduleManager, AnalyzerModuleConfig config) { - return new VirtualServiceAnalysisListener( - sourceReceiver, - Arrays.asList( - new VirtualCacheProcessor(namingControl, config), - new VirtualDatabaseProcessor(namingControl, config), - new VirtualMQProcessor(namingControl), - new VirtualGenAIProcessor(genAIMeterAnalyzerService) - ) - ); + List processors = new ArrayList<>(); + processors.add(new VirtualCacheProcessor(namingControl, config)); + processors.add(new VirtualDatabaseProcessor(namingControl, config)); + processors.add(new VirtualMQProcessor(namingControl)); + if (genAIMeterAnalyzerService != null) { + processors.add(new VirtualGenAIProcessor(genAIMeterAnalyzerService)); + } + return new VirtualServiceAnalysisListener(sourceReceiver, processors); } }