Skip to content

Implement SWIP-12: WeChat & Alipay Mini Program monitoring#13835

Merged
wu-sheng merged 14 commits intomasterfrom
feature/swip12-miniprogram-impl
Apr 21, 2026
Merged

Implement SWIP-12: WeChat & Alipay Mini Program monitoring#13835
wu-sheng merged 14 commits intomasterfrom
feature/swip12-miniprogram-impl

Conversation

@wu-sheng
Copy link
Copy Markdown
Member

Implement SWIP-12 — WeChat & Alipay Mini Program monitoring

This PR implements the SWIP-12 design (already merged in #13834) end to end. The SDK side (SkyAPM mini-program-monitor) has already shipped v0.4.0 with the componentIds / miniprogram.platform tag / clean serviceInstance defaults that this implementation depends on.

Delivered in 5 staged commits for reviewability:

Stage 1 — Layer enum, componentIds, listener layer mapping. Adds WECHAT_MINI_PROGRAM(48) and ALIPAY_MINI_PROGRAM(49) to Layer.java; registers WeChat-MiniProgram: 10002 and AliPay-MiniProgram: 10003 under the JavaScript block of component-libraries.yml; refactors CommonAnalysisListener to take IComponentLibraryCatalogService via constructor and extends identifyServiceLayer(SpanLayer) to also accept componentId so SDK-emitted exit spans land on the correct layer. All 5 call sites in RPCAnalysisListener + EndpointDepFromCrossThreadAnalysisListener pass span.getComponentId() through. Factories resolve the catalog service from CoreModule. No new SPI — the existing SegmentParserListenerManager pipeline picks up the new mapping automatically. Existing listener unit tests updated with a mock catalog stubbed to return 10002/10003 so span componentId=0 doesn't accidentally collide.

Stage 2 — MAL / LAL / log-MAL rules + application.yml wiring. Four MAL files under otel-rules/miniprogram/ — per-platform (WeChat / Alipay) × per-scope (service / instance), each with a top-level filter gating on miniprogram_platform so the two layers never double-count. Service-scoped rules follow the iOS precedent of avoiding service_instance_id fragmentation, and add endpoint-scoped variants via the chained .endpoint(...) override (APISIX pattern) so per-page dashboards populate from the same file. Alipay drops the WeChat-only metrics (route_duration, script_duration, package_load_duration, first_paint). One LAL file lal/miniprogram.yaml uses layer: auto and script-side dispatch on miniprogram.platform — one rule file produces two layers. Its metrics {} block emits miniprogram_error_count samples that the log-MAL rule log-mal-rules/miniprogram.yaml aggregates into per-layer error_count. application.yml defaults append miniprogram/* to enabledOtelMetricsRules and miniprogram to lalFiles / malFiles.

Note: the SWIP draft's ternary-in-layer expression and the nested metrics { metric_name { … } } block form don't match the actual LAL grammar — rewritten as if/else-if and the flat name/labels/value/timestamp form the grammar accepts.

Stage 3 — UI dashboards + menu. Two new folders (ui-initialized-templates/wechat_mini_program/ and alipay_mini_program/), each shipping 4 JSON templates: -root (isRoot: true, service-list landing), -service (Tab with Overview / Instance / Endpoint / Trace / Log), -instance (per-version perf), -endpoint (per-page perf). WeChat dashboards use the full perf set; Alipay drops WeChat-only metrics and labels launch/render panels as approximations. Service dashboard adds a dedicated Trace tab — native segments are queryable in the normal trace UI, unlike iOS. menu.yaml extends the Mobile group (added by SWIP-11) with two new entries. UITemplateCheckerTest passes.

Stage 4 — Docs. docs/en/setup/backend/backend-wechat-mini-program-monitoring.md and backend-alipay-mini-program-monitoring.md with prerequisites, OAP configuration (when defaults are overridden), SDK setup snippet, metric catalog, error-log categories, entity model, SDK version compatibility (v0.2.x / v0.3.x / v0.4.0+), dashboard overview, platform-specific limitations. docs/menu.yml extended under Mobile Monitoring. Changelog entry under OAP Server and Documentation. SWIP readme and security README were already updated in the design PR — left untouched.

Stage 5 — E2E + CI matrix + config-dump. Two cases under test/e2e-v2/cases/miniprogram/{wechat,alipay}/ drive hand-crafted OTLP metric + OTLP error-log payloads via curl (iOS-style, no external sim-image dependency). Verify that service is registered under the correct layer, MAL service/instance metrics populate, log-MAL error_count is non-zero, and the LAL error log persists. Native-segment layer mapping is covered by the Stage 1 unit-test updates. Both cases registered in .github/workflows/skywalking.yaml. test/e2e-v2/cases/storage/expected/config-dump.yml mirrors the application.yml default changes so the storage e2e passes.

  • If this is non-trivial feature, paste the links/URLs to the design doc. — docs/en/swip/SWIP-12.md

  • Update the documentation to include this new feature. — two setup guides + docs/menu.yml entries + changelog

  • Tests(including UT, IT, E2E) are added to verify the new feature. — listener UT updates, two new e2e cases registered in CI

  • If it's UI related, attach the screenshots below. — dashboards render against live metric data; will attach screenshots after CI e2e runs seed data into a preview env

  • If this pull request closes/resolves/fixes an existing issue, replace the issue number. Closes #.

  • Update the CHANGES log. — entries under #### OAP Server and #### Documentation

…ping

- Add WECHAT_MINI_PROGRAM(48) and ALIPAY_MINI_PROGRAM(49) to Layer.java.
- Register WeChat-MiniProgram(10002) and AliPay-MiniProgram(10003) in
  component-libraries.yml so topology renders the SDK's exit spans
  with proper component names.
- CommonAnalysisListener now takes IComponentLibraryCatalogService via
  constructor, resolves the two mini-program component ids at
  construction time, and extends identifyServiceLayer(SpanLayer) to
  also accept componentId: mini-program component ids map to the two
  new layers, FAAS continues to map to Layer.FAAS, everything else
  remains Layer.GENERAL.
- RPCAnalysisListener (4 callsites) and
  EndpointDepFromCrossThreadAnalysisListener (1 callsite) pass
  span.getComponentId() through. Their Factory classes resolve
  IComponentLibraryCatalogService from CoreModule. No SPI change —
  the existing SegmentParserListenerManager pipeline picks up the
  new mapping automatically.
- Tests updated with a mock catalog stubbed to return 10002 / 10003
  so span componentId == 0 doesn't accidentally collide with the new
  mini-program layers.
- otel-rules/miniprogram/ ships 4 MAL files: per-platform (WeChat /
  Alipay) x per-scope (service / instance). Each has a top-level
  filter gating on miniprogram_platform so the two layers do not
  double-count. Service-scoped rules avoid service_instance_id
  fragmentation (mirrors the ios-metrickit.yaml precedent) and also
  emit endpoint-scoped variants via the chained .endpoint(...)
  override (APISIX pattern) so per-page dashboards populate from the
  same file. Alipay drops route / script / package_load / first_paint
  which are WeChat-only.

- lal/miniprogram.yaml uses layer:auto — one rule produces two layers
  via script-side dispatch on miniprogram.platform. Corrected the
  SWIP draft's ternary-in-layer (LAL grammar does not allow ternary
  in valueAccess) to if / else-if, and the draft's nested metrics
  block form to the flat form the grammar actually accepts.
  Instance source is sourceAttribute("service.instance.id") — matches
  what OTLP metrics key on, so logs land on the same OAP instance
  entity when operators follow the recommended
  serviceInstance == serviceVersion pattern.

- log-mal-rules/miniprogram.yaml aggregates the LAL metrics{}-block
  miniprogram_error_count samples into meter_wechat_mp_error_count /
  meter_alipay_mp_error_count, one YAML doc per layer with its own
  top-level filter.

- application.yml appends miniprogram/* to
  enabledOtelMetricsRules, miniprogram to lalFiles and malFiles. The
  config-dump e2e expected file (cases/storage/expected/config-dump.yml)
  must mirror this — tracked for Stage 5.
- wechat_mini_program/ and alipay_mini_program/ each ship 4 JSON
  templates: -root (isRoot=true service list), -service (Tab with
  Overview / Instance / Endpoint / Trace / Log), -instance (per-version
  perf), -endpoint (per-page perf). UITemplateInitializer auto-discovers
  these folders from Layer enum names, so the new Layer entries from
  Stage 1 wire them up automatically.

- Folder names use Layer.name().toLowerCase() (underscores, not
  hyphens) — hyphenated folders would be silently skipped by the
  discovery pass.

- WeChat dashboards include the full perf set (launch, render, route,
  script, package_load, request percentile). Alipay drops the WeChat-only
  metrics and labels launch/render as lifecycle-based approximations so
  operators don't compare them head-to-head.

- Per-service dashboard adds a Trace tab — mini-program outbound spans
  are native segments and queryable in the normal trace UI, unlike
  iOS where traces go to Zipkin.

- menu.yaml extends the existing Mobile group (added by SWIP-11 iOS)
  with two new entries pointing to the per-layer root templates.

UITemplateCheckerTest passes.
- docs/en/setup/backend/backend-wechat-mini-program-monitoring.md and
  backend-alipay-mini-program-monitoring.md — prerequisites, OAP
  configuration (when defaults are overridden), SDK setup snippet,
  metric catalog per platform, error-log categories, entity model,
  SDK version compatibility (v0.2.x / v0.3.x / v0.4.0+), dashboard
  overview, and platform-specific limitations.

- docs/menu.yml — two new entries under Mobile Monitoring pointing
  at the new setup guides.

- docs/en/changes/changes.md — entry under OAP Server summarizing the
  layer / componentId / listener mapping / rules work, and an entry
  under Documentation for the two new guides.

docs/en/swip/readme.md already lists SWIP-12 under Accepted (from the
earlier design PR) and docs/en/security/README.md's Client-Side
Monitoring section already covers mini-programs — both untouched.
- test/e2e-v2/cases/miniprogram/{wechat,alipay}/: docker-compose.yml
  boots oap+banyandb with per-platform MAL rules, LAL file, log-MAL
  file wired via env vars. e2e.yaml drives hand-crafted OTLP metric
  and OTLP error-log payloads via curl (iOS-style, no external sim
  image dependency — the skyapm sim images are referenced in SWIP §10
  for the showcase but not pinned for OAP CI).

  Verify cases cover:
  * service registered under the correct layer
    (WECHAT_MINI_PROGRAM / ALIPAY_MINI_PROGRAM)
  * service-scoped MAL metric (app_launch_duration, first_render_duration)
    populated
  * log-MAL derived meter_*_mp_error_count non-zero
  * instance metric populated when serviceInstance == serviceVersion
  * LAL-persisted error log visible in logs query

  Native-segment layer mapping is covered by the unit tests updated
  in Stage 1 (RPCAnalysisListenerTest /
  EndpointDepFromCrossThreadAnalysisListenerTest).

- .github/workflows/skywalking.yaml registers both cases in the e2e
  matrix next to iOS Monitoring.

- test/e2e-v2/cases/storage/expected/config-dump.yml mirrors the
  application.yml default changes from Stage 2
  (enabledOtelMetricsRules, lalFiles, malFiles). Storage e2e diffs
  /debugging/config/dump against this file.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements SWIP-12 end-to-end support for WeChat and Alipay Mini Program monitoring in SkyWalking OAP, wiring new layers through native trace analysis, OTLP metric/log rule pipelines, UI dashboards/menus, docs, and CI e2e coverage.

Changes:

  • Add WECHAT_MINI_PROGRAM / ALIPAY_MINI_PROGRAM layers and register corresponding JavaScript component IDs.
  • Introduce OTLP MAL rules + LAL/log-MAL rules and enable them by default via application.yml.
  • Ship UI templates (dashboards + menu), docs, and new e2e cases wired into the GitHub Actions matrix.

Reviewed changes

Copilot reviewed 39 out of 39 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test/e2e-v2/cases/storage/expected/config-dump.yml Updates expected config dump to reflect new default-enabled rule sets.
test/e2e-v2/cases/miniprogram/wechat/expected/service.yml Asserts WeChat service appears under the new layer in e2e.
test/e2e-v2/cases/miniprogram/wechat/expected/metrics-has-value.yml Generic assertion for non-empty metric values in WeChat e2e.
test/e2e-v2/cases/miniprogram/wechat/expected/logs.yml Asserts LAL-processed logs are queryable in WeChat e2e.
test/e2e-v2/cases/miniprogram/wechat/e2e.yaml New WeChat mini program e2e case (OTLP metrics + OTLP logs).
test/e2e-v2/cases/miniprogram/wechat/docker-compose.yml Compose wiring for WeChat e2e (enables miniprogram rules).
test/e2e-v2/cases/miniprogram/alipay/expected/service.yml Asserts Alipay service appears under the new layer in e2e.
test/e2e-v2/cases/miniprogram/alipay/expected/metrics-has-value.yml Generic assertion for non-empty metric values in Alipay e2e.
test/e2e-v2/cases/miniprogram/alipay/expected/logs.yml Asserts LAL-processed logs are queryable in Alipay e2e.
test/e2e-v2/cases/miniprogram/alipay/e2e.yaml New Alipay mini program e2e case (OTLP metrics + OTLP logs).
test/e2e-v2/cases/miniprogram/alipay/docker-compose.yml Compose wiring for Alipay e2e (enables miniprogram rules).
oap-server/server-starter/src/main/resources/ui-initialized-templates/wechat_mini_program/wechat_mini_program-service.json WeChat service dashboard template (Overview/Instance/Endpoint/Trace/Log).
oap-server/server-starter/src/main/resources/ui-initialized-templates/wechat_mini_program/wechat_mini_program-root.json WeChat layer landing page (service list + docs link text).
oap-server/server-starter/src/main/resources/ui-initialized-templates/wechat_mini_program/wechat_mini_program-instance.json WeChat instance (version) dashboard template.
oap-server/server-starter/src/main/resources/ui-initialized-templates/wechat_mini_program/wechat_mini_program-endpoint.json WeChat endpoint (page) dashboard template.
oap-server/server-starter/src/main/resources/ui-initialized-templates/alipay_mini_program/alipay_mini_program-service.json Alipay service dashboard template (Alipay-specific metric set).
oap-server/server-starter/src/main/resources/ui-initialized-templates/alipay_mini_program/alipay_mini_program-root.json Alipay layer landing page (service list + docs link text).
oap-server/server-starter/src/main/resources/ui-initialized-templates/alipay_mini_program/alipay_mini_program-instance.json Alipay instance (version) dashboard template.
oap-server/server-starter/src/main/resources/ui-initialized-templates/alipay_mini_program/alipay_mini_program-endpoint.json Alipay endpoint (page) dashboard template.
oap-server/server-starter/src/main/resources/ui-initialized-templates/menu.yaml Adds Mobile menu entries for WeChat/Alipay mini program layers.
oap-server/server-starter/src/main/resources/otel-rules/miniprogram/wechat-mini-program.yaml WeChat service-scope MAL rules (+ endpoint variants).
oap-server/server-starter/src/main/resources/otel-rules/miniprogram/wechat-mini-program-instance.yaml WeChat instance-scope MAL rules.
oap-server/server-starter/src/main/resources/otel-rules/miniprogram/alipay-mini-program.yaml Alipay service-scope MAL rules (+ endpoint variants).
oap-server/server-starter/src/main/resources/otel-rules/miniprogram/alipay-mini-program-instance.yaml Alipay instance-scope MAL rules.
oap-server/server-starter/src/main/resources/log-mal-rules/miniprogram.yaml Aggregates LAL-emitted error counter samples into per-layer error_count.
oap-server/server-starter/src/main/resources/lal/miniprogram.yaml LAL rule for mini program error logs (layer:auto + metrics emission).
oap-server/server-starter/src/main/resources/component-libraries.yml Registers WeChat/Alipay mini program component IDs (10002/10003).
oap-server/server-starter/src/main/resources/application.yml Enables miniprogram MAL/LAL and OTLP rules by default.
oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/RPCAnalysisListenerTest.java Updates UTs to inject component catalog for new layer mapping logic.
oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/EndpointDepFromCrossThreadAnalysisListenerTest.java Updates UTs to inject component catalog for new layer mapping logic.
oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/Layer.java Adds WECHAT_MINI_PROGRAM(48) / ALIPAY_MINI_PROGRAM(49).
oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/RPCAnalysisListener.java Passes componentId into layer identification; wires catalog service via factory.
oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/EndpointDepFromCrossThreadAnalysisListener.java Passes componentId into layer identification; wires catalog service via factory.
oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/CommonAnalysisListener.java Adds componentId-driven layer mapping for mini-program segments.
docs/menu.yml Adds docs navigation entries under Mobile Monitoring.
docs/en/setup/backend/backend-wechat-mini-program-monitoring.md New setup guide for WeChat mini program monitoring.
docs/en/setup/backend/backend-alipay-mini-program-monitoring.md New setup guide for Alipay mini program monitoring.
docs/en/changes/changes.md Adds changelog entries for SWIP-12 implementation and docs.
.github/workflows/skywalking.yaml Adds WeChat/Alipay mini program e2e cases to CI matrix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +30 to +37
private final int wechatMiniProgramComponentId;
private final int alipayMiniProgramComponentId;

protected CommonAnalysisListener(IComponentLibraryCatalogService componentLibraryCatalogService) {
this.wechatMiniProgramComponentId = componentLibraryCatalogService.getComponentId("WeChat-MiniProgram");
this.alipayMiniProgramComponentId = componentLibraryCatalogService.getComponentId("AliPay-MiniProgram");
}

Comment thread test/e2e-v2/cases/miniprogram/wechat/e2e.yaml Outdated
method: POST
headers:
Content-Type: application/json
body: '{"resourceMetrics":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"alipay-mp-demo"}},{"key":"service.version","value":{"stringValue":"v1.2.0"}},{"key":"service.instance.id","value":{"stringValue":"v1.2.0"}},{"key":"miniprogram.platform","value":{"stringValue":"alipay"}}]},"scopeMetrics":[{"scope":{"name":"mini-program-monitor"},"metrics":[{"name":"miniprogram.app_launch.duration","unit":"ms","gauge":{"dataPoints":[{"timeUnixNano":"0","asDouble":220.0,"attributes":[{"key":"miniprogram.page.path","value":{"stringValue":"pages/index/index"}}]}]}},{"name":"miniprogram.first_render.duration","unit":"ms","gauge":{"dataPoints":[{"timeUnixNano":"0","asDouble":110.0,"attributes":[{"key":"miniprogram.page.path","value":{"stringValue":"pages/index/index"}}]}]}}]}]}]}'
if (platform != "wechat" && platform != "alipay") {
abort {}
}
if (tag("exception.type") == null) {
Addresses review: mini-programs are client-side (edge), same as browser —
exit-only segments, no inbound analysis, so OAL server-side metrics
(service_cpm / resp_time / sla / endpoint_*) don't populate. The earlier
componentId-driven layer override in CommonAnalysisListener was wrong.

Changes:

- CommonAnalysisListener / RPCAnalysisListener /
  EndpointDepFromCrossThreadAnalysisListener reverted to pre-Stage-1
  state — no IComponentLibraryCatalogService injection, no componentId
  arg on identifyServiceLayer, @requiredargsconstructor restored,
  5 callsites back to single-arg form. Listener unit tests revert too.
  Layer enums (WECHAT_MINI_PROGRAM=48, ALIPAY_MINI_PROGRAM=49) and
  component-libraries.yml entries (10002/10003) stay — they are
  registration only and still power topology tooltip / UI rendering.

- MAL rules corrected:
  * bucket-family name miniprogram_request_duration_histogram
    ~> miniprogram_request_duration (PrometheusMetricConverter emits
    the bucket family without a _histogram suffix).
  * .histogram() ~> .histogram("le", TimeUnit.MILLISECONDS) — SDK
    emits bucket bounds in ms; default MAL rescale (SECONDS, scale=1000)
    would inflate 1000x.
  * Added request_cpm per-scope rule from
    miniprogram_request_duration_count.sum([...]). Histogram is
    DELTA per-flush (fits mini-program's intermittent/offline
    sessions), so MAL's 1-minute bucketing sums per-flush counts into
    requests-per-minute directly — no .rate() / .increase() needed.
  * alipay rules mirror wechat, with Alipay-only metric subset.

- MALCodegenHelper.ENUM_FQCN registers TimeUnit so rule YAML can
  write TimeUnit.MILLISECONDS (one line, enables other future rules too).

- Dashboards rewritten to pull MAL-only metrics. Removed service_cpm /
  service_resp_time / service_sla / service_instance_cpm / endpoint_cpm
  etc. (won't populate without inbound analysis). Added Request Load
  widget backed by meter_*_mp_request_cpm. Trace tab kept (segments are
  stored, queryable via standard trace UI).

- Setup docs drop the "come for free from core.oal" paragraph and
  state the browser-parity pattern explicitly.

- SWIP-12 §3a retitled "Native Trace Segments — Client-Side Pattern
  (Browser Parity)" with the correct behavior. §6 revised: standard
  pipeline, no componentId override, no listener extension.

UITemplateCheckerTest + checkstyle + full install/javadoc all pass.
Updates reflect the direction established while reviewing the
mini-program PR:

- New 'Working posture' section at the top:
  * Traces are re-used as-is for most new monitoring features. OTLP /
    Zipkin span-metrics analysis already exists and is only extended
    for genuinely new semantic-convention attributes (e.g. gen_ai.*,
    mcp.* drove GenAISpanListener). No CommonAnalysisListener edits
    unless OAP core proto introduces a new SpanLayer enum value.
  * If the work is drifting larger than this skill suggests (new
    listener, new proto/receiver, componentId-based layer overrides),
    stop and confirm before continuing.
  * Compile / checkstyle / license-eye are necessary but not
    sufficient — the new feature must be verified end-to-end locally
    against a running OAP before pushing to CI.

- §2 header reframed: the common case is 'don't touch trace analysis'.
  The anti-pattern of componentId -> layer mapping on exit-only
  client-side segments is called out explicitly, with browser / iOS /
  mini-program listed as reference layers that mirror the right
  pattern (MAL + LAL produce the Service entity; trace pipeline
  unchanged).

- §3.1 OAL caveat: 'free' core metrics (service_cpm, service_resp_time,
  endpoint_cpm, ...) only populate for layers with inbound traffic
  (parseEntry fires). Client-side / edge layers must wire dashboards
  to MAL metrics instead.

- §5.1 dashboard section: collaborate with the developer on layout +
  metric selection, then manually set up the feature against a live
  OAP to confirm every widget renders non-empty before shipping.

- §9 traps table: two new entries for the client-side trace-analysis
  anti-pattern and for dashboards wired to OAL metrics that never
  populate.
CI caught: MALFilterExecutionTest failed with 'expected a single document
in the stream' on log-mal-rules/miniprogram.yaml at the '---' separator.

Rules.loadRules() uses Yaml.loadAs(r, Rule.class) — single-document only.
Multi-doc YAML would also fail at OAP startup, not just in tests.

Split into two single-doc files:
- log-mal-rules/miniprogram-wechat.yaml
- log-mal-rules/miniprogram-alipay.yaml

Update application.yml malFiles default, storage e2e config-dump
expected, and both miniprogram e2e docker-compose SW_LOG_MAL_FILES
env values.

MALFilterExecutionTest + MALExpressionExecutionTest + LALScriptExecutionTest
all green locally (1302 MAL, 134 LAL).
Local end-to-end verification against ghcr.io/skyapm/mini-program-monitor/
sim-{wechat,alipay}:v0.4.0 caught three issues the CI would have caught
one-by-one:

1) LAL '#' comments don't parse — the grammar only accepts '//' (and
   '/* */' blocks). Replaced the 5-line '#' comment in lal/miniprogram.yaml
   with '//'.

2) LAL can't reference a def var as a bare value (only via method chain
   like platform?.toString). 'tag 'platform': platform' and
   'labels ... miniprogram_platform: platform' would hit 'no matching
   codegen path' at OAP startup. Rewrote the rule to call
   sourceAttribute('miniprogram.platform') inline in the three value-access
   sites, keeping the conditionals working (conditions go through a
   different codegen path and DO handle bare def refs).

