Log to metric

Convert log events to metric events

status: stable egress: batch state: stateless output: metrics

Configuration

Example configurations

{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": {
        "field": "duration",
        "name": "duration_total",
        "namespace": "service",
        "tags": {
          "host": "${HOSTNAME}",
          "region": "us-east-1",
          "status": "{{status}}"
        },
        "type": "counter"
      }
    }
  }
}
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [transforms.my_transform_id.metrics]
  field = "duration"
  name = "duration_total"
  namespace = "service"
  type = "counter"

    [transforms.my_transform_id.metrics.tags]
    host = "${HOSTNAME}"
    region = "us-east-1"
    status = "{{status}}"
---
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      field: duration
      name: duration_total
      namespace: service
      tags:
        host: ${HOSTNAME}
        region: us-east-1
        status: "{{status}}"
      type: counter
{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": {
        "field": "duration",
        "increment_by_value": null,
        "name": "duration_total",
        "namespace": "service",
        "tags": {
          "host": "${HOSTNAME}",
          "region": "us-east-1",
          "status": "{{status}}"
        },
        "type": "counter"
      }
    }
  }
}
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [transforms.my_transform_id.metrics]
  field = "duration"
  name = "duration_total"
  namespace = "service"
  type = "counter"

    [transforms.my_transform_id.metrics.tags]
    host = "${HOSTNAME}"
    region = "us-east-1"
    status = "{{status}}"
---
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      field: duration
      increment_by_value: null
      name: duration_total
      namespace: service
      tags:
        host: ${HOSTNAME}
        region: us-east-1
        status: "{{status}}"
      type: counter

inputs

required [string]

A list of upstream source or transform IDs. Wildcards (*) are supported but must be the last character in the ID.

See configuration for more info.

Array string literal
Examples
[
  "my-source-or-transform-id",
  "prefix-*"
]

metrics

required [object]
A table of key/value pairs representing the keys to be added to the event.
Array object

Output

Metrics

counter

counter
A single value that can be incremented or reset to a zero value but not decremented.
* optional
Any tags present on the metric.

distribution

distribution
A distribution represents a distribution of sampled values. It is used with services that support global histograms and summaries.
* optional
Any tags present on the metric.

gauge

gauge
A gauge represents a point-in-time value that can increase and decrease. Vector’s internal gauge type represents changes to that value. Gauges should be used to track fluctuations in values, like current memory or CPU usage.
* optional
Any tags present on the metric.

set

gauge
A set represents an array of unique values.
* optional
Any tags present on the metric.

Telemetry

Metrics

link

events_in_total

counter
The number of events accepted by this component either from tagged origin like file and uri, or cumulatively from other origins.
component_kind required
The Vector component kind.
component_name required
The Vector component name.
component_type required
The Vector component type.
container_name optional
The name of the container from which the event originates.
file optional
The file from which the event originates.
mode optional
The connection mode used by the component.
peer_addr optional
The IP from which the event originates.
peer_path optional
The pathname from which the event originates.
pod_name optional
The name of the pod from which the event originates.
uri optional
The sanitized URI from which the event originates.

events_out_total

counter
The total number of events emitted by this component.
component_kind required
The Vector component kind.
component_name required
The Vector component name.
component_type required
The Vector component type.

processed_bytes_total

counter
The number of bytes processed by the component.
component_kind required
The Vector component kind.
component_name required
The Vector component name.
component_type required
The Vector component type.
container_name optional
The name of the container from which the bytes originate.
file optional
The file from which the bytes originate.
mode optional
The connection mode used by the component.
peer_addr optional
The IP from which the bytes originate.
peer_path optional
The pathname from which the bytes originate.
pod_name optional
The name of the pod from which the bytes originate.
uri optional
The sanitized URI from which the bytes originate.

processed_events_total

counter
The total number of events processed by this component. This metric is deprecated in place of using events_in_total and events_out_total metrics.
component_kind required
The Vector component kind.
component_name required
The Vector component name.
component_type required
The Vector component type.

processing_errors_total

counter
The total number of processing errors encountered by this component.
component_kind required
The Vector component kind.
component_name required
The Vector component name.
component_type required
The Vector component type.
error_type required
The type of the error

