Add logging stack: Loki + Alloy + Grafana for router/switch/phone syslog
Alloy receives syslog on 514/udp and 1514/tcp from network devices, forwards to a local Loki instance; Grafana provisioned with Loki as default datasource. Compose bind-mounts config from /mnt/containers/logging/... on the host (staged separately) since Portainer's GitOps pull only fetches the compose file, not the repo's other files.
This commit is contained in:
@@ -0,0 +1,64 @@
|
|||||||
|
// Receives syslog from routers, switches, and Yealink phones on this host's
|
||||||
|
// LAN interface, tags each message with useful labels, and ships it to the
|
||||||
|
// local Loki instance.
|
||||||
|
//
|
||||||
|
// Point network devices at this host's IP, port 514/udp (or 1514/tcp for
|
||||||
|
// devices that only speak TCP framing).
|
||||||
|
|
||||||
|
loki.relabel "syslog" {
|
||||||
|
forward_to = []
|
||||||
|
|
||||||
|
rule {
|
||||||
|
source_labels = ["__syslog_message_hostname"]
|
||||||
|
target_label = "hostname"
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
source_labels = ["__syslog_message_severity"]
|
||||||
|
target_label = "severity"
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
source_labels = ["__syslog_message_facility"]
|
||||||
|
target_label = "facility"
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
source_labels = ["__syslog_connection_ip_address"]
|
||||||
|
target_label = "source_ip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loki.source.syslog "network_devices_udp" {
|
||||||
|
listener {
|
||||||
|
address = "0.0.0.0:514"
|
||||||
|
protocol = "udp"
|
||||||
|
labels = {
|
||||||
|
job = "syslog",
|
||||||
|
transport = "udp",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
relabel_rules = loki.relabel.syslog.rules
|
||||||
|
forward_to = [loki.write.default.receiver]
|
||||||
|
}
|
||||||
|
|
||||||
|
loki.source.syslog "network_devices_tcp" {
|
||||||
|
listener {
|
||||||
|
address = "0.0.0.0:1514"
|
||||||
|
protocol = "tcp"
|
||||||
|
labels = {
|
||||||
|
job = "syslog",
|
||||||
|
transport = "tcp",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
relabel_rules = loki.relabel.syslog.rules
|
||||||
|
forward_to = [loki.write.default.receiver]
|
||||||
|
}
|
||||||
|
|
||||||
|
loki.write "default" {
|
||||||
|
endpoint {
|
||||||
|
url = "http://loki:3100/loki/api/v1/push"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
loki:
|
||||||
|
image: grafana/loki:latest
|
||||||
|
container_name: loki
|
||||||
|
command: -config.file=/etc/loki/config.yaml
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /mnt/containers/logging/loki-config/config.yaml:/etc/loki/config.yaml:Z
|
||||||
|
- /mnt/containers/logging/loki-data:/loki:Z
|
||||||
|
networks:
|
||||||
|
- logging-nw
|
||||||
|
|
||||||
|
alloy:
|
||||||
|
image: grafana/alloy:latest
|
||||||
|
container_name: alloy
|
||||||
|
command:
|
||||||
|
- run
|
||||||
|
- --server.http.listen-addr=0.0.0.0:12345
|
||||||
|
- --storage.path=/var/lib/alloy/data
|
||||||
|
- /etc/alloy/config.alloy
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- loki
|
||||||
|
volumes:
|
||||||
|
- /mnt/containers/logging/alloy-config/config.alloy:/etc/alloy/config.alloy:Z
|
||||||
|
- /mnt/containers/logging/alloy-data:/var/lib/alloy/data:Z
|
||||||
|
ports:
|
||||||
|
# syslog intake for routers/switches/phones (UDP, RFC3164/5424)
|
||||||
|
- '514:514/udp'
|
||||||
|
# optional TCP syslog for devices that don't do UDP
|
||||||
|
- '1514:1514/tcp'
|
||||||
|
networks:
|
||||||
|
- logging-nw
|
||||||
|
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana:latest
|
||||||
|
container_name: grafana
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- loki
|
||||||
|
environment:
|
||||||
|
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
|
||||||
|
- GF_USERS_ALLOW_SIGN_UP=false
|
||||||
|
volumes:
|
||||||
|
- /mnt/containers/logging/grafana-data:/var/lib/grafana:Z
|
||||||
|
- /mnt/containers/logging/grafana-config/provisioning/datasources:/etc/grafana/provisioning/datasources:Z
|
||||||
|
networks:
|
||||||
|
- logging-nw
|
||||||
|
- reverseproxy-nw
|
||||||
|
|
||||||
|
networks:
|
||||||
|
logging-nw:
|
||||||
|
reverseproxy-nw:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: 1
|
||||||
|
|
||||||
|
datasources:
|
||||||
|
- name: Loki
|
||||||
|
type: loki
|
||||||
|
access: proxy
|
||||||
|
url: http://loki:3100
|
||||||
|
isDefault: true
|
||||||
|
editable: false
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
auth_enabled: false
|
||||||
|
|
||||||
|
server:
|
||||||
|
http_listen_port: 3100
|
||||||
|
grpc_listen_port: 9096
|
||||||
|
log_level: info
|
||||||
|
|
||||||
|
common:
|
||||||
|
path_prefix: /loki
|
||||||
|
storage:
|
||||||
|
filesystem:
|
||||||
|
chunks_directory: /loki/chunks
|
||||||
|
rules_directory: /loki/rules
|
||||||
|
replication_factor: 1
|
||||||
|
ring:
|
||||||
|
instance_addr: 127.0.0.1
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
|
||||||
|
schema_config:
|
||||||
|
configs:
|
||||||
|
- from: 2024-01-01
|
||||||
|
store: tsdb
|
||||||
|
object_store: filesystem
|
||||||
|
schema: v13
|
||||||
|
index:
|
||||||
|
prefix: index_
|
||||||
|
period: 24h
|
||||||
|
|
||||||
|
limits_config:
|
||||||
|
reject_old_samples: true
|
||||||
|
reject_old_samples_max_age: 168h
|
||||||
|
retention_period: 2160h # 90 days — adjust to taste, disk on this host is ~42GB free
|
||||||
|
max_query_series: 5000
|
||||||
|
|
||||||
|
compactor:
|
||||||
|
working_directory: /loki/compactor
|
||||||
|
compaction_interval: 10m
|
||||||
|
retention_enabled: true
|
||||||
|
retention_delete_delay: 2h
|
||||||
|
delete_request_store: filesystem
|
||||||
|
|
||||||
|
ruler:
|
||||||
|
storage:
|
||||||
|
type: local
|
||||||
|
local:
|
||||||
|
directory: /loki/rules
|
||||||
Reference in New Issue
Block a user