3) meter_{wechat,alipay}_mp_error_count is labeled by exception_type so
   returns multiple series, not one — switched those verify cases to the
   metrics-has-value-label.yml expected shape.

E2E workflow revised to use the published sim images (MODE=timed 60s,
SCENARIO=demo, SERVICE_INSTANCE=sim, COLLECTOR_URL + TRACE_COLLECTOR_URL
pointed at oap:12800) instead of hand-crafted curl payloads. Sim drives
realistic OTLP logs + metrics + native trace segments against OAP.

Both cases verified green locally: 8/8 for wechat, 8/8 for alipay.
CI log: demo scenario fires 4+ distinct error surfaces (js / promise /
ajax / pageNotFound) producing a heterogeneous logs list. My prior
expected asserted two tag patterns (platform + exception.type) inside
the inner `contains` block; CI's go-cmp diff showed rendered-expected
as [pattern_rendered_for_A0, nil, nil, nil] which failed the length
check against actual [A0, A1, A2, A3, ...].

Minimised expected: assert service / instance / endpoint ids exist,
timestamp > 0, content non-empty, and at least one tag with
platform=wechat (resp. alipay) — enough to prove LAL dispatched to
the right layer from the right platform attribute. Drop exception.type
tag assertion; the earlier error_count metric case already proves that
channel.
…traps in run-e2e skill

