Metrics POC: github.com/NdoleStudio/go-otelroundtripper

Proof of concept implementation for collecting metrics
with go-otelroundtripper.

Pros:
- hooks into http clients for centralized tracing.
- otel compliance for easy consumption
- in-memory
- Could be stored in streamstore snapshot.

Cons:
- not human consumable, requries post-processing.
- without storage, consumption/usage is difficult.
This commit is contained in:
ryanfkeepers 2023-03-20 12:23:34 -06:00
parent fa2cf046bb
commit b7ebf40e08
4 changed files with 62 additions and 6 deletions

View File

@ -2,12 +2,17 @@ package cli
import (
"context"
"encoding/json"
"fmt"
"os"
"regexp"
"strings"
"time"
"github.com/spf13/cobra"
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
"go.opentelemetry.io/otel/metric/global"
"go.opentelemetry.io/otel/sdk/metric"
"golang.org/x/exp/slices"
"github.com/alcionai/corso/src/cli/backup"
@ -152,6 +157,29 @@ func Handle() {
ctx, cancel := context.WithDeadline(context.Background(), tenDays)
defer cancel()
// ----------------------------------------------------------
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
exporter, err := stdoutmetric.New(stdoutmetric.WithEncoder(enc))
if err != nil {
fmt.Printf("creating stdoutmetric exporter: %v\n", err)
} else {
// Register the exporter with an SDK via a periodic reader.
sdk := metric.NewMeterProvider(metric.WithReader(metric.NewPeriodicReader(exporter)))
global.SetMeterProvider(sdk)
defer func() {
if err := sdk.Shutdown(ctx); err != nil {
fmt.Printf("stopping sdk: %v\n", err)
}
}()
}
// ----------------------------------------------------------
ctx = config.Seed(ctx)
ctx = print.SetRootCmd(ctx, corsoCmd)
observe.SeedWriter(ctx, print.StderrWriter(ctx), observe.PreloadFlags())
@ -159,6 +187,7 @@ func Handle() {
BuildCommandTree(corsoCmd)
loglevel, logfile := logger.PreloadLoggingFlags()
ctx, log := logger.Seed(ctx, loglevel, logfile)
defer func() {

View File

@ -4,6 +4,7 @@ go 1.19
require (
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.0
github.com/NdoleStudio/go-otelroundtripper v0.0.6
github.com/alcionai/clues v0.0.0-20230314154528-c469e1adafb6
github.com/aws/aws-sdk-go v1.44.220
github.com/aws/aws-xray-sdk-go v1.8.1
@ -28,6 +29,9 @@ require (
github.com/tidwall/pretty v1.2.1
github.com/tomlazar/table v0.1.2
github.com/vbauerster/mpb/v8 v8.1.6
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.34.0
go.opentelemetry.io/otel/metric v0.34.0
go.opentelemetry.io/otel/sdk/metric v0.34.0
go.uber.org/zap v1.24.0
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
golang.org/x/tools v0.7.0
@ -50,6 +54,7 @@ require (
github.com/subosito/gotenv v1.4.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.34.0 // indirect
go.opentelemetry.io/otel/sdk v1.11.2 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)
@ -107,8 +112,8 @@ require (
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.opentelemetry.io/otel v1.11.2 // indirect
go.opentelemetry.io/otel/trace v1.11.2 // indirect
go.opentelemetry.io/otel v1.14.0
go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.5.0 // indirect

View File

@ -48,6 +48,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM=
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 h1:KeNholpO2xKjgaaSyd+DyQRrsQjhbSeS7qe4nEw8aQw=
github.com/NdoleStudio/go-otelroundtripper v0.0.6 h1:y9nUERqMQI34tfLE59sH/dEAEcEgjKu35fr9Wnbp3uY=
github.com/NdoleStudio/go-otelroundtripper v0.0.6/go.mod h1:gOnZQu6fktDW7PNvWX184+Gbgi0IRDZXVYdLkBwT7Zw=
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
@ -431,10 +433,18 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0=
go.opentelemetry.io/otel v1.11.2/go.mod h1:7p4EUV+AqgdlNV9gL97IgUZiVR3yrFXYo53f9BM3tRI=
go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0=
go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA=
go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.34.0 h1:O1E9/qhspQSz3O6/dSGLNBND2TO9mUaSvlhcKJMv278=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.34.0/go.mod h1:Id0oYi2ARij/um3gFV+t5rH1MTFdJpfTimsFsqKS7pE=
go.opentelemetry.io/otel/metric v0.34.0 h1:MCPoQxcg/26EuuJwpYN1mZTeCYAUGx8ABxfW07YkjP8=
go.opentelemetry.io/otel/metric v0.34.0/go.mod h1:ZFuI4yQGNCupurTXCwkeD/zHBt+C2bR7bw5JqUm/AP8=
go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNXUiU=
go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU=
go.opentelemetry.io/otel/sdk/metric v0.34.0 h1:7ElxfQpXCFZlRTvVRTkcUvK8Gt5DC8QzmzsLsO2gdzo=
go.opentelemetry.io/otel/sdk/metric v0.34.0/go.mod h1:l4r16BIqiqPy5rd14kkxllPy/fOI4tWo1jkpD9Z3ffQ=
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=

View File

@ -10,6 +10,7 @@ import (
"time"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
otelrt "github.com/NdoleStudio/go-otelroundtripper"
backoff "github.com/cenkalti/backoff/v4"
"github.com/microsoft/kiota-abstractions-go/serialization"
ka "github.com/microsoft/kiota-authentication-azure-go"
@ -17,6 +18,8 @@ import (
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
msgraphgocore "github.com/microsoftgraph/msgraph-sdk-go-core"
"github.com/pkg/errors"
"go.opentelemetry.io/otel/metric/global"
semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/pkg/account"
@ -202,6 +205,15 @@ func HTTPClient(opts ...option) *http.Client {
httpClient := msgraphgocore.GetDefaultClient(&clientOptions, middlewares...)
httpClient.Timeout = defaultHTTPClientTimeout
parentTripper := httpClient.Transport
meter := global.MeterProvider().Meter("corso")
httpClient.Transport = otelrt.New(
otelrt.WithParent(parentTripper),
otelrt.WithMeter(meter),
otelrt.WithAttributes(semconv.ServiceNameKey.String("corso")),
)
clientconfig.apply(httpClient)
return httpClient