Telegraf is an open-source, plugin-driven server agent built by InfluxData for collecting, processing, and writing metrics. It is part of the TICK stack (Telegraf, InfluxDB, Chronograf, Kapacitor) and supports over 300 input and output plugins out of the box. If you run infrastructure at any reasonable scale, Telegraf is one of the most practical tools for getting system and application metrics into a time-series database like InfluxDB, then visualizing them in Grafana.

This guide walks through installing Telegraf on Debian 13 (Trixie) or Debian 12 (Bookworm) from the official InfluxData repository, configuring it to collect system and application metrics, shipping those metrics to InfluxDB v2, and building a Grafana dashboard on top of the data.

What Telegraf Does

Telegraf runs as a lightweight agent on your servers. It pulls metrics from configured inputs (CPU, memory, disk, network, Docker, Nginx, PostgreSQL, and hundreds more), applies optional processing or aggregation, and pushes the results to one or more output destinations. The most common setup pairs Telegraf with InfluxDB for storage and Grafana for visualization.

Key characteristics:

  • Written in Go – single binary, no external dependencies
  • Plugin architecture – inputs, outputs, processors, and aggregators are all plugins
  • Low memory footprint – typically uses 50-100MB of RAM
  • Pull and push models – can scrape endpoints or receive pushed data

Prerequisites

Before you begin, make sure you have the following in place:

  • A server running Debian 13 (Trixie) or Debian 12 (Bookworm)
  • Root or sudo access
  • InfluxDB v2 installed and running (local or remote) – needed for the output configuration
  • Grafana installed (optional, for visualization)
  • Internet access to reach the InfluxData package repository

Update your system packages first:

sudo apt update && sudo apt upgrade -y

Step 1 – Add the InfluxData Repository

Telegraf is not in the default Debian repositories. You need to add the official InfluxData apt repository to get the latest stable release.

Install the prerequisite packages:

sudo apt install -y curl gnupg2 apt-transport-https software-properties-common

Import the InfluxData GPG key:

curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/influxdata-archive.gpg

Add the InfluxData repository:

echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive.gpg] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list

Verify the repository file was created:

cat /etc/apt/sources.list.d/influxdata.list

You should see the repository line pointing to https://repos.influxdata.com/debian stable main.

Step 2 – Install Telegraf

Update the package index and install Telegraf:

sudo apt update
sudo apt install -y telegraf

Verify the installation:

telegraf --version

Expected output (version number may differ):

Telegraf 1.33.x (git: HEAD xxxxxxxx)

Step 3 – Enable and Start Telegraf

Enable Telegraf to start on boot and start the service:

sudo systemctl enable --now telegraf

Verify the service is running:

sudo systemctl status telegraf

You should see active (running) in the output. If it shows a failure, check the logs:

sudo journalctl -u telegraf --no-pager -n 50

Step 4 – Configure Telegraf (telegraf.conf)

The main configuration file lives at /etc/telegraf/telegraf.conf. The default file is heavily commented and contains examples for every plugin. For a production setup, I recommend starting with a clean configuration and adding only what you need.

Back up the original configuration:

sudo cp /etc/telegraf/telegraf.conf /etc/telegraf/telegraf.conf.bak

Generate a fresh config with specific plugins:

sudo telegraf --input-filter cpu:mem:disk:diskio:net:system:docker:nginx:postgresql --output-filter influxdb_v2 config | sudo tee /etc/telegraf/telegraf.conf

This gives you a config file with only the input and output plugins you actually need. Now edit it to match your environment:

sudo nano /etc/telegraf/telegraf.conf

Global Tags and Agent Settings

Set global tags to identify this host in your metrics. These tags get appended to every metric Telegraf collects:

[global_tags]
  environment = "production"
  datacenter = "eu-west-1"

[agent]
  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "10s"
  flush_jitter = "0s"
  precision = ""
  hostname = ""
  omit_hostname = false

The interval setting controls how often Telegraf collects metrics. 10 seconds is a good default for most setups. Reduce it to 5s if you need higher resolution, but be aware of the increased load on InfluxDB.

Configure the InfluxDB v2 Output

This is the output section that ships metrics to InfluxDB v2. Replace the placeholder values with your actual InfluxDB details:

[[outputs.influxdb_v2]]
  urls = ["http://127.0.0.1:8086"]
  token = "your-influxdb-api-token"
  organization = "your-org"
  bucket = "telegraf"

To generate an API token in InfluxDB v2, use the InfluxDB UI or the CLI:

influx auth create --org your-org --description "Telegraf write token" --write-buckets

Make sure the bucket exists. Create it if it does not:

influx bucket create --name telegraf --org your-org --retention 30d

Configure Input Plugins

Here are the input plugin configurations for each data source.

CPU metrics:

[[inputs.cpu]]
  percpu = true
  totalcpu = true
  collect_cpu_time = false
  report_active = false

