Skip to content

Commit

Permalink
instrospection: bump to opentelemetry 0.16.0
Browse files Browse the repository at this point in the history
Signed-off-by: ldelossa <ldelossa@redhat.com>
  • Loading branch information
ldelossa authored and ldelossa committed Jan 27, 2021
1 parent 8e39fa4 commit b78f954
Show file tree
Hide file tree
Showing 9 changed files with 528 additions and 262 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:

strategy:
matrix:
go: ['1.13', '1.14', '1.15']
go: ['1.14', '1.15']
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down
24 changes: 14 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,35 @@ module github.com/quay/clair/v4
go 1.13

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/docker/docker v1.13.1 // indirect
github.com/go-stomp/stomp v2.0.6+incompatible
github.com/golang/mock v1.4.4 // indirect
github.com/google/go-cmp v0.4.0
github.com/google/go-cmp v0.5.4
github.com/google/go-containerregistry v0.0.0-20191206185556-eb7c14b719c6
github.com/google/uuid v1.1.2
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
github.com/jackc/pgx/v4 v4.7.2
github.com/jmoiron/sqlx v1.2.0
github.com/klauspost/compress v1.10.11
github.com/mattn/go-sqlite3 v1.11.0 // indirect
github.com/prometheus/client_golang v0.9.4 // indirect
github.com/prometheus/procfs v0.0.8 // indirect
github.com/prometheus/procfs v0.3.0 // indirect
github.com/quay/claircore v0.1.20
github.com/remind101/migrate v0.0.0-20170729031349-52c1edff7319
github.com/rs/zerolog v1.16.0
github.com/streadway/amqp v1.0.0
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
github.com/urfave/cli/v2 v2.2.0
go.opentelemetry.io/otel v0.2.1
go.opentelemetry.io/otel/exporter/metric/prometheus v0.2.2-0.20200111012159-d85178b63b15
go.opentelemetry.io/otel/exporter/trace/jaeger v0.2.1
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
golang.org/x/tools v0.0.0-20200928182047-19e03678916f // indirect
go.opentelemetry.io/contrib/exporters/metric/dogstatsd v0.16.0
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.16.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.16.0
go.opentelemetry.io/otel v0.16.0
go.opentelemetry.io/otel/exporters/metric/prometheus v0.16.0
go.opentelemetry.io/otel/exporters/stdout v0.16.0
go.opentelemetry.io/otel/exporters/trace/jaeger v0.16.0
go.opentelemetry.io/otel/sdk v0.16.0
golang.org/x/mod v0.4.0 // indirect
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
golang.org/x/sys v0.0.0-20210122093101-04d7465088b8 // indirect
golang.org/x/tools v0.0.0-20210112235408-75fd75db8797 // indirect
gopkg.in/square/go-jose.v2 v2.4.1
gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86
)
610 changes: 445 additions & 165 deletions go.sum

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions httptransport/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"net/http"

"github.com/rs/zerolog"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/plugin/othttp"
othttp "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel"

clairerror "github.com/quay/clair/v4/clair-error"
"github.com/quay/clair/v4/config"
Expand Down Expand Up @@ -71,7 +71,7 @@ func New(ctx context.Context, conf config.Config, indexer indexer.Service, match
indexer: indexer,
matcher: matcher,
notifier: notifier,
traceOpt: othttp.WithTracer(global.TraceProvider().Tracer("clair")),
traceOpt: othttp.WithTracerProvider(otel.GetTracerProvider()),
}

if err := t.configureDiscovery(ctx); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions httptransport/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
"github.com/quay/claircore"
"github.com/quay/claircore/libvuln/driver"
"github.com/quay/claircore/test/log"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/plugin/othttp"
othttp "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel"
)

