Skip to content

Commit 279269b

Browse files
authored
feat: refactor tracing to use OTel (frain-dev#1865)
* feat: Refactor tracing to use OTel * feat: added otel backend implementaion * fix: bump go version to l.20 for otel dependencies * feat: removed new relic and replace cli flags with new tracing flags * feat: added shutdown func to tracing backends * feat: fixed linter issues * feat: added tls config to otel exported * doc: updated api doc * fix: fixed linter errors * fix: fixed failing tests * fix: removed elastic support * fix: fixed otel insecure config * fix: tested dd implementation * fix: fixed failing tests * fix: removed dd debug log * fix: removed dd implementation * fix: add back traceId and spanId to request logs
1 parent d0d57a3 commit 279269b

File tree

32 files changed

+714
-653
lines changed

32 files changed

+714
-653
lines changed

.github/workflows/go.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
if: ${{ !(contains(github.head_ref, 'ui/')) || !(contains(github.head_ref, 'cms/')) }}
1111
strategy:
1212
matrix:
13-
go-version: [1.18.x]
13+
go-version: [1.20.x]
1414
os: [ubuntu-latest, macos-latest]
1515
postgres-version: ["15"]
1616
redis-version: ["6.2.6"]

api/api.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ const (
4949
DELETE = "DELETE"
5050
)
5151

52+
const (
53+
serverName = "apiserver"
54+
)
55+
5256
type ApplicationHandler struct {
5357
Router http.Handler
5458
A *types.APIOptions
@@ -72,7 +76,7 @@ func (a *ApplicationHandler) BuildRoutes() *chi.Mux {
7276
router.Use(chiMiddleware.RequestID)
7377
router.Use(chiMiddleware.Recoverer)
7478
router.Use(middleware.WriteRequestIDHeader)
75-
router.Use(middleware.InstrumentRequests())
79+
router.Use(middleware.InstrumentRequests(serverName, router))
7680
router.Use(middleware.LogHttpRequest(a.A))
7781
router.Use(chiMiddleware.Maybe(middleware.SetupCORS, shouldApplyCORS))
7882

api/server_suite_test.go

-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import (
3434
"github.com/frain-dev/convoy/pkg/log"
3535
"github.com/frain-dev/convoy/queue"
3636
redisqueue "github.com/frain-dev/convoy/queue/redis"
37-
"github.com/frain-dev/convoy/tracer"
3837
)
3938

4039
// TEST HELPERS.
@@ -102,7 +101,6 @@ func getQueueOptions() (queue.QueueOptions, error) {
102101
}
103102

104103
func buildServer() *ApplicationHandler {
105-
var t tracer.Tracer = nil
106104
var logger *log.Logger
107105
var qOpts queue.QueueOptions
108106

@@ -120,7 +118,6 @@ func buildServer() *ApplicationHandler {
120118
DB: db,
121119
Queue: newQueue,
122120
Logger: logger,
123-
Tracer: t,
124121
Cache: noopCache,
125122
})
126123

api/types/types.go

-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"github.com/frain-dev/convoy/internal/pkg/fflag"
88
"github.com/frain-dev/convoy/pkg/log"
99
"github.com/frain-dev/convoy/queue"
10-
"github.com/frain-dev/convoy/tracer"
1110
)
1211

1312
type ContextKey string
@@ -17,7 +16,6 @@ type APIOptions struct {
1716
DB database.Database
1817
Queue queue.Queuer
1918
Logger log.StdLogger
20-
Tracer tracer.Tracer
2119
Cache cache.Cache
2220
Authz *authz.Authz
2321
}

cmd/hooks/hooks.go

+66-21
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@ import (
2020
"github.com/frain-dev/convoy/database"
2121
"github.com/frain-dev/convoy/database/postgres"
2222
"github.com/frain-dev/convoy/datastore"
23-
"github.com/frain-dev/convoy/internal/pkg/apm"
2423
"github.com/frain-dev/convoy/internal/pkg/cli"
2524
"github.com/frain-dev/convoy/internal/pkg/rdb"
25+
"github.com/frain-dev/convoy/internal/pkg/tracer"
2626
"github.com/frain-dev/convoy/pkg/log"
2727
redisQueue "github.com/frain-dev/convoy/queue/redis"
28-
"github.com/frain-dev/convoy/tracer"
29-
"github.com/newrelic/go-agent/v3/newrelic"
3028
"github.com/spf13/cobra"
3129
)
3230

@@ -57,20 +55,11 @@ func PreRun(app *cli.App, db *postgres.Postgres) func(cmd *cobra.Command, args [
5755
return err
5856
}
5957

60-
nwCfg := cfg.Tracer.NewRelic
61-
nRApp, err := newrelic.NewApplication(
62-
newrelic.ConfigAppName(nwCfg.AppName),
63-
newrelic.ConfigLicense(nwCfg.LicenseKey),
64-
newrelic.ConfigDistributedTracerEnabled(nwCfg.DistributedTracerEnabled),
65-
newrelic.ConfigEnabled(nwCfg.ConfigEnabled),
66-
)
58+
app.TracerShutdown, err = tracer.Init(cfg.Tracer, cmd.Name())
6759
if err != nil {
6860
return err
6961
}
7062

71-
apm.SetApplication(nRApp)
72-
73-
var tr tracer.Tracer
7463
var ca cache.Cache
7564
var q queue.Queuer
7665

@@ -97,13 +86,6 @@ func PreRun(app *cli.App, db *postgres.Postgres) func(cmd *cobra.Command, args [
9786

9887
lo := log.NewLogger(os.Stdout)
9988

100-
if cfg.Tracer.Type == config.NewRelicTracerProvider {
101-
tr, err = tracer.NewTracer(cfg, lo.WithLogger())
102-
if err != nil {
103-
return err
104-
}
105-
}
106-
10789
ca, err = cache.NewCache(cfg.Redis)
10890
if err != nil {
10991
return err
@@ -142,7 +124,6 @@ func PreRun(app *cli.App, db *postgres.Postgres) func(cmd *cobra.Command, args [
142124
app.DB = postgresDB
143125
app.Queue = q
144126
app.Logger = lo
145-
app.Tracer = tr
146127
app.Cache = ca
147128

148129
if ok := shouldBootstrap(cmd); ok {
@@ -167,6 +148,11 @@ func PostRun(app *cli.App, db *postgres.Postgres) func(cmd *cobra.Command, args
167148
if err == nil {
168149
os.Exit(0)
169150
}
151+
152+
err = app.TracerShutdown(context.Background())
153+
if err == nil {
154+
os.Exit(0)
155+
}
170156
return err
171157
}
172158
}
@@ -330,6 +316,65 @@ func buildCliConfiguration(cmd *cobra.Command) (*config.Configuration, error) {
330316
c.FeatureFlag = config.ExperimentalFlagLevel
331317
}
332318

319+
// tracing
320+
tracingProvider, err := cmd.Flags().GetString("tracer-type")
321+
if err != nil {
322+
return nil, err
323+
}
324+
325+
c.Tracer = config.TracerConfiguration{
326+
Type: config.TracerProvider(tracingProvider),
327+
}
328+
329+
switch c.Tracer.Type {
330+
case config.OTelTracerProvider:
331+
sampleRate, err := cmd.Flags().GetFloat64("otel-sample-rate")
332+
if err != nil {
333+
return nil, err
334+
}
335+
336+
collectorURL, err := cmd.Flags().GetString("otel-collector-url")
337+
if err != nil {
338+
return nil, err
339+
}
340+
341+
headerName, err := cmd.Flags().GetString("otel-auth-header-name")
342+
if err != nil {
343+
return nil, err
344+
}
345+
346+
headerValue, err := cmd.Flags().GetString("otel-auth-header-value")
347+
if err != nil {
348+
return nil, err
349+
}
350+
351+
insecureSkipVerify, err := cmd.Flags().GetBool("otel-insecure-skip-verify")
352+
if err != nil {
353+
return nil, err
354+
}
355+
356+
c.Tracer.OTel = config.OTelConfiguration{
357+
SampleRate: sampleRate,
358+
CollectorURL: collectorURL,
359+
InsecureSkipVerify: insecureSkipVerify,
360+
OTelAuth: config.OTelAuthConfiguration{
361+
HeaderName: headerName,
362+
HeaderValue: headerValue,
363+
},
364+
}
365+
366+
case config.SentryTracerProvider:
367+
dsn, err := cmd.Flags().GetString("sentry-dsn")
368+
if err != nil {
369+
return nil, err
370+
}
371+
372+
c.Tracer.Sentry = config.SentryConfiguration{
373+
DSN: dsn,
374+
}
375+
376+
}
377+
333378
return c, nil
334379
}
335380

cmd/ingest/ingest.go

-51
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ func AddIngestCommand(a *cli.App) *cobra.Command {
1919
var logLevel string
2020
var interval int
2121

22-
var newRelicApp string
23-
var newRelicKey string
24-
var newRelicTracerEnabled bool
25-
var newRelicConfigEnabled bool
26-
2722
cmd := &cobra.Command{
2823
Use: "ingest",
2924
Short: "Ingest webhook events from Pub/Sub streams",
@@ -79,10 +74,6 @@ func AddIngestCommand(a *cli.App) *cobra.Command {
7974
cmd.Flags().Uint32Var(&ingestPort, "ingest-port", 5009, "Ingest port")
8075
cmd.Flags().StringVar(&logLevel, "log-level", "", "ingest log level")
8176
cmd.Flags().IntVar(&interval, "interval", 300, "the time interval, measured in seconds, at which the database should be polled for new pub sub sources")
82-
cmd.Flags().BoolVar(&newRelicConfigEnabled, "new-relic-config-enabled", false, "Enable new-relic config")
83-
cmd.Flags().BoolVar(&newRelicTracerEnabled, "new-relic-tracer-enabled", false, "Enable new-relic distributed tracer")
84-
cmd.Flags().StringVar(&newRelicApp, "new-relic-app", "", "NewRelic application name")
85-
cmd.Flags().StringVar(&newRelicKey, "new-relic-key", "", "NewRelic application license key")
8677

8778
return cmd
8879
}
@@ -110,47 +101,5 @@ func buildCliFlagConfiguration(cmd *cobra.Command) (*config.Configuration, error
110101

111102
c.Server.HTTP.IngestPort = ingestPort
112103

113-
// CONVOY_NEWRELIC_APP_NAME
114-
newReplicApp, err := cmd.Flags().GetString("new-relic-app")
115-
if err != nil {
116-
return nil, err
117-
}
118-
119-
if !util.IsStringEmpty(newReplicApp) {
120-
c.Tracer.NewRelic.AppName = newReplicApp
121-
}
122-
123-
// CONVOY_NEWRELIC_LICENSE_KEY
124-
newReplicKey, err := cmd.Flags().GetString("new-relic-key")
125-
if err != nil {
126-
return nil, err
127-
}
128-
129-
if !util.IsStringEmpty(newReplicKey) {
130-
c.Tracer.NewRelic.LicenseKey = newReplicKey
131-
}
132-
133-
// CONVOY_NEWRELIC_CONFIG_ENABLED
134-
isNRCESet := cmd.Flags().Changed("new-relic-config-enabled")
135-
if isNRCESet {
136-
newReplicConfigEnabled, err := cmd.Flags().GetBool("new-relic-config-enabled")
137-
if err != nil {
138-
return nil, err
139-
}
140-
141-
c.Tracer.NewRelic.ConfigEnabled = newReplicConfigEnabled
142-
}
143-
144-
// CONVOY_NEWRELIC_DISTRIBUTED_TRACER_ENABLED
145-
isNRTESet := cmd.Flags().Changed("new-relic-tracer-enabled")
146-
if isNRTESet {
147-
newReplicTracerEnabled, err := cmd.Flags().GetBool("new-relic-tracer-enabled")
148-
if err != nil {
149-
return nil, err
150-
}
151-
152-
c.Tracer.NewRelic.DistributedTracerEnabled = newReplicTracerEnabled
153-
}
154-
155104
return c, nil
156105
}

cmd/main.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func main() {
4747
var dbDatabase string
4848

4949
var fflag string
50+
var enableProfiling bool
5051

5152
var redisPort int
5253
var redisHost string
@@ -55,7 +56,15 @@ func main() {
5556
var redisUsername string
5657
var redisPassword string
5758
var redisDatabase string
58-
var enableProfiling bool
59+
60+
var tracerType string
61+
var sentryDSN string
62+
var datadogAgentURL string
63+
var datadogLicenseKey string
64+
var otelSampleRate float64
65+
var otelCollectorURL string
66+
var otelAuthHeaderName string
67+
var otelAuthHeaderValue string
5968

6069
var configFile string
6170

@@ -83,6 +92,16 @@ func main() {
8392
c.Flags().StringVar(&fflag, "feature-flag", "", "Enable feature flags (experimental)")
8493
c.Flags().BoolVar(&enableProfiling, "enable-profiling", false, "Enable profiling")
8594

95+
// tracing
96+
c.Flags().StringVar(&tracerType, "tracer-type", "", "Tracer backend, e.g. sentry, datadog or otel")
97+
c.Flags().StringVar(&sentryDSN, "sentry-dsn", "", "Sentry backend dsn")
98+
c.Flags().StringVar(&datadogAgentURL, "datadog-agent-url", "", "Datadog agent URL")
99+
c.Flags().StringVar(&datadogLicenseKey, "datadog-license-key", "", "Datadog license key")
100+
c.Flags().Float64Var(&otelSampleRate, "otel-sample-rate", 1.0, "OTel tracing sample rate")
101+
c.Flags().StringVar(&otelCollectorURL, "otel-collector-url", "", "OTel collector URL")
102+
c.Flags().StringVar(&otelAuthHeaderName, "otel-auth-header-name", "", "OTel backend auth header name")
103+
c.Flags().StringVar(&otelAuthHeaderValue, "otel-auth-header-value", "", "OTel backend auth header value")
104+
86105
c.PersistentPreRunE(hooks.PreRun(app, db))
87106
c.PersistentPostRunE(hooks.PostRun(app, db))
88107

0 commit comments

Comments
 (0)