forgejo-runner-sizer/cmd/collector/main.go
Waldemar Kindler 7201a527d8
All checks were successful
ci / build (push) Successful in 1m39s
feat(collector): Summaries metrics at the end of the process
2026-02-04 16:21:17 +01:00

89 lines
2.5 KiB
Go

package main
import (
"context"
"flag"
"fmt"
"log/slog"
"os"
"os/signal"
"syscall"
"time"
"edp.buildth.ing/DevFW-CICD/forgejo-runner-resource-collector/internal/collector"
"edp.buildth.ing/DevFW-CICD/forgejo-runner-resource-collector/internal/output"
"edp.buildth.ing/DevFW-CICD/forgejo-runner-resource-collector/internal/summary"
)
const (
defaultInterval = 5 * time.Second
defaultProcPath = "/proc"
defaultLogLevel = "info"
defaultLogFormat = "json"
defaultTopN = 5
)
func main() {
// Parse command line flags
interval := flag.Duration("interval", defaultInterval, "Collection interval (e.g., 5s, 1m)")
procPath := flag.String("proc-path", defaultProcPath, "Path to proc filesystem")
logLevel := flag.String("log-level", defaultLogLevel, "Log level: debug, info, warn, error")
logFormat := flag.String("log-format", defaultLogFormat, "Output format: json, text")
topN := flag.Int("top", defaultTopN, "Number of top processes to include")
flag.Parse()
// Setup structured logging for application logs
appLogLevel := output.ParseLogLevel(*logLevel)
appHandler := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
Level: appLogLevel,
})
appLogger := slog.New(appHandler)
// Setup metrics output writer
metricsWriter := output.NewLoggerWriter(output.LoggerConfig{
Output: os.Stdout,
Format: output.ParseLogFormat(*logFormat),
Level: slog.LevelInfo,
})
defer func() { _ = metricsWriter.Close() }()
// Create collector
c := collector.New(collector.Config{
ProcPath: *procPath,
Interval: *interval,
TopN: *topN,
}, metricsWriter, appLogger)
// Attach summary writer to emit run summary on shutdown
summaryWriter := summary.NewSummaryWriter(os.Stdout, *logFormat)
c.SetSummaryWriter(summaryWriter)
// Setup signal handling for graceful shutdown
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigChan
appLogger.Info("received signal", slog.String("signal", sig.String()))
cancel()
}()
// Run collector
appLogger.Info("starting resource collector",
slog.Duration("interval", *interval),
slog.String("proc_path", *procPath),
slog.String("log_level", *logLevel),
slog.String("log_format", *logFormat),
slog.Int("top_n", *topN),
)
if err := c.Run(ctx); err != nil && err != context.Canceled {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
appLogger.Info("collector stopped gracefully")
}