From 142b7ec54fc415e166854fccc184c4cbc2fc12b3 Mon Sep 17 00:00:00 2001 From: Tsuribori <30933799+Tsuribori@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:58:55 +0200 Subject: [PATCH] [feature] Add metrics for instance user count, statuses count and federating instances count (#2592) Co-authored-by: Tsuribori --- cmd/gotosocial/action/server/server.go | 10 ++-- cmd/gotosocial/action/testrig/testrig.go | 9 ++-- internal/metrics/metrics.go | 63 +++++++++++++++++++++++- internal/metrics/no_metrics.go | 3 +- 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/cmd/gotosocial/action/server/server.go b/cmd/gotosocial/action/server/server.go index de9b3b3f1..d72df1d41 100644 --- a/cmd/gotosocial/action/server/server.go +++ b/cmd/gotosocial/action/server/server.go @@ -82,11 +82,6 @@ var Start action.GTSAction = func(ctx context.Context) error { return fmt.Errorf("error initializing tracing: %w", err) } - // Initialize Metrics - if err := metrics.Initialize(); err != nil { - return fmt.Errorf("error initializing metrics: %w", err) - } - // Open connection to the database dbService, err := bundb.NewBunDBService(ctx, &state) if err != nil { @@ -218,6 +213,11 @@ var Start action.GTSAction = func(ctx context.Context) error { return fmt.Errorf("error scheduling poll expiries: %w", err) } + // Initialize metrics. + if err := metrics.Initialize(state.DB); err != nil { + return fmt.Errorf("error initializing metrics: %w", err) + } + /* HTTP router initialization */ diff --git a/cmd/gotosocial/action/testrig/testrig.go b/cmd/gotosocial/action/testrig/testrig.go index bf2c74f2f..dc5f1c7dc 100644 --- a/cmd/gotosocial/action/testrig/testrig.go +++ b/cmd/gotosocial/action/testrig/testrig.go @@ -69,10 +69,6 @@ var Start action.GTSAction = func(ctx context.Context) error { return fmt.Errorf("error initializing tracing: %w", err) } - if err := metrics.Initialize(); err != nil { - return fmt.Errorf("error initializing metrics: %w", err) - } - // Initialize caches and database state.DB = testrig.NewTestDB(&state) @@ -143,6 +139,11 @@ var Start action.GTSAction = func(ctx context.Context) error { processor := testrig.NewTestProcessor(&state, federator, emailSender, mediaManager) + // Initialize metrics. + if err := metrics.Initialize(state.DB); err != nil { + return fmt.Errorf("error initializing metrics: %w", err) + } + /* HTTP router initialization */ diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 97a763453..269974623 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -20,15 +20,18 @@ package metrics import ( + "context" "errors" "github.com/gin-gonic/gin" "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/technologize/otel-go-contrib/otelginmetrics" "github.com/uptrace/bun" "github.com/uptrace/bun/extra/bunotel" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/prometheus" + "go.opentelemetry.io/otel/metric" sdk "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/resource" semconv "go.opentelemetry.io/otel/semconv/v1.20.0" @@ -38,7 +41,8 @@ const ( serviceName = "GoToSocial" ) -func Initialize() error { +func Initialize(db db.DB) error { + if !config.GetMetricsEnabled() { return nil } @@ -54,6 +58,7 @@ func Initialize() error { resource.NewWithAttributes( semconv.SchemaURL, semconv.ServiceName(serviceName), + semconv.ServiceVersion(config.GetSoftwareVersion()), ), ) @@ -66,8 +71,64 @@ func Initialize() error { sdk.WithResource(r), sdk.WithReader(prometheusExporter), ) + otel.SetMeterProvider(meterProvider) + meter := meterProvider.Meter(serviceName) + + thisInstance := config.GetHost() + + _, err = meter.Int64ObservableGauge( + "gotosocial.instance.total_users", + metric.WithDescription("Total number of users on this instance"), + metric.WithInt64Callback(func(c context.Context, o metric.Int64Observer) error { + userCount, err := db.CountInstanceUsers(c, thisInstance) + if err != nil { + return err + } + o.Observe(int64(userCount)) + return nil + }), + ) + + if err != nil { + return err + } + + _, err = meter.Int64ObservableGauge( + "gotosocial.instance.total_statuses", + metric.WithDescription("Total number of statuses on this instance"), + metric.WithInt64Callback(func(c context.Context, o metric.Int64Observer) error { + statusCount, err := db.CountInstanceStatuses(c, thisInstance) + if err != nil { + return err + } + o.Observe(int64(statusCount)) + return nil + }), + ) + + if err != nil { + return err + } + + _, err = meter.Int64ObservableGauge( + "gotosocial.instance.total_federating_instances", + metric.WithDescription("Total number of other instances this instance is federating with"), + metric.WithInt64Callback(func(c context.Context, o metric.Int64Observer) error { + federatingCount, err := db.CountInstanceDomains(c, thisInstance) + if err != nil { + return err + } + o.Observe(int64(federatingCount)) + return nil + }), + ) + + if err != nil { + return err + } + return nil } diff --git a/internal/metrics/no_metrics.go b/internal/metrics/no_metrics.go index 590a3fbf8..25e156307 100644 --- a/internal/metrics/no_metrics.go +++ b/internal/metrics/no_metrics.go @@ -24,10 +24,11 @@ import ( "github.com/gin-gonic/gin" "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/uptrace/bun" ) -func Initialize() error { +func Initialize(db db.DB) error { if config.GetMetricsEnabled() { return errors.New("metrics was disabled at build time") }