-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- and rename ci > build
- Loading branch information
Showing
2 changed files
with
45 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
name: CI | ||
name: build | ||
|
||
on: | ||
push: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,49 @@ | ||
# go-spanlint | ||
|
||
![Latest release](https://img.shields.io/github/v/release/jjti/go-spanlint) | ||
[![CI](https://github.com/jjti/go-spanlint/actions/workflows/ci.yaml/badge.svg)](https://github.com/jjti/go-spanlint/actions/workflows/ci.yaml) | ||
[![build](https://github.com/jjti/go-spanlint/actions/workflows/build.yaml/badge.svg)](https://github.com/jjti/go-spanlint/actions/workflows/build.yaml) | ||
[![Go Report Card](https://goreportcard.com/badge/github.com/jjti/go-spanlint)](https://goreportcard.com/report/github.com/jjti/go-spanlint) | ||
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE) | ||
|
||
Checks usage of [OpenTelemetry spans](https://pkg.go.dev/go.opentelemetry.io/otel/trace). | ||
|
||
## Problem Statement | ||
|
||
Tracing is one of the pillars of observability. But it's easy to shoot yourself in the foot when creating and managing OTEL spans. For two reasons: | ||
|
||
### Forgetting to call `span.End()` | ||
|
||
Not calling `.End()` can cause memory leaks. | ||
|
||
> Any Span that is created MUST also be ended. This is the responsibility of the user. Implementations of this API may leak memory or other resources if Spans are not ended. | ||
[source: trace.go](https://github.com/open-telemetry/opentelemetry-go/blob/98b32a6c3a87fbee5d34c063b9096f416b250897/trace/trace.go#L523) | ||
|
||
```go | ||
func task(ctx context.Context) error { | ||
otel.Tracer().Start(ctx, "foo") // span is unassigned, probable memory leak | ||
_, span := otel.Tracer().Start(ctx, "foo") // span.End is not called on all paths, possible memory leak | ||
return nil // this return statement may be reached without calling span.End | ||
} | ||
``` | ||
|
||
### Forgetting to call `span.SetStatus(codes.Error, "msg")` | ||
|
||
Setting spans' status to `codes.Error` matters for a couple reasons. | ||
|
||
First, observability platforms and APMs differentiate "success" vs "failure" using [span's status codes](https://docs.datadoghq.com/tracing/metrics/). | ||
|
||
Second, telemetry collector agents, like the [Open Telemetry Collector](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/tailsamplingprocessor/README.md#:~:text=Sampling%20Processor.-,status_code,-%3A%20Sample%20based%20upon), are configurable to sample `Error` spans at a higher rate than `OK` spans. Similarly, observability platforms like DataDog support trace retention filters based on spans' status. In other words, `Error` spans often receive special treatment with the assumption they are more useful for debugging. | ||
|
||
```go | ||
func _() error { | ||
_, span := otel.Tracer("foo").Start(context.Background(), "bar") // span.SetStatus is not called on all paths | ||
defer span.End() | ||
|
||
if true { | ||
return errors.New("foo") // this return statement may be reached without calling span.SetStatus | ||
} | ||
|
||
return nil | ||
} | ||
``` |