Skip to content

switch to alloy for logging#154

Open
andyshinn wants to merge 6 commits into
mainfrom
ashinn/promtail-deprecated
Open

switch to alloy for logging#154
andyshinn wants to merge 6 commits into
mainfrom
ashinn/promtail-deprecated

Conversation

@andyshinn
Copy link
Copy Markdown
Collaborator

No description provided.

@andyshinn andyshinn requested a review from Copilot September 13, 2025 04:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR switches the logging system from Promtail to Alloy for collecting and processing logs from the Bridger application. The change modernizes the logging pipeline while maintaining compatibility with Loki for log storage.

  • Replaces Promtail with Grafana Alloy for log collection and processing
  • Adds new Alloy configuration files for both Docker and systemd journal-based deployments
  • Updates Grafana dashboard and datasource configurations to support the new logging setup

Reviewed Changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
config/quadlet/alloy.container New container configuration for running Alloy in systemd
config/alloy/config-journal.alloy Alloy configuration for collecting logs from systemd journal
config/alloy/config-docker.alloy Alloy configuration for collecting logs from Docker containers
config/deploy.sh Updated deployment script to copy Alloy configuration files
compose.yaml Replaced Promtail service with Alloy service and updated volume mounts
config/grafana/provisioning/datasources/grafana-datasources.yaml Made Loki datasource editable
config/grafana/provisioning/dashboards/file-dashboards.yaml New dashboard provisioning configuration
config/grafana/dashboards/updated/Bridger-1757731649448.json New Grafana dashboard for Bridger logs
bridger/gateway.py Added command-line interface for MQTT gateway user management

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread config/alloy/config-journal.alloy
Comment thread config/alloy/config-docker.alloy
Comment thread config/alloy/config-journal.alloy Outdated
Comment thread config/grafana/dashboards/updated/Bridger-1757731649448.json Outdated
Comment thread config/alloy/config-docker.alloy Outdated
@andyshinn andyshinn force-pushed the ashinn/promtail-deprecated branch from 31e442e to d710936 Compare April 18, 2026 06:06
Comment thread bridger/gateway.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated 10 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +26 to +29
"datasource": {
"type": "loki",
"uid": "P982945308D3682D1"
},
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dashboard references Loki datasource UID P982945308D3682D1, which won’t exist when datasources are provisioned (no uid is set for Loki). Either provision Loki with this exact UID or update the dashboard to reference the UID you provision.

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +28

labels = {
job = "bridger-services",
}
}
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All logs are labeled with job = "bridger-services" here, but existing/added dashboards query Loki with {job="bridger"} (and the prior promtail config used job: bridger). Unless dashboards are updated everywhere, this label change will make log queries return empty results; consider keeping job stable (e.g., bridger) and adding a separate label (like source="journal" or unit).

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +10
Exec = run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data /mnt/config/config-journal.alloy
Image = docker.io/grafana/alloy:v1.10.2
Network = bridger.network
HostName = alloy
PublishPort = 12345:12345
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This runs Alloy’s HTTP server on 0.0.0.0:12345 and publishes it to the host. Alloy’s HTTP endpoints typically expose metrics/config/debug info; unless you explicitly need remote access, bind to localhost and/or avoid publishing the port to reduce exposure.

Suggested change
Exec = run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data /mnt/config/config-journal.alloy
Image = docker.io/grafana/alloy:v1.10.2
Network = bridger.network
HostName = alloy
PublishPort = 12345:12345
Exec = run --server.http.listen-addr=127.0.0.1:12345 --storage.path=/var/lib/alloy/data /mnt/config/config-journal.alloy
Image = docker.io/grafana/alloy:v1.10.2
Network = bridger.network
HostName = alloy

Copilot uses AI. Check for mistakes.
SecurityLabelDisable = true
Volume = %t/podman/podman.sock:/var/run/docker.sock:ro
Volume = /home/andy/.config/bridger:/mnt/config
Volume = alloy-data.volume:/var/lib/alloy
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config-journal.alloy uses loki.source.journal, but this container unit doesn’t mount the host journal (e.g., /run/log/journal, /var/log/journal) or /etc/machine-id. Without those, Alloy inside the container typically can’t read journald and will ship no logs; add the required read-only mounts (and any needed group/capability) or switch to scraping file/stdout logs instead.

Suggested change
Volume = alloy-data.volume:/var/lib/alloy
Volume = alloy-data.volume:/var/lib/alloy
Volume = /run/log/journal:/run/log/journal:ro
Volume = /var/log/journal:/var/log/journal:ro
Volume = /etc/machine-id:/etc/machine-id:ro