CI caught: WeChat logs case failed with diff showing `- nil` at every
position in expected vs real log maps in actual. Root cause: sim-generated
log content like 'POST https://api.example.com/cart failed: 500' contains
colons; my expected used `content: {{ notEmpty .content }}` unquoted, so
after template rendering the YAML became invalid (`failed:` parsed as a
nested key) and every log entry marshalled to nil.

Fix: wrap in single quotes — `content: '{{ notEmpty .content }}'`.
`snakeyaml` preserves `:` inside single-quoted scalars.

Also addressing Copilot review comment (the only one still relevant on
the post-unwind branch): `if (tag('exception.type') == null)` in
`lal/miniprogram.yaml` never fires because LAL's `tag()` returns
empty string for missing tags, not null. Non-error logs matching the
platform filter would have passed through and emitted
`miniprogram_error_count` with an empty `exception_type` label.
Guard both: `tag(...) == null || tag(...) == ""`.

Skill refactor:
- Moved e2e-specific traps (YAML colon quoting, nested contains
  fragility, `timeUnixNano: "0"`, setup-curl swallowing failure,
  published-sim-image preference, swctl flag mismatch, image-pull
  cache miss) from new-monitoring-feature to run-e2e §9 — that's
  where they belong. new-monitoring-feature §7 now references
  run-e2e §6–§9 and keeps only the DSL-authoring / layer-mapping
  traps that are specific to adding a new feature.
