• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stillya / wg-relay / 17277209982

27 Aug 2025 07:52PM UTC coverage: 13.246% (+8.4%) from 4.874%
17277209982

Pull #3

github

stillya
added prom integration
Pull Request #3: Added metrics support

78 of 293 new or added lines in 11 files covered. (26.62%)

5 existing lines in 4 files now uncovered.

111 of 838 relevant lines covered (13.25%)

0.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/cmd/daemon/main.go
1
package main
2

3
import (
4
        "context"
5
        "fmt"
6
        log "log/slog"
7
        "net/http"
8
        "os"
9
        "os/signal"
10
        "syscall"
11

12
        "github.com/jessevdk/go-flags"
13
        "github.com/pkg/errors"
14
        "github.com/prometheus/client_golang/prometheus"
15
        "github.com/prometheus/client_golang/prometheus/promhttp"
16
        "github.com/stillya/wg-relay/pkg/dataplane/config"
17
        "github.com/stillya/wg-relay/pkg/dataplane/proxy"
18
        "github.com/stillya/wg-relay/pkg/metrics"
19

20
        "github.com/stillya/wg-relay/pkg/dataplane"
21
        "github.com/stillya/wg-relay/pkg/maps/metricsmap"
22
        "github.com/stillya/wg-relay/pkg/monitor"
23
)
24

25
// ProxyMode defines the operation mode
26
type ProxyMode string
27

28
const (
29
        ModeForward ProxyMode = "forward" // XDP-based forward proxy
30
        ModeReverse ProxyMode = "reverse" // TC-based reverse proxy
31
)
32

33
// Opts represents command line options
34
type Opts struct {
35
        ConfigFile string `short:"c" long:"config" description:"Path to configuration file" default:"config.yaml"`
36
        Debug      bool   `short:"d" long:"debug" description:"Enable debug logging"`
37
        Version    bool   `short:"v" long:"version" description:"Show version information"`
38
}
39

40
const version = "0.0.1"
41