Memory metrics:

[[inputs.mem]]
  # No additional configuration needed

Disk metrics:

[[inputs.disk]]
  ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]

[[inputs.diskio]]
  # Collect I/O stats for all devices

Network metrics:

[[inputs.net]]
  interfaces = ["eth0", "ens*"]
  ignore_protocol_stats = false

System metrics (uptime, load, etc.):

[[inputs.system]]
  # Collects load averages, uptime, number of users

Docker metrics (requires the telegraf user to be in the docker group):

[[inputs.docker]]
  endpoint = "unix:///var/run/docker.sock"
  gather_services = false
  container_names = []
  timeout = "5s"
  perdevice = true
  total = false

Add the telegraf user to the docker group so it can access the Docker socket:

sudo usermod -aG docker telegraf
sudo systemctl restart telegraf

Nginx metrics (requires the stub_status module):

[[inputs.nginx]]
  urls = ["http://127.0.0.1/nginx_status"]

Make sure your Nginx configuration includes a stub_status location block:

server {
    listen 127.0.0.1:80;
    location /nginx_status {
        stub_status on;
        allow 127.0.0.1;
        deny all;
    }
}

PostgreSQL metrics:

[[inputs.postgresql]]
  address = "host=localhost user=telegraf password=yourpassword dbname=postgres sslmode=disable"
  databases = ["postgres"]

Create a dedicated PostgreSQL user for Telegraf with read-only access:

sudo -u postgres psql -c "CREATE USER telegraf WITH PASSWORD 'yourpassword';"
sudo -u postgres psql -c "GRANT pg_monitor TO telegraf;"

Step 5 – Test the Configuration

Before restarting Telegraf with the new config, validate it:

sudo telegraf --config /etc/telegraf/telegraf.conf --test

The --test flag runs all configured input plugins once and prints the collected metrics to stdout without sending them to the output. This is the single most useful debugging command for Telegraf.

You should see output like this:

> cpu,cpu=cpu-total,host=debian-server usage_idle=98.5,usage_system=0.8,usage_user=0.7 1710000000000000000
> mem,host=debian-server available=6442450944i,total=8589934592i,used=2147483648i 1710000000000000000
> disk,device=sda1,fstype=ext4,host=debian-server,path=/ free=42949672960i,total=107374182400i,used=64424509440i 1710000000000000000

If a specific input plugin has errors (for example, Docker socket permission denied), the error will show up clearly in the test output. Fix it before proceeding.

You can also test a single input plugin in isolation:

sudo telegraf --config /etc/telegraf/telegraf.conf --input-filter cpu --test

Step 6 – Restart Telegraf and Verify Metrics Collection

Apply the new configuration:

sudo systemctl restart telegraf

Verify the service restarted cleanly:

sudo systemctl status telegraf
sudo journalctl -u telegraf --no-pager -n 20

Check that metrics are arriving in InfluxDB. Use the InfluxDB CLI to query:

influx query 'from(bucket: "telegraf") |> range(start: -5m) |> filter(fn: (r) => r._measurement == "cpu") |> limit(n: 5)' --org your-org

If you see results, Telegraf is successfully collecting and shipping metrics to InfluxDB.

Step 7 – View Metrics in Grafana

With metrics flowing into InfluxDB, you can now build Grafana dashboards to visualize the data.

Add InfluxDB as a Data Source in Grafana

Open Grafana in your browser (default: http://your-server:3000), then:

  1. Go to ConnectionsData SourcesAdd data source
  2. Select InfluxDB
  3. Set the query language to Flux
  4. Enter the InfluxDB URL: http://127.0.0.1:8086
  5. Enter your organization name, API token, and default bucket (telegraf)
  6. Click Save & Test to verify the connection

Import a Pre-built Dashboard

Rather than building panels from scratch, import a community dashboard. Grafana dashboard ID 928 (Telegraf System Dashboard) works well as a starting point:

  1. Go to DashboardsImport
  2. Enter dashboard ID 928 and click Load
  3. Select your InfluxDB data source
  4. Click Import

This gives you panels for CPU usage, memory usage, disk I/O, network traffic, and system load out of the box.

Build a Custom Panel

To create a custom panel – for example, CPU usage over the last hour – use a Flux query like this:

from(bucket: "telegraf")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "cpu")
  |> filter(fn: (r) => r._field == "usage_idle")
  |> filter(fn: (r) => r.cpu == "cpu-total")
  |> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
  |> map(fn: (r) => ({ r with _value: 100.0 - r._value }))

This query calculates CPU usage by subtracting idle percentage from 100, aggregated in 1-minute windows.

Step 8 – Custom Input Plugins

Telegraf supports drop-in configuration files. Instead of packing everything into the main telegraf.conf, put custom plugin configs in /etc/telegraf/telegraf.d/. Telegraf loads all .conf files from this directory automatically.

HTTP Response Check