- Added LAL `tag() == null` trap to new-monitoring-feature §9 (that
  one is a DSL semantic, not an e2e issue).

Local e2e: WeChat 8/8, Alipay 8/8 with both fixes applied.
…ndpoint() explicitly

Endpoint rules produced metric rows but no endpoint_traffic entries:
'swctl endpoint ls' returned []; the Endpoint sub-tab in the WeChat /
Alipay service dashboards stayed empty. 'swctl metrics exec' could still
hit the row if you guessed the endpoint name, which is misleading.

Root cause: MetricConvert.formatExp line 132 wraps each rule expression
as '(exp).<expSuffix>'. With 'expSuffix: service([...], Layer.X)' at the
top of the file and '.endpoint([...], ..., Layer.X)' in the endpoint-*
rules, the final compiled expression becomes
'(...avg(...).endpoint(...)).service([...], Layer.X)' — the trailing
.service(...) overrides the scope back to Service, and no EndpointTraffic
source ever fires (Analyzer.java:358 skips when getEndpointName() is
empty for a Service entity).

Fix: leave expSuffix empty and chain .service(...) / .endpoint(...)
explicitly on each rule in the mixed-scope files (the APISIX pattern).
The instance-only files (wechat-mini-program-instance.yaml,
alipay-mini-program-instance.yaml) keep 'expSuffix: instance(...)'
because every rule there is same-scope.

