Skip to content

Commit d45f57f

Browse files
committed
fix otel instrumentation
1 parent ac99e02 commit d45f57f

File tree

4 files changed

+61
-7
lines changed

4 files changed

+61
-7
lines changed

src/go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ require (
1313
github.com/spf13/cobra v1.9.1
1414
github.com/spf13/viper v1.20.1
1515
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.60.0
16+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0
17+
go.opentelemetry.io/otel v1.35.0
1618
go.opentelemetry.io/otel/trace v1.35.0
1719
go.uber.org/zap v1.27.0
1820
google.golang.org/grpc v1.72.0
@@ -63,7 +65,6 @@ require (
6365
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
6466
github.com/ugorji/go/codec v1.2.12 // indirect
6567
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
66-
go.opentelemetry.io/otel v1.35.0 // indirect
6768
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.11.0 // indirect
6869
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.11.0 // indirect
6970
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect

src/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
146146
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
147147
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.60.0 h1:jj/B7eX95/mOxim9g9laNZkOHKz/XCHG0G410SntRy4=
148148
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.60.0/go.mod h1:ZvRTVaYYGypytG0zRp2A60lpj//cMq3ZnxYdZaljVBM=
149+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw=
150+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM=
149151
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
150152
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
151153
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.11.0 h1:HMUytBT3uGhPKYY/u/G5MR9itrlSO2SMOsSD3Tk3k7A=

src/pkg/api/grpc_api.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/spechtlabs/go-otel-utils/otelzap"
99
"github.com/spf13/viper"
10+
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
1011
"google.golang.org/grpc"
1112
"google.golang.org/grpc/credentials/insecure"
1213

@@ -23,9 +24,14 @@ type GrpcApi struct {
2324
}
2425

2526
func NewGrpcApiServer(client *client.ICalClient) *GrpcApi {
27+
// Create a server with the OpenTelemetry interceptor
28+
srv := grpc.NewServer(
29+
grpc.StatsHandler(otelgrpc.NewServerHandler()),
30+
)
31+
2632
e := &GrpcApi{
2733
client: client,
28-
srv: grpc.NewServer(),
34+
srv: srv,
2935
}
3036

3137
pb.RegisterCalenderServiceServer(e.srv, e)
@@ -42,9 +48,13 @@ func NewGrpcApiServer(client *client.ICalClient) *GrpcApi {
4248
}
4349

4450
func NewGrpcApiClient(addr string) (*grpc.ClientConn, pb.CalenderServiceClient) {
51+
// Set up a connection to the server with OpenTelemetry instrumentation
52+
conn, err := grpc.NewClient(
53+
addr,
54+
grpc.WithTransportCredentials(insecure.NewCredentials()),
55+
grpc.WithStatsHandler(otelgrpc.NewClientHandler()),
56+
)
4557

46-
// Set up a connection to the server.
47-
conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
4858
if err != nil {
4959
otelzap.L().Fatal(fmt.Sprintf("gRPC API: failed to connect: %v", err))
5060
}

src/pkg/client/ical_client.go

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import (
1616
"github.com/apognu/gocal"
1717
"github.com/spechtlabs/go-otel-utils/otelzap"
1818
"github.com/spf13/viper"
19+
"go.opentelemetry.io/otel"
20+
"go.opentelemetry.io/otel/attribute"
21+
"go.opentelemetry.io/otel/codes"
22+
"go.opentelemetry.io/otel/trace"
1923
"go.uber.org/zap"
2024

2125
pb "github.com/SpechtLabs/CalendarAPI/pkg/protos"
@@ -25,6 +29,7 @@ type ICalClient struct {
2529
cacheMux sync.RWMutex
2630
cache *pb.CalendarResponse
2731
cacheExpiration time.Time
32+
tracer trace.Tracer
2833

2934
statusMux sync.RWMutex
3035
CustomStatus map[string]*pb.CustomStatus // custom status is a map from calendar-name to status
@@ -79,10 +84,14 @@ func NewICalClient() *ICalClient {
7984
cacheExpiration: time.Now(),
8085
cache: &pb.CalendarResponse{LastUpdated: time.Now().Unix()},
8186
CustomStatus: make(map[string]*pb.CustomStatus),
87+
tracer: otel.GetTracerProvider().Tracer("github.com/SpechtLabs/CalendarAPI/pkg/client"),
8288
}
8389
}
8490

8591
func (e *ICalClient) FetchEvents(ctx context.Context) {
92+
ctx, span := e.tracer.Start(ctx, "ICalClient.FetchEvents")
93+
defer span.End()
94+
8695
response := &pb.CalendarResponse{
8796
LastUpdated: time.Now().Unix(),
8897
Entries: make([]*pb.CalendarEntry, 0),
@@ -127,6 +136,9 @@ func (e *ICalClient) FetchEvents(ctx context.Context) {
127136
}
128137

129138
func (e *ICalClient) GetEvents(ctx context.Context) *pb.CalendarResponse {
139+
ctx, span := e.tracer.Start(ctx, "ICalClient.GetEvents")
140+
defer span.End()
141+
130142
if e.cache == nil {
131143
otelzap.L().Ctx(ctx).Sugar().Infow("Experiencing cold. Fetching events now!")
132144
e.FetchEvents(ctx)
@@ -138,6 +150,9 @@ func (e *ICalClient) GetEvents(ctx context.Context) *pb.CalendarResponse {
138150
}
139151

140152
func (e *ICalClient) GetCurrentEvent(ctx context.Context, calendar string) *pb.CalendarEntry {
153+
ctx, span := e.tracer.Start(ctx, "ICalClient.GetCurrentEvent")
154+
defer span.End()
155+
141156
if e.cache == nil {
142157
otelzap.L().Ctx(ctx).Sugar().Infow("Experiencing cold. Fetching events now!")
143158
e.FetchEvents(ctx)
@@ -186,7 +201,10 @@ func (e *ICalClient) GetCurrentEvent(ctx context.Context, calendar string) *pb.C
186201
return closest
187202
}
188203

189-
func (e *ICalClient) GetCustomStatus(_ context.Context, req *pb.GetCustomStatusRequest) *pb.CustomStatus {
204+
func (e *ICalClient) GetCustomStatus(ctx context.Context, req *pb.GetCustomStatusRequest) *pb.CustomStatus {
205+
ctx, span := e.tracer.Start(ctx, "ICalClient.GetCustomStatus")
206+
defer span.End()
207+
190208
e.statusMux.RLock()
191209
defer e.statusMux.RUnlock()
192210

@@ -197,14 +215,26 @@ func (e *ICalClient) GetCustomStatus(_ context.Context, req *pb.GetCustomStatusR
197215
return &pb.CustomStatus{}
198216
}
199217

200-
func (e *ICalClient) SetCustomStatus(_ context.Context, req *pb.SetCustomStatusRequest) {
218+
func (e *ICalClient) SetCustomStatus(ctx context.Context, req *pb.SetCustomStatusRequest) {
219+
ctx, span := e.tracer.Start(ctx, "ICalClient.SetCustomStatus")
220+
defer span.End()
221+
201222
e.statusMux.Lock()
202223
defer e.statusMux.Unlock()
203224

204225
e.CustomStatus[req.CalendarName] = req.Status
205226
}
206227

207228
func (e *ICalClient) loadEvents(ctx context.Context, calName string, from string, url string, rules []Rule) ([]*pb.CalendarEntry, *errors.ResolvingError) {
229+
ctx, span := e.tracer.Start(ctx, "ICalClient.loadEvents")
230+
defer span.End()
231+
232+
span.SetAttributes(
233+
attribute.String("calendar.name", calName),
234+
attribute.String("calendar.from", from),
235+
attribute.String("calendar.url", url),
236+
)
237+
208238
ical, err := e.getIcal(ctx, from, url)
209239
if ical == nil || err != nil {
210240
return nil, errors.Wrap(err, fmt.Errorf("failed to load iCal calendar file"), "")
@@ -328,14 +358,25 @@ func (e *ICalClient) getIcalFromFile(path string) (io.ReadCloser, *errors.Resolv
328358
}
329359

330360
func (e *ICalClient) getIcalFromURL(ctx context.Context, url string) (io.ReadCloser, *errors.ResolvingError) {
331-
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
361+
ctx, span := e.tracer.Start(ctx, "ICalClient.getIcalFromURL")
362+
defer span.End()
363+
364+
span.SetAttributes(
365+
attribute.String("http.method", http.MethodGet),
366+
)
367+
368+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
332369
if err != nil {
370+
span.RecordError(err)
371+
span.SetStatus(codes.Error, err.Error())
333372
return nil, errors.NewResolvingError(fmt.Errorf("failed creating request for %s: %w", url, err), "")
334373
}
335374

336375
client := http.DefaultClient
337376
resp, err := client.Do(req)
338377
if err != nil {
378+
span.RecordError(err)
379+
span.SetStatus(codes.Error, err.Error())
339380
return nil, errors.NewResolvingError(fmt.Errorf("failed making request to %s: %w", url, err), "verify if URL exists and is accessible")
340381
}
341382

0 commit comments

Comments
 (0)