Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Krakend OTEL #839

Merged
merged 25 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c235d72
add instrumented http client factory
dhontecillas Jan 20, 2024
4c22d8c
instrument pipe stage with krakend-otel
dhontecillas Jan 20, 2024
f5dafb1
add otel insturmentation at the router level
dhontecillas Jan 20, 2024
0733f08
fix error check and allow to override version when buildingdocker image
dhontecillas Jan 21, 2024
3647362
fix wrong err comparison
dhontecillas Jan 21, 2024
999e32d
update dependencies
dhontecillas Jan 22, 2024
66e44bc
update to global layer and new otel exporter config format
dhontecillas Jan 29, 2024
04dc9ab
update to most recen krakend-otel library draft
dhontecillas Feb 12, 2024
337a680
update krakend-otel lib
dhontecillas Feb 19, 2024
63bb6c9
update to latest krakend-otel
dhontecillas Feb 23, 2024
d2bf830
update to krakend otel with logger
dhontecillas Feb 27, 2024
e699ecc
fix otel global runserver position
dhontecillas Feb 27, 2024
aa01ad9
update to latest krakend-otel version
dhontecillas Feb 27, 2024
ce14f63
update to latest dev krakend-otel implementation
dhontecillas Mar 1, 2024
deaf509
fix deep source naming issue
dhontecillas Mar 1, 2024
ff57115
Merge branch 'dev-2.6' into krakend_otel
dhontecillas Mar 1, 2024
8c1e9b7
update to main branch of the otel library
dhontecillas Mar 5, 2024
8efe3ca
update to krakend-otel v0.1.0 and go mod tidy
dhontecillas Mar 5, 2024
d8034e5
use v0.2 of krakend-otel
dhontecillas Mar 5, 2024
5e0f271
move otel registration to MetricsAndTraces
dhontecillas Mar 5, 2024
441ebe5
update to use v0.2.0 of krakend-otel
dhontecillas Mar 6, 2024
802ea93
fix deep source issues
dhontecillas Mar 8, 2024
d2115e2
update to krakend-otel v0.2.0
dhontecillas Mar 11, 2024
54ff788
Merge pull request #854 from krakend/fix_move_otel_to_metrics_and_tra…
kpacha Mar 11, 2024
2b49cf1
remove non required interfaces
dhontecillas Mar 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

BIN_NAME :=krakend
OS := $(shell uname | tr '[:upper:]' '[:lower:]')
VERSION := 2.5.0
VERSION ?= 2.5.0
SCHEMA_VERSION := $(shell echo "${VERSION}" | cut -d '.' -f 1,2)
GIT_COMMIT := $(shell git rev-parse --short=7 HEAD)
PKGNAME := krakend
Expand Down
56 changes: 53 additions & 3 deletions backend_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package krakend

import (
"context"
"errors"
"fmt"

otelconfig "github.com/krakend/krakend-otel/config"
otellura "github.com/krakend/krakend-otel/lura"
otelstate "github.com/krakend/krakend-otel/state"
amqp "github.com/krakendio/krakend-amqp/v2"
cel "github.com/krakendio/krakend-cel/v2"
cb "github.com/krakendio/krakend-circuitbreaker/v2/gobreaker/proxy"
Expand Down Expand Up @@ -39,18 +43,28 @@ func NewBackendFactory(logger logging.Logger, metricCollector *metrics.Metrics)
return NewBackendFactoryWithContext(context.Background(), logger, metricCollector)
}

