Skip to content

Commit b1b55e0

Browse files
authored
feat(observability): refactor logging and tracing (#22)
1 parent 60e6e40 commit b1b55e0

33 files changed

+543
-174
lines changed

cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/formancehq/go-libs/v3/service"
1212
"github.com/formancehq/terraform-provider-cloud/internal"
1313
"github.com/formancehq/terraform-provider-cloud/internal/server"
14+
1415
"github.com/spf13/cobra"
1516
"github.com/spf13/pflag"
1617
"go.uber.org/fx"

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ require (
2929
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
3030
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
3131
go.opentelemetry.io/contrib/propagators/b3 v1.36.0 // indirect
32-
go.opentelemetry.io/otel v1.36.0 // indirect
32+
go.opentelemetry.io/otel v1.36.0
3333
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
3434
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 // indirect
3535
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 // indirect
3636
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 // indirect
3737
go.opentelemetry.io/otel/log v0.6.0 // indirect
3838
go.opentelemetry.io/otel/metric v1.36.0 // indirect
3939
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
40-
go.opentelemetry.io/otel/trace v1.36.0 // indirect
40+
go.opentelemetry.io/otel/trace v1.36.0
4141
go.opentelemetry.io/proto/otlp v1.6.0 // indirect
4242
go.uber.org/dig v1.19.0 // indirect
4343
go.uber.org/fx v1.24.0

internal/datasources/current_organization.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"fmt"
66

7-
"github.com/formancehq/go-libs/v3/logging"
87
"github.com/formancehq/terraform-provider-cloud/internal"
98
"github.com/formancehq/terraform-provider-cloud/internal/resources"
109
"github.com/formancehq/terraform-provider-cloud/pkg"
@@ -41,8 +40,7 @@ var SchemaCurrentOrganization = schema.Schema{
4140
}
4241

4342
type CurrentOrganization struct {
44-
logger logging.Logger
45-
store *internal.Store
43+
store *internal.Store
4644
}
4745

4846
// Configure implements datasource.DataSourceWithConfigure.
@@ -70,11 +68,9 @@ type CurrentOrganizationModel struct {
7068
Domain types.String `tfsdk:"domain"`
7169
}
7270

73-
func NewCurrentOrganization(logger logging.Logger) func() datasource.DataSource {
71+
func NewCurrentOrganization() func() datasource.DataSource {
7472
return func() datasource.DataSource {
75-
return &CurrentOrganization{
76-
logger: logger,
77-
}
73+
return &CurrentOrganization{}
7874
}
7975
}
8076

@@ -88,8 +84,6 @@ func (c *CurrentOrganization) Schema(ctx context.Context, req datasource.SchemaR
8884

8985
func (c *CurrentOrganization) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
9086
var data CurrentOrganizationModel
91-
ctx = logging.ContextWithLogger(ctx, c.logger.WithField("func", "current_organization_read"))
92-
logging.FromContext(ctx).Debugf("Reading current organization")
9387
organizationId, err := c.store.GetOrganizationID(ctx)
9488
if err != nil {
9589
resp.Diagnostics.AddError(

internal/datasources/current_organization_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func TestCurrentOrganizationConfigure(t *testing.T) {
3636
},
3737
} {
3838
ctx := logging.TestingContext()
39-
co := datasources.NewCurrentOrganization(logging.FromContext(ctx))().(datasource.DataSourceWithConfigure)
39+
co := datasources.NewCurrentOrganization()().(datasource.DataSourceWithConfigure)
4040

4141
res := datasource.ConfigureResponse{
4242
Diagnostics: []diag.Diagnostic{},
@@ -71,7 +71,7 @@ func TestCurrentOrganizationConfigure(t *testing.T) {
7171

7272
func TestCurrentOrganizationMetadata(t *testing.T) {
7373
ctx := logging.TestingContext()
74-
co := datasources.NewCurrentOrganization(logging.FromContext(ctx))().(datasource.DataSourceWithConfigure)
74+
co := datasources.NewCurrentOrganization()().(datasource.DataSourceWithConfigure)
7575

7676
res := datasource.MetadataResponse{}
7777

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package datasources
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"reflect"
7+
"strings"
8+
9+
"github.com/formancehq/go-libs/v3/logging"
10+
"github.com/formancehq/terraform-provider-cloud/pkg/tracing"
11+
"github.com/hashicorp/terraform-plugin-framework/datasource"
12+
"go.opentelemetry.io/otel/propagation"
13+
"go.opentelemetry.io/otel/trace"
14+
)
15+
16+
var (
17+
_ datasource.DataSource = &DatasourcesTracer{}
18+
_ datasource.DataSourceWithConfigure = &DatasourcesTracer{}
19+
_ datasource.DataSourceWithConfigValidators = &DatasourcesTracer{}
20+
)
21+
22+
type DatasourcesTracer struct {
23+
tracer trace.Tracer
24+
logger logging.Logger
25+
underlyingValue any
26+
}
27+
28+
func injectTraceContext(ctx context.Context, res any, funcName string) context.Context {
29+
headerCarrier := propagation.MapCarrier{}
30+
propagation.TraceContext{}.Inject(ctx, headerCarrier)
31+
32+
for k, v := range headerCarrier {
33+
ctx = logging.ContextWithField(ctx, k, v)
34+
}
35+
36+
name := reflect.TypeOf(res).Elem().Name()
37+
ctx = logging.ContextWithField(ctx, "resource", strings.ToLower(name))
38+
ctx = logging.ContextWithField(ctx, "operation", strings.ToLower(funcName))
39+
return ctx
40+
}
41+
42+
var (
43+
ErrConfigure = fmt.Errorf("error in configure")
44+
ErrRead = fmt.Errorf("error in read")
45+
ErrSchema = fmt.Errorf("error in schema")
46+
ErrMetadata = fmt.Errorf("error in metadata")
47+
ErrValidate = fmt.Errorf("error in validate")
48+
)
49+
50+
// Configure implements datasource.DataSourceWithConfigure.
51+
func (d *DatasourcesTracer) Configure(ctx context.Context, req datasource.ConfigureRequest, res *datasource.ConfigureResponse) {
52+
ctx = logging.ContextWithLogger(ctx, d.logger)
53+
operation := "Configure"
54+
if v, ok := d.underlyingValue.(datasource.DataSourceWithConfigure); ok {
55+
_ = tracing.TraceError(ctx, d.tracer, operation, func(ctx context.Context) error {
56+
ctx = injectTraceContext(ctx, d.underlyingValue, operation)
57+
logging.FromContext(ctx).Debugf(operation + " called")
58+
defer logging.FromContext(ctx).Debugf(operation + " completed")
59+
v.Configure(ctx, req, res)
60+
if res.Diagnostics.HasError() {
61+
return ErrConfigure
62+
}
63+
return nil
64+
})
65+
}
66+
}
67+
68+
// ConfigValidators implements datasource.DataSourceWithConfigValidators.
69+
func (d *DatasourcesTracer) ConfigValidators(ctx context.Context) []datasource.ConfigValidator {
70+
ctx = logging.ContextWithLogger(ctx, d.logger)
71+
operation := "ConfigValidators"
72+
if v, ok := d.underlyingValue.(datasource.DataSourceWithConfigValidators); ok {
73+
ret, _ := tracing.Trace(ctx, d.tracer, operation, func(ctx context.Context) ([]datasource.ConfigValidator, error) {
74+
ctx = injectTraceContext(ctx, d.underlyingValue, operation)
75+
logging.FromContext(ctx).Debugf(operation + " called")
76+
defer logging.FromContext(ctx).Debugf(operation + " completed")
77+
return v.ConfigValidators(ctx), nil
78+
})
79+
return ret
80+
}
81+
return nil
82+
}
83+
84+
// Metadata implements datasource.DataSourceWithConfigValidators.
85+
func (d *DatasourcesTracer) Metadata(ctx context.Context, req datasource.MetadataRequest, res *datasource.MetadataResponse) {
86+
ctx = logging.ContextWithLogger(ctx, d.logger)
87+
operation := "Metadata"
88+
if v, ok := d.underlyingValue.(datasource.DataSource); ok {
89+
_ = tracing.TraceError(ctx, d.tracer, operation, func(ctx context.Context) error {
90+
ctx = injectTraceContext(ctx, d.underlyingValue, operation)
91+
logging.FromContext(ctx).Debugf(operation + " called")
92+
defer logging.FromContext(ctx).Debugf(operation + " completed")
93+
v.Metadata(ctx, req, res)
94+
return nil
95+
})
96+
}
97+
}
98+
99+
// Read implements datasource.DataSourceWithConfigValidators.
100+
func (d *DatasourcesTracer) Read(ctx context.Context, req datasource.ReadRequest, res *datasource.ReadResponse) {
101+
ctx = logging.ContextWithLogger(ctx, d.logger)
102+
operation := "Read"
103+
if v, ok := d.underlyingValue.(datasource.DataSource); ok {
104+
_ = tracing.TraceError(ctx, d.tracer, operation, func(ctx context.Context) error {
105+
ctx = injectTraceContext(ctx, d.underlyingValue, operation)
106+
logging.FromContext(ctx).Debugf(operation + " called")
107+
defer logging.FromContext(ctx).Debugf(operation + " completed")
108+
v.Read(ctx, req, res)
109+
if res.Diagnostics.HasError() {
110+
return ErrRead
111+
}
112+
return nil
113+
})
114+
}
115+
}
116+
117+
// Schema implements datasource.DataSourceWithConfigValidators.
118+
func (d *DatasourcesTracer) Schema(ctx context.Context, req datasource.SchemaRequest, res *datasource.SchemaResponse) {
119+
ctx = logging.ContextWithLogger(ctx, d.logger)
120+
operation := "Schema"
121+
if v, ok := d.underlyingValue.(datasource.DataSource); ok {
122+
_ = tracing.TraceError(ctx, d.tracer, operation, func(ctx context.Context) error {
123+
ctx = injectTraceContext(ctx, d.underlyingValue, operation)
124+
logging.FromContext(ctx).Debugf(operation + " called")
125+
defer logging.FromContext(ctx).Debugf(operation + " completed")
126+
v.Schema(ctx, req, res)
127+
if res.Diagnostics.HasError() {
128+
return ErrSchema
129+
}
130+
return nil
131+
})
132+
}
133+
}
134+
135+
func NewDatasourcesTracer(tracer trace.Tracer, logger logging.Logger, res func() datasource.DataSource) *DatasourcesTracer {
136+
return &DatasourcesTracer{
137+
tracer: tracer,
138+
logger: logger,
139+
underlyingValue: res(),
140+
}
141+
}

internal/datasources/region_versions.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"slices"
77
"sort"
88

9-
"github.com/formancehq/go-libs/v3/logging"
109
"github.com/formancehq/terraform-provider-cloud/internal"
1110
"github.com/formancehq/terraform-provider-cloud/internal/resources"
1211
"github.com/formancehq/terraform-provider-cloud/pkg"
@@ -21,8 +20,7 @@ var (
2120
)
2221

2322
type RegionVersions struct {
24-
logger logging.Logger
25-
store *internal.Store
23+
store *internal.Store
2624
}
2725

2826
var SchemaRegionVersions = schema.Schema{
@@ -74,11 +72,9 @@ type Version struct {
7472
Name types.String `tfsdk:"name"`
7573
}
7674

77-
func NewRegionVersions(logger logging.Logger) func() datasource.DataSource {
75+
func NewRegionVersions() func() datasource.DataSource {
7876
return func() datasource.DataSource {
79-
return &RegionVersions{
80-
logger: logger,
81-
}
77+
return &RegionVersions{}
8278
}
8379
}
8480

@@ -91,8 +87,6 @@ func (r *RegionVersions) Schema(ctx context.Context, req datasource.SchemaReques
9187
}
9288

9389
func (r *RegionVersions) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
94-
ctx = logging.ContextWithLogger(ctx, r.logger.WithField("func", "region_versions_read"))
95-
r.logger.Debug("Reading region versions")
9690
var data RegionVersionsModel
9791
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
9892
if resp.Diagnostics.HasError() {

internal/datasources/regions.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66

77
"github.com/formancehq/go-libs/v3/collectionutils"
8-
"github.com/formancehq/go-libs/v3/logging"
98
"github.com/formancehq/terraform-provider-cloud/internal"
109
"github.com/formancehq/terraform-provider-cloud/internal/resources"
1110
"github.com/formancehq/terraform-provider-cloud/pkg"
@@ -24,8 +23,7 @@ var (
2423
)
2524

2625
type Region struct {
27-
logger logging.Logger
28-
store *internal.Store
26+
store *internal.Store
2927
}
3028

3129
var SchemaRegion = schema.Schema{
@@ -75,11 +73,9 @@ type RegionModel struct {
7573
Name types.String `tfsdk:"name"`
7674
}
7775

78-
func NewRegions(logger logging.Logger) func() datasource.DataSource {
76+
func NewRegions() func() datasource.DataSource {
7977
return func() datasource.DataSource {
80-
return &Region{
81-
logger: logger,
82-
}
78+
return &Region{}
8379
}
8480
}
8581

@@ -92,8 +88,6 @@ func (r *Region) Schema(ctx context.Context, req datasource.SchemaRequest, resp
9288
}
9389

9490
func (r *Region) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
95-
ctx = logging.ContextWithLogger(ctx, r.logger.WithField("func", "region_read"))
96-
r.logger.Debug("Reading region")
9791
var data RegionModel
9892
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
9993
if resp.Diagnostics.HasError() {

internal/datasources/regions_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func TestRegionsConfigure(t *testing.T) {
4545
},
4646
} {
4747
ctx := logging.TestingContext()
48-
og := datasources.NewRegions(logging.FromContext(ctx))().(datasource.DataSourceWithConfigure)
48+
og := datasources.NewRegions()().(datasource.DataSourceWithConfigure)
4949

5050
res := datasource.ConfigureResponse{
5151
Diagnostics: []diag.Diagnostic{},
@@ -78,7 +78,7 @@ func TestRegionsConfigure(t *testing.T) {
7878

7979
func TestRegionsMetadata(t *testing.T) {
8080
ctx := logging.TestingContext()
81-
og := datasources.NewRegions(logging.FromContext(ctx))().(datasource.DataSourceWithConfigure)
81+
og := datasources.NewRegions()().(datasource.DataSourceWithConfigure)
8282

8383
res := datasource.MetadataResponse{}
8484

@@ -116,7 +116,7 @@ func TestRegionsConfigvalidator(t *testing.T) {
116116
t.Parallel()
117117
ctx := logging.TestingContext()
118118

119-
r := datasources.NewRegions(logging.FromContext(ctx))().(datasource.DataSourceWithConfigValidators)
119+
r := datasources.NewRegions()().(datasource.DataSourceWithConfigValidators)
120120
validators := r.ConfigValidators(ctx)
121121

122122
for _, validator := range validators {

internal/datasources/stacks.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"sort"
77
"strings"
88

9-
"github.com/formancehq/go-libs/v3/logging"
109
"github.com/formancehq/terraform-provider-cloud/internal"
1110
"github.com/formancehq/terraform-provider-cloud/internal/resources"
1211
"github.com/formancehq/terraform-provider-cloud/pkg"
@@ -25,8 +24,7 @@ var (
2524
)
2625

2726
type Stack struct {
28-
logger logging.Logger
29-
store *internal.Store
27+
store *internal.Store
3028
}
3129

3230
// ConfigValidators implements datasource.DataSourceWithConfigValidators.
@@ -91,11 +89,9 @@ type StackModel struct {
9189
State types.String `tfsdk:"state"`
9290
}
9391

94-
func NewStacks(logger logging.Logger) func() datasource.DataSource {
92+
func NewStacks() func() datasource.DataSource {
9593
return func() datasource.DataSource {
96-
return &Stack{
97-
logger: logger,
98-
}
94+
return &Stack{}
9995
}
10096
}
10197

@@ -108,8 +104,6 @@ func (s *Stack) Schema(ctx context.Context, req datasource.SchemaRequest, resp *
108104
}
109105

110106
func (s *Stack) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
111-
ctx = logging.ContextWithLogger(ctx, s.logger.WithField("func", "stack_read"))
112-
s.logger.Debug("Reading stack")
113107
var data StackModel
114108
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
115109
if resp.Diagnostics.HasError() {

0 commit comments

Comments
 (0)