This is an automated email from the ASF dual-hosted git repository. wu-sheng pushed a commit to branch oal-debug-fields-codegen in repository https://gitbox.apache.org/repos/asf/skywalking.git
commit 7acf1d20a2100a3a8f7107cda2e03d1723f0d796 Author: Wu Sheng <[email protected]> AuthorDate: Sat May 9 20:32:07 2026 +0800 DSL debugger (OAL): emit source @ScopeDefaultColumn fields on output sample via codegen The terminal `output` sample of an OAL debug session was missing the source-derived @Column fields that the OAL-generated subclass carries on its instance — entityId + attr0..attr5 for any Service-style scope. Operators inspecting `service_cpm` saw only `total` / `value` from CPMMetrics.appendDebugFields; the layer name written to attr0 by ServiceDecorator (and any other source attributes) was on the live object and in the storage row, but invisible in the debug capture. Why the gap: `attr0..attr5` are NOT inherited from a fixed parent for OAL — they're declared on the source class via `@ScopeDefaultColumn.DefinedByField` and copied to the generated metrics subclass at OAL boot by `OALClassGeneratorV2.generateMetricsClass` (line 220, the per-source-field `addField` loop). The family parent (CPMMetrics, SumMetrics, ...) doesn't know they exist, so its `appendDebugFields` override can't surface them. Reflection-based or `Convert2Storage` shim approaches were considered; codegen-side generation is the right scope — the same pass that materialises the fields also emits their debug projection. Adds `appendDebugFields` to METRICS_CLASS_METHODS so the existing template loop generates an override on every OAL-generated `*Metrics` subclass. The override calls `super.appendDebugFields(obj)` first (delegating the family's value columns — total / value / summation / ...) then iterates `fieldsFromSource` to emit each @ScopeDefaultColumn-declared field with the right typed `obj.addProperty(...)` overload (Long / Integer / Double / Float / Boolean wrappers for primitives so Javassist resolves the `addProperty(String, Number)` overload unambiguously; null-safe `toString()` for object types). Verification: - `mvn test -pl oap-server/oal-rt`: 98/98 pass. - After deploy, an OAL debug session against `oal/core.oal` / `service_cpm` will show `payload.attr0=GENERAL` (set by ServiceDecorator) on the terminal output sample, alongside the family's `total` and `value`. Cost: zero when `SW_DSL_DEBUGGING_INJECTION_ENABLED=false` (codegen emits an `appendDebugFields` override either way; it's only invoked from `Metrics.toJson()` which is only called by the gated debug recorder). When debug is on, one extra method call per probed emit per debug session. --- .../oal/v2/generator/OALClassGeneratorV2.java | 11 ++++++++++- .../code-templates-v2/metrics/appendDebugFields.ftl | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/v2/generator/OALClassGeneratorV2.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/v2/generator/OALClassGeneratorV2.java index 3313ca8288..b50a142462 100644 --- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/v2/generator/OALClassGeneratorV2.java +++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/v2/generator/OALClassGeneratorV2.java @@ -89,7 +89,16 @@ public class OALClassGeneratorV2 { "deserialize", "getMeta", "toHour", - "toDay" + "toDay", + // Emits the source's @ScopeDefaultColumn fields (the codegen- + // materialised dynamic @Column fields on the generated subclass) + // onto the dsl-debugging `output` sample. For a Service-style + // scope that is exactly entityId + attr0..attr5 — nothing about + // the metric's own value, which is delegated upward via + // super.appendDebugFields(obj) to the family parent's override + // (CPMMetrics emits total + value, SumMetrics emits value, + // LongAvgMetrics emits summation + count + value, …). + "appendDebugFields" }; private static final String[] METRICS_BUILDER_CLASS_METHODS = { "entity2Storage", diff --git a/oap-server/oal-rt/src/main/resources/code-templates-v2/metrics/appendDebugFields.ftl b/oap-server/oal-rt/src/main/resources/code-templates-v2/metrics/appendDebugFields.ftl new file mode 100644 index 0000000000..0af18f7a90 --- /dev/null +++ b/oap-server/oal-rt/src/main/resources/code-templates-v2/metrics/appendDebugFields.ftl @@ -0,0 +1,18 @@ +protected void appendDebugFields(com.google.gson.JsonObject obj) { +super.appendDebugFields(obj); +<#list fieldsFromSource as field> + <#if field.typeName == "long"> + obj.addProperty("${field.columnName}", java.lang.Long.valueOf(${field.fieldGetter}())); + <#elseif field.typeName == "int"> + obj.addProperty("${field.columnName}", java.lang.Integer.valueOf(${field.fieldGetter}())); + <#elseif field.typeName == "double"> + obj.addProperty("${field.columnName}", java.lang.Double.valueOf(${field.fieldGetter}())); + <#elseif field.typeName == "float"> + obj.addProperty("${field.columnName}", java.lang.Float.valueOf(${field.fieldGetter}())); + <#elseif field.typeName == "boolean"> + obj.addProperty("${field.columnName}", java.lang.Boolean.valueOf(${field.fieldGetter}())); + <#else> + obj.addProperty("${field.columnName}", ${field.fieldGetter}() == null ? null : ${field.fieldGetter}().toString()); + </#if> +</#list> +}
