Repository navigation
Count gRPC alarm hook deliveries in the alarm delivery metrics and fix webhook hooks skipped next to other hook types - #14207
Conversation
|
Please list the screenshots of your UI side changes about your newly added metrics. |
|
screenshots UI apache/skywalking-horizon-ui#217 |
|
Grafana thing has nothing related with Horizon UI. |
|
Thanks for this. One design change before the line-by-line review: please record gRPC into the existing alarm delivery metrics instead of a separate metric family. Most deployments use one alarm channel, either the HTTP hooks or the gRPC hook, and few use both. The HTTP widgets are already split by channel (
Please keep the webhook null check, the configurable per-stream timeout, the stream cancel on interrupt, and the shared alarm/recovery stream code. Nits:
|
d2fd20f to
07d6982
Compare
surlymochan
left a comment
There was a problem hiding this comment.
I read the full diff of the current head and checked it against @wu-sheng's design comment from 2026-11-09 00:05 UTC. The rework looks complete on all eight points; two small leftovers below.
Verified as addressed:
- gRPC now records through the shared
AlarmHttpDeliveryMetricswithhook_type="gRPC"(GRPCCallback.recordDelivery,AlarmHooksType.gRPC.name()),statusClass = null, so noalarm_http_delivery_status_totalseries is added. No separateAlarmGrpcDeliveryMetrics, no new MAL rules, no new Grafana rows.record(..., null, ...)is safe: on master,record's javadoc saysstatusClassis "nullwhen no response was received" and the status counter is guarded byif (statusClass != null). - Status mapping in
AlarmHttpDeliveryMetrics.resultOf/classifyGrpcDeliveryResultmatches the requested table exactly, including peerCANCELLED->rejectedand interrupt winning over a concurrentDEADLINE_EXCEEDED. The interrupt path is covered byshouldRecordInterruptedWhenCallerInterruptedDuringWait(stalling server +caller.interrupt(), asserts 1 interrupted delivery and the caller finishing without waiting for the peer); the deadline path byshouldRecordTimeoutWhenPeerExceedsDeadline. - No
message_kindlabel and noalarm_grpc_delivery_messages_total. - No delivery is recorded when nothing is sent:
shouldSkipMessageHookMissingFromSettingsasserts 0 deliveries / 0 latency observations, and the newshouldIgnoreForeignHooksWithoutRecordingMetrics/shouldNotRecordWhenAllGrpcSettingsClearedtests pin the same for foreign hooks and cleared settings. - Grafana: only the "Alarm HTTP Delivery" row and its count/latency panels are retitled to "Alarm Delivery" in both
grafana-cluster.jsonandgrafana-instance.json; the status panel is untouched. - Docs:
backend-alarm.mdgains the gRPC timeout section and thehook_type=gRPCmapping paragraph;dashboards-so11y.mdretitles the count/latency rows and keeps the status row HTTP-only. changes.mdhas the three one-sentence entries (webhook NPE with the trigger condition, the newgrpcTimeoutsetting, gRPC on the shared metrics).- e2e asserts
alarm_http_delivery_total{hook_type="gRPC",result="success"}and, forgRPC.down,result="io_error". The webhook null check is kept (WebhookCallbackskips a null setting beforegetUrls), with the newignoresForeignHooksWithoutNperegression test. The configurable deadline, cancel-on-interrupt, and shared alarm/recovery stream code are all kept.
Two nits left:
- The
->nit was fixed inoap-server/server-starter/src/main/resources/application.yml("<= 0falls back to 10") but the same comment inoap-server/server-tools/data-generator/src/main/resources/application.ymlstill reads "<= 0 -> 10". Please make the two copies match. oap-server/analyzer/meter-analyzer-scripts-test/.../oap.data.yamlonly gains stray blank lines in this diff (two hunks, no content change). Please drop them so the file is untouched.
Note: this is a code-read review only — I did not run the OAP test suite locally. The RecordingDeliveryMetrics harness only counts hook_type=gRPC series, which is the right scoping for the new assertions.
|
Thanks for the review. Morning tip (already on this PR,
Latest tip (
Fork CI: songzhendong#34 Live so11y screenshots (OAP tip + Horizon)Same three positions as #14190: Horizon SO11Y_OAP Alarm Delivery row, Grafana OAP Instance, Grafana OAP Cluster. |
536c666 to
53fbb7f
Compare
|
Thanks for the quick rework. I rebased it onto master and squashed it into one commit with you as the author. If you have local work on this branch, save it before you
|
…x webhook hooks skipped next to other hook types The gRPC alarm hook now records each finished alarm or recovery stream on the alarm delivery self-observability metrics that the HTTP hooks use, alarm_http_delivery_total and alarm_http_delivery_latency_seconds, with hook_type=gRPC. It records no alarm_http_delivery_status_total series, since gRPC has no HTTP status. The metric names stay as released in 11.1.0, so the existing MAL rules, Grafana panels and UI widgets show the gRPC hook as one more channel. The Grafana "Alarm HTTP Delivery" row and its count and latency panels are retitled "Alarm Delivery". A failed stream maps its gRPC status to the existing results, following the HTTP mapping in google/rpc/code.proto: DEADLINE_EXCEEDED is timeout, UNAVAILABLE is io_error, UNAUTHENTICATED and PERMISSION_DENIED are auth_failed, RESOURCE_EXHAUSTED is rate_limited, UNKNOWN, INTERNAL, DATA_LOSS and UNIMPLEMENTED are server_error, and any other code, including a CANCELLED sent by the peer, is rejected. When the alarm thread is interrupted while waiting for the peer, OAP cancels the stream and records interrupted. A hook without a live client sends nothing and records nothing. Each gRPC stream's deadline is now alarm.default.grpcTimeout (SW_ALARM_GRPC_TIMEOUT), default 10 seconds, which was the fixed deadline before. Fix a webhook hook not being posted when the alarm also names a hook of another type: WebhookCallback looked up every hook name of the alarm in the webhook settings and read the URLs of the result without a null check, so a non-webhook name threw a NullPointerException. With webhook.default and gRPC.default, the gRPC name comes first and the webhook was never posted. The so11y and alarm e2e cases deliver to a gRPC hook server in the provider service and check the hook_type=gRPC series, including io_error for a hook whose target refuses the connection.
53fbb7f to
1405bad
Compare
|
Thanks for the rebase, squash, and the follow-up cleanups. I'll reset my local branch to the new tip and keep an eye on CI. |





Summary
Count gRPC alarm hook deliveries in the alarm delivery self-observability metrics that the HTTP hooks already use, and fix a webhook hook that was not posted when the alarm also named a hook of another type.
alarm_http_delivery_total{hook_type="gRPC", result}andalarm_http_delivery_latency_seconds{hook_type="gRPC"}. gRPC has no HTTP status, so it records noalarm_http_delivery_status_total. The metric names stay as released in 11.1.0, so the existing MAL rules, Grafana panels and Horizon widgets show the gRPC hook as one more channel.result: a failed stream maps its gRPC status to the existing values, following the HTTP mapping ingoogle/rpc/code.proto:DEADLINE_EXCEEDED→timeout,UNAVAILABLE→io_error,UNAUTHENTICATED/PERMISSION_DENIED→auth_failed,RESOURCE_EXHAUSTED→rate_limited,UNKNOWN/INTERNAL/DATA_LOSS/UNIMPLEMENTED→server_error, and any other code, including aCANCELLEDsent by the peer →rejected. An interrupted wait cancels the stream and recordsinterrupted. A hook without a live client sends nothing and records nothing.alarm.default.grpcTimeout/SW_ALARM_GRPC_TIMEOUTsets each gRPC stream's deadline (default10seconds, which was the fixed deadline before).WebhookCallbacklooked up every hook name of the alarm in the webhook settings and read the URLs without a null check, so a non-webhook name threw aNullPointerException. Withwebhook.defaultandgRPC.default, the gRPC name comes first and the webhook was never posted.grafana-instance.json,grafana-cluster.json): the "Alarm HTTP Delivery" row and its count and latency panels are retitled "Alarm Delivery".backend-alarm.md,dashboards-so11y.md,changes.md.Horizon UI: apache/skywalking-horizon-ui#217 (widget tips, the Responses widget's gate, docs). Screenshots of the Grafana and Horizon panels with the gRPC channel are in the comments.
Tests
Unit tests: gRPC status classification;
success,timeoutandinterruptedagainst a local gRPC server;io_erroragainst a refused loopback port; nothing recorded for missing or cleared gRPC settings;grpcTimeoutdefaulting, capping and propagation; webhook delivery alongside gRPC hook names.E2E: the so11y and alarm cases deliver to
AlarmGrpcHookServer(provider:9898) and check thehook_type="gRPC"series, includingio_errorfor the refusedgRPC.downhook.Update the documentation to include this new feature.
Tests (including UT, IT, E2E) are added to verify the new feature.
Update the
CHANGESlog.