// NewBackendFactoryWithContext creates a BackendFactory by stacking all the available middlewares and injecting the received context
func NewBackendFactoryWithContext(ctx context.Context, logger logging.Logger, metricCollector *metrics.Metrics) proxy.BackendFactory {
func newRequestExecutorFactory(logger logging.Logger, otelCfg *otelconfig.Config) func(*config.Backend) client.HTTPRequestExecutor {
requestExecutorFactory := func(cfg *config.Backend) client.HTTPRequestExecutor {
clientFactory := client.NewHTTPClient
if _, ok := cfg.ExtraConfig[oauth2client.Namespace]; ok {
clientFactory = oauth2client.NewHTTPClient(cfg)
} else {
clientFactory = httpcache.NewHTTPClient(cfg, clientFactory)
}

if otelCfg != nil {
clientFactory = otellura.InstrumentedHTTPClientFactory(clientFactory,
cfg, otelCfg.Layers.Backend, otelCfg.SkipPaths, otelstate.GlobalState)
}
// TODO: check what happens if we have both, opencensus and otel enabled ?
return opencensus.HTTPRequestExecutorFromConfig(clientFactory, cfg)
}
requestExecutorFactory = httprequestexecutor.HTTPRequestExecutor(logger, requestExecutorFactory)
return httprequestexecutor.HTTPRequestExecutor(logger, requestExecutorFactory)
}

func newBackendFactory(ctx context.Context, requestExecutorFactory func(*config.Backend) client.HTTPRequestExecutor,
logger logging.Logger, metricCollector *metrics.Metrics, otelCfg *otelconfig.Config) proxy.BackendFactory {

backendFactory := martian.NewConfiguredBackendFactory(logger, requestExecutorFactory)
bf := pubsub.NewBackendFactory(ctx, logger, backendFactory)
backendFactory = bf.New
Expand All @@ -63,14 +77,50 @@ func NewBackendFactoryWithContext(ctx context.Context, logger logging.Logger, me
backendFactory = metricCollector.BackendFactory("backend", backendFactory)
backendFactory = opencensus.BackendFactory(backendFactory)

if otelCfg != nil {
// full backend processing instrumentation:
backendFactory = otellura.BackendFactory(backendFactory, otelstate.GlobalState, otelCfg.Layers.Backend,
otelCfg.SkipPaths)
}
return func(remote *config.Backend) proxy.Proxy {
logger.Debug(fmt.Sprintf("[BACKEND: %s] Building the backend pipe", remote.URLPattern))
return backendFactory(remote)
}
}

// NewBackendFactoryWithContext creates a BackendFactory by stacking all the available middlewares and injecting the received context
func NewBackendFactoryWithContext(ctx context.Context, logger logging.Logger, metricCollector *metrics.Metrics) proxy.BackendFactory {
requestExecutorFactory := newRequestExecutorFactory(logger, nil)
return newBackendFactory(ctx, requestExecutorFactory, logger, metricCollector, nil)
}

func newBackendFactoryWithOTELConfig(ctx context.Context, logger logging.Logger,
metricCollector *metrics.Metrics, otelCfg *otelconfig.Config) proxy.BackendFactory {

if otelCfg == nil {
return NewBackendFactoryWithContext(ctx, logger, metricCollector)
}

requestExecutorFactory := newRequestExecutorFactory(logger, otelCfg)
return newBackendFactory(ctx, requestExecutorFactory, logger, metricCollector, otelCfg)
}

type backendFactory struct{}

func (backendFactory) NewBackendFactory(ctx context.Context, l logging.Logger, m *metrics.Metrics) proxy.BackendFactory {
return NewBackendFactoryWithContext(ctx, l, m)
}

func (backendFactory) NewBackendFactoryWithConfig(ctx context.Context, l logging.Logger,
metrics *metrics.Metrics, serviceCfg *config.ServiceConfig) proxy.BackendFactory {

var otelCfg *otelconfig.Config
if serviceCfg != nil {
var err error
otelCfg, err = otelconfig.FromLura(*serviceCfg)
if err != nil && !errors.Is(err, otelconfig.ErrNoConfig) {
l.Error(fmt.Sprintf("cannot load OpenTelemetry config: %s", err.Error()))
}
}
return newBackendFactoryWithOTELConfig(ctx, l, metrics, otelCfg)
}
52 changes: 45 additions & 7 deletions executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import (
"github.com/go-contrib/uuid"
"golang.org/x/sync/errgroup"

kotel "github.com/krakend/krakend-otel"
otelconfig "github.com/krakend/krakend-otel/config"
otellura "github.com/krakend/krakend-otel/lura"
otelgin "github.com/krakend/krakend-otel/router/gin"
otelstate "github.com/krakend/krakend-otel/state"
krakendbf "github.com/krakendio/bloomfilter/v2/krakend"
asyncamqp "github.com/krakendio/krakend-amqp/v2/async"
audit "github.com/krakendio/krakend-audit"
Expand Down Expand Up @@ -87,11 +92,20 @@ type ProxyFactory interface {
NewProxyFactory(logging.Logger, proxy.BackendFactory, *metrics.Metrics) proxy.Factory
}

type ProxyFactoryWithConfig interface {
kpacha marked this conversation as resolved.
Show resolved Hide resolved
NewProxyFactoryWithConfig(logging.Logger, proxy.BackendFactory, *metrics.Metrics, *config.ServiceConfig) proxy.Factory
}

// BackendFactory returns a KrakenD backend factory, ready to be passed to the KrakenD proxy factory
type BackendFactory interface {
NewBackendFactory(context.Context, logging.Logger, *metrics.Metrics) proxy.BackendFactory
}

type BackendFactoryWithConfig interface {
kpacha marked this conversation as resolved.
Show resolved Hide resolved
NewBackendFactoryWithConfig(context.Context, logging.Logger,
*metrics.Metrics, *config.ServiceConfig) proxy.BackendFactory
}

// HandlerFactory returns a KrakenD router handler factory, ready to be passed to the KrakenD RouterFactory
type HandlerFactory interface {
NewHandlerFactory(logging.Logger, *metrics.Metrics, jose.RejecterFactory) router.HandlerFactory
Expand Down Expand Up @@ -153,6 +167,12 @@ func (e *ExecutorBuilder) NewCmdExecutor(ctx context.Context) cmd.Executor {
return
}

shutdownFn, err := kotel.Register(ctx, cfg)
if err != nil {
logger.Error(fmt.Sprintf("[SERVICE: OpenTelemetry] cannot register exporters: %s", err.Error()))
}
defer shutdownFn()

logger.Info(fmt.Sprintf("Starting KrakenD v%s", core.KrakendVersion))
startReporter(ctx, logger, cfg)

Expand Down Expand Up @@ -180,14 +200,32 @@ func (e *ExecutorBuilder) NewCmdExecutor(ctx context.Context) cmd.Executor {
logger.Warning("[SERVICE: Bloomfilter]", err.Error())
}

pf := e.ProxyFactory.NewProxyFactory(
logger,
e.BackendFactory.NewBackendFactory(ctx, logger, metricCollector),
metricCollector,
)
var bpf proxy.BackendFactory
if bfwc, ok := e.BackendFactory.(BackendFactoryWithConfig); ok {
bpf = bfwc.NewBackendFactoryWithConfig(ctx, logger, metricCollector, &cfg)
} else {
bpf = e.BackendFactory.NewBackendFactory(ctx, logger, metricCollector)
}

var pf proxy.Factory
if pfwc, ok := e.ProxyFactory.(ProxyFactoryWithConfig); ok {
pf = pfwc.NewProxyFactoryWithConfig(logger, bpf, metricCollector, &cfg)
} else {
pf = e.ProxyFactory.NewProxyFactory(logger, bpf, metricCollector)
}

agentPing := make(chan string, len(cfg.AsyncAgents))

handlerF := e.HandlerFactory.NewHandlerFactory(logger, metricCollector, tokenRejecterFactory)
otelCfg, err := otelconfig.FromLura(cfg)
if err == nil {
handlerF = otelgin.New(handlerF, otelstate.GlobalState, otelCfg.SkipPaths)
}

runServerChain := router.RunServerFunc(e.RunServerFactory.NewRunServer(logger, serverhttp.RunServerWithLoggerFactory(logger)))
if otelCfg != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dhontecillas ideally shouldn't the first handler have instrumentation? In this case cors middleware execution results won't be captured in the telemetry data right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep! I am going to fix it .. thanks

runServerChain = otellura.GlobalRunServer(logger, otelCfg, otelstate.GlobalState, runServerChain)
}
// setup the krakend router
routerFactory := router.NewFactory(router.Config{
Engine: e.EngineFactory.NewEngine(cfg, router.EngineOptions{
Expand All @@ -198,8 +236,8 @@ func (e *ExecutorBuilder) NewCmdExecutor(ctx context.Context) cmd.Executor {
ProxyFactory: pf,
Middlewares: e.Middlewares,
Logger: logger,
HandlerFactory: e.HandlerFactory.NewHandlerFactory(logger, metricCollector, tokenRejecterFactory),
RunServer: router.RunServerFunc(e.RunServerFactory.NewRunServer(logger, serverhttp.RunServerWithLoggerFactory(logger))),
HandlerFactory: handlerF,
RunServer: runServerChain,
})

// start the engines
Expand Down
71 changes: 45 additions & 26 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.20
require (
github.com/gin-gonic/gin v1.9.1
github.com/go-contrib/uuid v1.2.0
github.com/krakend/krakend-otel v0.0.0-20240212120929-eb8a41d628f3
github.com/krakendio/bloomfilter/v2 v2.0.4
github.com/krakendio/krakend-amqp/v2 v2.1.0
github.com/krakendio/krakend-audit v0.0.3
Expand Down Expand Up @@ -34,19 +35,19 @@ require (
github.com/krakendio/krakend-usage/v2 v2.0.0
github.com/krakendio/krakend-viper/v2 v2.0.1
github.com/krakendio/krakend-xml/v2 v2.1.0
github.com/luraproject/lura/v2 v2.4.0
github.com/luraproject/lura/v2 v2.4.3-0.20240111145738-b6784e5701d8
github.com/xeipuuv/gojsonschema v1.2.1-0.20200424115421-065759f9c3d7
golang.org/x/sync v0.1.0
golang.org/x/sync v0.4.0
)

require (
cloud.google.com/go/compute v1.19.1 // indirect
cloud.google.com/go/compute v1.23.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.13.0 // indirect
cloud.google.com/go/kms v1.10.1 // indirect
cloud.google.com/go/monitoring v1.13.0 // indirect
cloud.google.com/go/pubsub v1.30.0 // indirect
cloud.google.com/go/trace v1.9.0 // indirect
cloud.google.com/go/iam v1.1.2 // indirect
cloud.google.com/go/kms v1.15.2 // indirect
cloud.google.com/go/monitoring v1.16.0 // indirect
cloud.google.com/go/pubsub v1.33.0 // indirect
cloud.google.com/go/trace v1.10.1 // indirect
contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9 // indirect
contrib.go.opencensus.io/exporter/jaeger v0.2.1 // indirect
contrib.go.opencensus.io/exporter/ocagent v0.6.0 // indirect
Expand Down Expand Up @@ -94,6 +95,7 @@ require (
github.com/bytedance/sonic v1.9.1 // indirect
github.com/catalinc/hashcash v0.0.0-20161205220751-e6bc29ff4de9 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
Expand All @@ -108,6 +110,8 @@ require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
Expand All @@ -117,13 +121,14 @@ require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/cel-go v0.11.4 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/google/uuid v1.4.0 // indirect
github.com/google/wire v0.5.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.4 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.3.1 // indirect
Expand Down Expand Up @@ -166,7 +171,7 @@ require (
github.com/magiconair/properties v1.8.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
Expand All @@ -189,10 +194,10 @@ require (
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
github.com/pierrec/lz4/v4 v4.1.14 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/prometheus/client_golang v1.13.1 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
github.com/prometheus/prometheus v0.40.5 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rs/cors v1.8.2 // indirect
Expand Down Expand Up @@ -227,26 +232,40 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.22.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.45.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.45.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/prometheus v0.44.0 // indirect
go.opentelemetry.io/otel/metric v1.22.0 // indirect
go.opentelemetry.io/otel/sdk v1.22.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.22.0 // indirect
go.opentelemetry.io/otel/trace v1.22.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
gocloud.dev v0.28.0 // indirect
gocloud.dev/pubsub/kafkapubsub v0.25.0 // indirect
gocloud.dev/pubsub/natspubsub v0.25.0 // indirect
gocloud.dev/pubsub/rabbitpubsub v0.25.0 // indirect
gocloud.dev/secrets/hashivault v0.28.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.7.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.114.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/grpc v1.56.3 // indirect
google.golang.org/protobuf v1.30.0 // indirect
google.golang.org/api v0.128.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/grpc v1.60.1 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/DataDog/dd-trace-go.v1 v1.22.0 // indirect
gopkg.in/Graylog2/go-gelf.v2 v2.0.0-20191017102106-1550ee647df0 // indirect
gopkg.in/ini.v1 v1.66.6 // indirect
Expand Down
Loading