main is the entry point of the application
()
| 442 | |
| 443 | // main is the entry point of the application |
| 444 | func main() { |
| 445 | // Setup initial logger before flag parsing |
| 446 | initialLogLevel := slog.LevelInfo |
| 447 | initialLogHandler := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: initialLogLevel, AddSource: true}) |
| 448 | slog.SetDefault(slog.New(initialLogHandler)) |
| 449 | |
| 450 | startTime = time.Now() |
| 451 | |
| 452 | // Define flags |
| 453 | port := flag.Int("port", 8080, "Port to listen on") |
| 454 | dedupSeconds := flag.Int("dedup-window", 1800, "Deduplication window in seconds") |
| 455 | metricsPath := flag.String("metrics-path", "/metrics", "Path for OpenTelemetry Prometheus metrics endpoint") |
| 456 | expvarPath := flag.String("expvar-path", "/debug/vars", "Path for expvar metrics endpoint (empty to disable)") |
| 457 | healthPath := flag.String("health-path", "/healthz", "Path for health check endpoint") |
| 458 | logFormat := flag.String("log-format", "json", "Log format: 'json' or 'text'") |
| 459 | logLevelFlag := flag.String("log-level", "info", "Log level: 'debug', 'info', 'warn', 'error'") |
| 460 | // Use the global dedupLogFile variable |
| 461 | flag.StringVar(&dedupLogFile, "dedup-logfile", "", "File to log deduplicated requests (empty to disable)") |
| 462 | flag.Var(&keyPaths, "dedup-key", "JSON path (dot-notation) for deduplication key (can be used multiple times)") |
| 463 | flag.StringVar(&dedupSeparator, "dedup-separator", "-", "Separator used between multi-key values") |
| 464 | flag.Parse() |
| 465 | |
| 466 | // Configure final logger based on flags |
| 467 | var level slog.Level |
| 468 | switch strings.ToLower(*logLevelFlag) { |
| 469 | case "debug": |
| 470 | level = slog.LevelDebug |
| 471 | case "info": |
| 472 | level = slog.LevelInfo |
| 473 | case "warn": |
| 474 | level = slog.LevelWarn |
| 475 | case "error": |
| 476 | level = slog.LevelError |
| 477 | default: |
| 478 | slog.Warn("invalid log level specified, defaulting to info", "value", *logLevelFlag) |
| 479 | level = slog.LevelInfo |
| 480 | } |
| 481 | var logHandler slog.Handler |
| 482 | if *logFormat == "text" { |
| 483 | logHandler = slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: level, AddSource: true}) |
| 484 | } else { |
| 485 | logHandler = slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: level, AddSource: true}) |
| 486 | } |
| 487 | slog.SetDefault(slog.New(logHandler)) |
| 488 | |
| 489 | // Initialize core components |
| 490 | seenIDs = make(map[[32]byte]seenEntry) |
| 491 | dedupWindow = time.Duration(*dedupSeconds) * time.Second |
| 492 | |
| 493 | // Open deduplication log file if specified |
| 494 | if dedupLogFile != "" { |
| 495 | var err error |
| 496 | dedupLogger, err = os.OpenFile(dedupLogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) |
| 497 | if err != nil { |
| 498 | slog.Error("failed to open deduplication log file", "file", dedupLogFile, "error", err) |
| 499 | os.Exit(1) |
| 500 | } |
| 501 | slog.Info("deduplication log file opened", "path", dedupLogFile) |
nothing calls this directly
no test coverage detected
searching dependent graphs…