Commit Graph
82 Commits
Author SHA1 Message Date
pipistrello 0f8620c405 02-tekhnohim logging: add Zabbix Global view to Grafana
Pin alexanderzobnin-zabbix-app 6.5.0 for synchronous startup installation on Grafana 13.1.0, keeping the plugin reproducible across Portainer redeploys.

Reconstruct Zabbix dashboard 1 as a provisioned Grafana dashboard with eight site rows, 27 full-width traffic/storage graphs, a one-hour default range, and a computer-selectable failed-logon panel. Traffic errors and discards use a separate packets-per-second right axis.

Validated the compose model with Docker Compose 5.3.0, parsed the dashboard JSON, confirmed the Zabbix datasource against API 7.0.24, and ran all 28 panel queries: 263 frames returned with no query errors. Five panels are blank because their source Zabbix items have no retained history.
2026-07-17 17:56:26 +03:00
pipistrello a4aa0e90fe grafana: expose phone LDAP DNS root cause
Verbose Yealink traces show LDAP binds fail before authentication because the provisioned short hostname SERVERPDC cannot be resolved. The failures started before the separate AD unauthenticated-bind hardening, so credentials and that security change are not the cause.\n\nInclude the explicit domain-resolution signature in current-state, trend, top-phone, and operational-log queries. Update panel guidance to direct investigation toward a resolvable LDAP FQDN or stable IP.\n\nThe added LogQL alternative was executed successfully against production Loki 3.7.2.
2026-07-17 14:25:30 +03:00
pipistrello 1a42f89c11 grafana: separate phone health signals from firmware noise
The Yealink dashboard treated nearly every level-3 line as actionable, making routine boot and firmware chatter look like fleet-wide failures.\n\nReplace generic error counts with recent LDAP, provisioning, and internal-database signals. Add dedicated operational trend and log panels, and relabel raw severity as diagnostic-only while retaining web-password, registration, and DHCP context.\n\nValidated all 17 LogQL targets directly against Loki 3.7.2. In the inspected 24-hour sample, provisioning had settled, LDAP failures remained active, and one handset reported a malformed internal database.
2026-07-17 14:19:32 +03:00
pipistrello 43be2d8bb0 upgrade logging loki and alloy 2026-07-17 13:53:39 +03:00
pipistrello 1496e07d19 upgrade logging grafana to 13.1.0 2026-07-17 13:38:09 +03:00
pipistrelloandClaude Opus 4.8 f438f3845c Key Yealink phones by MAC, and stop pretending fleet-wide sums are thresholds
Two changes driven by the fleet syslog rollout (~4 -> 106 senders) and the
operator enabling Yealink's prepend-MAC on the autoprovisioned handsets.

1. Alloy: lift the MAC into a real `mac` label.

   UDP syslog offers only three possible identities: sender IP, RFC3164
   HOSTNAME, message body.
   - source_ip is DHCP (observed lease 1200s) so it is NOT stable: a re-IP
     looks like a new device, and a recycled IP silently inherits another
     phone's history.
   - HOSTNAME is useless: Yealink puts its subsystem there (sua/GUI/cfg/sys),
     and after prepend-MAC the bracketed MAC lands in that slot and is rejected
     as a hostname, so the label is simply absent on new lines.
   So the body is the only place identity exists. A loki.process regex stage
   extracts it. Non-Yealink senders (the D-Link switches) don't match and pass
   through with no mac label. Cardinality is safe: mac is 1:1 with a device and
   does not multiply against source_ip.

   Verified on a disposable alloy+loki rig by replaying 406 REAL captured lines:
   0 parse errors, both branches confirmed — Yealink lines get
   mac=80:5e:0c:b2:44:d3, the switch line passes through with no mac label.

2. Dashboard: identity by MAC, comparative panels, no invented thresholds.

   - Variable is now label_values(mac) with allValue ".+" (not ".*") so "All"
     matches only streams that HAVE a mac — excluding switches automatically.
   - Removed the absolute colour thresholds. They were derived from a ~4-hour
     sample of TWO atypically verbose handsets and were already wrong at 2
     phones (actionable errors read 537 against a red line of 800; scheduler
     timeouts 193 against yellow at 150). They were fleet-wide SUMS, so they
     scale with phone count rather than with health. The fleet onboarded today,
     so no representative 24h baseline exists to replace them with — panels are
     comparative (worst offenders) until a week of real data exists. The one
     surviving threshold is "phones failing provisioning" >= 1, which is a
     qualitative fault rather than a magnitude.
   - Stats now count AFFECTED DEVICES, not fleet-wide line totals.
   - "Phones reporting" -> "Phones heard from", documented as NOT a health
     count: most of the fleet runs at Yealink default log level 3 (Error) and
     is silent unless something breaks. A silent phone is a healthy phone.
   - Registration/DHCP panels labelled level-6-only: they key on info/notice
     lines that level-3 phones never send, so an absent phone there means
     "quiet", not "unregistered".
   - Added "loudest phones by log volume" to surface handsets left at level 6
     (two of them are ~80% of all volume).
   - refresh 1m -> 5m.

   Verified by firing all 14 panel queries CONCURRENTLY against a sink loaded
   with replayed real data: 14/14 return data, 0 rejected. Last time these were
   verified sequentially, which is what let the 429 bug ship.

