diff --git a/cmd/ursrv/serve/metrics.go b/cmd/ursrv/serve/metrics.go new file mode 100644 index 000000000..7c0075111 --- /dev/null +++ b/cmd/ursrv/serve/metrics.go @@ -0,0 +1,26 @@ +// Copyright (C) 2023 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +package serve + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +var metricReportsTotal = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: "syncthing", + Subsystem: "ursrv", + Name: "reports_total", +}, []string{"version"}) + +func init() { + metricReportsTotal.WithLabelValues("fail") + metricReportsTotal.WithLabelValues("duplicate") + metricReportsTotal.WithLabelValues("v1") + metricReportsTotal.WithLabelValues("v2") + metricReportsTotal.WithLabelValues("v3") +} diff --git a/cmd/ursrv/serve/serve.go b/cmd/ursrv/serve/serve.go index 846dcca2c..a6fd21acb 100644 --- a/cmd/ursrv/serve/serve.go +++ b/cmd/ursrv/serve/serve.go @@ -11,6 +11,7 @@ import ( "database/sql" "embed" "encoding/json" + "fmt" "html/template" "io" "log" @@ -26,6 +27,7 @@ import ( _ "github.com/lib/pq" // PostgreSQL driver "github.com/oschwald/geoip2-golang" + "github.com/prometheus/client_golang/prometheus/promhttp" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -196,6 +198,7 @@ func (cli *CLI) Run() error { http.HandleFunc("/performance.json", srv.performanceHandler) http.HandleFunc("/blockstats.json", srv.blockStatsHandler) http.HandleFunc("/locations.json", srv.locationsHandler) + http.Handle("/metrics", promhttp.Handler()) http.Handle("/static/", http.FileServer(http.FS(statics))) go srv.cacheRefresher() @@ -289,6 +292,12 @@ func (s *server) locationsHandler(w http.ResponseWriter, _ *http.Request) { } func (s *server) newDataHandler(w http.ResponseWriter, r *http.Request) { + version := "fail" + defer func() { + // Version is "fail", "duplicate", "v2", "v3", ... + metricReportsTotal.WithLabelValues(version).Inc() + }() + defer r.Body.Close() addr := r.Header.Get("X-Forwarded-For") @@ -334,6 +343,7 @@ func (s *server) newDataHandler(w http.ResponseWriter, r *http.Request) { if err.Error() == `pq: duplicate key value violates unique constraint "uniqueidjsonindex"` { // We already have a report today for the same unique ID; drop // this one without complaining. + version = "duplicate" return } log.Println("insert:", err) @@ -343,6 +353,8 @@ func (s *server) newDataHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, "Database Error", http.StatusInternalServerError) return } + + version = fmt.Sprintf("v%d", rep.URVersion) } func (s *server) summaryHandler(w http.ResponseWriter, r *http.Request) {