42
func main() {
×
43
        var opts Opts
×
44
        parser := flags.NewParser(&opts, flags.Default)
×
45

×
46
        _, err := parser.Parse()
×
47
        if _, err := parser.Parse(); err != nil {
×
48
                var flagsErr *flags.Error
×
49
                if errors.As(err, &flagsErr) && errors.Is(flagsErr.Type, flags.ErrHelp) {
×
50
                        os.Exit(0)
×
51
                }
×
52
                os.Exit(1)
×
53
        }
54

55
        if opts.Version {
×
56
                fmt.Printf("wg-proxy daemon version %s\n", version)
×
57
                os.Exit(0)
×
58
        }
×
59

60
        logLevel := log.LevelInfo
×
61
        if opts.Debug {
×
62
                logLevel = log.LevelDebug
×
63
        }
×
64

65
        logger := log.New(log.NewTextHandler(os.Stdout, &log.HandlerOptions{
×
66
                Level: logLevel,
×
67
        }))
×
68
        log.SetDefault(logger)
×
69

×
70
        log.Info("Starting wg-proxy daemon", "version", version)
×
71

×
72
        cfg, err := loadConfig(opts)
×
73
        if err != nil {
×
74
                log.Error("Failed to load configuration", "error", err)
×
75
                os.Exit(1)
×
76
        }
×
77

78
        ctx, cancel := context.WithCancel(context.Background())
×
79
        defer cancel()
×
80

×
81
        sigCh := make(chan os.Signal, 1)
×
82
        signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
×
83

×
84
        // Create and start dataplane manager
×
85
        var loader dataplane.Loader
×
86

×
NEW
87
        switch ProxyMode(cfg.Proxy.Mode) {
×
88
        case ModeForward:
×
89
                loader, err = proxy.NewForwardLoader()
×
90
        case ModeReverse:
×
91
                loader, err = proxy.NewReverseLoader()
×
92
        default:
×
NEW
93
                log.Error("Unsupported proxy mode", "mode", cfg.Proxy.Mode)
×
94
        }
95

96
        if err != nil {
×
97
                log.Error("Failed to create loader", "error", err)
×
98
                os.Exit(1)
×
99
        }
×
100

101
        managerCfg := dataplane.ManagerConfig{
×
NEW
102
                Cfg:    cfg.Proxy,
×
103
                Loader: loader,
×
104
        }
×
105

×
106
        dataplaneManager, err := dataplane.NewManager(managerCfg)
×
107
        if err != nil {
×
108
                log.Error("Failed to create dataplane manager", "error", err)
×
109
                os.Exit(1)
×
110
        }
×
111

112
        if err := dataplaneManager.Start(ctx); err != nil {
×
113
                log.Error("Failed to start dataplane", "error", err)
×
114
                os.Exit(1)
×
115
        }
×
116
        defer dataplaneManager.Stop()
×
117

×
NEW
118
        var metricsSource *metricsmap.BPFMapSource
×
NEW
119
        var bpfCollector *metrics.BpfCollector
×
NEW
120
        var statsMonitor *monitor.StatMonitor
×
NEW
121

×
NEW
122
        maps := dataplaneManager.Maps()
×
NEW
123
        if maps != nil && maps.Metrics != nil {
×
NEW
124
                metricsSource = metricsmap.NewBPFMapSource("wg-relay-metrics", maps.Metrics)
×
NEW
125

×
NEW
126
                if cfg.Monitoring.Prometheus.Enabled {
×
NEW
127
                        bpfCollector = metrics.NewBpfCollector(metricsSource, cfg.Proxy.Mode)
×
NEW
128
                        prometheus.MustRegister(bpfCollector)
×
NEW
129

×
NEW
130
                        // Start Prometheus HTTP server
×
NEW
131
                        go func() {
×
NEW
132
                                mux := http.NewServeMux()
×
NEW
133
                                mux.Handle("/metrics", promhttp.Handler())
×
NEW
134

×
NEW
135
                                log.Info("Starting Prometheus metrics server", "listen", cfg.Monitoring.Prometheus.Listen)
×
NEW
136
                                if err := http.ListenAndServe(cfg.Monitoring.Prometheus.Listen, mux); err != nil {
×
NEW
137
                                        log.Error("Prometheus metrics server failed", "error", err)
×
NEW
138
                                }
×
139
                        }()
140
                }
141

NEW
142
                if cfg.Monitoring.Statistics.Enabled {
×
NEW
143
                        statsMonitor = monitor.NewStatMonitor(monitor.StatMonitorParams{
×
NEW
144
                                Source:   metricsSource,
×
NEW
145
                                Interval: cfg.Monitoring.Statistics.Interval,
×
NEW
146
                        })
×
NEW
147
                        go statsMonitor.Start(ctx)
×
NEW
148
                        defer statsMonitor.Stop()
×
NEW
149
                }
×
150
        }
151

152
        log.Info("Daemon started successfully",
×
NEW
153
                "mode", cfg.Proxy.Mode,
×
NEW
154
                "interfaces", cfg.Proxy.Interfaces,
×
NEW
155
                "listen", cfg.Daemon.Listen,
×
NEW
156
                "statistics", cfg.Monitoring.Statistics.Enabled,
×
NEW
157
                "prometheus", cfg.Monitoring.Prometheus.Enabled)
×
158

×
159
        <-sigCh
×
160
        log.Info("Received shutdown signal, stopping daemon...")
×
161

×
162
        cancel()
×
163

×
164
        log.Info("Daemon stopped")
×
165
}
166

NEW
167
func loadConfig(opts Opts) (*config.Config, error) {
×
NEW
168
        configData, err := config.Load(opts.ConfigFile)
×
169
        if err != nil {
×
170
                return nil, fmt.Errorf("failed to load config: %w", err)
×
171
        }
×
172

NEW
173
        return configData, nil
×
174
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc