@@ -9,88 +9,56 @@ import (
9
9
"context"
10
10
11
11
"github.com/z5labs/bedrock"
12
-
12
+ "github.com/z5labs/bedrock/app"
13
13
"go.opentelemetry.io/otel"
14
- "go.opentelemetry.io/otel/log"
15
14
"go.opentelemetry.io/otel/log/global"
16
- "go.opentelemetry.io/otel/metric"
17
- "go.opentelemetry.io/otel/propagation"
18
- "go.opentelemetry.io/otel/trace"
19
15
)
20
16
21
- // TextMapPropagatorInitializer
22
- type TextMapPropagatorInitializer interface {
23
- InitTextMapPropogator (context.Context ) (propagation. TextMapPropagator , error )
17
+ // OTelInitializer represents anything which can initialize the OTel SDK.
18
+ type OTelInitializer interface {
19
+ InitializeOTel (context.Context ) error
24
20
}
25
21
26
- // TracerProviderInitializer
27
- type TracerProviderInitializer interface {
28
- InitTracerProvider (context.Context ) (trace.TracerProvider , error )
29
- }
22
+ // OTel is a [bedrock.AppBuilder] middleware which initializes the OTel SDK.
23
+ // It also ensures that the OTel SDK is properly shutdown when the built [bedrock.App]
24
+ // stops running.
25
+ func OTel [T OTelInitializer ](builder bedrock.AppBuilder [T ]) bedrock.AppBuilder [T ] {
26
+ return bedrock.AppBuilderFunc [T ](func (ctx context.Context , cfg T ) (bedrock.App , error ) {
27
+ err := cfg .InitializeOTel (ctx )
28
+ if err != nil {
29
+ return nil , err
30
+ }
30
31
31
- // MeterProviderInitializer
32
- type MeterProviderInitializer interface {
33
- InitMeterProvider (context. Context ) (metric. MeterProvider , error )
34
- }
32
+ base , err := builder . Build ( ctx , cfg )
33
+ if err != nil {
34
+ return nil , err
35
+ }
35
36
36
- // LoggerProviderInitializer
37
- type LoggerProviderInitializer interface {
38
- InitLoggerProvider (context.Context ) (log.LoggerProvider , error )
37
+ base = app .WithLifecycleHooks (base , app.Lifecycle {
38
+ PostRun : app .ComposeLifecycleHooks (
39
+ tryShutdown (otel .GetTracerProvider ()),
40
+ tryShutdown (otel .GetMeterProvider ()),
41
+ tryShutdown (global .GetLoggerProvider ()),
42
+ ),
43
+ })
44
+ return base , nil
45
+ })
39
46
}
40
47
41
- // OTelInitializer
42
- type OTelInitializer interface {
43
- TextMapPropagatorInitializer
44
- TracerProviderInitializer
45
- MeterProviderInitializer
46
- LoggerProviderInitializer
48
+ type shutdowner interface {
49
+ Shutdown (context.Context ) error
47
50
}
48
51
49
- // OTel
50
- func OTel [T OTelInitializer ](builder bedrock.AppBuilder [T ]) bedrock.AppBuilder [T ] {
51
- return bedrock.AppBuilderFunc [T ](func (ctx context.Context , cfg T ) (bedrock.App , error ) {
52
- fs := []func (context.Context ) error {
53
- func (ctx context.Context ) error {
54
- tmp , err := cfg .InitTextMapPropogator (ctx )
55
- if err != nil || tmp == nil {
56
- return err
57
- }
58
- otel .SetTextMapPropagator (tmp )
59
- return nil
60
- },
61
- func (ctx context.Context ) error {
62
- tp , err := cfg .InitTracerProvider (ctx )
63
- if err != nil || tp == nil {
64
- return err
65
- }
66
- otel .SetTracerProvider (tp )
67
- return nil
68
- },
69
- func (ctx context.Context ) error {
70
- mp , err := cfg .InitMeterProvider (ctx )
71
- if err != nil || mp == nil {
72
- return err
73
- }
74
- otel .SetMeterProvider (mp )
75
- return nil
76
- },
77
- func (ctx context.Context ) error {
78
- lp , err := cfg .InitLoggerProvider (ctx )
79
- if err != nil || lp == nil {
80
- return err
81
- }
82
- global .SetLoggerProvider (lp )
83
- return nil
84
- },
52
+ func tryShutdown (v any ) app.LifecycleHookFunc {
53
+ return func (ctx context.Context ) error {
54
+ if v == nil {
55
+ return nil
85
56
}
86
57
87
- for _ , f := range fs {
88
- err := f (ctx )
89
- if err != nil {
90
- return nil , err
91
- }
58
+ s , ok := v .(shutdowner )
59
+ if ! ok {
60
+ return nil
92
61
}
93
-
94
- return builder .Build (ctx , cfg )
95
- })
62
+ return s .Shutdown (ctx )
63
+ }
96
64
}
0 commit comments