type testMatcher struct {
Expand Down Expand Up @@ -61,7 +61,7 @@ func TestUpdateEndpoints(t *testing.T) {
matcher: m,
indexer: i,
ServeMux: http.NewServeMux(),
traceOpt: othttp.WithTracer(global.TraceProvider().Tracer("clair")),
traceOpt: othttp.WithTracerProvider(otel.GetTracerProvider()),
}
ctx, done := log.TestLogger(context.Background(), t)
defer done()
Expand Down
2 changes: 1 addition & 1 deletion httptransport/vulnerabilityreporthandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

"github.com/quay/claircore"
je "github.com/quay/claircore/pkg/jsonerr"
oteltrace "go.opentelemetry.io/otel/plugin/httptrace"
oteltrace "go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace"

"github.com/quay/clair/v4/indexer"
"github.com/quay/clair/v4/matcher"
Expand Down
69 changes: 29 additions & 40 deletions introspection/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import (
"net/http/pprof"

"github.com/rs/zerolog"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/key"
"go.opentelemetry.io/otel/exporter/metric/dogstatsd"
"go.opentelemetry.io/otel/exporter/metric/prometheus"
"go.opentelemetry.io/otel/exporter/trace/jaeger"
"go.opentelemetry.io/otel/exporter/trace/stdout"
"go.opentelemetry.io/contrib/exporters/metric/dogstatsd"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/metric/prometheus"
"go.opentelemetry.io/otel/exporters/stdout"
"go.opentelemetry.io/otel/exporters/trace/jaeger"
"go.opentelemetry.io/otel/label"
sdktrace "go.opentelemetry.io/otel/sdk/trace"

"github.com/quay/clair/v4/config"
Expand Down Expand Up @@ -95,7 +95,9 @@ func New(ctx context.Context, conf config.Config, health func() bool) (*Server,
sampler = sdktrace.AlwaysSample()
case i.conf.Trace.Probability != nil:
p := *i.conf.Trace.Probability
sampler = sdktrace.ProbabilitySampler(p)
sampler = sdktrace.ParentBased(
sdktrace.TraceIDRatioBased(p),
)
default:
sampler = sdktrace.NeverSample()
}
Expand All @@ -104,7 +106,7 @@ func New(ctx context.Context, conf config.Config, health func() bool) (*Server,
traceCfg := sdktrace.Config{
DefaultSampler: sampler,
}
traceOpts := []sdktrace.ProviderOption{
traceOpts := []sdktrace.TracerProviderOption{
sdktrace.WithConfig(traceCfg),
}
switch conf.Trace.Name {
Expand Down Expand Up @@ -155,22 +157,19 @@ func (i *Server) withDiagnostics(_ context.Context) error {
}

// withStdOut configures the stdout exporter for distributed tracing
func (i *Server) withStdOut(_ context.Context, traceOpts []sdktrace.ProviderOption) error {
exporter, err := stdout.NewExporter(stdout.Options{})
func (i *Server) withStdOut(_ context.Context, traceOpts []sdktrace.TracerProviderOption) error {
exporter, err := stdout.NewExporter()
if err != nil {
return err
}
traceOpts = append(traceOpts, sdktrace.WithSyncer(exporter))
tp, err := sdktrace.NewProvider(traceOpts...)
if err != nil {
return err
}
global.SetTraceProvider(tp)
tp := sdktrace.NewTracerProvider(traceOpts...)
otel.SetTracerProvider(tp)
return nil
}

// withJaeger configures the Jaeger exporter for distributed tracing.
func (i *Server) withJaeger(ctx context.Context, traceOpts []sdktrace.ProviderOption) error {
func (i *Server) withJaeger(ctx context.Context, traceOpts []sdktrace.TracerProviderOption) error {
logger := zerolog.Ctx(ctx).With().
Str("component", "introspection/Introspection.withJaeger").
Logger()
Expand Down Expand Up @@ -211,14 +210,7 @@ func (i *Server) withJaeger(ctx context.Context, traceOpts []sdktrace.ProviderOp
}

// configure the exporter
component := fmt.Sprintf("jaeger-exporter:%v", endpoint)
// jaegerLog := log.With().Str("component", component).Logger()
jaegerLog := zerolog.Ctx(ctx).With().Str("component", component).Logger()
opts := []jaeger.Option{
jaeger.WithOnError(func(err error) {
jaegerLog.Error().Err(err).Msg("jaeger-exporter error")
}),
}
opts := []jaeger.Option{}
if conf.BufferMax != 0 {
opts = append(opts, jaeger.WithBufferMaxCount(conf.BufferMax))
}
Expand All @@ -227,23 +219,23 @@ func (i *Server) withJaeger(ctx context.Context, traceOpts []sdktrace.ProviderOp
}
if len(conf.Tags) != 0 {
for k, v := range conf.Tags {
p.Tags = append(p.Tags, key.String(k, v))
p.Tags = append(p.Tags, label.String(k, v))
}
}
opts = append(opts, jaeger.WithProcess(p))
exporter, err := jaeger.NewExporter(e, opts...)
exporter, err := jaeger.NewRawExporter(e, opts...)
if err != nil {
return err
}
traceOpts = append(traceOpts, sdktrace.WithSyncer(exporter))

i.RegisterOnShutdown(exporter.Flush)

tp, err := sdktrace.NewProvider(traceOpts...)
tp := sdktrace.NewTracerProvider(traceOpts...)
if err != nil {
return err
}
global.SetTraceProvider(tp)
otel.SetTracerProvider(tp)
return nil
}

Expand All @@ -267,7 +259,10 @@ func (i *Server) withDogStatsD(ctx context.Context) error {
if err != nil {
return fmt.Errorf("failed to create dogstatsd pipeline: %v", err)
}
i.RegisterOnShutdown(pipeline.Stop)
i.RegisterOnShutdown(
func() {
pipeline.Stop(ctx)
})
return nil
}

Expand All @@ -287,20 +282,14 @@ func (i *Server) withPrometheus(ctx context.Context) error {
Str("server", i.Addr).
Msg("configuring prometheus")

promlog := zerolog.Ctx(ctx).With().
Str("component", "prometheus-metrics-exporter").
Logger()

pipeline, hr, err := prometheus.InstallNewPipeline(prometheus.Config{
OnError: func(err error) {
promlog.Error().Err(err).Msg("prometheus error")
},
})
pipeline, err := prometheus.InstallNewPipeline(prometheus.Config{})
if err != nil {
return err
}

i.RegisterOnShutdown(pipeline.Stop)
i.HandleFunc(endpoint, hr)
i.RegisterOnShutdown(func() {
pipeline.Controller().Stop(ctx)
})
i.HandleFunc(endpoint, pipeline.ServeHTTP)
return nil
}
40 changes: 15 additions & 25 deletions middleware/introspection/latency.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,11 @@ import (
"net/http"
"time"

"go.opentelemetry.io/otel/api/core"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/key"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/api/unit"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/metric"
)

// pathKey is the label for the http path a latency
// metric pertains to.
var pathKey = key.New("http.path")

// methodKey is the label accompanying pathKey and
// provides the http method of the requested path
var methodKey = key.New("http.method")

// Handler wraps the provided http.Handler and provides
// latency recordings per incoming http path using the
// open telemetry library
Expand All @@ -28,18 +18,18 @@ var methodKey = key.New("http.method")
// For example a resulting prometheus latency metric will take the form
// "clair_http_latence{http_path={path}, http.method={method}}"
func Handler(next http.Handler, path string) http.Handler {
meter := global.MeterProvider().Meter("clair")
late := meter.NewInt64Measure("clair.http.latency",
metric.WithDescription("latency of http requests"),
metric.WithUnit(unit.Milliseconds),
metric.WithAbsolute(true),
metric.WithKeys(pathKey),
metric.WithKeys(methodKey),
meter := otel.Meter("clair")
latency := metric.Must(meter).NewInt64UpDownCounter(
// for some reason, the namespace of "clair" is not applied
// to the metric when it lands in prometheus, so add it to the name anyway
// same goes with the WithUnit option.
"clair_http_latency_ms",
metric.WithDescription("latency of http request"),
)
h := &handler{
meter: meter,
latency: late,
pathKV: pathKey.String(path),
latency: latency,
pathKV: label.String("http_path", path),
next: next,
}

Expand All @@ -51,9 +41,9 @@ type handler struct {
// an instance to the ot metrics provider
meter metric.Meter
// the metric we will instrument http latency with
latency metric.Int64Measure
latency metric.Int64UpDownCounter
// an ot KV which represents the handler path this middleware is wrapping
pathKV core.KeyValue
pathKV label.KeyValue
// the next handler to call in the chain
next http.Handler
}
Expand All @@ -62,5 +52,5 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
start := time.Now()
h.next.ServeHTTP(w, r)
h.latency.Record(ctx, time.Now().Sub(start).Milliseconds(), h.meter.Labels(h.pathKV, methodKV(r)))
h.latency.Add(ctx, int64(time.Now().Sub(start).Milliseconds()), h.pathKV, methodKV(r))
}
31 changes: 17 additions & 14 deletions middleware/introspection/methodkv.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,33 @@ package introspection
import (
"net/http"

"go.opentelemetry.io/otel/api/core"
"go.opentelemetry.io/otel/api/key"
"go.opentelemetry.io/otel/label"
)

var methods = map[string]core.KeyValue{
http.MethodConnect: key.New("http.method").String(http.MethodConnect),
http.MethodDelete: key.New("http.method").String(http.MethodDelete),
http.MethodGet: key.New("http.method").String(http.MethodGet),
http.MethodHead: key.New("http.method").String(http.MethodHead),
http.MethodOptions: key.New("http.method").String(http.MethodOptions),
http.MethodPatch: key.New("http.method").String(http.MethodPatch),
http.MethodPost: key.New("http.method").String(http.MethodPost),
http.MethodPut: key.New("http.method").String(http.MethodPut),
http.MethodTrace: key.New("http.method").String(http.MethodTrace),
// methodKey is the label accompanying pathKey and
// provides the http method of the requested path
var methodKey = label.Key("http.method")

var methods = map[string]label.KeyValue{
http.MethodConnect: methodKey.String(http.MethodDelete),
http.MethodDelete: methodKey.String(http.MethodDelete),
http.MethodGet: methodKey.String(http.MethodGet),
http.MethodHead: methodKey.String(http.MethodHead),
http.MethodOptions: methodKey.String(http.MethodOptions),
http.MethodPatch: methodKey.String(http.MethodPatch),
http.MethodPost: methodKey.String(http.MethodPost),
http.MethodPut: methodKey.String(http.MethodPut),
http.MethodTrace: methodKey.String(http.MethodTrace),
}

// methodKV provides an O(1) function for creating
// a core.KeyValue representing the http method.
//
// in best case no construction of a KeyValue will
// be necessary
func methodKV(r *http.Request) core.KeyValue {
func methodKV(r *http.Request) label.KeyValue {
if kv, ok := methods[r.Method]; ok {
return kv
}
return key.New("http.method").String(r.Method)
return label.String("http.method", r.Method)
}

0 comments on commit b78f954

Please sign in to comment.