diff --git a/README.md b/README.md index 7b0cb176e3..a788117b2d 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,7 @@ Internal k8gb architecture and its components are described [here](/docs/compone * [Local playground for testing and development](/docs/local.md) * [Local playground with Kuar web app](/docs/local-kuar.md) * [Metrics](/docs/metrics.md) +* [Traces](/docs/traces.md) * [Ingress annotations](/docs/ingress_annotations.md) * [Integration with Admiralty](/docs/admiralty.md) * [Integration with Liqo](/docs/liqo.md) diff --git a/chart/k8gb/templates/NOTES.txt b/chart/k8gb/templates/NOTES.txt index d3e27bf358..3a529a0913 100644 --- a/chart/k8gb/templates/NOTES.txt +++ b/chart/k8gb/templates/NOTES.txt @@ -6,6 +6,16 @@ done |_|\_\___/ \__, |_.__/ & all dependencies are installed |___/ +{{- if and .Values.tracing.enabled .Values.tracing.deployJaeger }} + + +To check the OpenTelemetry (tracing) data: +------------------------------------------ +kubectl port-forward svc/jaeger-collector -n k8gb 16686 +open http://localhost:16686 + +{{- end }} + 1. Check if your DNS Zone is served by K8GB CoreDNS $ kubectl -n {{ .Release.Namespace }} run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools --command -- /usr/bin/dig @{{ .Release.Name }}-coredns SOA . +short diff --git a/chart/k8gb/templates/infoblox-cm.yaml b/chart/k8gb/templates/infoblox-cm.yaml index 2436bd672d..4627d0c593 100644 --- a/chart/k8gb/templates/infoblox-cm.yaml +++ b/chart/k8gb/templates/infoblox-cm.yaml @@ -9,4 +9,6 @@ data: kind: ConfigMap metadata: name: infoblox + labels: +{{ include "chart.labels" . | indent 4 }} {{- end }} diff --git a/chart/k8gb/templates/operator.yaml b/chart/k8gb/templates/operator.yaml index 81d5460c1b..af8c77b1d4 100644 --- a/chart/k8gb/templates/operator.yaml +++ b/chart/k8gb/templates/operator.yaml @@ -14,6 +14,8 @@ spec: metadata: labels: name: k8gb + annotations: + kubectl.kubernetes.io/default-container: k8gb spec: serviceAccountName: k8gb containers: @@ -103,6 +105,18 @@ spec: - name: COREDNS_EXPOSED value: "true" {{- end }} + {{- if .Values.tracing.enabled }} + {{- with .Values.tracing }} + - name: TRACING_ENABLED + value: {{ .enabled | quote }} + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: {{ .endpoint | quote }} + {{- with .samplingRatio }} + - name: TRACING_SAMPLING_RATIO + value: {{ . | quote }} + {{- end }} + {{- end }} + {{- end }} - name: LOG_FORMAT value: {{ quote .Values.k8gb.log.format }} - name: LOG_LEVEL @@ -113,3 +127,20 @@ spec: value: {{ quote .Values.k8gb.splitBrainCheck }} - name: METRICS_ADDRESS value: {{ .Values.k8gb.metricsAddress }} + {{- if .Values.tracing.enabled }} + - image: {{ .Values.tracing.sidecarImage.repository }}:{{ .Values.tracing.sidecarImage.tag }} + name: otel-collector + imagePullPolicy: {{ .Values.tracing.sidecarImage.pullPolicy }} + args: + - --config=/conf/agent.yaml + volumeMounts: + - mountPath: /conf + name: agent-config + volumes: + - configMap: + items: + - key: agent.yaml + path: agent.yaml + name: agent-config + name: agent-config + {{- end }} diff --git a/chart/k8gb/templates/otel/jaeger-deployment.yaml b/chart/k8gb/templates/otel/jaeger-deployment.yaml new file mode 100644 index 0000000000..2a951e28c4 --- /dev/null +++ b/chart/k8gb/templates/otel/jaeger-deployment.yaml @@ -0,0 +1,39 @@ +{{- if .Values.tracing.enabled }} +{{- if .Values.tracing.deployJaeger }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: jaeger + labels: +{{ include "chart.labels" . | indent 4 }} +spec: + selector: + matchLabels: + id: jaeger + replicas: 1 + template: + metadata: + labels: + id: jaeger + spec: + containers: + - name: jaeger + image: {{ .Values.tracing.jaegerImage.repository }}:{{ .Values.tracing.jaegerImage.tag }} + imagePullPolicy: {{ .Values.tracing.jaegerImage.pullPolicy }} + readinessProbe: + httpGet: + path: "/" + port: 14269 + initialDelaySeconds: 5 + env: + - name: COLLECTOR_OTLP_ENABLED + value: "true" + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi +{{- end }} +{{- end }} diff --git a/chart/k8gb/templates/otel/jaeger-svc.yaml b/chart/k8gb/templates/otel/jaeger-svc.yaml new file mode 100644 index 0000000000..1874439f85 --- /dev/null +++ b/chart/k8gb/templates/otel/jaeger-svc.yaml @@ -0,0 +1,27 @@ +{{- if .Values.tracing.enabled }} +{{- if .Values.tracing.deployJaeger }} +apiVersion: v1 +kind: Service +metadata: + name: jaeger-collector + labels: +{{ include "chart.labels" . | indent 4 }} +spec: + ports: + - name: dashboard + port: 16686 + protocol: TCP + targetPort: 16686 + - name: grpc-otlp-collector + port: 4317 + protocol: TCP + targetPort: 4317 + - name: http-otlp-collector + port: 4318 + protocol: TCP + targetPort: 4318 + selector: + id: jaeger + type: ClusterIP +{{- end }} +{{- end }} diff --git a/chart/k8gb/templates/otel/otel-config.yaml b/chart/k8gb/templates/otel/otel-config.yaml new file mode 100644 index 0000000000..8db88ba914 --- /dev/null +++ b/chart/k8gb/templates/otel/otel-config.yaml @@ -0,0 +1,36 @@ +{{- if .Values.tracing.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: agent-config + namespace: k8gb + labels: +{{ include "chart.labels" . | indent 4 }} +data: +{{- if or .Values.tracing.deployJaeger (not .Values.tracing.otelConfig ) }} + agent.yaml: | + receivers: + otlp: + protocols: + http: + grpc: + processors: + exporters: + otlp: + endpoint: jaeger-collector.k8gb:4317 + tls: + insecure: true + retry_on_failure: + enabled: true + logging: + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [otlp] +{{- else -}} + agent.yaml: | +{{ toYaml .Values.tracing.otelConfig | indent 4 }} +{{- end }} +{{- end }} diff --git a/chart/k8gb/templates/otel/otel-svc.yaml b/chart/k8gb/templates/otel/otel-svc.yaml new file mode 100644 index 0000000000..0d141489cf --- /dev/null +++ b/chart/k8gb/templates/otel/otel-svc.yaml @@ -0,0 +1,21 @@ +{{- if .Values.tracing.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: otel-collector + labels: +{{ include "chart.labels" . | indent 4 }} +spec: + ports: + - name: http-otlp + port: 4318 + protocol: TCP + targetPort: 4318 + - name: grpc-otlp + port: 4317 + protocol: TCP + targetPort: 4317 + selector: + name: k8gb + type: ClusterIP +{{- end }} diff --git a/chart/k8gb/templates/role.yaml b/chart/k8gb/templates/role.yaml index bc44ab65fa..15502a9013 100644 --- a/chart/k8gb/templates/role.yaml +++ b/chart/k8gb/templates/role.yaml @@ -4,6 +4,8 @@ kind: ClusterRole metadata: creationTimestamp: null name: k8gb + labels: +{{ include "chart.labels" . | indent 4 }} rules: - apiGroups: - "" diff --git a/chart/k8gb/templates/role_binding.yaml b/chart/k8gb/templates/role_binding.yaml index 3a47e4a461..3b37994fe3 100644 --- a/chart/k8gb/templates/role_binding.yaml +++ b/chart/k8gb/templates/role_binding.yaml @@ -3,6 +3,8 @@ kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: k8gb + labels: +{{ include "chart.labels" . | indent 4 }} subjects: - kind: ServiceAccount name: k8gb diff --git a/chart/k8gb/templates/service_account.yaml b/chart/k8gb/templates/service_account.yaml index b67e14ec1f..d54b17e84c 100644 --- a/chart/k8gb/templates/service_account.yaml +++ b/chart/k8gb/templates/service_account.yaml @@ -4,5 +4,7 @@ kind: ServiceAccount metadata: name: k8gb namespace: {{ .Release.Namespace }} + labels: +{{ include "chart.labels" . | indent 4 }} imagePullSecrets: {{ toYaml .Values.global.imagePullSecrets | nindent 2 }} {{- end }} diff --git a/chart/k8gb/values.schema.json b/chart/k8gb/values.schema.json index 5fece87fad..4273902021 100644 --- a/chart/k8gb/values.schema.json +++ b/chart/k8gb/values.schema.json @@ -32,6 +32,9 @@ }, "rfc2136": { "$ref": "#/definitions/Rfc2136" + }, + "tracing": { + "$ref": "#/definitions/Tracing" } }, "required": [] @@ -155,6 +158,27 @@ "required": [], "title": "Global" }, + "Image": { + "type": "object", + "required": [], + "additionalProperties": false, + "properties": { + "repository": { + "type": "string", + "minLength": 1 + }, + "pullPolicy": { + "enum": [ + "Always", + "IfNotPresent", + "Never" + ] + }, + "tag": { + "type": "string" + } + } + }, "Infoblox": { "type": "object", "additionalProperties": false, @@ -389,6 +413,43 @@ "irsaRole" ], "title": "Route53" + }, + "Tracing": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "deployJaeger": { + "type": "boolean" + }, + "endpoint": { + "type": "string", + "pattern": "^.{2,256}:\\d{2,5}$" + }, + "samplingRatio": { + "type": [ + "string", + "null" + ], + "pattern": "^(0(\\.\\d{1,3})?|1(\\.0)?)$" + }, + "otelConfig": { + "type": ["object", "null"], + "additionalProperties": true + }, + "sidecarImage": { + "$ref": "#/definitions/Image" + }, + "jaegerImage": { + "$ref": "#/definitions/Image" + } + }, + "required": [ + "enabled" + ], + "title": "Tracing" } } } diff --git a/chart/k8gb/values.yaml b/chart/k8gb/values.yaml index ed06152eb3..594c46d5ff 100644 --- a/chart/k8gb/values.yaml +++ b/chart/k8gb/values.yaml @@ -115,3 +115,35 @@ rfc2136: - port: 1053 - tsig-secret-alg: hmac-sha256 - tsig-keyname: externaldns-key + +tracing: + # -- if the application should be sending the traces to OTLP collector (env var `TRACING_ENABLED`) + enabled: false + + # -- should the Jaeger be deployed together with the k8gb operator? In case of using another OpenTracing solution, + # make sure that configmap for OTEL agent has the correct exporters set up (`tracing.otelConfig`). + deployJaeger: false + + # -- `host:port` where the spans from the applications (traces) should be sent, sets the `OTEL_EXPORTER_OTLP_ENDPOINT` env var + # This is not the final destination where all the traces are going. Otel collector has its configuration in the associated configmap (`tracing.otelConfig`). + endpoint: localhost:4318 + + # -- float representing the ratio of how often the span should be kept/dropped (env var `TRACING_SAMPLING_RATIO`) + # if not specified, the AlwaysSample will be used which is the same as 1.0. `0.1` would mean that 10% of samples will be kept + samplingRatio: null + + # -- configuration for OTEL collector, this will be represented as configmap called `agent-config` + otelConfig: null + + sidecarImage: + # -- OpenTelemetry collector into which the k8gb operator sends the spans. It can be further configured to send its data + # to somewhere else using exporters (Jaeger for instance) + repository: otel/opentelemetry-collector + tag: 0.57.2 + pullPolicy: Always + + jaegerImage: + # -- if `tracing.deployJaeger==true` this image will be used in the deployment for Jaeger + repository: jaegertracing/all-in-one + tag: 1.37.0 + pullPolicy: Always diff --git a/controllers/depresolver/depresolver.go b/controllers/depresolver/depresolver.go index 577b61ab2f..ce900e873d 100644 --- a/controllers/depresolver/depresolver.go +++ b/controllers/depresolver/depresolver.go @@ -150,6 +150,13 @@ type Config struct { extDNSEnabled bool `env:"EXTDNS_ENABLED, default=false"` // SplitBrainCheck flag decides whether split brain TXT records will be stored in edge DNS SplitBrainCheck bool `env:"SPLIT_BRAIN_CHECK, default=false"` + // TracingEnabled flag decides whether to use a real otlp tracer or a noop one + TracingEnabled bool `env:"TRACING_ENABLED, default=false"` + // TracingSamplingRatio how many traces should be kept and sent (1.0 - all, 0.0 - none) + TracingSamplingRatio float64 `env:"TRACING_SAMPLING_RATIO, default=1.0"` + // OtelExporterOtlpEndpoint where the traces should be sent to (in case of otel collector deployed on the same pod as sidecar -> localhost:4318) + // otel collector itself can be configured via a configmap to send it somewhere else + OtelExporterOtlpEndpoint string `env:"OTEL_EXPORTER_OTLP_ENDPOINT, default=localhost:4318"` } // DependencyResolver resolves configuration for GSLB diff --git a/controllers/depresolver/depresolver_config.go b/controllers/depresolver/depresolver_config.go index a11d999544..71d99e9e2b 100644 --- a/controllers/depresolver/depresolver_config.go +++ b/controllers/depresolver/depresolver_config.go @@ -53,6 +53,9 @@ const ( LogFormatKey = "LOG_FORMAT" LogNoColorKey = "NO_COLOR" SplitBrainCheckKey = "SPLIT_BRAIN_CHECK" + TracingEnabled = "TRACING_ENABLED" + OtelExporterOtlpEndpoint = "OTEL_EXPORTER_OTLP_ENDPOINT" + TracingSamplingRatio = "TRACING_SAMPLING_RATIO" MetricsAddressKey = "METRICS_ADDRESS" ) diff --git a/controllers/depresolver/depresolver_test.go b/controllers/depresolver/depresolver_test.go index 46e7d098d3..8f5912af0c 100644 --- a/controllers/depresolver/depresolver_test.go +++ b/controllers/depresolver/depresolver_test.go @@ -1522,7 +1522,8 @@ func cleanup() { for _, s := range []string{ReconcileRequeueSecondsKey, ClusterGeoTagKey, ExtClustersGeoTagsKey, EdgeDNSZoneKey, DNSZoneKey, EdgeDNSServersKey, ExtDNSEnabledKey, InfobloxGridHostKey, InfobloxVersionKey, InfobloxPortKey, InfobloxUsernameKey, InfobloxPasswordKey, K8gbNamespaceKey, CoreDNSExposedKey, InfobloxHTTPRequestTimeoutKey, - InfobloxHTTPPoolConnectionsKey, LogLevelKey, LogFormatKey, LogNoColorKey, MetricsAddressKey, SplitBrainCheckKey} { + InfobloxHTTPPoolConnectionsKey, LogLevelKey, LogFormatKey, LogNoColorKey, MetricsAddressKey, SplitBrainCheckKey, TracingEnabled, + TracingSamplingRatio, OtelExporterOtlpEndpoint} { if os.Unsetenv(s) != nil { panic(fmt.Errorf("cleanup %s", s)) } @@ -1553,6 +1554,9 @@ func configureEnvVar(config Config) { _ = os.Setenv(LogNoColorKey, strconv.FormatBool(config.Log.NoColor)) _ = os.Setenv(MetricsAddressKey, config.MetricsAddress) _ = os.Setenv(SplitBrainCheckKey, strconv.FormatBool(config.SplitBrainCheck)) + _ = os.Setenv(TracingEnabled, strconv.FormatBool(config.TracingEnabled)) + _ = os.Setenv(TracingSamplingRatio, strconv.FormatFloat(config.TracingSamplingRatio, 'f', 2, 64)) + _ = os.Setenv(OtelExporterOtlpEndpoint, config.OtelExporterOtlpEndpoint) } func getTestContext(testData string) (client.Client, *k8gbv1beta1.Gslb) { diff --git a/controllers/dnsupdate.go b/controllers/dnsupdate.go index 92fd7c4683..3e5a1cb952 100644 --- a/controllers/dnsupdate.go +++ b/controllers/dnsupdate.go @@ -19,6 +19,7 @@ Generated by GoLic, for more details see: https://github.com/AbsaOSS/golic */ import ( + "context" "fmt" "strings" @@ -32,6 +33,8 @@ import ( ) func (r *GslbReconciler) gslbDNSEndpoint(gslb *k8gbv1beta1.Gslb) (*externaldns.DNSEndpoint, error) { + _, s := r.Tracer.Start(context.Background(), "gslbDNSEndpoint") + defer s.End() var gslbHosts []*externaldns.Endpoint var ttl = externaldns.TTL(gslb.Spec.Strategy.DNSTtlSeconds) diff --git a/controllers/gslb_controller.go b/controllers/gslb_controller.go index e942f1532b..24af69f06b 100644 --- a/controllers/gslb_controller.go +++ b/controllers/gslb_controller.go @@ -30,6 +30,8 @@ import ( "github.com/k8gb-io/k8gb/controllers/internal/utils" "github.com/k8gb-io/k8gb/controllers/logging" "github.com/k8gb-io/k8gb/controllers/providers/dns" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace" corev1 "k8s.io/api/core/v1" netv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -52,6 +54,7 @@ type GslbReconciler struct { Config *depresolver.Config DepResolver depresolver.GslbResolver DNSProvider dns.Provider + Tracer trace.Tracer } const ( @@ -71,6 +74,9 @@ var m = metrics.Metrics() // Reconcile runs main reconiliation loop func (r *GslbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + ctx, span := r.Tracer.Start(ctx, "Reconcile") + defer span.End() + result := utils.NewReconcileResultHandler(r.Config.ReconcileRequeueSeconds) // Fetch the Gslb instance gslb := &k8gbv1beta1.Gslb{} @@ -103,12 +109,15 @@ func (r *GslbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. if isGslbMarkedToBeDeleted { // For the legacy reasons, delete all finalizers that corresponds with the slice // see: https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.4.0/#change-your-operators-finalizer-names + _, fSpan := r.Tracer.Start(ctx, "finalize") for _, f := range []string{gslbFinalizer, "finalizer.k8gb.absa.oss"} { if contains(gslb.GetFinalizers(), f) { // Run finalization logic for gslbFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. if err := r.finalizeGslb(gslb); err != nil { + fSpan.RecordError(err) + fSpan.SetStatus(codes.Error, err.Error()) return result.RequeueError(err) } @@ -117,10 +126,14 @@ func (r *GslbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. gslb.SetFinalizers(remove(gslb.GetFinalizers(), f)) err := r.Update(ctx, gslb) if err != nil { + fSpan.RecordError(err) + fSpan.SetStatus(codes.Error, err.Error()) return result.RequeueError(err) } } + } + fSpan.End() log.Info().Msg("reconciler exit") return result.Stop() } @@ -153,19 +166,23 @@ func (r *GslbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. return result.RequeueError(err) } + _, s := r.Tracer.Start(ctx, "SaveDNSEndpoint") err = r.DNSProvider.SaveDNSEndpoint(gslb, dnsEndpoint) if err != nil { m.IncrementError(gslb) return result.RequeueError(err) } + s.End() // == handle delegated zone in Edge DNS + _, szd := r.Tracer.Start(ctx, "CreateZoneDelegationForExternalDNS") err = r.DNSProvider.CreateZoneDelegationForExternalDNS(gslb) if err != nil { log.Err(err).Msg("Unable to create zone delegation") m.IncrementError(gslb) return result.Requeue() } + szd.End() // == Status = err = r.updateGslbStatus(gslb, dnsEndpoint) diff --git a/controllers/gslb_controller_test.go b/controllers/gslb_controller_test.go index 2ece4a1139..24a9525e7c 100644 --- a/controllers/gslb_controller_test.go +++ b/controllers/gslb_controller_test.go @@ -38,6 +38,7 @@ import ( "github.com/k8gb-io/k8gb/controllers/providers/assistant" "github.com/k8gb-io/k8gb/controllers/providers/dns" "github.com/k8gb-io/k8gb/controllers/providers/metrics" + "github.com/k8gb-io/k8gb/controllers/tracing" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" @@ -1298,10 +1299,22 @@ func provideSettings(t *testing.T, expected depresolver.Config) (settings testSe s.AddKnownTypes(schema.GroupVersion{Group: "externaldns.k8s.io", Version: "v1alpha1"}, &externaldns.DNSEndpoint{}) // Create a fake client to mock API calls. cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() + + // tracing + cfg := tracing.Settings{ + Enabled: expected.TracingEnabled, + Endpoint: expected.OtelExporterOtlpEndpoint, + SamplingRatio: expected.TracingSamplingRatio, + Commit: "commit", + AppVersion: "version", + } + cleanup, tracer := tracing.SetupTracing(context.Background(), cfg, log) + defer cleanup() // Create a GslbReconciler object with the scheme and fake client. r := &GslbReconciler{ Client: cl, Scheme: s, + Tracer: tracer, } r.DepResolver = depresolver.NewDependencyResolver() r.Config = &expected diff --git a/controllers/tracing/tracing.go b/controllers/tracing/tracing.go new file mode 100644 index 0000000000..3006bfe750 --- /dev/null +++ b/controllers/tracing/tracing.go @@ -0,0 +1,96 @@ +package tracing + +/* +Copyright 2022 The k8gb Contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Generated by GoLic, for more details see: https://github.com/AbsaOSS/golic +*/ + +import ( + "context" + "fmt" + "math" + + "github.com/rs/zerolog" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.6.1" + "go.opentelemetry.io/otel/trace" +) + +const ( + instrumentationName = "github.com/k8gb-io/k8gb" +) + +type Settings struct { + Enabled bool + Endpoint string + SamplingRatio float64 + Commit string + AppVersion string +} + +func SetupTracing(ctx context.Context, cfg Settings, log *zerolog.Logger) (func(), trace.Tracer) { + if !cfg.Enabled { + log.Info().Msg("OTLP tracing is disabled") + return func() {}, trace.NewNoopTracerProvider().Tracer(instrumentationName) + } + log.Info().Msg("OTLP tracing is ON") + client := otlptracehttp.NewClient( + otlptracehttp.WithEndpoint(cfg.Endpoint), + otlptracehttp.WithInsecure(), + ) + exporter, err := otlptrace.New(ctx, client) + if err != nil { + log.Err(err).Msg("creating OTLP trace exporter") + } + var samplerOption sdktrace.TracerProviderOption + eps := 0.0001 + if math.Abs(cfg.SamplingRatio-1.0) > eps { // not equal 1.0 (IEEE 754) + samplerOption = sdktrace.WithSampler(sdktrace.TraceIDRatioBased(cfg.SamplingRatio)) + log.Info().Msg(fmt.Sprintf("Tracing: sampling ratio is set to '%.3f'", cfg.SamplingRatio)) + } else { + log.Info().Msg("Tracing: sampling ratio is not specified, using AlwaysSample") + samplerOption = sdktrace.WithSampler(sdktrace.AlwaysSample()) + } + + tracerProvider := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exporter), + sdktrace.WithResource(newResource(cfg.Commit)), + samplerOption, + ) + otel.SetTracerProvider(tracerProvider) + tracer := tracerProvider.Tracer( + instrumentationName, + trace.WithInstrumentationVersion(cfg.AppVersion), + trace.WithSchemaURL(semconv.SchemaURL)) + + return func() { + if err := tracerProvider.Shutdown(ctx); err != nil { + log.Err(err).Msg("stopping tracer provider") + } + }, tracer +} + +func newResource(commit string) *resource.Resource { + return resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceNameKey.String("k8gb"), + semconv.ServiceVersionKey.String(commit), + ) +} diff --git a/docs/metrics.md b/docs/metrics.md index d33e27b81d..3f65cc5f59 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -90,3 +90,7 @@ The k8gb exposes several metrics to help you monitor the health and behavior. | `k8gb_infoblox_zone_updates_total` | Counter | Number of k8gb Infoblox zone updates. | `namespace`, `name` | | `k8gb_endpoint_status_num` | Gauge | Number of targets in DNS endpoint. | `namespace`, `name`, `dns_name` | | `k8gb_runtime_info` | Gauge | K8gb runtime info. | `namespace`, `k8gb_version`,
`go_version`, `arch`, `os`, `git_sha` | + +## OpenTracing + +Optionally k8gb operator can expose traces in OpenTelemetry format to any available OTEL compliant tracing solution. Consult the [following page](/docs/traces.md) for more details. \ No newline at end of file diff --git a/docs/traces.md b/docs/traces.md new file mode 100644 index 0000000000..bca0abed46 --- /dev/null +++ b/docs/traces.md @@ -0,0 +1,73 @@ +# Traces + +K8GB can create and send spans/traces to either Jaeger which is supported also on the Helm chart level or to +any other OTEL compliant solution. We don't recommend sending the tracing data directly to the tracer, because +of the possible vendor lock-in. OTEL collector can be deployed as a side-car container for k8gb pod and +forward all the traces to a configurable sink or event multiple sinks for redundancy. + +### Architecture + +We are not opinionated about the OpenTracing vendors. In the following diagram `X` can be Jaeger, Zipkin, LigthStep, Grafana's Tempo, Instana, etc. It can also be another OTEL collector to form more [sophisticated](https://opentelemetry.io/docs/collector/configuration/) pipeline setup. + +Sidecar use-case: + +```text ++--------------+ +------------+ +----------+ +| k8gb | | X | http | User | +| ------------ | otlp | +------------>| | +| OTEL sidecar +-------------->| | | | ++--------------+ +------------+ +----------+ +``` + +### Deployment + +By default the tracing is disabled and no sidecar container is being created during the k8gb deployment. To +enable the tracing, one has to set the `tracing.enabled=true` in Helm Chart. This will create the sidecar container for k8gb deployment, tweaks couple of env vars there. It will create the [configmap](https://github.com/k8gb-io/k8gb/blob/master/chart/k8gb/templates/otel/otel-config.yaml) for OTEL sidecar. This configuration of OTEL collector can be overriden by `tracing.otelConfig`. + +If you need something quickly up and running, make sure that `tracing.deployJaeger` is also set to `true`. +In this scenario you will end up also with Jaeger deployed and service for it. To be able to access it one can continue with: + +```bash +kubectl port-forward svc/jaeger-collector 16686 +open http://localhost:16686 +``` + +Also both sidecar container image and jaeger deployment's container image can be tweaked by +`tracing.{sidecarImage,jaegerImage}.{repository,tag,pullPolicy}`. + +### Custom Architecture + +In case you have already a OTEL collector present in the Kubernetes cluster and you do not want to introduce +a new one, you can deploy also the following topology: + +```text ++----------+ +----------------+ +--------+ +---------+ +| k8gb | | OTEL collector | otlp | X | http | User | +| | otlp | +------------>| +------------>| | +| +-------------->| | | | | | ++----------+ +----------------+ +--------+ +---------+ +``` + +However, we don't support this use-case on the Helm chart level so you are on your own with the setup. Nonetheless, it should be relatively straightforward. All you have to do is set the following env vars for k8gb deployment: + - `TRACING_ENABLED` (set it to `true`) + - `OTEL_EXPORTER_OTLP_ENDPOINT` (`host:port` of OTEL collector from the ASCII diagram) + - `TRACING_SAMPLING_RATIO` (optional, float representing the % ratio of how many traces are being collected) + + +#### Distributed Tracing & Context Propagation + +K8gb is a k8s controller/operator so in nature event-based system, where the invocation of the request is done +using creating custom resource (`gslb`) or `Ingress` with certain annotation. In more traditional +micro-service world, the context propagation between traced systems is done using HTTP headers. Provided that +the comm client is also instrumented with OpenTracing bits one doesn't have to call the `Extract` and +`Inject` on his own. However, for the CRD space nothing has been introduced so far and having the tracing +key-value metadata stored in each custom resource would be overkill here. Not speaking about increasing the +overall complexity of such a system. + +If k8gb had a REST api, it would be a very low-hanging fruit on the other hand. + +As for the propagation of context down for the calls that k8gb does, this may make sense for direct HTTP +calls to external systems such as Infoblox or Route53. Then provided that those systems also support +OpenTracing and they have the context propagation done right on their part, one could see the full insight +into the requests and examine what takes most of the time or where the issue happened. As for communication +with `ExternalDNS`, it's again on the "CRD level" -> hard to achieve + the ExternalDNS operator is not traced. diff --git a/go.mod b/go.mod index 9d1ded9e3d..f3b5719637 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,18 @@ require ( github.com/AbsaOSS/env-binder v1.0.1 github.com/AbsaOSS/gopkg v0.1.3 github.com/ghodss/yaml v1.0.0 - github.com/go-logr/logr v1.2.0 + github.com/go-logr/logr v1.2.3 github.com/golang/mock v1.6.0 github.com/infobloxopen/infoblox-go-client v1.1.1 github.com/miekg/dns v1.1.48 github.com/prometheus/client_golang v1.11.1 github.com/rs/zerolog v1.21.0 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 + go.opentelemetry.io/otel v1.7.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 + go.opentelemetry.io/otel/sdk v1.7.0 + go.opentelemetry.io/otel/trace v1.7.0 k8s.io/api v0.23.3 k8s.io/apimachinery v0.23.3 k8s.io/client-go v0.23.3 @@ -23,10 +28,12 @@ require ( require ( cloud.google.com/go/compute v1.5.0 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -34,6 +41,7 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.1.2 // indirect github.com/googleapis/gnostic v0.5.5 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kr/pretty v0.3.0 // indirect @@ -47,6 +55,8 @@ require ( github.com/prometheus/procfs v0.6.0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect + go.opentelemetry.io/proto/otlp v0.16.0 // indirect golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect @@ -58,7 +68,9 @@ require ( golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb // indirect + google.golang.org/grpc v1.46.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 4a954f961e..f0fcb2ba92 100644 --- a/go.sum +++ b/go.sum @@ -203,8 +203,11 @@ github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8n github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= @@ -336,6 +339,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220112105034-1553555e45ad/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.3.0-java.0.20200609174644-bd816e4522c1/go.mod h1:bjmEhrMDubXDd0uKxnWwRmgSsiEv2CkJliIHnj6ETm8= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= @@ -394,8 +398,12 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU= github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= @@ -520,6 +528,7 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -654,7 +663,10 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= @@ -1146,8 +1158,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/terra-farm/udnssdk v1.3.5/go.mod h1:8RnM56yZTR7mYyUIvrDgXzdRaEyFIzqdEi7+um26Sv8= @@ -1234,14 +1247,29 @@ go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUz go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= +go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= +go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= +go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 h1:7Yxsak1q4XrJ5y7XBnNwqWx9amMZvoidCctv62XOQ6Y= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 h1:cMDtmgJ5FpRvqx9x2Aq+Mm0O6K/zcUkH73SFz20TuBw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0/go.mod h1:ceUgdyfNv4h4gLxHR0WNfDiiVmZFodZhZSbOLhpxqXE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 h1:pLP0MH4MAqeTEV0g/4flxw9O8Is48uAIauAnjznbW50= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0/go.mod h1:aFXT9Ng2seM9eizF+LfKiyPBGy8xIZKwhusC1gIu3hA= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= +go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= +go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.16.0 h1:WHzDWdXUvbc5bG2ObdrGfaNpQz7ft7QN9HHmJlbiB1E= +go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1534,6 +1562,7 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1801,6 +1830,7 @@ google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2 google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -1840,6 +1870,8 @@ google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1853,8 +1885,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/main.go b/main.go index d82f4eb059..a49d6e26e1 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,7 @@ Generated by GoLic, for more details see: https://github.com/AbsaOSS/golic */ import ( + "context" "os" k8gbv1beta1 "github.com/k8gb-io/k8gb/api/v1beta1" @@ -27,6 +28,7 @@ import ( "github.com/k8gb-io/k8gb/controllers/logging" "github.com/k8gb-io/k8gb/controllers/providers/dns" "github.com/k8gb-io/k8gb/controllers/providers/metrics" + "github.com/k8gb-io/k8gb/controllers/tracing" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -138,6 +140,19 @@ func run() error { return err } metrics.Metrics().SetRuntimeInfo(version, commit) + + // tracing + cfg := tracing.Settings{ + Enabled: config.TracingEnabled, + Endpoint: config.OtelExporterOtlpEndpoint, + SamplingRatio: config.TracingSamplingRatio, + Commit: commit, + AppVersion: version, + } + cleanup, tracer := tracing.SetupTracing(context.Background(), cfg, log) + reconciler.Tracer = tracer + defer cleanup() + // +kubebuilder:scaffold:builder log.Info().Msg("Starting k8gb") if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {