Skip to content

Commit f7e1de5

Browse files
j-mcfaddenJosh
authored andcommitted
adds some simple counter and gauge metrics
Signed-off-by: Josh <[email protected]>
1 parent b54cbbb commit f7e1de5

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

go.mod

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.24.4
55
toolchain go1.24.5
66

77
require (
8-
github.com/google/go-cmp v0.6.0
8+
github.com/google/go-cmp v0.7.0
99
golang.org/x/net v0.40.0
1010
modernc.org/sqlite v1.19.4
1111
tailscale.com v1.86.2
@@ -29,6 +29,8 @@ require (
2929
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 // indirect
3030
github.com/aws/aws-sdk-go-v2/service/sts v1.33.13 // indirect
3131
github.com/aws/smithy-go v1.22.2 // indirect
32+
github.com/beorn7/perks v1.0.1 // indirect
33+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
3234
github.com/coder/websocket v1.8.12 // indirect
3335
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect
3436
github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect
@@ -47,15 +49,20 @@ require (
4749
github.com/jmespath/go-jmespath v0.4.0 // indirect
4850
github.com/jsimonetti/rtnetlink v1.4.0 // indirect
4951
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
50-
github.com/klauspost/compress v1.17.11 // indirect
52+
github.com/klauspost/compress v1.18.0 // indirect
5153
github.com/mattn/go-isatty v0.0.20 // indirect
5254
github.com/mdlayher/genetlink v1.3.2 // indirect
5355
github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 // indirect
5456
github.com/mdlayher/sdnotify v1.0.0 // indirect
5557
github.com/mdlayher/socket v0.5.0 // indirect
5658
github.com/miekg/dns v1.1.58 // indirect
5759
github.com/mitchellh/go-ps v1.0.0 // indirect
60+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
5861
github.com/prometheus-community/pro-bing v0.4.0 // indirect
62+
github.com/prometheus/client_golang v1.23.0 // indirect
63+
github.com/prometheus/client_model v0.6.2 // indirect
64+
github.com/prometheus/common v0.65.0 // indirect
65+
github.com/prometheus/procfs v0.16.1 // indirect
5966
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
6067
github.com/safchain/ethtool v0.3.0 // indirect
6168
github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e // indirect
@@ -81,6 +88,7 @@ require (
8188
golang.org/x/tools v0.33.0 // indirect
8289
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
8390
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
91+
google.golang.org/protobuf v1.36.6 // indirect
8492
gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 // indirect
8593
lukechampine.com/uint128 v1.2.0 // indirect
8694
modernc.org/cc/v3 v3.40.0 // indirect

go.sum

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.33.13 h1:3LXNnmtH3TURctC23hnC0p/39Q5
4040
github.com/aws/aws-sdk-go-v2/service/sts v1.33.13/go.mod h1:7Yn+p66q/jt38qMoVfNvjbm3D89mGBnkwDcijgtih8w=
4141
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
4242
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
43+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
44+
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
45+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
46+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
4347
github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk=
4448
github.com/cilium/ebpf v0.15.0/go.mod h1:DHp1WyrLeiBh19Cf/tfiSMhqheEiK8fXFZ4No0P1Hso=
4549
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
@@ -83,6 +87,8 @@ github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
8387
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
8488
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
8589
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
90+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
91+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
8692
github.com/google/go-tpm v0.9.4 h1:awZRf9FwOeTunQmHoDYSHJps3ie6f1UlhS1fOdPEt1I=
8793
github.com/google/go-tpm v0.9.4/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
8894
github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 h1:wG8RYIyctLhdFk6Vl1yPGtSRtwGpVkWyZww1OCil2MI=
@@ -107,6 +113,8 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
107113
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
108114
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
109115
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
116+
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
117+
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
110118
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ=
111119
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk=
112120
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
@@ -144,10 +152,18 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
144152
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
145153
github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4=
146154
github.com/prometheus-community/pro-bing v0.4.0/go.mod h1:b7wRYZtCcPmt4Sz319BykUU241rWLe1VFXyiyWK/dH4=
155+
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
156+
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
147157
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
148158
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
159+
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
160+
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
149161
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
150162
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
163+
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
164+
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
165+
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
166+
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
151167
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
152168
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
153169
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
@@ -228,6 +244,8 @@ golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus
228244
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
229245
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
230246
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
247+
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
248+
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
231249
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
232250
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
233251
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=

golink.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import (
3030
texttemplate "text/template"
3131
"time"
3232

33+
"github.com/prometheus/client_golang/prometheus"
34+
"github.com/prometheus/client_golang/prometheus/promhttp"
3335
"golang.org/x/net/xsrftoken"
3436
"tailscale.com/client/tailscale"
3537
"tailscale.com/hostinfo"
@@ -76,6 +78,35 @@ var stats struct {
7678
dirty ClickStats
7779
}
7880

81+
var (
82+
clickCounter = prometheus.NewCounterVec(
83+
prometheus.CounterOpts{
84+
Name: "golink_clicks_total",
85+
Help: "Total number of clicks for a recognized GoLink",
86+
},
87+
[]string{"path"},
88+
)
89+
)
90+
91+
var (
92+
clickNotFound = prometheus.NewCounterVec(
93+
prometheus.CounterOpts{
94+
Name: "golink_not_found_total",
95+
Help: "Total number of clicks for a GoLink doesn't exist",
96+
},
97+
[]string{"path"},
98+
)
99+
)
100+
101+
var (
102+
totalLinkCount = prometheus.NewGauge(
103+
prometheus.GaugeOpts{
104+
Name: "golinks_total",
105+
Help: "Total number of GoLinks being served",
106+
},
107+
)
108+
)
109+
79110
// LastSnapshot is the data snapshot (as returned by the /.export handler)
80111
// that will be loaded on startup.
81112
var LastSnapshot []byte
@@ -374,6 +405,7 @@ func flushStatsLoop() {
374405

375406
// deleteLinkStats removes the link stats from memory.
376407
func deleteLinkStats(link *Link) {
408+
totalLinkCount.Dec()
377409
stats.mu.Lock()
378410
delete(stats.clicks, link.Short)
379411
delete(stats.dirty, link.Short)
@@ -416,6 +448,13 @@ func HSTS(h http.Handler) http.Handler {
416448
})
417449
}
418450

451+
// Initalize Prometheus Metrics
452+
func initMetrics() {
453+
prometheus.MustRegister(clickCounter)
454+
prometheus.MustRegister(totalLinkCount)
455+
prometheus.MustRegister(clickNotFound)
456+
}
457+
419458
// serverHandler returns the main http.Handler for serving all requests.
420459
func serveHandler() http.Handler {
421460
mux := http.NewServeMux()
@@ -426,8 +465,11 @@ func serveHandler() http.Handler {
426465
mux.HandleFunc("/.opensearch", serveOpenSearch)
427466
mux.HandleFunc("/.all", serveAll)
428467
mux.HandleFunc("/.delete/", serveDelete)
468+
mux.Handle("/.metrics", promhttp.Handler())
429469
mux.Handle("/.static/", http.StripPrefix("/.", http.FileServer(http.FS(embeddedFS))))
430470

471+
initMetrics()
472+
431473
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
432474
// all internal URLs begin with a leading "."; any other URL is treated as a go link.
433475
// Serve go links directly without passing through the ServeMux,
@@ -547,16 +589,20 @@ func serveGo(w http.ResponseWriter, r *http.Request) {
547589
}
548590

549591
if errors.Is(err, fs.ErrNotExist) {
592+
clickNotFound.WithLabelValues(short).Inc()
550593
w.WriteHeader(http.StatusNotFound)
551594
serveHome(w, r, short)
552595
return
553596
}
554597
if err != nil {
598+
clickNotFound.WithLabelValues(short).Inc()
555599
log.Printf("serving %q: %v", short, err)
556600
http.Error(w, err.Error(), http.StatusInternalServerError)
557601
return
558602
}
559603

604+
clickCounter.WithLabelValues(link.Short).Inc()
605+
560606
stats.mu.Lock()
561607
if stats.clicks == nil {
562608
stats.clicks = make(ClickStats)
@@ -940,6 +986,7 @@ func serveSave(w http.ResponseWriter, r *http.Request) {
940986
w.Header().Set("Content-Type", "application/json")
941987
json.NewEncoder(w).Encode(link)
942988
}
989+
totalLinkCount.Inc()
943990
}
944991

945992
// canEditLink returns whether the specified user has permission to edit link.

0 commit comments

Comments
 (0)