-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(fxtrace): Provided module (#28)
- Loading branch information
Showing
13 changed files
with
1,391 additions
and
0 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
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 |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: "fxtrace-ci" | ||
|
||
on: | ||
push: | ||
branches: | ||
- "feat**" | ||
- "fix**" | ||
- "hotfix**" | ||
- "chore**" | ||
paths: | ||
- "fxtrace/**.go" | ||
- "fxtrace/go.mod" | ||
- "fxtrace/go.sum" | ||
pull_request: | ||
types: | ||
- opened | ||
- synchronize | ||
- reopened | ||
branches: | ||
- main | ||
paths: | ||
- "fxtrace/**.go" | ||
- "fxtrace/go.mod" | ||
- "fxtrace/go.sum" | ||
|
||
jobs: | ||
ci: | ||
uses: ./.github/workflows/common-ci.yml | ||
secrets: inherit | ||
with: | ||
module: "fxtrace" |
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
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 |
---|---|---|
@@ -0,0 +1,64 @@ | ||
run: | ||
timeout: 5m | ||
concurrency: 8 | ||
|
||
linters: | ||
enable: | ||
- asasalint | ||
- asciicheck | ||
- bidichk | ||
- bodyclose | ||
- containedctx | ||
- contextcheck | ||
- decorder | ||
- dogsled | ||
- dupl | ||
- durationcheck | ||
- errcheck | ||
- errchkjson | ||
- errname | ||
- errorlint | ||
- forbidigo | ||
- forcetypeassert | ||
- gocognit | ||
- goconst | ||
- gocritic | ||
- gocyclo | ||
- godot | ||
- godox | ||
- gofmt | ||
- goheader | ||
- gomoddirectives | ||
- gomodguard | ||
- goprintffuncname | ||
- gosec | ||
- gosimple | ||
- govet | ||
- grouper | ||
- importas | ||
- ineffassign | ||
- interfacebloat | ||
- logrlint | ||
- maintidx | ||
- makezero | ||
- misspell | ||
- nestif | ||
- nilerr | ||
- nilnil | ||
- nlreturn | ||
- nolintlint | ||
- nosprintfhostport | ||
- prealloc | ||
- predeclared | ||
- promlinter | ||
- reassign | ||
- staticcheck | ||
- tenv | ||
- thelper | ||
- tparallel | ||
- typecheck | ||
- unconvert | ||
- unparam | ||
- unused | ||
- usestdlibvars | ||
- whitespace |
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 |
---|---|---|
@@ -0,0 +1,225 @@ | ||
# Fx Trace Module | ||
|
||
[![ci](https://github.com/ankorstore/yokai/actions/workflows/fxtrace-ci.yml/badge.svg)](https://github.com/ankorstore/yokai/actions/workflows/fxtrace-ci.yml) | ||
[![go report](https://goreportcard.com/badge/github.com/ankorstore/yokai/fxtrace)](https://goreportcard.com/report/github.com/ankorstore/yokai/fxtrace) | ||
[![codecov](https://codecov.io/gh/ankorstore/yokai/graph/badge.svg?token=ghUBlFsjhR&flag=fxtrace)](https://app.codecov.io/gh/ankorstore/yokai/tree/main/fxtrace) | ||
[![Deps](https://img.shields.io/badge/osi-deps-blue)](https://deps.dev/go/github.com%2Fankorstore%2Fyokai%2Ffxtrace) | ||
[![PkgGoDev](https://pkg.go.dev/badge/github.com/ankorstore/yokai/fxtrace)](https://pkg.go.dev/github.com/ankorstore/yokai/fxtrace) | ||
|
||
> [Fx](https://uber-go.github.io/fx/) module for [trace](https://github.com/ankorstore/yokai/tree/main/trace). | ||
<!-- TOC --> | ||
* [Installation](#installation) | ||
* [Documentation](#documentation) | ||
* [Dependencies](#dependencies) | ||
* [Loading](#loading) | ||
* [Configuration](#configuration) | ||
* [Override](#override) | ||
* [Testing](#testing) | ||
<!-- TOC --> | ||
|
||
## Installation | ||
|
||
```shell | ||
go get github.com/ankorstore/yokai/fxtrace | ||
``` | ||
|
||
## Documentation | ||
|
||
### Dependencies | ||
|
||
This module is intended to be used alongside the [fxconfig](https://github.com/ankorstore/yokai/tree/main/fxconfig) | ||
module. | ||
|
||
### Loading | ||
|
||
To load the module in your Fx application: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/ankorstore/yokai/config" | ||
"github.com/ankorstore/yokai/fxconfig" | ||
"github.com/ankorstore/yokai/fxtrace" | ||
oteltrace "go.opentelemetry.io/otel/trace" | ||
"go.uber.org/fx" | ||
) | ||
|
||
func main() { | ||
fx.New( | ||
fxconfig.FxConfigModule, // load the module dependency | ||
fxtrace.FxTraceModule, // load the module | ||
fx.Invoke(func(tracerProvider oteltrace.TracerProvider) { | ||
// invoke the tracer provider to create a span | ||
_, span := tracerProvider.Tracer("some tracer").Start(context.Background(), "some span") | ||
defer span.End() | ||
}), | ||
).Run() | ||
} | ||
``` | ||
|
||
### Configuration | ||
|
||
This module provides the possibility to configure the `processor`: | ||
|
||
- `noop`: to async void traces (default and fallback) | ||
- `stdout`: to async print traces to stdout | ||
- `otlp-grpc`: to async send traces to [OTLP/gRPC](https://opentelemetry.io/docs/specs/otlp/#otlpgrpc) collectors (ex: [Jaeger](https://www.jaegertracing.io/), [Grafana](https://grafana.com/docs/tempo/latest/configuration/grafana-agent/#grafana-agent), etc.) | ||
- `test`: to sync store traces in memory (for testing assertions) | ||
|
||
If an error occurs while creating the processor (for example failing OTLP/gRPC connection), the `noop` processor will be | ||
used as safety fallback (to prevent outages). | ||
|
||
This module also provides possibility to configure the `sampler`: | ||
|
||
- `parent-based-always-on`: always on depending on parent (default) | ||
- `parent-based-always-off`: always off depending on parent | ||
- `parent-based-trace-id-ratio`: trace id ratio based depending on parent | ||
- `always-on`: always on | ||
- `always-off`: always off | ||
- `trace-id-ratio`: trace id ratio based | ||
|
||
Example with `stdout` processor (with pretty print) and `parent-based-trace-id-ratio` sampler (ratio=0.5): | ||
|
||
```yaml | ||
# ./configs/config.yaml | ||
app: | ||
name: app | ||
env: dev | ||
version: 0.1.0 | ||
debug: false | ||
modules: | ||
trace: | ||
processor: | ||
type: stdout | ||
options: | ||
pretty: true | ||
sampler: | ||
type: parent-based-trace-id-ratio | ||
options: | ||
ratio: 0.5 | ||
``` | ||
|
||
Another example with `otlp-grpc` processor (on jaeger:4317 host) and `always-on` sampler: | ||
|
||
```yaml | ||
# ./configs/config.yaml | ||
app: | ||
name: app | ||
env: dev | ||
version: 0.1.0 | ||
debug: false | ||
modules: | ||
trace: | ||
processor: | ||
type: otlp-grpc | ||
options: | ||
host: jaeger:4317 | ||
sampler: | ||
type: always-on | ||
``` | ||
|
||
### Override | ||
|
||
By default, the `oteltrace.TracerProvider` is created by the [DefaultTracerProviderFactory](https://github.com/ankorstore/yokai/blob/main/trace/factory.go). | ||
|
||
If needed, you can provide your own factory and override the module: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/ankorstore/yokai/fxconfig" | ||
"github.com/ankorstore/yokai/fxtrace" | ||
"github.com/ankorstore/yokai/trace" | ||
otelsdktrace "go.opentelemetry.io/otel/sdk/trace" | ||
oteltrace "go.opentelemetry.io/otel/trace" | ||
"go.uber.org/fx" | ||
) | ||
|
||
type CustomTracerProviderFactory struct{} | ||
|
||
func NewCustomTracerProviderFactory() trace.TracerProviderFactory { | ||
return &CustomTracerProviderFactory{} | ||
} | ||
|
||
func (f *CustomTracerProviderFactory) Create(options ...trace.TracerProviderOption) (*otelsdktrace.TracerProvider, error) { | ||
return &otelsdktrace.TracerProvider{...}, nil | ||
} | ||
|
||
func main() { | ||
fx.New( | ||
fxconfig.FxConfigModule, // load the module dependency | ||
fxtrace.FxTraceModule, // load the module | ||
fx.Decorate(NewCustomTracerProviderFactory), // override the module with a custom factory | ||
fx.Invoke(func(tracerProvider oteltrace.TracerProvider) { // invoke the custom tracer provider | ||
_, span := tracerProvider.Tracer("custom tracer").Start(context.Background(), "custom span") | ||
defer span.End() | ||
}), | ||
).Run() | ||
} | ||
``` | ||
|
||
### Testing | ||
|
||
This module provides the possibility to easily test your trace spans, using the [TestTraceExporter](https://github.com/ankorstore/yokai/blob/main/trace/tracetest/exporter.go) with `modules.trace.processor.type=test`. | ||
|
||
```yaml | ||
# ./configs/config.test.yaml | ||
modules: | ||
trace: | ||
processor: | ||
type: test # to send traces to test buffer | ||
``` | ||
|
||
You can then test: | ||
|
||
```go | ||
package main_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/ankorstore/yokai/fxconfig" | ||
"github.com/ankorstore/yokai/fxtrace" | ||
"github.com/ankorstore/yokai/trace/tracetest" | ||
"go.opentelemetry.io/otel/attribute" | ||
oteltrace "go.opentelemetry.io/otel/trace" | ||
"go.uber.org/fx" | ||
"go.uber.org/fx/fxtest" | ||
) | ||
|
||
func TestTracerProvider(t *testing.T) { | ||
t.Setenv("APP_NAME", "test") | ||
t.Setenv("APP_ENV", "test") | ||
|
||
var exporter tracetest.TestTraceExporter | ||
|
||
fxtest.New( | ||
t, | ||
fx.NopLogger, | ||
fxconfig.FxConfigModule, | ||
fxtrace.FxTraceModule, | ||
fx.Invoke(func(tracerProvider oteltrace.TracerProvider) { | ||
_, span := tracerProvider.Tracer("some tracer").Start( | ||
context.Background(), | ||
"some span", | ||
oteltrace.WithAttributes(attribute.String("some attribute name", "some attribute value")), | ||
) | ||
defer span.End() | ||
}), | ||
fx.Populate(&exporter), // extracts the TestTraceExporter from the Fx container | ||
).RequireStart().RequireStop() | ||
|
||
// assertion success | ||
tracetest.AssertHasTraceSpan(t, exporter, "some span", attribute.String("some attribute name", "some attribute value")) | ||
} | ||
``` | ||
|
||
See the `trace` module testing [documentation](https://github.com/ankorstore/yokai/tree/main/trace#test-span-processor) for more details. |
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 |
---|---|---|
@@ -0,0 +1,57 @@ | ||
module github.com/ankorstore/yokai/fxtrace | ||
|
||
go 1.20 | ||
|
||
require ( | ||
github.com/ankorstore/yokai/config v1.1.0 | ||
github.com/ankorstore/yokai/fxconfig v1.0.0 | ||
github.com/ankorstore/yokai/trace v1.0.0 | ||
github.com/stretchr/testify v1.8.4 | ||
go.opentelemetry.io/otel v1.16.0 | ||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.16.0 | ||
go.opentelemetry.io/otel/sdk v1.16.0 | ||
go.opentelemetry.io/otel/trace v1.16.0 | ||
go.uber.org/fx v1.20.1 | ||
) | ||
|
||
require ( | ||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect | ||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect | ||
github.com/fsnotify/fsnotify v1.7.0 // indirect | ||
github.com/go-logr/logr v1.2.4 // indirect | ||
github.com/go-logr/stdr v1.2.2 // indirect | ||
github.com/golang/protobuf v1.5.3 // indirect | ||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect | ||
github.com/hashicorp/hcl v1.0.0 // indirect | ||
github.com/magiconair/properties v1.8.7 // indirect | ||
github.com/mitchellh/mapstructure v1.5.0 // indirect | ||
github.com/pelletier/go-toml/v2 v2.1.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect | ||
github.com/sagikazarmark/locafero v0.4.0 // indirect | ||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect | ||
github.com/sourcegraph/conc v0.3.0 // indirect | ||
github.com/spf13/afero v1.11.0 // indirect | ||
github.com/spf13/cast v1.6.0 // indirect | ||
github.com/spf13/pflag v1.0.5 // indirect | ||
github.com/spf13/viper v1.18.2 // indirect | ||
github.com/subosito/gotenv v1.6.0 // indirect | ||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect | ||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect | ||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 // indirect | ||
go.opentelemetry.io/otel/metric v1.16.0 // indirect | ||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect | ||
go.uber.org/dig v1.17.1 // indirect | ||
go.uber.org/multierr v1.11.0 // indirect | ||
go.uber.org/zap v1.26.0 // indirect | ||
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e // indirect | ||
golang.org/x/net v0.19.0 // indirect | ||
golang.org/x/sys v0.16.0 // indirect | ||
golang.org/x/text v0.14.0 // indirect | ||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect | ||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect | ||
google.golang.org/grpc v1.59.0 // indirect | ||
google.golang.org/protobuf v1.31.0 // indirect | ||
gopkg.in/ini.v1 v1.67.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
Oops, something went wrong.