The interface is localized. Skill descriptions and documents are machine-translated by AI into your language; code, commands, paths and technical terms stay in the original, and the author's document governs.
Explore skills
Data & research · SKILL.md

vector

vector

Vector is a high-performance observability data pipeline written in Rust and maintained by Datadog. It collects, transforms and routes logs, metrics and traces from any source to any destination using TOML or YAML configs and the VRL remap language. Use it to replace Logstash, Fluentd or Filebeat, filter and sample noisy logs, archive to S3, or write and de…

Independent GitHub snapshot · Automated classification · Original documentation governs

Tterminalskills / skillsApache-2.0

Skill documentation

GitHub

name: vector description: >- Vector is a high-performance observability data pipeline written in Rust and maintained by Datadog. It collects, transforms and routes logs, metrics and traces from any source to any destination using TOML or YAML configs and the VRL remap language. Use it to replace Logstash, Fluentd or Filebeat, filter and sample noisy logs, archive to S3, or write and debug vector.toml, VRL and vector test unit tests. license: Apache-2.0 compatibility: Vector 0.58 or newer (config shown was validated with 0.58.0); Linux, macOS, Windows, Docker or Kubernetes metadata: author: terminal-skills version: 1.1.0 category: devops repository: https://github.com/vectordotdev/vector tags:

  • log-pipeline
  • data-pipeline
  • observability
  • rust
  • transform

Vector — High-Performance Observability Data Pipeline

Overview

Vector reads data from sources, reshapes it with transforms and delivers it to sinks. Each component has a name and an inputs list that wires it to upstream components. It runs as an agent on every host (DaemonSet in Kubernetes) or as a central aggregator, and ships as a single static binary. Configuration can be TOML, YAML or JSON; this skill uses TOML.

Changes in recent releases that older tutorials get wrong:

  • 0.57: environment-variable interpolation (${ES_PASSWORD}) in config files is off by default. Re-enable it with --dangerously-allow-env-var-interpolation or VECTOR_DANGEROUSLY_ALLOW_ENV_VAR_INTERPOLATION=true, run the file through envsubst first, or use a secrets backend.
  • 0.57: sinks that accept {{ field }} templates (S3, Elasticsearch, Kafka, HTTP, Loki, file and others) refuse templates with no literal prefix, such as topic = "{{ x }}". Write topic = "logs-{{ x }}", or set dangerously_allow_unconfined_template_resolution = true only if you accept the injection risk. vector validate reports these at startup.
  • Elasticsearch auth needs auth.strategy = "basic"; without it validation fails with "missing field strategy".
  • The http sink has no condition option; route errors to it through a filter transform, and keep errors out of sampling with exclude on sample.
  • Latest release when checked: 0.58.0 (26 August 2026).

Instructions

Install

Prefer a package manager or container image:

brew install vector                       # macOS
helm repo add vector https://helm.vector.dev
helm install vector vector/vector         # Kubernetes
docker run --rm -v "$PWD/vector.toml:/etc/vector/vector.toml:ro" \
  timberio/vector:0.58.0-alpine --config /etc/vector/vector.toml

For apt, yum and archive installs follow https://vector.dev/docs/setup/installation/. If you download an archive from packages.timber.io, verify its published checksum before unpacking, and avoid piping the install script into a shell.

Configuration

# vector.toml — collect, filter, sample and route logs and metrics
data_dir = "/var/lib/vector"

# --- Sources ---
[sources.app_logs]
type = "file"
include = ["/var/log/app/*.log"]
read_from = "end"                     # "beginning" re-reads old files on first start

[sources.http_logs]                   # apps POST JSON here
type = "http_server"
address = "127.0.0.1:8686"
decoding.codec = "json"

[sources.host_metrics]
type = "host_metrics"
collectors = ["cpu", "memory", "disk", "network"]
scrape_interval_secs = 15

[sources.otel]                        # OpenTelemetry: outputs are otel.logs / otel.metrics / otel.traces
type = "opentelemetry"
grpc.address = "127.0.0.1:4317"
http.address = "127.0.0.1:4318"

# --- Transforms ---
[transforms.parse_json]
type = "remap"
inputs = ["app_logs"]
source = '''
  . = parse_json!(.message)
  .environment = get_env_var("ENVIRONMENT") ?? "production"
  .timestamp = parse_timestamp!(.timestamp, format: "%Y-%m-%dT%H:%M:%S%.fZ")
  if exists(.email) {
    .email = redact(string!(.email), filters: [r'\S+@\S+'])
  }
'''

[transforms.filter_noise]
type = "filter"
inputs = ["parse_json"]
condition = '''
  !includes(["GET /health", "GET /ready", "GET /metrics"], .request) && .level != "debug"
'''

[transforms.sample_info]              # keeps 1 in 10 events, never drops errors or warnings
type = "sample"
inputs = ["filter_noise"]
rate = 10
exclude = '.level == "error" || .level == "warn"'