Copilot uses AI. Check for mistakes.
Comment thread compose.yaml
Comment on lines 168 to +175
- GF_SERVER_ROOT_URL
- GF_SERVER_PROTOCOL
# - GF_INSTALL_PLUGINS=influxdb
- INFLUXDB_V2_TOKEN
- GF_PATHS_PROVISIONING=/etc/grafana/provisioning
volumes:
- ./config/grafana/provisioning:/etc/grafana/provisioning
- ./config/grafana/dashboards:/mnt/dashboards
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grafana provisioning uses $INFLUXDB_V2_ORG / $INFLUXDB_V2_BUCKET (and token) from the container environment, but the Grafana service only passes INFLUXDB_V2_TOKEN here. This will provision an InfluxDB datasource with missing org/bucket and break dashboards on a fresh start; pass the required env vars (and ensure names match the provisioning file).

Copilot uses AI. Check for mistakes.
Comment on lines 3 to 7
- name: loki
type: loki
editable: true
url: http://loki:3100
- name: influxdb
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new Loki dashboard JSON pins a datasource UID, but this provisioning file doesn’t set a stable uid for the loki (or influxdb) datasource. With provisioning enabled, Grafana will generate new UIDs and the dashboards will fail to resolve their datasources; set explicit uid values here and update dashboards to match (or change dashboards to reference the provisioned uid).

Suggested change
- name: loki
type: loki
editable: true
url: http://loki:3100
- name: influxdb
- name: loki
uid: loki
type: loki
editable: true
url: http://loki:3100
- name: influxdb
uid: influxdb

Copilot uses AI. Check for mistakes.
},
"direction": "backward",
"editorMode": "builder",
"expr": "{job=\"bridger\"} | json | label_format level=record_level_name",
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Loki query is unlikely to return anything with the current Alloy configs: Alloy sets job to bridger-services / bridger-docker, but this query filters on {job="bridger"}. Also, label_format level=record_level_name doesn’t correspond to any extracted field/label in the Alloy pipeline (it extracts level and then promotes it to a level label). Update the query (or Alloy labels) so they match.

Suggested change
"expr": "{job=\"bridger\"} | json | label_format level=record_level_name",
"expr": "{job=~\"bridger-(services|docker)\"} | json",

Copilot uses AI. Check for mistakes.
forward_to = [loki.process.bridger_parsing.receiver]
relabel_rules = loki.relabel.docker_labels.rules

labels = { "job" = "bridger-docker" }
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, this config sets job = "bridger-docker", which won’t match dashboards/alerts that expect job="bridger" (and it differs from the journal config). If you want to keep a single query surface, keep job consistent and add another label to distinguish docker vs journal sources.

Suggested change
labels = { "job" = "bridger-docker" }
labels = {
"job" = "bridger"
"source" = "docker"
}

Copilot uses AI. Check for mistakes.
disableDeletion: false
allowUiUpdates: true
options:
path: /mnt/dashboards/updated
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dashboard provider path points at /mnt/dashboards/updated, so none of the existing dashboards committed under config/grafana/dashboards/*.json will be provisioned. If those dashboards are still intended to ship, either point the provider at /mnt/dashboards or add an additional provider for the non-updated directory.

Suggested change
path: /mnt/dashboards/updated
path: /mnt/dashboards/updated
- name: bridger-default
type: file
disableDeletion: false
allowUiUpdates: true
options:
path: /mnt/dashboards

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +12
discovery.docker "containers" {
host = "unix:///var/run/docker.sock"
refresh_interval = "5s"

filter {
name = "label"
values = ["com.docker.compose.project=bridger"]
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discovery.docker is filtered to com.docker.compose.project=bridger, which depends on the compose project name (by default it’s derived from the directory name). If the project name differs, Alloy will discover zero targets and no logs will be shipped; consider making the project name configurable (env var) or filtering by a more stable label/pattern.

Suggested change
discovery.docker "containers" {
host = "unix:///var/run/docker.sock"
refresh_interval = "5s"
filter {
name = "label"
values = ["com.docker.compose.project=bridger"]
compose_project_name = coalesce(env("BRIDGER_COMPOSE_PROJECT"), "bridger")
discovery.docker "containers" {
host = "unix:///var/run/docker.sock"
refresh_interval = "5s"
filter {
name = "label"
values = ["com.docker.compose.project=" + compose_project_name]

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants