Skip to content

Commit e5f5618

Browse files
authored
feat: add otel instrumentation (#51)
1 parent d00c697 commit e5f5618

File tree

9 files changed

+647
-65
lines changed

9 files changed

+647
-65
lines changed

cmd/engine.go

Lines changed: 129 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"context"
45
"log/slog"
56
"sync"
67
"time"
@@ -19,12 +20,119 @@ import (
1920
"github.com/w-h-a/workflow/internal/engine/config"
2021
"github.com/w-h-a/workflow/internal/engine/services/coordinator"
2122
"github.com/w-h-a/workflow/internal/engine/services/worker"
23+
"go.opentelemetry.io/contrib/bridges/otelslog"
24+
"go.opentelemetry.io/contrib/instrumentation/host"
25+
"go.opentelemetry.io/contrib/instrumentation/runtime"
26+
"go.opentelemetry.io/otel"
27+
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
28+
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
29+
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog"
30+
globallog "go.opentelemetry.io/otel/log/global"
31+
"go.opentelemetry.io/otel/propagation"
32+
logsdk "go.opentelemetry.io/otel/sdk/log"
33+
metricsdk "go.opentelemetry.io/otel/sdk/metric"
34+
"go.opentelemetry.io/otel/sdk/resource"
35+
tracesdk "go.opentelemetry.io/otel/sdk/trace"
36+
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
2237
)
2338

2439
func StartEngine(ctx *cli.Context) error {
2540
// cfg
2641
config.New()
2742

43+
// resource
44+
name := config.Name()
45+
46+
resource, err := resource.New(
47+
context.Background(),
48+
resource.WithAttributes(
49+
semconv.ServiceName(name),
50+
),
51+
resource.WithProcess(),
52+
)
53+
if err != nil {
54+
return err
55+
}
56+
57+
// logs
58+
logsExporter, err := initLogsExporter()
59+
if err != nil {
60+
return err
61+
}
62+
63+
lp := logsdk.NewLoggerProvider(
64+
logsdk.WithResource(resource),
65+
logsdk.WithProcessor(
66+
logsdk.NewBatchProcessor(logsExporter),
67+
),
68+
)
69+
70+
defer lp.Shutdown(context.Background())
71+
72+
globallog.SetLoggerProvider(lp)
73+
74+
logger := otelslog.NewLogger(
75+
config.Name(),
76+
otelslog.WithLoggerProvider(lp),
77+
)
78+
79+
slog.SetDefault(logger)
80+
81+
// traces
82+
traceExporter, err := initTracesExporter()
83+
if err != nil {
84+
return err
85+
}
86+
87+
tp := tracesdk.NewTracerProvider(
88+
tracesdk.WithResource(resource),
89+
tracesdk.WithSampler(tracesdk.AlwaysSample()),
90+
tracesdk.WithSpanProcessor(
91+
tracesdk.NewBatchSpanProcessor(
92+
traceExporter,
93+
),
94+
),
95+
)
96+
97+
defer tp.Shutdown(context.Background())
98+
99+
otel.SetTracerProvider(tp)
100+
otel.SetTextMapPropagator(
101+
propagation.NewCompositeTextMapPropagator(
102+
propagation.TraceContext{},
103+
propagation.Baggage{},
104+
),
105+
)
106+
107+
// metrics
108+
metricsExporter, err := initMetricsExporter()
109+
if err != nil {
110+
return err
111+
}
112+
113+
mp := metricsdk.NewMeterProvider(
114+
metricsdk.WithResource(resource),
115+
metricsdk.WithReader(
116+
metricsdk.NewPeriodicReader(
117+
metricsExporter,
118+
metricsdk.WithInterval(15*time.Second),
119+
metricsdk.WithProducer(runtime.NewProducer()),
120+
),
121+
),
122+
)
123+
124+
defer mp.Shutdown(context.Background())
125+
126+
otel.SetMeterProvider(mp)
127+
128+
if err := host.Start(); err != nil {
129+
return err
130+
}
131+
132+
if err := runtime.Start(runtime.WithMinimumReadMemStatsInterval(time.Second)); err != nil {
133+
return err
134+
}
135+
28136
// broker client
29137
brokerClient := initBroker()
30138

@@ -105,7 +213,7 @@ func StartEngine(ctx *cli.Context) error {
105213
}
106214

107215
// block
108-
err := <-ch
216+
err = <-ch
109217
if err != nil {
110218
slog.ErrorContext(ctx.Context, "failed to start", "error", err)
111219
return err
@@ -138,6 +246,26 @@ func StartEngine(ctx *cli.Context) error {
138246
return nil
139247
}
140248

249+
func initLogsExporter() (logsdk.Exporter, error) {
250+
return stdoutlog.New()
251+
}
252+
253+
func initTracesExporter() (tracesdk.SpanExporter, error) {
254+
return otlptracehttp.New(
255+
context.Background(),
256+
otlptracehttp.WithEndpoint(config.TracesAddress()),
257+
otlptracehttp.WithInsecure(),
258+
)
259+
}
260+
261+
func initMetricsExporter() (metricsdk.Exporter, error) {
262+
return otlpmetrichttp.New(
263+
context.Background(),
264+
otlpmetrichttp.WithEndpoint(config.MetricsAddress()),
265+
otlpmetrichttp.WithInsecure(),
266+
)
267+
}
268+
141269
func initBroker() broker.Broker {
142270
switch config.Broker() {
143271
case string(broker.Rabbit):

docker-compose.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,35 @@
11
services:
2+
jaeger:
3+
container_name: jaeger
4+
image: jaegertracing/all-in-one:1.62.0
5+
ports:
6+
- '16686:16686'
7+
healthcheck:
8+
test: ["CMD-SHELL", "wget --spider http://localhost:16686/"] # Updated command
9+
interval: 10s
10+
timeout: 5s
11+
retries: 5
12+
start_period: 30s
13+
14+
prometheus:
15+
container_name: prometheus
16+
image: prom/prometheus:v3.0.0
17+
command:
18+
- "--config.file=/etc/prometheus/prometheus.yaml"
19+
- "--web.enable-otlp-receiver"
20+
- "--web.enable-remote-write-receiver"
21+
- "--enable-feature=remote-write-receiver"
22+
ports:
23+
- '9090:9090'
24+
volumes:
25+
- ./prometheus.yaml:/etc/prometheus/prometheus.yaml
26+
healthcheck:
27+
test: ["CMD-SHELL", "wget --spider http://localhost:9090/metrics"] # Updated command
28+
interval: 10s
29+
timeout: 5s
30+
retries: 5
31+
start_period: 30s
32+
233
rabbitmq:
334
container_name: rabbitmq
435
image: rabbitmq:3.13-management
@@ -39,13 +70,20 @@ services:
3970
- VERSION=0.1.0-alpha.0
4071
- MODE=worker
4172
- HTTP_ADDRESS=:4001
73+
- TRACES_ADDRESS=jaeger:4318
74+
- METRICS_ADDRESS=prometheus:9090
75+
- OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://prometheus:9090/api/v1/otlp/v1/metrics
4276
- BROKER=rabbit
4377
- BROKER_LOCATION=amqp://guest:guest@rabbitmq:5672
4478
- RUNNER=docker
4579
- RUNNER_HOST=unix:///var/run/docker.sock
4680
volumes:
4781
- /var/run/docker.sock:/var/run/docker.sock
4882
depends_on:
83+
jaeger:
84+
condition: service_healthy
85+
prometheus:
86+
condition: service_healthy
4987
rabbitmq:
5088
condition: service_healthy
5189

@@ -61,11 +99,18 @@ services:
6199
- VERSION=0.1.0-alpha.0
62100
- MODE=coordinator
63101
- HTTP_ADDRESS=:4000
102+
- TRACES_ADDRESS=jaeger:4318
103+
- METRICS_ADDRESS=prometheus:9090
104+
- OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://prometheus:9090/api/v1/otlp/v1/metrics
64105
- BROKER=rabbit
65106
- BROKER_LOCATION=amqp://guest:guest@rabbitmq:5672
66107
- READ_WRITER=postgres
67108
- READ_WRITER_LOCATION=postgres://tasks:tasks@postgres:5432/tasks?sslmode=disable
68109
depends_on:
110+
jaeger:
111+
condition: service_healthy
112+
prometheus:
113+
condition: service_healthy
69114
rabbitmq:
70115
condition: service_healthy
71116
postgres:

go.mod

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,61 @@ require (
1111
github.com/urfave/cli/v2 v2.27.7
1212
github.com/w-h-a/pkg v0.41.0
1313
go.nhat.io/otelsql v0.16.0
14+
go.opentelemetry.io/contrib/bridges/otelslog v0.13.0
15+
go.opentelemetry.io/contrib/instrumentation/host v0.63.0
1416
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0
15-
go.opentelemetry.io/otel v1.37.0
17+
go.opentelemetry.io/contrib/instrumentation/runtime v0.63.0
18+
go.opentelemetry.io/otel v1.38.0
19+
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0
20+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0
21+
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0
22+
go.opentelemetry.io/otel/log v0.14.0
23+
go.opentelemetry.io/otel/sdk v1.38.0
24+
go.opentelemetry.io/otel/sdk/log v0.14.0
25+
go.opentelemetry.io/otel/sdk/metric v1.38.0
26+
go.opentelemetry.io/otel/trace v1.38.0
1627
)
1728

1829
require (
1930
github.com/Microsoft/go-winio v0.4.14 // indirect
31+
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
2032
github.com/containerd/log v0.1.0 // indirect
2133
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
2234
github.com/distribution/reference v0.6.0 // indirect
2335
github.com/docker/go-connections v0.5.0 // indirect
2436
github.com/docker/go-units v0.5.0 // indirect
37+
github.com/ebitengine/purego v0.8.4 // indirect
2538
github.com/felixge/httpsnoop v1.0.4 // indirect
2639
github.com/go-logr/logr v1.4.3 // indirect
2740
github.com/go-logr/stdr v1.2.2 // indirect
41+
github.com/go-ole/go-ole v1.3.0 // indirect
2842
github.com/gogo/protobuf v1.3.2 // indirect
43+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
44+
github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 // indirect
2945
github.com/moby/docker-image-spec v1.3.1 // indirect
3046
github.com/moby/term v0.5.2 // indirect
3147
github.com/morikuni/aec v1.0.0 // indirect
3248
github.com/opencontainers/go-digest v1.0.0 // indirect
3349
github.com/opencontainers/image-spec v1.1.1 // indirect
3450
github.com/pkg/errors v0.9.1 // indirect
51+
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
3552
github.com/russross/blackfriday/v2 v2.1.0 // indirect
53+
github.com/shirou/gopsutil/v4 v4.25.7 // indirect
54+
github.com/tklauser/go-sysconf v0.3.15 // indirect
55+
github.com/tklauser/numcpus v0.10.0 // indirect
3656
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
57+
github.com/yusufpapurcu/wmi v1.2.4 // indirect
3758
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
38-
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect
39-
go.opentelemetry.io/otel/metric v1.37.0 // indirect
40-
go.opentelemetry.io/otel/trace v1.37.0 // indirect
41-
golang.org/x/sys v0.33.0 // indirect
59+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
60+
go.opentelemetry.io/otel/metric v1.38.0 // indirect
61+
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
62+
golang.org/x/net v0.43.0 // indirect
63+
golang.org/x/sys v0.35.0 // indirect
64+
golang.org/x/text v0.28.0 // indirect
4265
golang.org/x/time v0.12.0 // indirect
66+
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
67+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
68+
google.golang.org/grpc v1.75.0 // indirect
69+
google.golang.org/protobuf v1.36.8 // indirect
4370
gotest.tools/v3 v3.5.2 // indirect
4471
)

0 commit comments

Comments
 (0)