How to set up centralized logging with Vector and Loki and query it in Grafana


When you run multiple servers, tailing logs over SSH stops scaling. Centralized logging with Loki and Vector ships every host’s logs to one place you can search. This walkthrough stands up Loki (the log store) and Grafana (the query UI) on a central server with Docker Compose, then installs Vector on a client host to forward its logs. By the end you will query logs from all your hosts in one Grafana search bar.

Prerequisites

  • A central server with Docker and the Compose plugin installed.
  • One or more client hosts whose logs you want to collect.
  • Network access from clients to the central server on TCP 3100.

Step 1: run Loki and Grafana on the central server

Create a working directory and a Loki config:

mkdir -p ~/logging && cd ~/logging
cat > loki-config.yml <<'EOF'
auth_enabled: false
server:
  http_listen_port: 3100
common:
  instance_addr: 127.0.0.1
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory
schema_config:
  configs:
    - from: 2024-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h
limits_config:
  retention_period: 168h
EOF

Now the Compose file:

cat > docker-compose.yml <<'EOF'
services:
  loki:
    image: grafana/loki:3.0.0
    command: -config.file=/etc/loki/config.yml
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yml:/etc/loki/config.yml
      - loki-data:/loki
  grafana:
    image: grafana/grafana:11.1.0
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
volumes:
  loki-data:
  grafana-data:
EOF

docker compose up -d

Confirm Loki is ready:

curl -s http://localhost:3100/ready

It returns ready once it has started (give it 30 seconds).

Step 2: install Vector on a client host

curl --proto '=https' --tlsv1.2 -sSf https://sh.vector.dev | bash


Configure it to read the journal and auth log, tag each line with the hostname, and ship to Loki. Replace the endpoint with your central server IP:

sudo tee /etc/vector/vector.yaml > /dev/null <<'EOF'
sources:
  journal:
    type: journald
    current_boot_only: true

transforms:
  tag_host:
    type: remap
    inputs: [journal]
    source: |
      .host = get_hostname!()

sinks:
  loki:
    type: loki
    inputs: [tag_host]
    endpoint: http://<central-server-ip>:3100
    encoding:
      codec: json
    labels:
      host: "{{ host }}"
      unit: "{{ _SYSTEMD_UNIT }}"
      source: vector
EOF

sudo systemctl enable --now vector

Check Vector is running and shipping:

sudo systemctl status vector --no-pager

Step 3: Query the logs in Grafana

Open http://<central-server-ip>:3000 and log in (default admin/admin, change it on first login). Add a data source: Connections, Add data source, Loki, URL http://loki:3100, Save and test.

Go to Explore, pick the Loki data source, and run LogQL queries:

{source="vector"}
{host="agent01"} |= "error"
{unit="ssh.service"} |= "Failed password"

The last one surfaces failed SSH logins across every host forwarding to Loki.

What goes wrong in centralized logging

Nothing shows up in Grafana. Vector cannot reach Loki. Confirm port 3100 is open from the client and that the endpoint IP is correct.

Loki rejects logs with an “out of order” or timestamp error. The client clock is skewed. Run NTP on every host.

Queries are slow or Loki uses too much memory. You put a high-cardinality value in labels (like a request ID or user ID). Labels must be low-cardinality (host, unit, environment). Put everything else in the log line and filter it with |= at query time.

Logs stop after a week. That is the retention_period of 168h in the config. Raise it if you need longer, and remember disk grows with it.

BlueGrid.io Content Team

Three people pose together against a plain white background. The woman on the left is smiling with her hand on her hip, while the two men beside her stand closely, one in a hoodie and the other in a plaid shirt.

BlueGrid.io Content Team

BlueGrid.io Team is an editorial collective of engineers, practitioners, and contributors sharing insights across technology, operations, company culture, and the people behind the systems. Content is created through interviews, hands-on experience, internal collaboration, and editorial review, reflecting both how systems are built and how teams work together in real-world environments.

Share this post

Share this link via

Or copy link