hono-webhooks 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -545,63 +545,47 @@ createWebhooks(webhooks, {
545
545
  })
546
546
  ```
547
547
 
548
- ### OpenTelemetry metrics
548
+ ### OpenTelemetry
549
549
 
550
- ```ts
551
- import { metrics } from '@opentelemetry/api'
552
-
553
- const duration = metrics.getMeter('webhooks').createHistogram('webhook.duration', { unit: 'ms' })
550
+ `hono-webhooks/otel` puts each request in a server span and records two
551
+ metrics. It needs `@opentelemetry/api` (an optional peer dependency):
554
552
 
555
- createWebhooks(webhooks, {
556
- onEvent: (e) =>
557
- duration.record(e.durationMs, {
558
- 'http.route': e.route ?? 'unmatched',
559
- 'http.request.method': e.method,
560
- 'http.response.status_code': e.status
561
- })
562
- })
553
+ ```bash
554
+ bun add @opentelemetry/api
563
555
  ```
564
556
 
565
- ### OpenTelemetry traces
566
-
567
- One span per request, named by the route pattern (low cardinality), with
568
- `onEvent` logs attached to it:
569
-
570
557
  ```ts
571
- import { SpanKind, SpanStatusCode, trace } from '@opentelemetry/api'
572
-
573
- const tracer = trace.getTracer('webhooks')
558
+ import { otelWebhooks } from 'hono-webhooks/otel'
574
559
 
575
560
  createWebhooks(webhooks, {
576
- around: ({ c, route, method }, next) =>
577
- tracer.startActiveSpan(
578
- `webhook ${method} ${route ?? 'unmatched'}`,
579
- {
580
- kind: SpanKind.SERVER,
581
- attributes: {
582
- 'http.request.method': method,
583
- 'http.route': route ?? 'unmatched',
584
- 'url.path': c.req.path
585
- }
586
- },
587
- async (span) => {
588
- try {
589
- const res = await next()
590
- span.setAttribute('http.response.status_code', res.status)
591
- if (res.status >= 500) span.setStatus({ code: SpanStatusCode.ERROR })
592
- return res
593
- } finally {
594
- span.end()
595
- }
596
- }
597
- ),
598
- onEvent: (e) => {
599
- // trace.getActiveSpan() is the span above
600
- if (e.error instanceof Error) trace.getActiveSpan()?.recordException(e.error)
601
- }
561
+ ...otelWebhooks({
562
+ ignoreRoutes: ['/health'],
563
+ onWebhookCall(call, event) {
564
+ // `call` is summarizeEvent(event); the request's span is active here
565
+ logger.info('webhook.completed', { route: call.route, status: call.status })
566
+ }
567
+ }),
568
+ // onWebhookCall logs errors with the route and span
569
+ logErrors: false
602
570
  })
603
571
  ```
604
572
 
573
+ - **Span** `webhook: POST /orders/:id` (kind `SERVER`) with `http.method`,
574
+ `http.route`, `http.status_code`, `webhook.duration_ms`, `webhook.success`
575
+ and, for validation failures, `webhook.validation_error`. Status is `ERROR`
576
+ for 4xx and 5xx; 5xx errors are recorded as exceptions. Spans created in
577
+ handlers nest under it when an OTel context manager is registered.
578
+ - **Metrics** `webhook_request_total` (counter) and
579
+ `webhook_request_duration_ms` (histogram, ms), both by `route` (the pattern,
580
+ `__unmatched__` for a 404) and `status` (`success` below 400, else `failed`).
581
+ - `ignoreRoutes` skips metrics only; the span and `onWebhookCall` still run.
582
+ - `tracer` and `meter` default to `trace.getTracer('webhooks')` and
583
+ `metrics.getMeter('webhooks')`. The meter is resolved on the first request,
584
+ so registering the SDK after import works.
585
+
586
+ It returns `{ around, onEvent }`. To add your own, call them from yours, or
587
+ use `onWebhookCall` instead of `onEvent`.
588
+
605
589
  ### Skipping noise
606
590
 
607
591
  `onEvent` fires for everything, so filter in the hook:
@@ -771,6 +755,11 @@ import {
771
755
  hmac // (options) => a scheme like the ones above
772
756
  } from 'hono-webhooks/signatures'
773
757
 
758
+ import {
759
+ otelWebhooks, // (options?) => { around, onEvent } with spans and metrics
760
+ UNMATCHED_ROUTE // '__unmatched__', the route label for 404s
761
+ } from 'hono-webhooks/otel'
762
+
774
763
  import type {
775
764
  Webhook,
776
765
  WebhookConfig,
@@ -791,6 +780,8 @@ import type {
791
780
  PathParams,
792
781
  StandardSchemaV1
793
782
  } from 'hono-webhooks'
783
+
784
+ import type { OtelWebhooksOptions } from 'hono-webhooks/otel'
794
785
  ```
795
786
 
796
787
  Use `Webhook` to type a list: `const all: Webhook<AppEnv>[] = [a, b]`.
@@ -0,0 +1 @@
1
+ export declare const cli: import("hanzio/cli").Cli;