diff --git a/docs/content/configuration.md b/docs/content/configuration.md index ad3bb12615..7f295fa36e 100644 --- a/docs/content/configuration.md +++ b/docs/content/configuration.md @@ -88,6 +88,7 @@ distributed_tracing: service_namespace: "my-namespace" service_version: "1.1" service_instance_id: "1" + deployment_environment: "prod" server: decoding: @@ -876,20 +877,21 @@ respectively, and the `json.schema_match` built-in function for compiled JSON sc Distributed tracing represents the configuration of the OpenTelemetry Tracing. -| Field | Type | Required | Description | -|----------------------------------------------------|----------| --- |------------------------------------------------------------------------------------| -| `distributed_tracing.type` | `string` | No | Setting this to "grpc" enables distributed tracing with an collector gRPC endpoint | -| `distributed_tracing.address` | `string` | No (default: `localhost:4317`) | Address of the OpenTelemetry Collector gRPC endpoint. | -| `distributed_tracing.service_name` | `string` | No (default: `opa`) | Logical name of the service. | -| `distributed_tracing.sample_percentage` | `int` | No (default: `100`) | Percentage of traces that are sampled and exported. | -| `distributed_tracing.encryption` | `string` | No (default: `off`) | Configures TLS. | -| `distributed_tracing.allow_insecure_tls` | `bool` | No (default: `false`) | Allow insecure TLS. | -| `distributed_tracing.tls_ca_cert_file` | `string` | No | The path to the root CA certificate. | -| `distributed_tracing.tls_cert_file` | `string` | No (unless `encryption` equals `mtls`) | The path to the client certificate to authenticate with. | -| `distributed_tracing.tls_private_key_file` | `string` | No (unless `tls_cert_file` provided) | The path to the private key of the client certificate. | -| `distributed_tracing.resource.service_version` | `string` | No | Service version | -| `distributed_tracing.resource.service_instance_id` | `string` | No | Service instance id | -| `distributed_tracing.resource.service_namespace` | `string` | No | Service namespace | +| Field | Type | Required | Description | +|-------------------------------------------------------|----------|----------------------------------------|------------------------------------------------------------------------------------| +| `distributed_tracing.type` | `string` | No | Setting this to "grpc" enables distributed tracing with an collector gRPC endpoint | +| `distributed_tracing.address` | `string` | No (default: `localhost:4317`) | Address of the OpenTelemetry Collector gRPC endpoint. | +| `distributed_tracing.service_name` | `string` | No (default: `opa`) | Logical name of the service. | +| `distributed_tracing.sample_percentage` | `int` | No (default: `100`) | Percentage of traces that are sampled and exported. | +| `distributed_tracing.encryption` | `string` | No (default: `off`) | Configures TLS. | +| `distributed_tracing.allow_insecure_tls` | `bool` | No (default: `false`) | Allow insecure TLS. | +| `distributed_tracing.tls_ca_cert_file` | `string` | No | The path to the root CA certificate. | +| `distributed_tracing.tls_cert_file` | `string` | No (unless `encryption` equals `mtls`) | The path to the client certificate to authenticate with. | +| `distributed_tracing.tls_private_key_file` | `string` | No (unless `tls_cert_file` provided) | The path to the private key of the client certificate. | +| `distributed_tracing.resource.service_version` | `string` | No | Service version | +| `distributed_tracing.resource.service_instance_id` | `string` | No | Service instance id | +| `distributed_tracing.resource.service_namespace` | `string` | No | Service namespace | +| `distributed_tracing.resource.deployment_environment` | `string` | No | Deployment environment name | The following encryption methods are supported: diff --git a/internal/distributedtracing/distributedtracing.go b/internal/distributedtracing/distributedtracing.go index ec047cc297..3fe11d3c13 100644 --- a/internal/distributedtracing/distributedtracing.go +++ b/internal/distributedtracing/distributedtracing.go @@ -55,9 +55,10 @@ func isSupportedSampleRatePercentage(sampleRate int) bool { } type resourceConfig struct { - ServiceVersion string `json:"service_version,omitempty"` - ServiceInstanceID string `json:"service_instance_id,omitempty"` - ServiceNamespace string `json:"service_namespace,omitempty"` + ServiceVersion string `json:"service_version,omitempty"` + ServiceInstanceID string `json:"service_instance_id,omitempty"` + ServiceNamespace string `json:"service_namespace,omitempty"` + DeploymentEnvironment string `json:"deployment_environment,omitempty"` } type distributedTracingConfig struct { @@ -117,6 +118,13 @@ func Init(ctx context.Context, raw []byte, id string) (*otlptrace.Exporter, *tra if distributedTracingConfig.Resource.ServiceNamespace != "" { resourceAttributes = append(resourceAttributes, semconv.ServiceNamespaceKey.String(distributedTracingConfig.Resource.ServiceNamespace)) } + + // NOTE: this is currently using the `deployment.environment` setting which is being deprecated + // in favour of `deployment.environment.name` in future versions of the OpenTelemetry schema. + // This will need to be taken into account when upgrading the library version in the future. + if distributedTracingConfig.Resource.DeploymentEnvironment != "" { + resourceAttributes = append(resourceAttributes, semconv.DeploymentEnvironmentKey.String(distributedTracingConfig.Resource.DeploymentEnvironment)) + } res, err := resource.New(ctx, resource.WithAttributes( semconv.ServiceNameKey.String(distributedTracingConfig.ServiceName), diff --git a/v1/server/server_test.go b/v1/server/server_test.go index 3882a6baf2..752177e5ba 100644 --- a/v1/server/server_test.go +++ b/v1/server/server_test.go @@ -37,6 +37,9 @@ import ( "testing" "time" + "go.opentelemetry.io/otel/attribute" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + "github.com/gorilla/mux" "github.com/open-policy-agent/opa/internal/distributedtracing" @@ -5857,15 +5860,28 @@ func TestDistributedTracingEnabled(t *testing.T) { func TestDistributedTracingResourceAttributes(t *testing.T) { t.Parallel() - c := []byte(`{"distributed_tracing": { + attributes := map[attribute.Key]string{ + semconv.DeploymentEnvironmentKey: "prod", + semconv.ServiceNameKey: "my-service", + semconv.ServiceVersionKey: "1.0", + semconv.ServiceNamespaceKey: "my-namespace", + semconv.ServiceInstanceIDKey: "1", + } + + c := []byte(fmt.Sprintf(`{"distributed_tracing": { "type": "grpc", - "service_name": "my-service", + "service_name": "%s", "resource": { - "service_namespace": "my-namespace", - "service_version": "1.0", - "service_instance_id": "1" + "service_namespace": "%s", + "service_version": "%s", + "service_instance_id": "%s", + "deployment_environment": "%s" } - }}`) + }}`, attributes[semconv.ServiceNameKey], + attributes[semconv.ServiceNamespaceKey], + attributes[semconv.ServiceVersionKey], + attributes[semconv.ServiceInstanceIDKey], + attributes[semconv.DeploymentEnvironmentKey])) ctx := context.Background() _, traceProvider, resource, err := distributedtracing.Init(ctx, c, "foo") @@ -5878,9 +5894,16 @@ func TestDistributedTracingResourceAttributes(t *testing.T) { if resource == nil { t.Fatalf("Resource was not initialized") } - if len(resource.Attributes()) != 4 { - t.Fatalf("Unexpected resource attributes count. Expected: %v, Got: %v", 4, len(resource.Attributes())) + if len(resource.Attributes()) != 5 { + t.Fatalf("Unexpected resource attributes count. Expected: %v, Got: %v", 5, len(resource.Attributes())) } + + for _, value := range resource.Attributes() { + if attribute.StringValue(attributes[value.Key]) != value.Value { + t.Fatalf("Unexpected resource attribute. Expected: %v, Got: %v", attributes[value.Key], value) + } + } + } func TestCertPoolReloading(t *testing.T) {