diff --git a/cmd/gotosocial/action/server/server.go b/cmd/gotosocial/action/server/server.go
index 4060eeb7f..dcd30a9b5 100644
--- a/cmd/gotosocial/action/server/server.go
+++ b/cmd/gotosocial/action/server/server.go
@@ -50,9 +50,9 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/media"
"github.com/superseriousbusiness/gotosocial/internal/media/ffmpeg"
"github.com/superseriousbusiness/gotosocial/internal/messages"
- "github.com/superseriousbusiness/gotosocial/internal/metrics"
"github.com/superseriousbusiness/gotosocial/internal/middleware"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
+ "github.com/superseriousbusiness/gotosocial/internal/observability"
"github.com/superseriousbusiness/gotosocial/internal/oidc"
"github.com/superseriousbusiness/gotosocial/internal/processing"
tlprocessor "github.com/superseriousbusiness/gotosocial/internal/processing/timeline"
@@ -61,7 +61,6 @@ import (
gtsstorage "github.com/superseriousbusiness/gotosocial/internal/storage"
"github.com/superseriousbusiness/gotosocial/internal/subscriptions"
"github.com/superseriousbusiness/gotosocial/internal/timeline"
- "github.com/superseriousbusiness/gotosocial/internal/tracing"
"github.com/superseriousbusiness/gotosocial/internal/transport"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
"github.com/superseriousbusiness/gotosocial/internal/web"
@@ -196,7 +195,7 @@ var Start action.GTSAction = func(ctx context.Context) error {
}
// Initialize tracing (noop if not enabled).
- if err := tracing.Initialize(); err != nil {
+ if err := observability.InitializeTracing(); err != nil {
return fmt.Errorf("error initializing tracing: %w", err)
}
@@ -393,7 +392,7 @@ var Start action.GTSAction = func(ctx context.Context) error {
}
// Initialize metrics.
- if err := metrics.Initialize(state.DB); err != nil {
+ if err := observability.InitializeMetrics(state.DB); err != nil {
return fmt.Errorf("error initializing metrics: %w", err)
}
@@ -426,12 +425,12 @@ var Start action.GTSAction = func(ctx context.Context) error {
// Add tracing middleware if enabled.
if config.GetTracingEnabled() {
- middlewares = append(middlewares, tracing.InstrumentGin())
+ middlewares = append(middlewares, observability.TracingMiddleware())
}
// Add metrics middleware if enabled.
if config.GetMetricsEnabled() {
- middlewares = append(middlewares, metrics.InstrumentGin())
+ middlewares = append(middlewares, observability.MetricsMiddleware())
}
middlewares = append(middlewares, []gin.HandlerFunc{
diff --git a/cmd/gotosocial/action/testrig/testrig.go b/cmd/gotosocial/action/testrig/testrig.go
index 7de3f78a1..b19325234 100644
--- a/cmd/gotosocial/action/testrig/testrig.go
+++ b/cmd/gotosocial/action/testrig/testrig.go
@@ -38,8 +38,8 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/language"
"github.com/superseriousbusiness/gotosocial/internal/log"
- "github.com/superseriousbusiness/gotosocial/internal/metrics"
"github.com/superseriousbusiness/gotosocial/internal/middleware"
+ "github.com/superseriousbusiness/gotosocial/internal/observability"
"github.com/superseriousbusiness/gotosocial/internal/oidc"
tlprocessor "github.com/superseriousbusiness/gotosocial/internal/processing/timeline"
"github.com/superseriousbusiness/gotosocial/internal/router"
@@ -47,7 +47,6 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/storage"
"github.com/superseriousbusiness/gotosocial/internal/subscriptions"
"github.com/superseriousbusiness/gotosocial/internal/timeline"
- "github.com/superseriousbusiness/gotosocial/internal/tracing"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
"github.com/superseriousbusiness/gotosocial/internal/web"
"github.com/superseriousbusiness/gotosocial/testrig"
@@ -127,7 +126,7 @@ var Start action.GTSAction = func(ctx context.Context) error {
}
config.SetInstanceLanguages(parsedLangs)
- if err := tracing.Initialize(); err != nil {
+ if err := observability.InitializeTracing(); err != nil {
return fmt.Errorf("error initializing tracing: %w", err)
}
@@ -195,7 +194,7 @@ var Start action.GTSAction = func(ctx context.Context) error {
defer testrig.StopWorkers(state)
// Initialize metrics.
- if err := metrics.Initialize(state.DB); err != nil {
+ if err := observability.InitializeMetrics(state.DB); err != nil {
return fmt.Errorf("error initializing metrics: %w", err)
}
@@ -213,11 +212,11 @@ var Start action.GTSAction = func(ctx context.Context) error {
middleware.AddRequestID(config.GetRequestIDHeader()), // requestID middleware must run before tracing
}
if config.GetTracingEnabled() {
- middlewares = append(middlewares, tracing.InstrumentGin())
+ middlewares = append(middlewares, observability.TracingMiddleware())
}
if config.GetMetricsEnabled() {
- middlewares = append(middlewares, metrics.InstrumentGin())
+ middlewares = append(middlewares, observability.MetricsMiddleware())
}
middlewares = append(middlewares, []gin.HandlerFunc{
diff --git a/internal/api/metrics/metrics.go b/internal/api/metrics/metrics.go
index bbca861ef..5161a3b71 100644
--- a/internal/api/metrics/metrics.go
+++ b/internal/api/metrics/metrics.go
@@ -15,7 +15,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-//go:build !nometrics
+//go:build !nootel
package metrics
diff --git a/internal/api/metrics/no_metrics.go b/internal/api/metrics/no_metrics.go
index ae7fc7ce7..5aa7b722d 100644
--- a/internal/api/metrics/no_metrics.go
+++ b/internal/api/metrics/no_metrics.go
@@ -15,7 +15,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-//go:build nometrics
+//go:build nootel
package metrics
diff --git a/internal/db/bundb/bundb.go b/internal/db/bundb/bundb.go
index c9dd7866d..18fe5384c 100644
--- a/internal/db/bundb/bundb.go
+++ b/internal/db/bundb/bundb.go
@@ -41,9 +41,8 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/db/bundb/migrations"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/log"
- "github.com/superseriousbusiness/gotosocial/internal/metrics"
+ "github.com/superseriousbusiness/gotosocial/internal/observability"
"github.com/superseriousbusiness/gotosocial/internal/state"
- "github.com/superseriousbusiness/gotosocial/internal/tracing"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect"
"github.com/uptrace/bun/dialect/pgdialect"
@@ -324,11 +323,10 @@ func bunDB(sqldb *sql.DB, dialect func() schema.Dialect) *bun.DB {
// Add our SQL connection hooks.
db.AddQueryHook(queryHook{})
- if config.GetTracingEnabled() {
- db.AddQueryHook(tracing.InstrumentBun())
- }
- if config.GetMetricsEnabled() {
- db.AddQueryHook(metrics.InstrumentBun())
+ metricsEnabled := config.GetMetricsEnabled()
+ tracingEnabled := config.GetTracingEnabled()
+ if metricsEnabled || tracingEnabled {
+ db.AddQueryHook(observability.InstrumentBun(tracingEnabled, metricsEnabled))
}
// table registration is needed for many-to-many, see:
diff --git a/internal/tracing/no_trace.go b/internal/observability/bun.go
similarity index 60%
rename from internal/tracing/no_trace.go
rename to internal/observability/bun.go
index 12f46ce53..4baf786e4 100644
--- a/internal/tracing/no_trace.go
+++ b/internal/observability/bun.go
@@ -15,29 +15,28 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-//go:build notracing
+//go:build !nootel
-package tracing
+package observability
import (
- "errors"
-
- "github.com/gin-gonic/gin"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/uptrace/bun"
+ "github.com/uptrace/bun/extra/bunotel"
+ metricnoop "go.opentelemetry.io/otel/metric/noop"
+ tracenoop "go.opentelemetry.io/otel/trace/noop"
)
-func Initialize() error {
- if config.GetTracingEnabled() {
- return errors.New("tracing was disabled at build time")
+func InstrumentBun(traces bool, metrics bool) bun.QueryHook {
+ opts := []bunotel.Option{
+ bunotel.WithFormattedQueries(true),
}
- return nil
-}
-
-func InstrumentGin() gin.HandlerFunc {
- return func(c *gin.Context) {}
-}
-
-func InstrumentBun() bun.QueryHook {
- return nil
+ if !traces {
+ opts = append(opts, bunotel.WithTracerProvider(tracenoop.NewTracerProvider()))
+ }
+ if !metrics {
+ opts = append(opts, bunotel.WithMeterProvider(metricnoop.NewMeterProvider()))
+ }
+ return bunotel.NewQueryHook(
+ opts...,
+ )
}
diff --git a/internal/metrics/metrics.go b/internal/observability/metrics.go
similarity index 91%
rename from internal/metrics/metrics.go
rename to internal/observability/metrics.go
index e22a67dad..f2ff2ac0d 100644
--- a/internal/metrics/metrics.go
+++ b/internal/observability/metrics.go
@@ -15,24 +15,24 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-//go:build !nometrics
+//go:build !nootel
-package metrics
+package observability
import (
"context"
"errors"
- "github.com/gin-gonic/gin"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
+
+ "github.com/gin-gonic/gin"
"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/metric/exemplar"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
)
@@ -41,7 +41,7 @@ const (
serviceName = "GoToSocial"
)
-func Initialize(db db.DB) error {
+func InitializeMetrics(db db.DB) error {
if !config.GetMetricsEnabled() {
return nil
}
@@ -66,6 +66,7 @@ func Initialize(db db.DB) error {
}
meterProvider := sdk.NewMeterProvider(
+ sdk.WithExemplarFilter(exemplar.AlwaysOffFilter),
sdk.WithResource(r),
sdk.WithReader(prometheusExporter),
)
@@ -127,12 +128,6 @@ func Initialize(db db.DB) error {
return nil
}
-func InstrumentGin() gin.HandlerFunc {
+func MetricsMiddleware() gin.HandlerFunc {
return otelginmetrics.Middleware(serviceName)
}
-
-func InstrumentBun() bun.QueryHook {
- return bunotel.NewQueryHook(
- bunotel.WithMeterProvider(otel.GetMeterProvider()),
- )
-}
diff --git a/internal/metrics/no_metrics.go b/internal/observability/no_otel.go
similarity index 73%
rename from internal/metrics/no_metrics.go
rename to internal/observability/no_otel.go
index 25e156307..122d7a897 100644
--- a/internal/metrics/no_metrics.go
+++ b/internal/observability/no_otel.go
@@ -15,30 +15,32 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-//go:build nometrics
+//go:build nootel
-package metrics
+package observability
import (
- "errors"
+ "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/gin-gonic/gin"
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/uptrace/bun"
)
-func Initialize(db db.DB) error {
- if config.GetMetricsEnabled() {
- return errors.New("metrics was disabled at build time")
- }
+func InitializeMetrics(db db.DB) error {
+ return nil
+}
+func InitializeTracing() error {
return nil
}
-func InstrumentGin() gin.HandlerFunc {
- return func(c *gin.Context) {}
-}
-
-func InstrumentBun() bun.QueryHook {
+func MetricsMiddleware() gin.HandlerFunc {
+ return nil
+}
+
+func TracingMiddleware() gin.HandlerFunc {
+ return nil
+}
+
+func InstrumentBun(traces bool, metrics bool) bun.QueryHook {
return nil
}
diff --git a/internal/tracing/tracing.go b/internal/observability/tracing.go
similarity index 95%
rename from internal/tracing/tracing.go
rename to internal/observability/tracing.go
index dd1e19be9..7827004a3 100644
--- a/internal/tracing/tracing.go
+++ b/internal/observability/tracing.go
@@ -15,9 +15,9 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-//go:build !notracing
+//go:build !nootel
-package tracing
+package observability
import (
"context"
@@ -25,8 +25,6 @@ import (
"codeberg.org/gruf/go-kv"
"github.com/gin-gonic/gin"
- "github.com/uptrace/bun"
- "github.com/uptrace/bun/extra/bunotel"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
@@ -45,10 +43,10 @@ import (
const (
tracerKey = "gotosocial-server-tracer"
- tracerName = "github.com/superseriousbusiness/gotosocial/internal/tracing"
+ tracerName = "github.com/superseriousbusiness/gotosocial/internal/observability"
)
-func Initialize() error {
+func InitializeTracing() error {
if !config.GetTracingEnabled() {
return nil
}
@@ -119,7 +117,7 @@ func Initialize() error {
// InstrumentGin is a middleware injecting tracing information based on the
// otelgin implementation found at
// https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/instrumentation/github.com/gin-gonic/gin/otelgin/gintrace.go
-func InstrumentGin() gin.HandlerFunc {
+func TracingMiddleware() gin.HandlerFunc {
provider := otel.GetTracerProvider()
tracer := provider.Tracer(
tracerName,
@@ -182,9 +180,3 @@ func InjectRequestID() gin.HandlerFunc {
}
}
}
-
-func InstrumentBun() bun.QueryHook {
- return bunotel.NewQueryHook(
- bunotel.WithFormattedQueries(true),
- )
-}
diff --git a/scripts/build.sh b/scripts/build.sh
index 3e60cd306..b22861240 100755
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -17,8 +17,7 @@ GO_GCFLAGS=${GO_GCFLAGS-}
# Available Go build tags, with explanation, followed by benefits of enabling it:
# - kvformat: enables prettier output of log fields (slightly better performance)
# - timetzdata: embed timezone database inside binary (allow setting local time inside Docker containers, at cost of 450KB)
-# - notracing: disables compiling-in otel tracing support (reduced binary size, better performance)
-# - nometrics: disables compiling-in otel metrics support (reduced binary size, better performance)
+# - nootel: disables compiling-in otel support (reduced binary size)
# - noerrcaller: disables caller function prefix in errors (slightly better performance, at cost of err readability)
# - debug: enables /debug/pprof endpoint (adds debug, at performance cost)
# - debugenv: enables /debug/pprof endpoint if DEBUG=1 env during runtime (adds debug, at performance cost)