Examples

Counter

Given this event...
{
  "log": {
    "host": "10.22.11.222",
    "message": "Sent 200 in 54.2ms",
    "status": 200
  }
}
...and this configuration...
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [[transforms.my_transform_id.metrics]]
  type = "counter"
  field = "status"
  name = "response_total"
  namespace = "service"

    [transforms.my_transform_id.metrics.tags]
    status = "{{status}}"
    host = "{{host}}"
---
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      - type: counter
        field: status
        name: response_total
        namespace: service
        tags:
          status: "{{status}}"
          host: "{{host}}"
{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": [
        {
          "type": "counter",
          "field": "status",
          "name": "response_total",
          "namespace": "service",
          "tags": {
            "status": "{{status}}",
            "host": "{{host}}"
          }
        }
      ]
    }
  }
}
...this Vector event is produced:
[
  {
    "metric": {
      "counter": {
        "value": 1
      },
      "kind": "incremental",
      "name": "response_total",
      "namespace": "service",
      "tags": {
        "host": "10.22.11.222",
        "status": "200"
      }
    }
  }
]

Sum

Given this event...
{
  "log": {
    "host": "10.22.11.222",
    "message": "Order placed for $122.20",
    "total": 122.2
  }
}
...and this configuration...
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [[transforms.my_transform_id.metrics]]
  type = "counter"
  field = "total"
  name = "order_total"
  increment_by_value = true

    [transforms.my_transform_id.metrics.tags]
    host = "{{host}}"
---
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      - type: counter
        field: total
        name: order_total
        increment_by_value: true
        tags:
          host: "{{host}}"
{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": [
        {
          "type": "counter",
          "field": "total",
          "name": "order_total",
          "increment_by_value": true,
          "tags": {
            "host": "{{host}}"
          }
        }
      ]
    }
  }
}
...this Vector event is produced:
[
  {
    "metric": {
      "counter": {
        "value": 122.2
      },
      "kind": "incremental",
      "name": "order_total",
      "tags": {
        "host": "10.22.11.222"
      }
    }
  }
]

Gauges

Given this event...
{
  "log": {
    "15m_load_avg": 48.7,
    "1m_load_avg": 78.2,
    "5m_load_avg": 56.2,
    "host": "10.22.11.222",
    "message": "CPU activity sample"
  }
}
...and this configuration...
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [[transforms.my_transform_id.metrics]]
  type = "gauge"
  field = "1m_load_avg"

    [transforms.my_transform_id.metrics.tags]
    host = "{{host}}"

  [[transforms.my_transform_id.metrics]]
  type = "gauge"
  field = "5m_load_avg"

    [transforms.my_transform_id.metrics.tags]
    host = "{{host}}"

  [[transforms.my_transform_id.metrics]]
  type = "gauge"
  field = "15m_load_avg"

    [transforms.my_transform_id.metrics.tags]
    host = "{{host}}"
---
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      - type: gauge
        field: 1m_load_avg
        tags:
          host: "{{host}}"
      - type: gauge
        field: 5m_load_avg
        tags:
          host: "{{host}}"
      - type: gauge
        field: 15m_load_avg
        tags:
          host: "{{host}}"
{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": [
        {
          "type": "gauge",
          "field": "1m_load_avg",
          "tags": {
            "host": "{{host}}"
          }
        },
        {
          "type": "gauge",
          "field": "5m_load_avg",
          "tags": {
            "host": "{{host}}"
          }
        },
        {
          "type": "gauge",
          "field": "15m_load_avg",
          "tags": {
            "host": "{{host}}"
          }
        }
      ]
    }
  }
}
...this Vector event is produced:
[
  {
    "metric": {
      "gauge": {
        "value": 78.2
      },
      "kind": "absolute",
      "name": "1m_load_avg",
      "tags": {
        "host": "10.22.11.222"
      }
    }
  },
  {
    "metric": {
      "gauge": {
        "value": 56.2
      },
      "kind": "absolute",
      "name": "5m_load_avg",
      "tags": {
        "host": "10.22.11.222"
      }
    }
  },
  {
    "metric": {
      "gauge": {
        "value": 48.7
      },
      "kind": "absolute",
      "name": "15m_load_avg",
      "tags": {
        "host": "10.22.11.222"
      }
    }
  }
]

