diff --git a/logging/alloy-config.alloy b/logging/alloy-config.alloy new file mode 100644 index 0000000..8d9dec5 --- /dev/null +++ b/logging/alloy-config.alloy @@ -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" + } +} diff --git a/logging/docker-compose.yaml b/logging/docker-compose.yaml new file mode 100644 index 0000000..4abfece --- /dev/null +++ b/logging/docker-compose.yaml @@ -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 diff --git a/logging/grafana-provisioning/datasources/loki.yaml b/logging/grafana-provisioning/datasources/loki.yaml new file mode 100644 index 0000000..050b3c4 --- /dev/null +++ b/logging/grafana-provisioning/datasources/loki.yaml @@ -0,0 +1,9 @@ +apiVersion: 1 + +datasources: + - name: Loki + type: loki + access: proxy + url: http://loki:3100 + isDefault: true + editable: false diff --git a/logging/loki-config.yaml b/logging/loki-config.yaml new file mode 100644 index 0000000..31d5118 --- /dev/null +++ b/logging/loki-config.yaml @@ -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