Monitor whether your web application is responding:

sudo tee /etc/telegraf/telegraf.d/http_response.conf <<'EOF'
[[inputs.http_response]]
  urls = ["https://example.com", "https://api.example.com/health"]
  response_timeout = "5s"
  method = "GET"
  follow_redirects = true
  response_string_match = "ok"
  [inputs.http_response.tags]
    check = "uptime"
EOF

Exec Plugin – Custom Script Output

Run a custom script and collect its output as metrics:

sudo tee /etc/telegraf/telegraf.d/custom_script.conf <<'EOF'
[[inputs.exec]]
  commands = ["/usr/local/bin/custom_metrics.sh"]
  timeout = "10s"
  data_format = "influx"
  name_suffix = "_custom"
EOF

The script should output data in InfluxDB line protocol format:

#!/bin/bash
# /usr/local/bin/custom_metrics.sh
echo "app_queue_depth,queue=email value=$(wc -l < /var/spool/mail/queue 2>/dev/null || echo 0)"

Prometheus Input

Scrape any Prometheus-compatible metrics endpoint:

sudo tee /etc/telegraf/telegraf.d/prometheus.conf <<'EOF'
[[inputs.prometheus]]
  urls = ["http://localhost:9090/metrics", "http://localhost:8080/metrics"]
  metric_version = 2
EOF

After adding any new plugin configs, restart Telegraf:

sudo systemctl restart telegraf
sudo telegraf --config /etc/telegraf/telegraf.conf --config-directory /etc/telegraf/telegraf.d --test

Step 9 – Monitoring System Services

Telegraf can monitor the state of systemd services, which is useful for alerting when a service goes down.

sudo tee /etc/telegraf/telegraf.d/systemd_services.conf <<'EOF'
[[inputs.systemd_units]]
  unittype = "service"
  pattern = "nginx* postgresql* docker* influxdb* grafana*"
  timeout = "5s"
EOF

This plugin reports the active state, load state, and sub state of each matched service. You can then set up Grafana alerts to notify you when any service leaves the “running” state.

Verify the systemd service monitoring is working:

sudo telegraf --config /etc/telegraf/telegraf.d/systemd_services.conf --test

Troubleshooting

Here are the most common issues you will run into and how to fix them.

Telegraf fails to start

Check the journal for the exact error:

sudo journalctl -u telegraf --no-pager -n 100

Most startup failures come from syntax errors in the config file. Validate the configuration:

sudo telegraf --config /etc/telegraf/telegraf.conf --test 2>&1 | head -20

Permission denied on Docker socket

The telegraf user needs to be in the docker group:

sudo usermod -aG docker telegraf
sudo systemctl restart telegraf

Verify group membership:

groups telegraf

Metrics not appearing in InfluxDB

Check the following in order:

  1. Is Telegraf running?sudo systemctl status telegraf
  2. Is the output config correct? – Verify the URL, token, org, and bucket in the [[outputs.influxdb_v2]] section
  3. Can Telegraf reach InfluxDB?curl -s http://127.0.0.1:8086/health
  4. Is the API token valid? – Check for 401 errors in the Telegraf logs
  5. Does the bucket exist?influx bucket list --org your-org

Nginx input plugin returns connection refused

Make sure the stub_status module is enabled and the URL in Telegraf matches the Nginx config:

curl http://127.0.0.1/nginx_status

If this returns “Active connections” and connection stats, Nginx is configured correctly. If not, check your Nginx configuration and reload it:

sudo nginx -t && sudo systemctl reload nginx

PostgreSQL authentication failure

Verify the telegraf database user can connect:

psql -h localhost -U telegraf -d postgres -c "SELECT 1;"

If this fails, check pg_hba.conf for local authentication rules and make sure the password is correct in the Telegraf config.

High memory usage

If Telegraf is using too much memory, reduce the buffer sizes in the agent section:

[agent]
  metric_batch_size = 500
  metric_buffer_limit = 5000

Also check if any input plugin is collecting an unexpectedly large number of series (common with Docker or Kubernetes plugins on busy hosts).

Debug mode

For detailed debugging, run Telegraf in the foreground with debug logging:

sudo telegraf --config /etc/telegraf/telegraf.conf --debug

This prints every metric collected and every write to the output, which makes it straightforward to identify where things break down.

Conclusion

You now have Telegraf running on Debian 13 or Debian 12, collecting system metrics (CPU, memory, disk, network), application metrics (Docker, Nginx, PostgreSQL), and shipping everything to InfluxDB v2. With Grafana connected to InfluxDB, you have a full monitoring pipeline from data collection through visualization.

The drop-in config directory at /etc/telegraf/telegraf.d/ makes it easy to add new data sources as your infrastructure grows. Add a new .conf file, restart Telegraf, and the metrics start flowing. For a full list of available plugins, check the official Telegraf plugin documentation.

2 COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here