Histogram distribution

Given this event...
{
  "log": {
    "host": "10.22.11.222",
    "message": "Sent 200 in 54.2ms",
    "status": 200,
    "time": 54.2
  }
}
...and this configuration...
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [[transforms.my_transform_id.metrics]]
  type = "histogram"
  field = "time"
  name = "time_ms"

    [transforms.my_transform_id.metrics.tags]
    status = "{{status}}"
    host = "{{host}}"
---
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      - type: histogram
        field: time
        name: time_ms
        tags:
          status: "{{status}}"
          host: "{{host}}"
{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": [
        {
          "type": "histogram",
          "field": "time",
          "name": "time_ms",
          "tags": {
            "status": "{{status}}",
            "host": "{{host}}"
          }
        }
      ]
    }
  }
}
...this Vector event is produced:
[
  {
    "metric": {
      "distribution": {
        "samples": [
          {
            "rate": 1,
            "value": 54.2
          }
        ],
        "statistic": "histogram"
      },
      "kind": "incremental",
      "name": "time_ms",
      "tags": {
        "host": "10.22.11.222",
        "status": "200"
      }
    }
  }
]

Summary distribution

Given this event...
{
  "log": {
    "host": "10.22.11.222",
    "message": "Sent 200 in 54.2ms",
    "status": 200,
    "time": 54.2
  }
}
...and this configuration...
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [[transforms.my_transform_id.metrics]]
  type = "summary"
  field = "time"
  name = "time_ms"

    [transforms.my_transform_id.metrics.tags]
    status = "{{status}}"
    host = "{{host}}"
---
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      - type: summary
        field: time
        name: time_ms
        tags:
          status: "{{status}}"
          host: "{{host}}"
{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": [
        {
          "type": "summary",
          "field": "time",
          "name": "time_ms",
          "tags": {
            "status": "{{status}}",
            "host": "{{host}}"
          }
        }
      ]
    }
  }
}
...this Vector event is produced:
[
  {
    "metric": {
      "distribution": {
        "samples": [
          {
            "rate": 1,
            "value": 54.2
          }
        ],
        "statistic": "summary"
      },
      "kind": "incremental",
      "name": "time_ms",
      "tags": {
        "host": "10.22.11.222",
        "status": "200"
      }
    }
  }
]

Set

Given this event...
{
  "log": {
    "branch": "dev",
    "host": "10.22.11.222",
    "message": "Sent 200 in 54.2ms",
    "remote_addr": "233.221.232.22"
  }
}
...and this configuration...
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [[transforms.my_transform_id.metrics]]
  type = "set"
  field = "remote_addr"
  namespace = "{{branch}}"

    [transforms.my_transform_id.metrics.tags]
    host = "{{host}}"
---
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      - type: set
        field: remote_addr
        namespace: "{{branch}}"
        tags:
          host: "{{host}}"
{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": [
        {
          "type": "set",
          "field": "remote_addr",
          "namespace": "{{branch}}",
          "tags": {
            "host": "{{host}}"
          }
        }
      ]
    }
  }
}
...this Vector event is produced:
[
  {
    "metric": {
      "kind": "incremental",
      "name": "remote_addr",
      "namespace": "dev",
      "set": {
        "values": [
          "233.221.232.22"
        ]
      },
      "tags": {
        "host": "10.22.11.222"
      }
    }
  }
]

How it works

Multiple Metrics

For clarification, when you convert a single log event into multiple metric events, the metric events are not emitted as a single array. They are emitted individually, and the downstream components treat them as individual events. Downstream components are not aware they were derived from a single log event.

Null Fields

If the target log field contains a null value it will ignored, and a metric will not be emitted.

Reducing

It’s important to understand that this transform does not reduce multiple logs to a single metric. Instead, this transform converts logs into granular individual metrics that can then be reduced at the edge. Where the reduction happens depends on your metrics storage. For example, the prometheus_exporter sink will reduce logs in the sink itself for the next scrape, while other metrics sinks will proceed to forward the individual metrics for reduction in the metrics storage itself.

State

This component is stateless, meaning its behavior is consistent across each input.