[transforms.errors_only]
type = "filter"
inputs = ["filter_noise"]
condition = '.level == "error"'

[transforms.aggregate_metrics]
type = "aggregate"
inputs = ["host_metrics"]
interval_ms = 60000

# --- Sinks ---
[sinks.elasticsearch]
type = "elasticsearch"
inputs = ["sample_info"]
endpoints = ["https://es.internal.shopwave.io:9200"]
bulk.index = "logs-%Y-%m-%d"
auth.strategy = "basic"
auth.user = "${ES_USER}"              # needs env-var interpolation enabled (see Overview)
auth.password = "${ES_PASSWORD}"
compression = "gzip"
batch.max_bytes = 10485760
batch.timeout_secs = 5
buffer.type = "disk"                  # survives destination outages and restarts
buffer.max_size = 1073741824
buffer.when_full = "block"

[sinks.s3_archive]
type = "aws_s3"
inputs = ["sample_info"]
bucket = "shopwave-logs-archive"
region = "us-east-1"
key_prefix = "logs/{{ service }}/year=%Y/month=%m/day=%d/"   # literal prefix keeps 0.57+ confinement happy
compression = "gzip"
encoding.codec = "json"
batch.max_bytes = 104857600
batch.timeout_secs = 300

[sinks.prometheus]
type = "prometheus_exporter"
inputs = ["aggregate_metrics"]
address = "0.0.0.0:9598"

[sinks.slack_errors]
type = "http"
inputs = ["errors_only"]
uri = "${SLACK_WEBHOOK_URL}"
method = "post"
encoding.codec = "json"
batch.max_events = 1
request.rate_limit_duration_secs = 1
request.rate_limit_num = 5

Validate, then run:

vector validate --no-environment vector.toml      # add --dangerously-allow-env-var-interpolation if the file uses ${VAR}
vector --config vector.toml

--no-environment skips network health checks, so it works offline; drop it in CI to also check that destinations are reachable. Unused sources only produce warnings.

VRL (Vector Remap Language)

VRL is compiled and type-checked: fallible calls must be handled with ! (abort the event on error) or ?? default.

. = parse_json!(.message)

if starts_with(string!(.message), "AUDIT:") {
  .route = "audit"
} else if (to_int(.status_code) ?? 0) >= 500 {
  .route = "error"
} else {
  .route = "general"
}

.duration_ms = to_float(.duration_ms) ?? 0.0
.user_id = del(.user.id)
del(.user)

Try snippets interactively with vector vrl, or watch live events with vector tap and vector top against a running instance.

Unit tests

[[tests]]
name = "normalizes warning and redacts email"
[[tests.inputs]]
insert_at = "parse_json"
type = "log"
[tests.inputs.log_fields]
message = '{"level":"warning","status_code":"503","email":"dana@shopwave.io"}'
[[tests.outputs]]
extract_from = "parse_json"
[[tests.outputs.conditions]]
type = "vrl"
source = '''
  assert_eq!(.severity, "warn")
  assert!(!contains(string!(.email), "dana"))
'''

Put the [[tests]] next to the transforms they cover and run vector test vector.toml. Output: test normalizes warning and redacts email ... passed.

Examples

Example 1: Cut Elasticsearch cost for a Node.js API

User request: "Our Node API logs JSON to /var/log/api/*.log and Elasticsearch costs too much. Drop health checks and debug, keep all errors, sample the rest."

Create vector.toml from the configuration above, with include = ["/var/log/api/*.log"]. Run vector validate --no-environment vector.toml; it prints Validated for transforms and sinks. Start with vector --config vector.toml and confirm with vector top that filter_noise receives more events than sample_info emits. Errors and warnings all reach Elasticsearch; about one in ten info events does.

Example 2: Fix a failing VRL remap

User request: "Vector says unhandled fallible assignment on .timestamp = parse_timestamp(.ts, \"%+\")."

parse_timestamp can fail, so VRL refuses to compile it. Change the line to .timestamp = parse_timestamp!(.ts, format: "%+") to drop events with a bad timestamp, or parse_timestamp(.ts, format: "%+") ?? now() to keep them. Add a [[tests]] case with a malformed ts and run vector test vector.toml to lock in the behaviour.

Guidelines

  • Pin the image or package version; upgrade one minor at a time and read the upgrade guide, since 0.57 changed env-var and template handling.
  • Never put secrets in the config file. Use a secrets backend, or env vars with interpolation explicitly enabled, and keep the file out of Git.
  • Filter noise and sample high-volume info logs before sinks; keep 100% of errors and warnings.
  • Archive everything cheaply to S3 and send only recent or important data to Elasticsearch.
  • Enable disk buffers on sinks that must not lose data during outages; the default buffer is in memory.
  • Bind source addresses to 127.0.0.1 unless remote hosts must reach them; 0.0.0.0 on syslog or HTTP exposes the port.
  • Prefer VRL over regex-heavy chains and test every remap with vector test before deploying.
Saved skills