-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
114 lines (95 loc) · 2.73 KB
/
main.go
File metadata and controls
114 lines (95 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"context"
"fmt"
"log/slog"
"net/http"
"os"
"os/signal"
"runtime/debug"
"strings"
"syscall"
"time"
"github.com/UnitVectorY-Labs/ghook2pubsub/internal/publisher"
"github.com/UnitVectorY-Labs/ghook2pubsub/internal/webhook"
)
// Version is injected via ldflags at build time.
var Version = ""
func main() {
if Version == "" {
if info, ok := debug.ReadBuildInfo(); ok {
Version = info.Main.Version
}
if Version == "" {
Version = "dev"
}
}
cfg, err := webhook.LoadConfig()
if err != nil {
fmt.Fprintf(os.Stderr, "configuration error: %v\n", err)
os.Exit(1)
}
// Parse log level
var level slog.Level
switch strings.ToLower(cfg.LogLevel) {
case "debug":
level = slog.LevelDebug
case "warn":
level = slog.LevelWarn
case "error":
level = slog.LevelError
default:
level = slog.LevelInfo
}
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: level})))
slog.Info("starting ghook2pubsub",
"version", Version,
"listen_addr", cfg.ListenAddr,
"listen_port", cfg.ListenPort,
"pubsub_project_id", cfg.PubSubProjectID,
"pubsub_topic_id", cfg.PubSubTopicID,
"payload_compression", cfg.PayloadCompression.String(),
"payload_compression_attribute", cfg.PayloadCompression.AttributeName,
"webhook_secrets_count", len(cfg.WebhookSecrets),
"log_level", cfg.LogLevel,
)
ctx := context.Background()
pub, err := publisher.NewPubSubPublisher(ctx, cfg.PubSubProjectID, cfg.PubSubTopicID)
if err != nil {
slog.Error("failed to create pubsub publisher", "error", err.Error())
os.Exit(1)
}
defer pub.Close()
publishingTarget := publisher.NewCompressingPublisher(pub, cfg.PayloadCompression)
metrics := &webhook.Metrics{}
handler := webhook.NewHandler(publishingTarget, cfg.WebhookSecrets, metrics)
mux := http.NewServeMux()
mux.Handle("POST /webhook", handler)
mux.HandleFunc("GET /healthz", webhook.HealthHandler)
addr := fmt.Sprintf("%s:%s", cfg.ListenAddr, cfg.ListenPort)
server := &http.Server{
Addr: addr,
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 60 * time.Second,
}
// Graceful shutdown
stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT)
go func() {
slog.Info("server listening", "addr", addr)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
slog.Error("server error", "error", err.Error())
os.Exit(1)
}
}()
<-stop
slog.Info("shutdown signal received")
shutdownCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if err := server.Shutdown(shutdownCtx); err != nil {
slog.Error("server shutdown error", "error", err.Error())
}
slog.Info("server stopped")
}