diff --git a/README.md b/README.md index b36aa6db..f43edc6a 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ spec: * [Storage Options](./doc/storage.md) * [Rate Limit Headers](./doc/rate-limit-headers.md) * [Logging](./doc/logging.md) +* [Tracing](./doc/tracing.md) ## Contributing diff --git a/api/v1alpha1/limitador_types.go b/api/v1alpha1/limitador_types.go index 4c403f7b..e5e901ad 100644 --- a/api/v1alpha1/limitador_types.go +++ b/api/v1alpha1/limitador_types.go @@ -86,6 +86,9 @@ type LimitadorSpec struct { // +optional Telemetry *Telemetry `json:"telemetry,omitempty"` + // +optional + Tracing *Tracing `json:"tracing,omitempty"` + // +optional Limits []RateLimit `json:"limits,omitempty"` @@ -324,6 +327,10 @@ type Ports struct { GRPC int32 `json:"grpc,omitempty"` } +type Tracing struct { + Endpoint string `json:"endpoint"` +} + type PodDisruptionBudgetType struct { // An eviction is allowed if at most "maxUnavailable" limitador pods // are unavailable after the eviction, i.e. even in absence of diff --git a/bundle/manifests/limitador-operator.clusterserviceversion.yaml b/bundle/manifests/limitador-operator.clusterserviceversion.yaml index 451b77a3..d24e0f99 100644 --- a/bundle/manifests/limitador-operator.clusterserviceversion.yaml +++ b/bundle/manifests/limitador-operator.clusterserviceversion.yaml @@ -37,7 +37,7 @@ metadata: capabilities: Basic Install categories: Integration & Delivery containerImage: quay.io/kuadrant/limitador-operator:latest - createdAt: "2024-04-04T14:34:19Z" + createdAt: "2024-04-15T10:48:14Z" operators.operatorframework.io/builder: operator-sdk-v1.32.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/Kuadrant/limitador-operator diff --git a/bundle/manifests/limitador.kuadrant.io_limitadors.yaml b/bundle/manifests/limitador.kuadrant.io_limitadors.yaml index ca2c66bd..45cc39b8 100644 --- a/bundle/manifests/limitador.kuadrant.io_limitadors.yaml +++ b/bundle/manifests/limitador.kuadrant.io_limitadors.yaml @@ -1083,6 +1083,13 @@ spec: - basic - exhaustive type: string + tracing: + properties: + endpoint: + type: string + required: + - endpoint + type: object verbosity: description: Sets the level of verbosity maximum: 4 diff --git a/config/crd/bases/limitador.kuadrant.io_limitadors.yaml b/config/crd/bases/limitador.kuadrant.io_limitadors.yaml index b5e5baea..a869157e 100644 --- a/config/crd/bases/limitador.kuadrant.io_limitadors.yaml +++ b/config/crd/bases/limitador.kuadrant.io_limitadors.yaml @@ -1084,6 +1084,13 @@ spec: - basic - exhaustive type: string + tracing: + properties: + endpoint: + type: string + required: + - endpoint + type: object verbosity: description: Sets the level of verbosity maximum: 4 diff --git a/doc/tracing.md b/doc/tracing.md new file mode 100644 index 00000000..fc16e5d0 --- /dev/null +++ b/doc/tracing.md @@ -0,0 +1,30 @@ +# Tracing + +Limitador offers distributed tracing enablement using the `.spec.tracing` CR configuration: + +```yaml +--- +apiVersion: limitador.kuadrant.io/v1alpha1 +kind: Limitador +metadata: + name: limitador-sample +spec: + listener: + http: + port: 8080 + grpc: + port: 8081 + limits: + - conditions: ["get_toy == 'yes'"] + max_value: 2 + namespace: toystore-app + seconds: 30 + variables: [] + verbosity: 3 + tracing: + endpoint: rpc://my-otlp-collector:4317 +``` + +Currently limitador only supports collectors using the OpenTelemetry Protocol with TLS disabled. The `endpoint` configuration option should contain the scheme, host and port of the service. The quantity and level of the information provided by the spans is configured via the `verbosity` argument. + +![Limitador tracing example](https://github.com/Kuadrant/limitador-operator/assets/6575004/7bdc7c17-37a5-4dfe-ac56-432efa1070c4) diff --git a/pkg/limitador/deployment_options.go b/pkg/limitador/deployment_options.go index 17add9f4..07427a86 100644 --- a/pkg/limitador/deployment_options.go +++ b/pkg/limitador/deployment_options.go @@ -45,6 +45,10 @@ func DeploymentCommand(limObj *limitadorv1alpha1.Limitador, storageOptions Deplo command = append(command, "--limit-name-in-labels") } + if limObj.Spec.Tracing != nil { + command = append(command, "--tracing-endpoint", limObj.Spec.Tracing.Endpoint) + } + if limObj.Spec.Verbosity != nil { command = append(command, fmt.Sprintf("-%s", strings.Repeat("v", int(*limObj.Spec.Verbosity)))) } diff --git a/pkg/limitador/deployment_options_test.go b/pkg/limitador/deployment_options_test.go index d571bd7d..d81d0166 100644 --- a/pkg/limitador/deployment_options_test.go +++ b/pkg/limitador/deployment_options_test.go @@ -107,6 +107,26 @@ func TestDeploymentCommand(t *testing.T) { }) } }) + + t.Run("command from tracing endpoint appended", func(subT *testing.T) { + testEndpoint := "rpc://tracing-endpoint:4317" + limObj := basicLimitador() + limObj.Spec.Tracing = &limitadorv1alpha1.Tracing{ + Endpoint: testEndpoint, + } + command := DeploymentCommand(limObj, DeploymentStorageOptions{}) + assert.DeepEqual(subT, command, + []string{ + "limitador-server", + "--tracing-endpoint", + testEndpoint, + "--http-port", + strconv.Itoa(int(limitadorv1alpha1.DefaultServiceHTTPPort)), + "--rls-port", + strconv.Itoa(int(limitadorv1alpha1.DefaultServiceGRPCPort)), + "/home/limitador/etc/limitador-config.yaml", + }) + }) } func TestDeploymentVolumeMounts(t *testing.T) {