Log to metric

Convert log events to metric events

status: stable egress: batch state: stateless output: metrics
Derives one or more metric events from a log event.

Configuration

Example configurations

{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": {
        "field": null,
        "type": "counter"
      }
    }
  }
}
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [transforms.my_transform_id.metrics]
  type = "counter"
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      field: null
      type: counter
{
  "transforms": {
    "my_transform_id": {
      "type": "log_to_metric",
      "inputs": [
        "my-source-or-transform-id"
      ],
      "metrics": {
        "field": null,
        "increment_by_value": null,
        "kind": "incremental",
        "type": "counter"
      }
    }
  }
}
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]

  [transforms.my_transform_id.metrics]
  kind = "incremental"
  type = "counter"
transforms:
  my_transform_id:
    type: log_to_metric
    inputs:
      - my-source-or-transform-id
    metrics:
      field: null
      increment_by_value: null
      kind: incremental
      type: counter

all_metrics

optional bool

Setting this flag changes the behavior of this transformation.

Notably the `metrics` field will be ignored.

All incoming events will be processed and if possible they will be converted to log events. Otherwise, only items specified in the 'metrics' field will be processed.

use serde_json::json;
let json_event = json!({
    "counter": {
        "value": 10.0
    },
    "kind": "incremental",
    "name": "test.transform.counter",
    "tags": {
        "env": "test_env",
        "host": "localhost"
    }
});

This is an example JSON representation of a counter with the following properties:

  • counter: An object with a single property value representing the counter value, in this case, 10.0).
  • kind: A string indicating the kind of counter, in this case, “incremental”.
  • name: A string representing the name of the counter, here set to “test.transform.counter”.
  • tags: An object containing additional tags such as “env” and “host”.

Objects that can be processed include counter, histogram, gauge, set and summary.

inputs

required [string]

A list of upstream source or transform IDs.

Wildcards (*) are supported.

See configuration for more info.

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

metrics

required [object]
A list of metrics to generate.
Array object

Outputs

<component_id>

Default output stream of the component. Use this component’s ID as an input to downstream transforms and sinks.

Output Data

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

component_discarded_events_total

counter
The number of events dropped by this component.
component_id
The Vector component ID.
component_kind
The Vector component kind.
component_type
The Vector component type.
host optional
The hostname of the system Vector is running on.
intentional
True if the events were discarded intentionally, like a filter transform, or false if due to an error.
pid optional
The process ID of the Vector instance.

component_errors_total

counter
The total number of errors encountered by this component.
component_id
The Vector component ID.
component_kind
The Vector component kind.
component_type
The Vector component type.
error_type
The type of the error
host optional
The hostname of the system Vector is running on.
pid optional
The process ID of the Vector instance.
stage
The stage within the component at which the error occurred.

component_received_event_bytes_total

counter
The number of event bytes accepted by this component either from tagged origins like file and uri, or cumulatively from other origins.
component_id
The Vector component ID.
component_kind
The Vector component kind.
component_type
The Vector component type.
container_name optional
The name of the container from which the data originated.
file optional
The file from which the data originated.
host optional
The hostname of the system Vector is running on.
mode optional
The connection mode used by the component.
peer_addr optional
The IP from which the data originated.
peer_path optional
The pathname from which the data originated.
pid optional
The process ID of the Vector instance.
pod_name optional
The name of the pod from which the data originated.
uri optional
The sanitized URI from which the data originated.

component_received_events_count

histogram

A histogram of the number of events passed in each internal batch in Vector’s internal topology.

Note that this is separate than sink-level batching. It is mostly useful for low level debugging performance issues in Vector due to small internal batches.

component_id
The Vector component ID.
component_kind
The Vector component kind.
component_type
The Vector component type.
container_name optional
The name of the container from which the data originated.
file optional
The file from which the data originated.
host optional
The hostname of the system Vector is running on.
mode optional
The connection mode used by the component.
peer_addr optional
The IP from which the data originated.
peer_path optional
The pathname from which the data originated.
pid optional
The process ID of the Vector instance.
pod_name optional
The name of the pod from which the data originated.
uri optional
The sanitized URI from which the data originated.

component_received_events_total

counter
The number of events accepted by this component either from tagged origins like file and uri, or cumulatively from other origins.
component_id
The Vector component ID.
component_kind
The Vector component kind.
component_type
The Vector component type.
container_name optional
The name of the container from which the data originated.
file optional
The file from which the data originated.
host optional
The hostname of the system Vector is running on.
mode optional
The connection mode used by the component.
peer_addr optional
The IP from which the data originated.
peer_path optional
The pathname from which the data originated.
pid optional
The process ID of the Vector instance.
pod_name optional
The name of the pod from which the data originated.
uri optional
The sanitized URI from which the data originated.

component_sent_event_bytes_total

counter
The total number of event bytes emitted by this component.
component_id
The Vector component ID.
component_kind
The Vector component kind.
component_type
The Vector component type.
host optional
The hostname of the system Vector is running on.
output optional
The specific output of the component.
pid optional
The process ID of the Vector instance.

component_sent_events_total

counter
The total number of events emitted by this component.
component_id
The Vector component ID.
component_kind
The Vector component kind.
component_type
The Vector component type.
host optional
The hostname of the system Vector is running on.
output optional
The specific output of the component.
pid optional
The process ID of the Vector instance.

utilization

gauge
A ratio from 0 to 1 of the load on a component. A value of 0 would indicate a completely idle component that is simply waiting for input. A value of 1 would indicate a that is never idle. This value is updated every 5 seconds.
component_id
The Vector component ID.
component_kind
The Vector component kind.
component_type
The Vector component type.
host optional
The hostname of the system Vector is running on.
pid optional
The process ID of the Vector instance.

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
    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" ]

  [[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}}"
          }
        }
      ]
    }
  }
}
...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
    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" ]

  [[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}}"
          }
        }
      ]
    }
  }
}
...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
    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" ]

  [[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}}"
          }
        }
      ]
    }
  }
}
...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
    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" ]

  [[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}}"
          }
        }
      ]
    }
  }
}
...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
    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" ]

  [[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}}"
          }
        }
      ]
    }
  }
}
...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
    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" ]

  [[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}}"
          }
        }
      ]
    }
  }
}
...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.