Verified locally: endpoint ls now returns pages/detail/index,
pages/profile/index, pages/index/index, pages/cart/index for
mini-program-sim-wechat.

new-monitoring-feature §9 trap table: add this case.
…escription

The banner description spans ~260 chars (SDK name + signal list) and
wraps to 2 lines at normal browser widths; h=2 clipped the second line.
Both WeChat and Alipay root dashboards bumped to h=3, ServiceList widget
shifted from y=2 to y=3 to preserve the 48-row total.
SkyAPM mini-program-monitor v0.4.1 (commit e795c188) adds route,
script, loadPackage PerformanceObserver entries to the WeChat sim's
firePerfEntries(). The SDK's OAP-side contract (metric names, labels,
histogram temporality / bounds) didn't change — only the sim is more
faithful to real WeChat runtime now.

Bump both WeChat and Alipay docker-compose image tags to v0.4.1. Add
three verify cases on the WeChat e2e to lock in the newly-emitted
perf gauges:

  - meter_wechat_mp_route_duration
  - meter_wechat_mp_script_duration
  - meter_wechat_mp_package_load_duration

Alipay's PerformanceObserver surface is still absent by platform so its
case stays at the app_launch / first_render subset.

Local run: WeChat 11/11, Alipay 8/8.
@wu-sheng wu-sheng added backend OAP backend related. feature New feature labels Apr 21, 2026
@wu-sheng wu-sheng added this to the 10.5.0 milestone Apr 21, 2026
@wu-sheng wu-sheng merged commit c171fbf into master Apr 21, 2026
423 of 427 checks passed
@wu-sheng wu-sheng deleted the feature/swip12-miniprogram-impl branch April 21, 2026 07:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend OAP backend related. feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants