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

stillya / wg-relay / 20543022641

27 Dec 2025 06:53PM UTC coverage: 26.309% (-2.1%) from 28.375%
20543022641

Pull #8

github

stillya
polish commit
Pull Request #8: feat(agent): made seperation on control plane and cli

271 of 938 new or added lines in 7 files covered. (28.89%)

412 of 1566 relevant lines covered (26.31%)

0.27 hits per line

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

0.0
/cmd/cli/printer.go
1
package main
2

3
import (
4
        "fmt"
5
        "io"
6
        "os"
7
        "strings"
8
        "time"
9

10
        "github.com/stillya/wg-relay/pkg/api"
11
)
12

13
type Printer struct {
14
        out io.Writer
15
        err io.Writer
16
}
17

NEW
18
func NewPrinter() *Printer {
×
NEW
19
        return &Printer{
×
NEW
20
                out: os.Stdout,
×
NEW
21
                err: os.Stderr,
×
NEW
22
        }
×
NEW
23
}
×
24

NEW
25
func (p *Printer) printf(w io.Writer, format string, args ...interface{}) {
×
NEW
26
        if _, err := fmt.Fprintf(w, format, args...); err != nil {
×
NEW
27
                fmt.Fprintf(os.Stderr, "Error writing output: %v\n", err)
×
NEW
28
        }
×
29
}
30

NEW
31
func (p *Printer) Print(msg string) {
×
NEW
32
        p.printf(p.out, "%s\n", msg)
×
NEW
33
}
×
34

NEW
35
func (p *Printer) Printf(format string, args ...interface{}) {
×
NEW
36
        p.printf(p.out, format, args...)
×
NEW
37
}
×
38

NEW
39
func (p *Printer) Error(format string, args ...interface{}) {
×
NEW
40
        p.printf(p.err, format, args...)
×
NEW
41
}
×
42

NEW
43
func (p *Printer) PrintStatus(status *api.StatusResponse) {
×
NEW
44
        p.Printf("State:      %s\n", status.State)
×
NEW
45
        p.Printf("Uptime:     %s\n", formatDuration(status.Uptime))
×
NEW
46

×
NEW
47
        if status.Mode != "" {
×
NEW
48
                p.Printf("Mode:       %s\n", status.Mode)
×
NEW
49
        }
×
50

NEW
51
        if len(status.Interfaces) > 0 {
×
NEW
52
                p.Printf("Interfaces: %v\n", status.Interfaces)
×
NEW
53
        }
×
54

NEW
55
        if status.ErrorMessage != "" {
×
NEW
56
                p.Printf("Error:      %s\n", status.ErrorMessage)
×
NEW
57
        }
×
58
}
59

NEW
60
func (p *Printer) PrintStats(stats *api.StatsResponse) {
×
NEW
61
        if len(stats.Metrics) == 0 {
×
NEW
62
                p.Print("No metrics available")
×
NEW
63
                return
×
NEW
64
        }
×
65

NEW
66
        type srcStats struct {
×
NEW
67
                rxBytes uint64
×
NEW
68
                txBytes uint64
×
NEW
69
        }
×
NEW
70

×
NEW
71
        perSrcStats := make(map[string]*srcStats)
×
NEW
72
        var rxBytes, txBytes uint64
×
NEW
73

×
NEW
74
        for _, metric := range stats.Metrics {
×
NEW
75
                if metric.Reason == "forwarded" {
×
NEW
76
                        srcAddr := metric.SrcAddr
×
NEW
77

×
NEW
78
                        if _, exists := perSrcStats[srcAddr]; !exists {
×
NEW
79
                                perSrcStats[srcAddr] = &srcStats{}
×
NEW
80
                        }
×
81

NEW
82
                        if metric.Direction == "from_wg" {
×
NEW
83
                                rxBytes += metric.Bytes
×
NEW
84
                                perSrcStats[srcAddr].rxBytes += metric.Bytes
×
NEW
85
                        } else if metric.Direction == "to_wg" {
×
NEW
86
                                txBytes += metric.Bytes
×
NEW
87
                                perSrcStats[srcAddr].txBytes += metric.Bytes
×
NEW
88
                        }
×
89
                }
90
        }
91

NEW
92
        totalBytes := rxBytes + txBytes
×
NEW
93
        avgRate := float64(totalBytes) / stats.Uptime.Seconds()
×
NEW
94

×
NEW
95
        secondsInDay := float64(24 * 60 * 60)
×
NEW
96
        estimatedRxDaily := uint64(float64(rxBytes) / stats.Uptime.Seconds() * secondsInDay)
×
NEW
97
        estimatedTxDaily := uint64(float64(txBytes) / stats.Uptime.Seconds() * secondsInDay)
×
NEW
98
        estimatedTotalDaily := estimatedRxDaily + estimatedTxDaily
×
NEW
99

×
NEW
100
        p.Printf("\n")
×
NEW
101
        p.Printf("                         wg-relay traffic statistics\n")
×
NEW
102
        p.Printf("\n")
×
NEW
103
        p.Printf(" %-18s | %12s | %12s | %12s | %12s\n", "", "from_wg", "to_wg", "total", "avg. rate")
×
NEW
104
        p.Printf(" %s+%s+%s+%s+%s\n",
×
NEW
105
                strings.Repeat("-", 18),
×
NEW
106
                strings.Repeat("-", 14),
×
NEW
107
                strings.Repeat("-", 14),
×
NEW
108
                strings.Repeat("-", 14),
×
NEW
109
                strings.Repeat("-", 14))
×
NEW
110
        p.Printf(" %-18s | %12s | %12s | %12s | %9s/s\n", "traffic",
×
NEW
111
                formatBytes(rxBytes),
×
NEW
112
                formatBytes(txBytes),
×
NEW
113
                formatBytes(totalBytes),
×
NEW
114
                formatBytes(uint64(avgRate)))
×
NEW
115
        p.Printf(" %s+%s+%s+%s+%s\n",
×
NEW
116
                strings.Repeat("-", 18),
×
NEW
117
                strings.Repeat("-", 14),
×
NEW
118
                strings.Repeat("-", 14),
×
NEW
119
                strings.Repeat("-", 14),
×
NEW
120
                strings.Repeat("-", 14))
×
NEW
121
        p.Printf(" %-18s | %12s | %12s | %12s |\n", "estimated",
×
NEW
122
                formatBytes(estimatedRxDaily),
×
NEW
123
                formatBytes(estimatedTxDaily),
×
NEW
124
                formatBytes(estimatedTotalDaily))
×
NEW
125

×
NEW
126
        if len(perSrcStats) > 0 {
×
NEW
127
                p.Printf("\n")
×
NEW
128
                p.Printf(" Per-source statistics:\n")
×
NEW
129
                p.Printf(" %-18s | %12s | %12s | %12s\n", "src_addr", "from_wg", "to_wg", "total")
×
NEW
130
                p.Printf(" %s+%s+%s+%s\n",
×
NEW
131
                        strings.Repeat("-", 18),
×
NEW
132
                        strings.Repeat("-", 14),
×
NEW
133
                        strings.Repeat("-", 14),
×
NEW
134
                        strings.Repeat("-", 14))
×
NEW
135

×
NEW
136
                for srcAddr, stats := range perSrcStats {
×
NEW
137
                        total := stats.rxBytes + stats.txBytes
×
NEW
138
                        p.Printf(" %-18s | %12s | %12s | %12s\n",
×
NEW
139
                                srcAddr,
×
NEW
140
                                formatBytes(stats.rxBytes),
×
NEW
141
                                formatBytes(stats.txBytes),
×
NEW
142
                                formatBytes(total))
×
NEW
143
                }
×
144
        }
145

NEW
146
        p.Printf("\n")
×
147
}
148

NEW
149
func formatDuration(d time.Duration) string {
×
NEW
150
        d = d.Round(time.Second)
×
NEW
151
        h := d / time.Hour
×
NEW
152
        d -= h * time.Hour
×
NEW
153
        m := d / time.Minute
×
NEW
154
        d -= m * time.Minute
×
NEW
155
        s := d / time.Second
×
NEW
156

×
NEW
157
        if h > 0 {
×
NEW
158
                return fmt.Sprintf("%dh%dm%ds", h, m, s)
×
NEW
159
        }
×
NEW
160
        if m > 0 {
×
NEW
161
                return fmt.Sprintf("%dm%ds", m, s)
×
NEW
162
        }
×
NEW
163
        return fmt.Sprintf("%ds", s)
×
164
}
165

NEW
166
func formatBytes(bytes uint64) string {
×
NEW
167
        const unit = 1024
×
NEW
168
        if bytes < unit {
×
NEW
169
                return fmt.Sprintf("%d B", bytes)
×
NEW
170
        }
×
NEW
171
        div, exp := uint64(unit), 0
×
NEW
172
        for n := bytes / unit; n >= unit; n /= unit {
×
NEW
173
                div *= unit
×
NEW
174
                exp++
×
NEW
175
        }
×
NEW
176
        return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
×
177
}
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

© 2026 Coveralls, Inc