diff --git a/otel-playground/README.md b/otel-playground/README.md new file mode 100644 index 0000000..ea275eb --- /dev/null +++ b/otel-playground/README.md @@ -0,0 +1,27 @@ +# OpenTelemetry Playground + +This repo has a few parts that allow you to play with opentelemetry using Docker Compose and cURL. + +1. Clone the repository +1. Set up refinery in the `refinery` directory and start it with `docker compose up` +1. Edit the `otelcol-config.yaml` file so it has API keys and such +1. `docker compose up -d` +1. Edit your trace.json file +1. `curl -X POST -H "Content-Type: application/json" -d @trace.json -i http://localhost:4318/v1/traces` +1. Go into Honeycomb and take a look! + +## Setting up OpenTelemetry Collector + +Suggest that you create a few environments: + +1. Raw spans environment for trace data +1. Metrics environment for information about the collector and refinery +1. Sampled spans environrment for refinery testing + +Each exporter gets one of those API keys. + +## Curling stuff + +If you've started the collector + +curl -X POST -H "Content-Type: application/json" -d @trace.json -i http://localhost:4318/v1/traces diff --git a/otel-playground/otelcol/docker-compose.yml b/otel-playground/otelcol/docker-compose.yml new file mode 100644 index 0000000..21f94f5 --- /dev/null +++ b/otel-playground/otelcol/docker-compose.yml @@ -0,0 +1,13 @@ +services: + otel-collector: + image: otel/opentelemetry-collector-contrib + restart: always + command: ["--config=/etc/otel-collector-config.yaml"] + volumes: + - ./otelcol-config.yaml:/etc/otel-collector-config.yaml + ports: + - "8888:8888" # Prometheus metrics exposed by the collector + - "8889:8889" # Prometheus exporter metrics + - "13133:13133" # health_check extension + - "4317:4317" # OTLP gRPC receiver + - "4318:4318" # OTLP HTTP receiver diff --git a/otel-playground/otelcol/otelcol-config.yaml b/otel-playground/otelcol/otelcol-config.yaml new file mode 100644 index 0000000..6256e31 --- /dev/null +++ b/otel-playground/otelcol/otelcol-config.yaml @@ -0,0 +1,86 @@ +exporters: + otlp/sampled: + endpoint: "localhost:8080" + headers: + "x-honeycomb-team": "" + compression: zstd + sending_queue: + enabled: true + num_consumers: 2 + debug: + verbosity: detailed + otlp: + endpoint: "api.honeycomb.io:443" + headers: + "x-honeycomb-team": "" + compression: zstd + sending_queue: + enabled: true + num_consumers: 2 + otlp/metrics: + endpoint: "api.honeycomb.io:443" + headers: + "x-honeycomb-team": "" + "x-honeycomb-dataset": "otelcol" + +processors: + memory_limiter: + check_interval: 5s + limit_mib: 16000 + spike_limit_mib: 1000 + batch: + send_batch_size: 1000 + timeout: 150ms + send_batch_max_size: 2000 + transform/labelme: + metric_statements: + - context: resource + statements: + - set(attributes["collector.name"], "${env:HOSTNAME}") + trace_statements: + - context: resource + statements: + - set(attributes["collector.name"], "${env:HOSTNAME}") + - context: span + statements: # The following add 48 hours to the spans so you can replay the same ones with new timestamps. + - set(start_time, start_time + Duration("48h")) + - set(end_time, end_time + Duration("48h")) + - set(attributes["mike.added_time"], "48 hours") + log_statements: + - context: resource + statements: + - set(attributes["collector.name"], "${env:HOSTNAME}") + +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + prometheus: + config: + scrape_configs: + - job_name: "otelcol" + scrape_interval: 60s + static_configs: + - targets: ["0.0.0.0:8888"] + metric_relabel_configs: + - source_labels: [__name__] + regex: ".*grpc_io.*" + action: drop + +service: + pipelines: + traces: + receivers: [otlp] + processors: [memory_limiter, transform/labelme, batch] + exporters: [otlphttp/sampled] + metrics: + receivers: [prometheus] + processors: [batch, transform/labelme] + exporters: [otlp/metrics] + telemetry: + metrics: + level: detailed + address: ":8888" diff --git a/otel-playground/refinery/config.yaml b/otel-playground/refinery/config.yaml new file mode 100644 index 0000000..af255b3 --- /dev/null +++ b/otel-playground/refinery/config.yaml @@ -0,0 +1,54 @@ +General: + ConfigurationVersion: 2 + MinRefineryVersion: v2.0 +Network: + ListenAddr: "0.0.0.0:8080" + PeerListenAddr: "0.0.0.0:8081" + +RefineryTelemetry: + AddRuleReasonToTrace: true + AddSpanCountToRoot: true + AddHostMetadataToTrace: true +Traces: + LinkStrategy: RootLinkOverride +IDFields: + TraceNames: [ trace.trace_id ] + ParentNames: [ trace.parent_id ] + LinkNames: [ trace.link.trace_id ] +Debugging: + QueryAuthToken: sneaky-longer-token + AdditionalErrorFields: + - trace.span_id + DryRun: true +Logger: + Type: honeycomb + Level: debug +HoneycombLogger: + APIKey: + Dataset: refinery-logs +LegacyMetrics: + Enabled: true + APIKey: + Dataset: refinery-metrics + ReportingInterval: 20s +OTelMetrics: + Enabled: false +PeerManagement: + Type: redis + IdentifierInterfaceName: eth0 +RedisPeerManagement: + Host: redis:6379 +Collection: + MaxAlloc: 6Gb +Specialized: + AdditionalAttributes: + ClusterName: homelab +GRPCServerParameters: + Enabled: true + ListenAddr: "0.0.0.0:4317" +StressRelief: + Mode: monitor + ActivationLevel: 90 + DeactivationLevel: 70 + SamplingRate: 300 + \ No newline at end of file diff --git a/otel-playground/refinery/docker-compose.yml b/otel-playground/refinery/docker-compose.yml new file mode 100644 index 0000000..5f56365 --- /dev/null +++ b/otel-playground/refinery/docker-compose.yml @@ -0,0 +1,35 @@ +services: + refinery1: + image: honeycombio/refinery + ports: + - 4317:4317 + - 8080:8080 + entrypoint: + - "refinery" + command: + - "-c" + - "/etc/refinery/config.yaml" + - "-r" + - "/etc/refinery/rules.yaml" + volumes: + - ./config.yaml:/etc/refinery/config.yaml + - ./rules.yaml:/etc/refinery/rules.yaml + refinery2: + image: honeycombio/refinery + ports: + - 4817:4317 + - 8880:8080 + entrypoint: + - "refinery" + command: + - "-c" + - "/etc/refinery/config.yaml" + - "-r" + - "/etc/refinery/rules.yaml" + volumes: + - ./config.yaml:/etc/refinery/config.yaml + - ./rules.yaml:/etc/refinery/rules.yaml + redis: + image: redis:6.2.5 + expose: + - "6379" \ No newline at end of file diff --git a/otel-playground/refinery/rules.yaml b/otel-playground/refinery/rules.yaml new file mode 100644 index 0000000..ff29583 --- /dev/null +++ b/otel-playground/refinery/rules.yaml @@ -0,0 +1,19 @@ +RulesVersion: 2 +Samplers: + __default__: + RulesBasedSampler: + Rules: + - Name: drop jobs + Drop: true + Conditions: + - Field: job.emitted_by + Operator: = + Value: worker + - Name: keep scheduler + SampleRate: 1 + Conditions: + - Field: name + Operator: = + Value: "Evaluate the queue and environment" + - Name: Everything else + SampleRate: 1 \ No newline at end of file diff --git a/otel-playground/trace.json b/otel-playground/trace.json new file mode 100644 index 0000000..5d3c961 --- /dev/null +++ b/otel-playground/trace.json @@ -0,0 +1,97 @@ +{ + "resourceSpans": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { + "stringValue": "Website" + } + }, + { + "key": "service.version", + "value": { + "stringValue": "0.4.3" + } + }, + { + "key": "resource.attribute", + "value": { + "stringValue": "Cool." + } + } + ] + }, + "scopeSpans": [ + { + "scope": { + "name": "actually library.name", + "version": "1.0.0", + "attributes": [ + { + "key": "scope span attribute", + "value": { + "stringValue": "This right here!" + } + } + ] + }, + "spans": [ + { + "traceId": "5B8EFFF798038103D269B633813BC60B", + "spanId": "EEE19B7EC3C1B173", + "name": "HTTP Get with 404 and error", + "startTimeUnixNano": "1715181832792586068", + "endTimeUnixNano": "1715181855919708789", + "kind": 2, + "attributes": [ + { + "key": "http.path", + "value": { + "stringValue": "http://productapi/v1/soft_error" + } + }, + { + "key": "http.status_code", + "value": { + "intValue": 404 + } + } + ], + "status": { + "code": 2 + } + }, + { + "traceId": "5B8EFFF798038103D269B633813BC60B", + "spanId": "EEE19B7EC3C1B172", + "parentSpanId": "EEE19B7EC3C1B173", + "name": "HTTP GET with 200 status", + "startTimeUnixNano": "1715181843799532705", + "endTimeUnixNano": "1715181849901447102", + "kind": 2, + "attributes": [ + { + "key": "http.path", + "value": { + "stringValue": "http://productapi/api/product/v1" + } + }, + { + "key": "http.status_code", + "value": { + "intValue": 200 + } + } + ], + "status": { + "code": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file