Note: data predating the MAC rollout has no mac label and won't appear.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 19:55:09 +03:00
pipistrelloandClaude Opus 4.8 bb4c92d5e5 Fix Loki 429s that blanked out dashboard panels at random
Symptom: the Yealink dashboard showed data, then panels went empty. Not data
loss — Loki has every line (per-device counts only ever grew; no ingestion
errors, no rejections, compactor deleted nothing). Loki was rejecting the
dashboard's own queries with HTTP 429 "too many outstanding requests" for ~45%
of requests (53 rejected vs 64 OK in 30 min), so on each refresh a random
subset of panels won the race and the rest blanked.

Cause: split_queries_by_interval defaulted to 30m, so each 24h panel query was
split into 48 sub-queries. 14 panels refreshing together = ~672 sub-queries
against a scheduler queue of 100, on a 2-core host.

Reproduced deterministically: 14 identical queries fired sequentially = 14/14
OK; the same 14 fired concurrently = 5/14 OK, 9 rejected.

Fix:
- split_queries_by_interval: 24h — 48 sub-queries become 1, and it matches the
  schema_config index period. This fleet produces ~35k lines/day; splitting
  buys nothing at this scale.
- query_scheduler.max_outstanding_requests_per_tenant: 2048 (was 100) — headroom
  so one refresh cannot overflow the queue.
- max_query_parallelism: 8 (was 32) — realistic for 2 cores.

Validated on a disposable loki:2.9.8 container with its own data dir before
commit: starts clean, and /config confirms split_queries_by_interval=1d,
max_query_parallelism=8, max_outstanding_requests_per_tenant=2048.

Note for future dashboard work: the panel queries were individually verified
against live Loki before the dashboard shipped, but sequentially — which never
exercised the concurrency a dashboard actually creates. Verify dashboards by
loading them, not by looping their queries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 16:33:09 +03:00
pipistrelloandClaude Opus 4.8 13b1887a16 Add provisioned Grafana dashboard for Yealink IP phones
Phones are ~99% of this Loki's log volume and nothing surfaced them. Adds a
file-provisioned dashboard (uid yealink-phones, folder "Network") plus the
provider config and the two grafana bind mounts it needs.

Built against a 24h baseline of real handset traffic; all 14 panel queries were
executed against live Loki before commit. Three findings shaped it, each of
which contradicts the obvious reading of the data:

- severity=emergency is NOT an emergency. All 24 emergency lines are the phone
  printing its own log-level table at boot ("sys log :type=1,E=3,W=4,N=5,I=6,D=7")
  — Yealink emits its logging config at level 0. Alerting on it would be 100%
  false positive. Filtered out.
- "LSYS<3+error> rtpcap get len not enough" is 467 of 830 error lines (56%) — a
  noise floor, not a fault. Excluded from every "actionable" panel.
- The hostname label cannot identify a device: its values are Yealink subsystems
  (sua, GUI, sys, cfg, ipp, dev, WEB, ATP), because the phones put the subsystem
  in the RFC3164 HOSTNAME field. Everything keys on source_ip. Yealink lines are
  separated from switch/router traffic on the same Loki by the |~ "<[0-7][+]"
  module marker (26,450 Yealink vs 33 non-Yealink lines in the baseline).

Thresholds are seeded from measured 24h counts: check passwd err 21 (auth),
data_task schedule time out 117 (handset scheduler overrunning its 30s
threshold — the best "phone is unwell" proxy), tftp/provisioning failures 3,
Register: update server 175 (SIP beat, 120s period), DHCP lease 9.

Caveat: only two handsets report today, so thresholds are baselined on a
2-phone sample and want revisiting once the fleet is onboarded.

