Add YAML config loading with validation, env overrides for secrets, and a web dashboard exposing health, stats, and recent events.
76 lines
1.6 KiB
V
76 lines
1.6 KiB
V
module main
|
|
|
|
import time
|
|
$if linux || macos {
|
|
import net.unix
|
|
import os
|
|
}
|
|
import sources as _
|
|
|
|
fn (mut app App) docker_watch_loop() {
|
|
$if linux || macos {
|
|
for {
|
|
for src in app.cfg.sources.docker {
|
|
for host in src.hosts {
|
|
app.watch_docker_host(src, host)
|
|
}
|
|
}
|
|
time.sleep(10 * time.second)
|
|
}
|
|
} $else {
|
|
app.logger.warn('docker', 'watch',
|
|
'Docker socket watching is only supported on Linux/macOS')
|
|
for {
|
|
time.sleep(60 * time.second)
|
|
}
|
|
}
|
|
}
|
|
|
|
$if linux || macos {
|
|
fn (mut app App) watch_docker_host(src _.DockerSource, host string) {
|
|
socket_path := host.replace('unix://', '')
|
|
if !os.exists(socket_path) {
|
|
app.logger.warn('docker', 'watch', 'socket not found: ${socket_path}')
|
|
return
|
|
}
|
|
|
|
mut conn := unix.connect_stream(socket_path) or {
|
|
app.logger.warn('docker', 'watch', 'failed to connect to ${socket_path}: ${err}')
|
|
return
|
|
}
|
|
defer {
|
|
conn.close() or {}
|
|
}
|
|
|
|
filters := build_docker_filters(src.events)
|
|
request := 'GET /events?filters=${filters} HTTP/1.1\r\nHost: localhost\r\n\r\n'
|
|
conn.write_string(request) or {
|
|
app.logger.warn('docker', 'watch', 'write error: ${err}')
|
|
return
|
|
}
|
|
|
|
mut buf := []u8{len: 4096}
|
|
for {
|
|
read := conn.read(mut buf) or { break }
|
|
if read <= 0 {
|
|
break
|
|
}
|
|
lines := buf[..read].bytestr().split_into_lines()
|
|
for line in lines {
|
|
if line.starts_with('{') {
|
|
event := sources.transform_docker_event(line, src, host) or { continue }
|
|
app.publish(event)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn build_docker_filters(events []string) string {
|
|
mut parts := []string{}
|
|
for event in events {
|
|
parts << '"${event}":true'
|
|
}
|
|
return '{' + parts.join(',') + '}'
|
|
}
|
|
}
|