Send Metrics to a Webhook

Extract metrics from logs and send them to a webhook endpoint using the Edge Delta webhook destination.

Overview

This guide demonstrates how to extract metrics from logs and send them to a webhook endpoint. This is useful when you want to:

  • Send metric data to systems that accept webhook callbacks
  • Create custom metric payloads for third-party integrations
  • Monitor application performance metrics via webhooks

The webhook destination supports metric and signal data types. It does not support logs directly—you must first extract metrics from logs using the Extract Metric processor.

Pipeline Flow

flowchart LR classDef icon-logs fill:#EFE7FC,stroke:#7C3AED,color:#321059; classDef icon-process fill:#E7F0FB,stroke:#2563EB,color:#1E3A8A; classDef icon-destination fill:#FCEADB,stroke:#EA580C,color:#7C2D12; Logs["<span class='ph ph-file-text'></span> Log Source"] Extract["<span class='ph ph-chart-line-up'></span> Extract Metric"] Webhook["<span class='ph ph-paper-plane-tilt'></span> Webhook Destination"] Logs --> Extract Extract --> Webhook class Logs icon-logs; class Extract icon-process; class Webhook icon-destination;

Example Configuration

This example extracts a response_time_ms metric from JSON logs and sends it to a webhook endpoint.

Source Logs

The pipeline processes JSON logs containing a numeric field:

{"timestamp":"2026-01-26T23:08:43.000Z","test_type":"webhook_metric","sequence":1,"response_time_ms":319,"endpoint":"/api/test","method":"GET","status":200}

Pipeline Configuration

nodes:
  # Kubernetes log source
  - name: kubernetes_input_busy
    type: kubernetes_input
    include:
    - k8s.namespace.name=busy
    log_parsing_mode: full

  # Extract metric from logs
  - name: extract_metric_processor
    type: sequence
    processors:
    - type: extract_metric
      condition: body["test_type"] == "webhook_metric"
      keep_item: true
      data_types:
      - log
      extract_metric_rules:
      - name: demo.response_time
        description: Response time metric extracted for webhook demo
        unit: "1"
        gauge:
          value: body["response_time_ms"]

  # Webhook destination for metrics
  - name: webhook_metrics_output
    type: webhook_output
    endpoint: https://api.example.com/webhook
    headers:
    - header: Content-Type
      value: "application/json"
    - header: Authorization
      value: "Bearer ${API_TOKEN}"
    payload: |
      {
        "metric_name": "{{ .item.name }}",
        "metric_kind": "{{ .item.kind }}",
        "value": {{ .item.gauge.value }},
        "timestamp": "{{ .item.timestamp }}",
        "host": "{{ index .item.resource "host.name" }}",
        "namespace": "{{ index .item.resource "k8s.namespace.name" }}",
        "pod": "{{ index .item.resource "k8s.pod.name" }}"
      }      

links:
  - from: kubernetes_input_busy
    to: extract_metric_processor
  - from: extract_metric_processor
    to: webhook_metrics_output

Webhook Payload Output

When metrics are sent to the webhook, the payload is rendered using the Go template. Here’s an example of the actual webhook payload:

{
  "metric_name": "demo.response_time",
  "metric_kind": "gauge",
  "value": 319,
  "timestamp": "1769468902176",
  "host": "worker-node-1",
  "namespace": "busy",
  "pod": "my-app-pod"
}

Metric Template Variables

When processing metrics, the following variables are available in the .item object:

VariableDescriptionExample
.item.nameMetric namedemo.response_time
.item.kindMetric kindgauge
.item._stat_typeInternal stat typevalue
.item.unitMetric unit1
.item.descriptionMetric descriptionResponse time metric...
.item.timestampUnix timestamp (ms)1769468902176
.item.gauge.valueGauge value (for gauge metrics)319
.item.sum.value.sumSum value (for sum metrics)1000
.item.resourceResource attributes mapSee below

Resource Attributes

Access resource attributes using the index function:

{{ index .item.resource "host.name" }}
{{ index .item.resource "k8s.namespace.name" }}
{{ index .item.resource "k8s.pod.name" }}
{{ index .item.resource "k8s.container.name" }}

Full Metric Item Structure

For reference, here’s the complete structure of a metric item as received by the webhook destination:

{
  "_type": "metric",
  "_stat_type": "value",
  "name": "demo.response_time",
  "kind": "gauge",
  "unit": "1",
  "description": "Response time metric extracted for webhook demo",
  "timestamp": 1769468902176,
  "gauge": {
    "value": 47
  },
  "attributes": {},
  "resource": {
    "host.name": "worker-node-1",
    "host.ip": "172.18.0.4",
    "k8s.namespace.name": "busy",
    "k8s.pod.name": "my-app-pod",
    "k8s.container.name": "app",
    "k8s.node.name": "worker-node-1",
    "container.id": "abc123...",
    "container.image.name": "myapp:latest",
    "ed.source.name": "kubernetes_input",
    "ed.source.type": "kubernetes_input"
  }
}

Conditional Value Access

Use Go template conditionals to handle different metric types:

{{ if eq .item.kind "gauge" }}
  "value": {{ .item.gauge.value }}
{{ else if eq .item.kind "sum" }}
  "value": {{ .item.sum.value.sum }}
{{ end }}

See Also