dnswatcher/internal/watcher/watcher.go
sneak 144a2df665 Initial scaffold with per-nameserver DNS monitoring model
Full project structure following upaas conventions: uber/fx DI, go-chi
routing, slog logging, Viper config. State persisted as JSON file with
per-nameserver record tracking for inconsistency detection. Stub
implementations for resolver, portcheck, tlscheck, and watcher.
2026-02-19 21:05:39 +01:00

95 lines
2.1 KiB
Go

// Package watcher provides the main monitoring orchestrator and scheduler.
package watcher
import (
"context"
"log/slog"
"go.uber.org/fx"
"sneak.berlin/go/dnswatcher/internal/config"
"sneak.berlin/go/dnswatcher/internal/logger"
"sneak.berlin/go/dnswatcher/internal/notify"
"sneak.berlin/go/dnswatcher/internal/portcheck"
"sneak.berlin/go/dnswatcher/internal/resolver"
"sneak.berlin/go/dnswatcher/internal/state"
"sneak.berlin/go/dnswatcher/internal/tlscheck"
)
// Params contains dependencies for Watcher.
type Params struct {
fx.In
Logger *logger.Logger
Config *config.Config
State *state.State
Resolver *resolver.Resolver
PortCheck *portcheck.Checker
TLSCheck *tlscheck.Checker
Notify *notify.Service
}
// Watcher orchestrates all monitoring checks on a schedule.
type Watcher struct {
log *slog.Logger
config *config.Config
state *state.State
resolver *resolver.Resolver
portCheck *portcheck.Checker
tlsCheck *tlscheck.Checker
notify *notify.Service
cancel context.CancelFunc
}
// New creates a new Watcher instance.
func New(
lifecycle fx.Lifecycle,
params Params,
) (*Watcher, error) {
watcher := &Watcher{
log: params.Logger.Get(),
config: params.Config,
state: params.State,
resolver: params.Resolver,
portCheck: params.PortCheck,
tlsCheck: params.TLSCheck,
notify: params.Notify,
}
lifecycle.Append(fx.Hook{
OnStart: func(startCtx context.Context) error {
ctx, cancel := context.WithCancel(startCtx)
watcher.cancel = cancel
go watcher.Run(ctx)
return nil
},
OnStop: func(_ context.Context) error {
if watcher.cancel != nil {
watcher.cancel()
}
return nil
},
})
return watcher, nil
}
// Run starts the monitoring loop.
func (w *Watcher) Run(ctx context.Context) {
w.log.Info(
"watcher starting",
"domains", len(w.config.Domains),
"hostnames", len(w.config.Hostnames),
"dnsInterval", w.config.DNSInterval,
"tlsInterval", w.config.TLSInterval,
)
// Stub: wait for context cancellation.
// Implementation will add initial check + periodic scheduling.
<-ctx.Done()
w.log.Info("watcher stopped")
}