Skip to main content

Grafana Alloy

src

1. Overview​

This setup uses OpenTelemetry Collector to ingest, process, and export telemetry data. It integrates with Grafana Loki for logs, Prometheus for metrics, and Tempo for traces. The configuration includes:

  • Logging: Configures logging levels and formats.
  • Receivers: Ingest telemetry data via OTLP, Docker, and file-based logs.
  • Exporters: Sends processed data to backend systems (Loki, Prometheus, Tempo).
  • Processors: Enhances data (e.g., adds attributes, filters noise).
  • Sources: Defines specific log and metric scraping.

Use a config.alloy file for writing these configurations to...

2. Logging​

Configure logging for OpenTelemetry Collector:

logging {
level = "info"
format = "logfmt"
}

Options:​

  • level: Adjust verbosity (e.g., debug, info, warn, error).
  • format: Specify format (e.g., json, logfmt).

3. Receivers and Discovery​

OTLP Receiver​

The OTLP receiver handles incoming metrics, logs, and traces.

otelcol.receiver.otlp "default" {
grpc {
endpoint = "0.0.0.0:4317"
}
http {
endpoint = "0.0.0.0:4318"
}
output {
// This will send all recived items into a memory limiter, more info below
metrics = [otelcol.processor.memory_limiter.default.input]
logs = [otelcol.processor.memory_limiter.default.input]
traces = [otelcol.processor.memory_limiter.default.input]
}
}

Local File Matcher​

Match log files from the host system.

local.file_match "node_logs" {
path_targets = [{
__path__ = "/var/log/*.log",
node_name = sys.env("HOSTNAME"),
cluster = sys.env("CLUSTER"),
}]
}

Docker Discovery​

Discover Docker container logs. (optional)

discovery.docker "docker_host" {
host = "unix:///var/run/docker.sock"
}

4. Exporters​

Logs​

Export logs to Grafana Loki. assuming loki is running on a local container on the same network

loki.write "grafana_loki" {
endpoint {
url = "http://loki:3100/loki/api/v1/push"
}
}

// For Otel Format Logs
otelcol.exporter.loki "default" {
forward_to = [loki.write.grafana_loki.receiver]
}

Metrics​

Export metrics to Prometheus.

prometheus.remote_write "c0" {
endpoint {
url = "http://prometheus:9090/api/v1/write"
}
}

// For otel format metrics
otelcol.exporter.prometheus "shar" {
forward_to = [prometheus.remote_write.c0.receiver]
}

Traces​

Export traces to Tempo.

otelcol.exporter.otlphttp "tempo" {
client {
endpoint = "http://tempo:4318"
}
}

5. Sources​

Log Sources​

File-based Logs​

loki.source.file "log_scrape" {
targets = local.file_match.node_logs.targets
forward_to = [loki.process.filter_logs.receiver]
tail_from_end = true
}

Docker Logs​

loki.source.docker "docker_logs" {
host = "unix:///var/run/docker.sock"
targets = discovery.docker.docker_host.targets
labels = {
"container_id" = sys.env("HOSTNAME"),
// "container_name" = "__meta_docker_container_name"
}
forward_to = [loki.write.grafana_loki.receiver]
}

6. Processors​

Log Processors​

Filter noisy logs before sending to Loki.

loki.process "filter_logs" {
stage.drop {
source = ""
expression = ".*Connection closed by authenticating user root"
drop_counter_reason = "noisy"
}
forward_to = [loki.write.grafana_loki.receiver]
}

add attributes as labels.

otelcol.processor.attributes "default" {
action {
key = "loki.attribute.labels"
action = "insert"
value = "event.domain, event.name"
}

action {
key = "loki.resource.labels"
action = "insert"
value = "service.name, service.namespace"
}

output {
logs = [otelcol.processor.batch.default.input]
}
}

Memory Limiter​

Limit memory usage for telemetry processing.

otelcol.processor.memory_limiter "default" {
check_interval = "1s"
limit = "1GiB"
output {
metrics = [otelcol.processor.batch.default.input]
// Send logs to get attribute labels
logs = [otelcol.processor.attributes.default.input]
traces = [otelcol.processor.batch.default.input]
}
}

Batch Processing​

Batch data before exporting.

otelcol.processor.batch "default" {
output {
metrics = [otelcol.exporter.prometheus.shar.input]
logs = [otelcol.exporter.loki.default.input]
traces = [otelcol.exporter.otlphttp.tempo.input]
}
}

7. Metrics Scraping​

Alloy Metrics Scrape​

Scrape metrics from a local service.

prometheus.scrape "alloy_metrics" {
targets = [{
__address__ = "127.0.0.1:12345",
}]
forward_to = [prometheus.remote_write.c0.receiver]
}

Docker Container Metrics​

Scrape metrics from Docker containers. (optional)

prometheus.scrape "docker_containers" {
targets = discovery.docker.docker_host.targets
forward_to = [prometheus.remote_write.c0.receiver]
}

Deploy​

version: '3.8'

networks:
proxy:
external: true
volumes:
data:

services:
alloy:
image: grafana/alloy:latest
container_name: alloy
ports:
- "12345:12345" # Map port 12345
- "4318:4318" # Map port 4318
- "4317:4317" # Map port 4317
networks:
- proxy
volumes:
- //var/run/docker.sock://var/run/docker.sock:ro
- ./config.alloy:/etc/alloy/config.alloy
- data:/var/lib/alloy/data
- /var/log:/var/log
command: >
run
--server.http.listen-addr=0.0.0.0:12345
--storage.path=/var/lib/alloy/data
/etc/alloy/config.alloy