Dashboards are file-provisioned, so UI edits are not persisted — change the
JSON here and redeploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 15:53:11 +03:00
pipistrello 9809cddbdf Extend Loki retention to 365 days (was 90)
Operator requirement: logs must persist at least one year. Applied
live (data-preserving restart, verified prior data survived) and
here for the next redeploy to stay in sync.
2026-07-15 14:30:24 +03:00
pipistrello fb3ac50522 Parse RFC3164 (BSD) syslog in Alloy — real devices don't send RFC5424
Confirmed via packet capture: a Yealink phone and (per RouterOS's known
default behavior) the fleet's routers send classic BSD-style syslog,
not RFC5424. Alloy's loki.source.syslog defaults to RFC5424-only and
was silently dropping every message ("expecting a version value in the
range 1-999"). syslog_format = "rfc3164" fixes it, but that argument
only exists from Alloy v1.5.0 onward (confirmed empirically against
v1.4.3, which fails config load) — bump the pin accordingly. v1.5.0 is
an adjacent minor release, not the kind of large version jump that hit
the Loki/Grafana :latest kernel-incompatibility bug fixed earlier.
2026-07-15 13:03:37 +03:00
pipistrello 4c1033b460 Pin logging stack images; fix Loki common.instance_addr placement
:latest images (loki 3.7.3/go1.26.4, presumably grafana/alloy too) reset
every TCP connection on this host — kernel is 5.16.7 (Fedora 35, EOL
since 2023), too old for whatever the newer Go toolchains need.
Confirmed via a disposable grafana/loki:2.9.8 test container: same
config, same host, works cleanly. Pin all three images to older stable
releases instead of chasing this again on every redeploy.

Also fixes an unrelated config bug: instance_addr belongs directly
under `common:`, not nested under `common.ring:` — the misplaced field
was silently ignored, which didn't help but wasn't the actual cause.
2026-07-15 12:09:15 +03:00
pipistrello 22dfb732d3 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.
2026-07-15 11:41:00 +03:00
pipistrello c3589732f2 fix 2025-09-26 12:52:35 +03:00
pipistrello 951135658a test 2025-09-26 12:52:06 +03:00
pipistrello 91bedb35eb fix 2025-09-26 12:42:42 +03:00
pipistrello e957700a5b port change 2025-09-26 12:33:21 +03:00
pipistrello 2d37c51730 network test 2025-09-26 12:29:04 +03:00
pipistrello 127aad886a port change 2025-09-26 12:27:27 +03:00
pipistrello c3bb96be45 port closed 2025-09-26 12:23:21 +03:00
pipistrello 2892f25229 syntax 2025-09-26 12:22:15 +03:00
pipistrello 793c6dbc5c syntax 2025-09-26 12:20:24 +03:00
pipistrello 5c9f91cd3d syntax 2025-09-26 12:12:01 +03:00
pipistrello 33ad5ddb0b syntax 2025-09-26 11:54:49 +03:00
pipistrello 9c3475edae syntax 2025-09-26 11:53:58 +03:00
pipistrello 9bee0f99d0 syntax fix 2025-09-26 11:53:07 +03:00
pipistrello 25089cb668 syntax 2025-09-26 11:52:45 +03:00
pipistrello 8dd2ef0151 syntax 2025-09-26 11:52:16 +03:00
pipistrello e511b19ac5 Merge branch 'master' of https://git.it-depot.ru/technohim/docker-infrastructure 2025-09-26 11:47:40 +03:00
pipistrello 8a8be44d59 initial 2025-09-26 11:47:37 +03:00
pipistrello bb3b69b1c1 Удалить IMG_1642.DNG 2025-03-12 10:16:06 +03:00
pipistrello 0e70f29d3a Загрузить файлы в «/» 2025-03-12 10:15:28 +03:00
pipistrello b5590d411a image path changed 2025-02-17 11:23:14 +03:00
pipistrello 1447b836ec python version 2023-12-11 13:53:51 +03:00
pipistrello 790f54b289 fix 2023-12-01 17:47:14 +03:00
pipistrello ae906c9e45 closing port 8080 2023-12-01 17:45:28 +03:00
pipistrello 83dbd962d6 rework 2023-12-01 17:40:29 +03:00
pipistrello 7dbdc8264e Merge branch 'master' of https://git.it-depot.ru/technohim/docker-infrastructure 2023-11-30 11:57:47 +03:00
pipistrello b83814a298 come on 2023-11-30 11:54:55 +03:00
pipistrello 5ff1953c21 Изменил(а) на 'nginx-proxy-manager/docker-compose.yaml' 2023-10-24 13:15:26 +03:00
pipistrello 76fb22db84 Изменил(а) на 'wireguard/docker-compose.yaml'
добавлено количество пиров
2023-08-30 09:35:08 +03:00
pipistrello 4e447d738c syntax 2023-07-19 12:54:50 +03:00
pipistrello f824ce1081 syntax 2023-07-19 12:54:19 +03:00
pipistrello 85e9e83e95 html 2023-07-19 12:53:15 +03:00
pipistrello 5baf5e4908 syntax 2023-07-19 12:35:55 +03:00
pipistrello bcf629fd20 volume 2023-07-19 12:35:13 +03:00
pipistrello 0df6da6472 no volumes 2023-07-19 12:23:32 +03:00
pipistrello 96cf0766c4 no volumes 2023-07-19 12:23:04 +03:00
pipistrello f5a44efbc0 test 2023-07-19 12:22:10 +03:00
pipistrello 77d55ffbe2 syntax 2023-07-19 12:21:20 +03:00
pipistrello fa6a41ba30 syntax 2023-07-19 12:13:40 +03:00