### Docker Compose Setup Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/A_Typical_Example_with_HTTP.jl/index.md Start the necessary services for collecting logs, traces, and metrics using Docker Compose. ```bash cd docs/src/tutorials/A_Typical_Example_with_HTTP.jl docker compose up -d ``` -------------------------------- ### Start Docker Compose for OpenTelemetry Collector and Prometheus Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus_through_Open_Telemetry_Collector/index.md Navigate to the tutorial directory and start the necessary services using Docker Compose. ```bash cd docs/src/tutorials/View_Metrics_in_Prometheus_through_Open_Telemetry_Collector docker compose up ``` -------------------------------- ### Setup Prometheus with Docker Compose Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Clones the OpenTelemetry.jl repository and starts Prometheus using Docker Compose. This is a common method for quick experiments and local testing. ```bash git clone git@github.com:oolong-dev/OpenTelemetry.jl.git cd docs/src/tutorials/View_Metrics_in_Prometheus docker compose up ``` -------------------------------- ### Start Docker Compose for Collector, Loki, and Grafana Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/Send_Logs_to_Loki_via_OpenTelemetry_Collector/index.md Starts the necessary services (OpenTelemetry Collector, Loki, Grafana) using Docker Compose. Navigate to the directory containing the `docker-compose.yml` file before running. ```bash cd docs/src/tutorials/Send_Logs_to_Loki_via_OpenTelemetry_Collector docker compose up ``` -------------------------------- ### Metrics Collection with Counters in Julia Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/README.md Illustrates how to use Meter and Counter to collect metrics. This example shows incrementing a counter with different attributes and observing the collected metrics. ```julia m = Meter("demo_metrics"); c = Counter{Int}("fruit_counter", m); c(; name = "apple", color = "red") c(2; name = "lemon", color = "yellow") c(1; name = "lemon", color = "yellow") c(2; name = "apple", color = "green") c(5; name = "apple", color = "red") c(4; name = "lemon", color = "yellow") r = MetricReader(); r() ``` -------------------------------- ### Start Elastic APM Stack with Docker Compose Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Logs_Traces,_and_Metrics_Together_in_Grafana_ElasticAPM/index.md Quickly set up Elasticsearch, Kibana, and APM Server for testing purposes using Docker Compose. Note: These configurations are for testing only and not recommended for production. ```bash cd docs/src/tutorials/View_Logs_Traces,_and_Metrics_Together_in_Grafana_Logstash_SigNoz docker-compose up ``` -------------------------------- ### Docker Compose for Jaeger Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Traces_in_Jaeger/index.md Starts a Jaeger instance using Docker Compose. Ensure you are in the correct directory before running. ```bash cd docs/src/tutorials/View_Traces_in_Jaeger docker compose up ``` -------------------------------- ### Simulate HTTP Requests Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/A_Typical_Example_with_HTTP.jl/index.md Send multiple GET requests to the locally running HTTP service to generate logs, traces, and metrics. ```julia for _ in 1:10 HTTP.get("http://127.0.0.1:8122") end ``` -------------------------------- ### Setup OpenTelemetry Providers Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/A_Typical_Example_with_HTTP.jl/index.md Configure OpenTelemetry providers for logs, traces, and metrics using HTTP exporters. A PeriodicMetricReader is used to avoid manual metric sending. ```julia using OpenTelemetry using Logging global_logger(OtelSimpleLogger(OtlpHttpLogsExporter())) global_tracer_provider(TracerProvider(;span_processor=SimpleSpanProcessor(OtlpHttpTracesExporter()))) global_meter_provider(MeterProvider()) METRIC_READER = PeriodicMetricReader(MetricReader(OtlpHttpMetricsExporter())) ``` -------------------------------- ### Instrument Distribution Measurement with Histogram Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Demonstrates the setup for a `Histogram` instrument, which records arbitrary numerical values for statistical analysis like latency or size. Default bucket boundaries are provided. ```julia using OpenTelemetrySDK global_meter_provider(MeterProvider()) m = Meter("myapp") latency = Histogram{Float64}("http.server.duration", m; unit = "ms", description = "HTTP server request duration in milliseconds", ) ``` -------------------------------- ### Instrument Synchronous Metrics with Counter Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Shows how to create and use a `Counter` instrument to track monotonically increasing values, with examples of incrementing by default or by a specific amount, and adding attributes. ```julia using OpenTelemetrySDK global_meter_provider(MeterProvider()) m = Meter("http.server"; provider = global_meter_provider()) request_counter = Counter{Int}("http.server.request_count", m; unit = "1", description = "Total number of HTTP requests received", ) # Increment by 1 (default) with attributes request_counter(; method = "GET", status = "200", route = "/api/users") # Increment by explicit amount request_counter(5; method = "POST", status = "201", route = "/api/items") # Read and print all metrics to console r = MetricReader() r() ``` -------------------------------- ### Start Jaeger Collector with Docker Compose Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Logs_Traces,_and_Metrics_Together_in_Grafana_ElasticAPM/index.md Launch a Jaeger collector instance using Docker Compose for trace visualization. Ensure you are in the correct directory. ```bash cd docs/src/tutorials/View_Logs_Traces,_and_Metrics_Together_in_Grafana_ElasticAPM docker-compose -f docker-compose-jaeger.yml up ``` -------------------------------- ### Setup HTTP Service with OpenTelemetry Middleware Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/A_Typical_Example_with_HTTP.jl/index.md Define a simple HTTP handler and register it with a router that includes the OpenTelemetry middleware. The server will sleep randomly and log messages upon receiving requests. ```julia # For now, we still need to manually set the OpenTelemetry middleware layer # Watch: https://github.com/JuliaWeb/HTTP.jl/issues/801#issuecomment-1484097096 function handle(req) sleep(rand()) @info "hello" HTTP.Response(200, "world") end router = HTTP.Router(HTTP.Handlers.default404, HTTP.Handlers.default405, otel_http_middleware) HTTP.register!(router, "/", handle) server = HTTP.serve!(router, "127.0.0.1", 8122) ``` -------------------------------- ### Histogram Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Provides an example of creating and using a Histogram instrument for measuring distributions like latency. ```APIDOC ## Histogram ### Description `Histogram{T}` records arbitrary numerical values intended for statistical analysis (latency, sizes, etc.). Default bucket boundaries are `(0, 5, 10, 25, 50, 75, 100, 250, 500, 1000)`. ### Code Example #### Creating a Histogram ```julia using OpenTelemetrySDK global_meter_provider(MeterProvider()) m = Meter("myapp") latency = Histogram{Float64}("http.server.duration", m; unit = "ms", description = "HTTP server request duration in milliseconds", ) ``` ``` -------------------------------- ### MetricReader for on-demand metric pulling Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Use MetricReader to trigger async instrument callbacks and export current metric data. This example shows a one-shot read to the console. ```julia using OpenTelemetrySDK global_meter_provider(MeterProvider()) m = Meter("myapp") c = Counter{Int}("events", m) c(100) # One-shot read to console r = MetricReader() r() ``` -------------------------------- ### UpDownCounter for synchronous additive and subtractive increments Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Utilize UpDownCounter for synchronous operations that can increase or decrease, like tracking active HTTP requests. Remember to increment on start and decrement on end. ```julia using OpenTelemetrySDK global_meter_provider(MeterProvider()) m = Meter("myapp") active_requests = UpDownCounter{Int}("http.server.active_requests", m; description = "Number of currently active HTTP requests", ) # Simulate request lifecycle active_requests(1; method = "GET") # +1 on request start active_requests(1; method = "POST") active_requests(-1; method = "GET") # -1 on request end r = MetricReader() r() ``` -------------------------------- ### Initialize Meter Provider and Create a Counter Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus_through_Open_Telemetry_Collector/index.md Set up the global meter provider and create a Counter metric to record event occurrences. ```julia using OpenTelemetry global_meter_provider(MeterProvider()); m = Meter("demo_metrics"); c = Counter{UInt}("fruit_counter", m) c(2; name = "apple", color = "green") ``` -------------------------------- ### Configure Samplers in OpenTelemetry.jl Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Demonstrates configuring different samplers: ALWAYS_ON, ParentBasedSampler with TraceIdRatioBased for root traces, and automatic reading from environment variables. ```julia using OpenTelemetrySDK # Always sample (default DEFAULT_ON is ParentBased(root=ALWAYS_ON)) p1 = TracerProvider(; sampler = ALWAYS_ON) ``` ```julia # Sample exactly 5% of root traces, respect parent decisions otherwise p2 = TracerProvider(; sampler = ParentBasedSampler( root_sampler = TraceIdRatioBased(0.05), remote_parent_sampled = ALWAYS_ON, remote_parent_not_sampled = ALWAYS_OFF, )) ``` ```julia # Configure sampler via environment variable at startup: # OTEL_TRACES_SAMPLER=traceidratio OTEL_TRACES_SAMPLER_ARG=0.1 p3 = TracerProvider() # reads OTEL_TRACES_SAMPLER automatically ``` -------------------------------- ### Initialize Default Logger Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/Send_Logs_to_Loki_via_OpenTelemetry_Collector/index.md Sets up the default `OtelSimpleLogger` to print logs to the console. Ensure `OpenTelemetry`, `Term`, and `Logging` are imported. ```julia using OpenTelemetry using Term # optional, for better display using Logging global_logger(OtelSimpleLogger()); @info "Hello, World!" @warn "from" @error "OpenTelemetry.jl!" ``` -------------------------------- ### Configure BatchSpanProcessor for Production Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Sets up a BatchSpanProcessor with OTLP HTTP exporter and configures global tracer provider. Adjust queue size, delay, and batch size for production environments. ```julia batch_processor = BatchSpanProcessor( OtlpHttpTracesExporter(); max_queue_size = 2048, scheduled_delay_millis = 5000, max_export_batch_size = 512, ) global_tracer_provider(TracerProvider(; span_processor = batch_processor)) ``` -------------------------------- ### Create and Use an ObservableGauge Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus_through_Open_Telemetry_Collector/index.md Illustrates how to use ObservableGauge to measure the latest value of a metric, such as temperature readings. ```julia g = ObservableGauge{Float64}("temperature", m) do rand() * 30 - 10 end for _ in 1:10 r() sleep(3) end ``` -------------------------------- ### Meter and Counter Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Demonstrates creating a Meter and a Counter instrument for recording basic synchronous metric data. ```APIDOC ## Meter and Counter ### Description A `Meter` groups related instruments under a named scope. `Counter{T}` is a monotonically-increasing synchronous instrument that records non-negative increments. Call the counter as a functor with an optional amount and keyword attribute dimensions. ### Code Examples #### Creating and Using a Counter ```julia using OpenTelemetrySDK global_meter_provider(MeterProvider()) m = Meter("http.server"; provider = global_meter_provider()) request_counter = Counter{Int}("http.server.request_count", m; unit = "1", description = "Total number of HTTP requests received", ) # Increment by 1 (default) with attributes request_counter(; method = "GET", status = "200", route = "/api/users") # Increment by explicit amount request_counter(5; method = "POST", status = "201", route = "/api/items") # Read and print all metrics to console r = MetricReader() r() ``` ``` -------------------------------- ### Import OpenTelemetry and Term Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Traces_in_Jaeger/index.md Import necessary libraries for OpenTelemetry tracing and optional enhanced terminal output. ```julia using OpenTelemetry using Term # optional, for better display ``` -------------------------------- ### OpenTelemetry SDK Metrics Design Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/OpenTelemetrySDK.md Illustrates the structure of the MeterProvider and its components, including meters, views, and metrics. ```text ``` ┌──────────────────────────────────────────┐ │MeterProvider │ │ │ │ meters │ │ views │ │ │ │ instrument_associated_metric_names │ │ instrument => Set{metric_name} │ │ │ │ metrics │ │ name => metric │ │ ┌───────────────────────────────────┐ │ │ │Metric │ │ │ │ │ │ │ │ name │ │ │ │ description │ │ │ │ criteria │ │ │ │ aggregation │ │ │ │ ┌──────────────────────────┐ │ │ │ │ │AggregationStore │ │ │ │ │ │ │ │ │ │ │ │ attributes => data_point│ │ │ │ │ │ ┌─────────────────┐ │ │ │ │ │ │ │AbstractDataPoint│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ value │ │ │ │ │ │ │ │ start_time │ │ │ │ │ │ │ │ end_time │ │ │ │ │ │ │ │ exemplars │ │ │ │ │ │ │ │ ┌────────────┐ │ │ │ │ │ │ │ │ │Exemplar │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ value │ │ │ │ │ │ │ │ │ │ trace_id │ │ │ │ │ │ │ │ │ │ span_id │ │ │ │ │ │ │ │ │ └────────────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─────────────────┘ │ │ │ │ │ │ │ │ │ │ │ └──────────────────────────┘ │ │ │ │ │ │ │ └───────────────────────────────────┘ │ │ │ └──────────────────────────────────────────┘ ``` ``` -------------------------------- ### Log Messages in Julia Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/README.md Demonstrates how to log messages using the @info, @warn, and @error macros. Ensure OpenTelemetry and Term (optional) are imported. ```julia using OpenTelemetry using Term # optional, for better display using Logging @info "Hello, World!" @warn "from" @error "OpenTelemetry.jl!" ``` -------------------------------- ### Configure TracerProvider for production trace export Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Sets up a TracerProvider with resource information, sampling strategy, and a batch span processor for exporting traces to an OTLP collector. Ensure to flush and close the provider before application shutdown. ```julia using OpenTelemetrySDK using OpenTelemetryExporterOtlpProtoHttp # Production setup: batch-export traces to Jaeger/OTLP collector provider = TracerProvider(; resource = Resource((; "service.name" => "my-julia-service", "service.version" => "1.2.0")), sampler = TraceIdRatioBased(0.1), # sample 10% of traces span_processor = BatchSpanProcessor(OtlpHttpTracesExporter(; url = "http://localhost:4318", headers = ["Authorization" => "Bearer mytoken"], timeout = 10, )), limit_info = LimitInfo(; span_attribute_count_limit = 64), ) global_tracer_provider(provider) with_span("checkout") do with_span("payment-service"; kind = SPAN_KIND_CLIENT) do current_span()["payment.amount"] = 99.99 current_span()["payment.currency"] = "USD" end end flush(provider) # force-flush pending spans before shutdown close(provider) # shut down processors ``` -------------------------------- ### Initialize Pushgateway Exporter Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Initializes a Prometheus Pushgateway exporter. This exporter uses the push-based approach, sending metrics to the default push gateway endpoint each time the reader is called. ```julia prometheus_reader = MetricReader(PrometheusPushgatewayExporter(;resource_to_telemetry_conversion=true)); ``` -------------------------------- ### Import OpenTelemetry.jl Meta Package Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Import the main OpenTelemetry.jl meta package. This is often done for tutorial purposes; in practice, specific sub-packages are usually imported. ```julia using OpenTelemetry ``` -------------------------------- ### Create a Metric Reader Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Instantiate a MetricReader to collect and export metrics. By default, it reads from the global meter provider and exports to the console. ```julia r = MetricReader(); ``` -------------------------------- ### Configure span processors for development and testing Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Demonstrates using CompositSpanProcessor to fan out spans to both a ConsoleExporter for immediate visibility and an InMemoryExporter for testing. SimpleSpanProcessor is used for immediate export. ```julia using OpenTelemetrySDK using OpenTelemetryExporterOtlpProtoHttp mem_exporter = InMemoryExporter() # Composite: send to console AND keep in memory for testing processor = CompositSpanProcessor( SimpleSpanProcessor(ConsoleExporter()), SimpleSpanProcessor(mem_exporter), ) global_tracer_provider(TracerProvider(; span_processor = processor)) with_span("test-span") do current_span()["key"] = "value" end println("Captured spans: ", length(mem_exporter)) # => Captured spans: 1 ``` -------------------------------- ### Configure OtlpHttpMetricsExporter Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus_through_Open_Telemetry_Collector/index.md Initialize the OtlpHttpMetricsExporter to send metrics to the OpenTelemetry Collector via HTTP. ```julia r = MetricReader(OtlpHttpMetricsExporter()) ``` -------------------------------- ### OpenTelemetry SDK Miscellaneous Modules Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/OpenTelemetrySDK.md Provides documentation for miscellaneous modules within the OpenTelemetry SDK. ```julia ```@autodocs Modules = [OpenTelemetrySDK] ``` ``` -------------------------------- ### Configure Tracer Provider for OTLP Export Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Logs_Traces,_and_Metrics_Together_in_Grafana_ElasticAPM/index.md Configure the global tracer provider to use a `SimpleSpanProcessor` with an `OtlpProtoGrpcTraceExporter` to forward spans to an OpenTelemetry Collector. ```julia global_tracer_provider!( TracerProvider( span_processor=SimpleSpanProcessor( OtlpProtoGrpcTraceExporter() ) ) ) ``` -------------------------------- ### Initialize Prometheus Exporter Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Initializes a Prometheus exporter that listens on the default endpoint http://localhost:9496/metrics. This exporter uses the pull-based approach. ```julia prometheus_reader = MetricReader(PrometheusExporter()); ``` -------------------------------- ### OpenTelemetry SDK Samplers Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/OpenTelemetrySDK.md Provides documentation for the sampler modules within the OpenTelemetry SDK. ```julia ```@autodocs Modules = [OpenTelemetrySDK] Pages = ["sampling.jl"] Private = false ``` ``` -------------------------------- ### Create and Use an UpDownCounter Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus_through_Open_Telemetry_Collector/index.md Demonstrates the usage of UpDownCounter for metrics that can increase or decrease, such as account balances. ```julia b = UpDownCounter{Float64}("balance", m) b(1.8) b(-2) r() # upload measurements b(3.3) r() # upload measurements ``` -------------------------------- ### Configure Tracer Provider with BatchSpanProcessor for Jaeger Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Traces_in_Jaeger/index.md Replaces SimpleSpanProcessor with BatchSpanProcessor for more efficient span export to Jaeger, reducing time cost. ```julia global_tracer_provider(TracerProvider(;span_processor=BatchSpanProcessor(OtlpHttpTracesExporter()))) ``` -------------------------------- ### MeterProvider for SDK metrics management Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Configure the SDK metrics provider with resource information, views, and maximum metrics. Pass the MeterProvider to MetricReader for metric collection. ```julia using OpenTelemetrySDK provider = MeterProvider(; resource = Resource((; "service.name" => "billing-service")), views = [View(; instrument_name = "*")], # enable all metrics (default) max_metrics = 1000, ) global_meter_provider(provider) m = Meter("billing"; provider = provider) invoices = Counter{Int}("billing.invoices.processed", m) invoices(1; plan = "pro") invoices(3; plan = "enterprise") # Inspect metrics directly for metric in metrics(provider) println(metric.name, " has ", length(metric), " data points") end ``` -------------------------------- ### Record observations with Counter Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Demonstrates recording observations using a Counter instrument. Ensure a MetricReader is set up to collect these observations. ```julia for _ in 1:100 latency(rand() * 500; route = "/api/data", method = "GET") end r = MetricReader() r() ``` -------------------------------- ### BatchSpanProcessor Configuration Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Configures a BatchSpanProcessor for production use with OtlpHttpTracesExporter and sets it as the global tracer provider. ```APIDOC ## BatchSpanProcessor Configuration ### Description Configures a `BatchSpanProcessor` for production use with `OtlpHttpTracesExporter` and sets it as the global tracer provider. ### Code Example ```julia using OpenTelemetrySDK batch_processor = BatchSpanProcessor( OtlpHttpTracesExporter(); max_queue_size = 2048, scheduled_delay_millis = 5000, max_export_batch_size = 512, ) global_tracer_provider(TracerProvider(; span_processor = batch_processor)) ``` ``` -------------------------------- ### Samplers Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Demonstrates the usage of different samplers: ALWAYS_ON, ALWAYS_OFF, TraceIdRatioBased, and ParentBasedSampler for controlling span recording. ```APIDOC ## Samplers ### Description Samplers control whether a span is recorded and exported. `ALWAYS_ON` records every span, `ALWAYS_OFF` drops all spans, `TraceIdRatioBased` samples a deterministic fraction, and `ParentBasedSampler` defers to the parent span's decision with configurable fallbacks for root spans and remote parents. ### Code Examples #### Always Sample ```julia using OpenTelemetrySDK # Always sample (default DEFAULT_ON is ParentBased(root=ALWAYS_ON)) p1 = TracerProvider(; sampler = ALWAYS_ON) ``` #### ParentBasedSampler with TraceIdRatioBased ```julia # Sample exactly 5% of root traces, respect parent decisions otherwise p2 = TracerProvider(; sampler = ParentBasedSampler( root_sampler = TraceIdRatioBased(0.05), remote_parent_sampled = ALWAYS_ON, remote_parent_not_sampled = ALWAYS_OFF, )) ``` #### Environment Variable Configuration ```julia # Configure sampler via environment variable at startup: # OTEL_TRACES_SAMPLER=traceidratio OTEL_TRACES_SAMPLER_ARG=0.1 p3 = TracerProvider() # reads OTEL_TRACES_SAMPLER automatically ``` ``` -------------------------------- ### Record Events and Links on Spans Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Demonstrates adding custom events with attributes and recording exceptions to the current span. Also shows how to link to a producer span from another trace. ```julia using OpenTelemetrySDK global_tracer_provider(TracerProvider()) with_span("process-message") do # Record a custom timed event push!(Event("message.received"; Symbol("messaging.message_id") => "msg-123")) # Record an exception without rethrowing try error("parse error") catch ex push!(current_span(), ex; is_rethrow_followed = false) span_status!(SPAN_STATUS_ERROR, string(ex)) end # Link to a producer span from another trace producer_ctx = SpanContext (; trace_id = rand(UInt128), span_id = rand(UInt64), is_remote = true, trace_flag = TraceFlag(sampled = true), ) push!(Link(producer_ctx, Dict("messaging.system" => "kafka"))) end ``` -------------------------------- ### Configure OTLP/HTTP exporters for traces, logs, and metrics Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Configures OTLP/HTTP exporters to send telemetry data to an OpenTelemetry Collector or compatible backend. Defaults are read from `OTEL_EXPORTER_OTLP_*` environment variables. Requires `OpenTelemetryExporterOtlpProtoHttp` and `OpenTelemetrySDK`. ```julia using OpenTelemetryExporterOtlpProtoHttp # Traces exporter traces_exp = OtlpHttpTracesExporter(; url = "http://otel-collector:4318", headers = ["X-Honeycomb-Team" => "my-api-key"], timeout = 30, ) # Logs exporter logs_exp = OtlpHttpLogsExporter(; url = "http://otel-collector:4318", ) # Metrics exporter metrics_exp = OtlpHttpMetricsExporter(; url = "http://otel-collector:4318", ) # Wire them up using OpenTelemetrySDK global_tracer_provider(TracerProvider(; span_processor = BatchSpanProcessor(traces_exp) )) global_logger(OtelBatchLogger(logs_exp)) global_meter_provider(MeterProvider()) READER = PeriodicMetricReader(MetricReader(metrics_exp); export_interval_seconds = 60) ``` -------------------------------- ### Create a Meter Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Instantiate a Meter with a specific name. Meters are used to group related instruments. It's implicitly associated with the global meter provider, but explicit provider assignment is recommended. ```julia m = Meter("demo_metrics"); ``` -------------------------------- ### Julia Logging Integration with OpenTelemetry Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Use `OtelSimpleLogger` for immediate export or `OtelBatchLogger` for asynchronous batching of Julia log messages as OpenTelemetry `LogRecord`s. Both correlate logs with active spans. ```julia using OpenTelemetrySDK using OpenTelemetryExporterOtlpProtoHttp using Logging # Simple synchronous logger — exports each log immediately simple_logger = OtelSimpleLogger(OtlpHttpLogsExporter(; url = "http://localhost:4318")) global_logger(simple_logger) global_tracer_provider(TracerProvider(; span_processor = SimpleSpanProcessor(OtlpHttpTracesExporter(; url = "http://localhost:4318")) )) with_span("handle-request") do @info "Request received" user_id = 42 path = "/checkout" @warn "Inventory low" product_id = "sku-7" remaining = 2 @error "Payment failed" error_code = "CARD_DECLINED" end # Logs automatically carry the trace_id/span_id of the enclosing span # Batch logger — queues and exports asynchronously batch_logger = OtelBatchLogger( OtlpHttpLogsExporter(); max_queue_size = 2048, scheduled_delay_millis = 5000, resource = Resource((; "service.name" => "checkout")), ) global_logger(batch_logger) @info "Batch logger active" flush(batch_logger) close(batch_logger) ``` -------------------------------- ### `SimpleSpanProcessor` / `BatchSpanProcessor` / `CompositSpanProcessor` — Span export strategies Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt These classes define strategies for exporting spans. `SimpleSpanProcessor` exports spans immediately, `BatchSpanProcessor` exports them in batches, and `CompositSpanProcessor` fans out to multiple processors. ```APIDOC ## `SimpleSpanProcessor` / `BatchSpanProcessor` / `CompositSpanProcessor` — Span export strategies `SimpleSpanProcessor` exports each span immediately when it ends (good for development). `BatchSpanProcessor` queues spans and exports them in batches on a background task (recommended for production). `CompositSpanProcessor` fans out to multiple processors simultaneously. ```julia using OpenTelemetrySDK using OpenTelemetryExporterOtlpProtoHttp mem_exporter = InMemoryExporter() # Composite: send to console AND keep in memory for testing processor = CompositSpanProcessor( SimpleSpanProcessor(ConsoleExporter()), SimpleSpanProcessor(mem_exporter), ) global_tracer_provider(TracerProvider(; span_processor = processor)) with_span("test-span") do current_span()["key"] = "value" end println("Captured spans: ", length(mem_exporter)) # => Captured spans: 1 ``` ``` -------------------------------- ### Import Term.jl for Enhanced Rendering Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Import the Term.jl package for improved rendering of output in the Julia REPL. This enhances the visibility of metrics and other information. ```julia using Term ``` -------------------------------- ### Inspect and Build SpanContext Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Shows how to inspect the current span's context (trace ID, span ID, sampled status) and build a remote SpanContext, useful for incoming requests. ```julia using OpenTelemetryAPI # Inspect the current span's context with_span("my-op") do ctx = span_context() println("trace_id = ", string(ctx.trace_id, base=16, pad=32)) println("span_id = ", string(ctx.span_id, base=16, pad=16)) println("sampled = ", ctx.trace_flag.sampled) # Mark span successful span_status!(SPAN_STATUS_OK) # Or mark it failed with a description # span_status!(SPAN_STATUS_ERROR, "downstream timeout") end ``` ```julia # Build a remote SpanContext (e.g., from incoming HTTP headers) remote_ctx = SpanContext(; trace_id = parse(UInt128, "4bf92f3577b34da6a3ce929d0e0e4736", base=16), span_id = parse(UInt64, "00f067aa0ba902b7", base=16), is_remote = true, trace_flag = TraceFlag(sampled = true), trace_state = TraceState("vendor1" => "value1", "vendor2" => "value2"), ) ``` -------------------------------- ### `TracerProvider` — SDK tracer provider with sampler, processor, and resource Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Configures how spans are sampled, processed, and exported. It holds a sampler, span processor, ID generator, resource, and limit information. This provider must be set globally or passed explicitly to `Tracer` to activate SDK tracing. ```APIDOC ## `TracerProvider` — SDK tracer provider with sampler, processor, and resource Configures how spans are sampled, processed, and exported. Holds a `sampler`, `span_processor`, `id_generator`, `resource`, and `limit_info`. Must be set as the global provider (or passed explicitly to `Tracer`) to activate SDK tracing. Supports `flush` and `close` lifecycle methods and allows adding extra span processors with `push!`. ```julia using OpenTelemetrySDK using OpenTelemetryExporterOtlpProtoHttp # Production setup: batch-export traces to Jaeger/OTLP collector provider = TracerProvider(; resource = Resource((; "service.name" => "my-julia-service", "service.version" => "1.2.0")), sampler = TraceIdRatioBased(0.1), # sample 10% of traces span_processor = BatchSpanProcessor(OtlpHttpTracesExporter(; url = "http://localhost:4318", headers = ["Authorization" => "Bearer mytoken"], timeout = 10, )), limit_info = LimitInfo(; span_attribute_count_limit = 64), ) global_tracer_provider(provider) with_span("checkout") do with_span("payment-service"; kind = SPAN_KIND_CLIENT) do current_span()["payment.amount"] = 99.99 current_span()["payment.currency"] = "USD" end end flush(provider) # force-flush pending spans before shutdown close(provider) # shut down processors ``` ``` -------------------------------- ### Set Global Meter Provider Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Configure the global meter provider for OpenTelemetry.jl. Replacing the default DummyMeterProvider with MeterProvider() is necessary to enable metric collection and export. ```julia global_meter_provider(MeterProvider()); ``` -------------------------------- ### OpenTelemetry SDK Metrics Modules Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/OpenTelemetrySDK.md Documents the core modules for the metrics implementation in the OpenTelemetry SDK. ```julia ```@autodocs Modules = [OpenTelemetrySDK] Pages = ["aggregation.jl", "datapoint_atomic.jl", "datapoint_lock.jl", "meter_provider.jl", "meter_reader.jl", "view.jl"] Private = false ``` ``` -------------------------------- ### Configure Tracer Provider for Jaeger OTLP/HTTP Export Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Traces_in_Jaeger/index.md Sets the global tracer provider to use a SimpleSpanProcessor with an OtlpHttpTracesExporter to send spans to Jaeger. ```julia global_tracer_provider(TracerProvider(;span_processor=SimpleSpanProcessor(OtlpHttpTracesExporter()))) ``` -------------------------------- ### SpanContext, TraceState, SpanStatus Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Illustrates how to work with SpanContext for span identity, TraceState for vendor-specific data, and SpanStatus for operation outcomes. ```APIDOC ## SpanContext, TraceState, SpanStatus ### Description `SpanContext` carries the immutable identity of a span (`trace_id`, `span_id`, `trace_flag`, `trace_state`) conforming to W3C Trace Context. `TraceState` holds vendor-specific key-value pairs. `SpanStatus` records operation outcome (`SPAN_STATUS_UNSET`, `SPAN_STATUS_OK`, `SPAN_STATUS_ERROR`). ### Code Examples #### Inspecting Current Span Context ```julia using OpenTelemetryAPI # Inspect the current span's context with_span("my-op") do ctx = span_context() println("trace_id = ", string(ctx.trace_id, base=16, pad=32)) println("span_id = ", string(ctx.span_id, base=16, pad=16)) println("sampled = ", ctx.trace_flag.sampled) # Mark span successful span_status!(SPAN_STATUS_OK) # Or mark it failed with a description # span_status!(SPAN_STATUS_ERROR, "downstream timeout") end ``` #### Building a Remote SpanContext ```julia # Build a remote SpanContext (e.g., from incoming HTTP headers) remote_ctx = SpanContext(; trace_id = parse(UInt128, "4bf92f3577b34da6a3ce929d0e0e4736", base=16), span_id = parse(UInt64, "00f067aa0ba902b7", base=16), is_remote = true, trace_flag = TraceFlag(sampled = true), trace_state = TraceState("vendor1" => "value1", "vendor2" => "value2"), ) ``` ``` -------------------------------- ### Event and Link Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Shows how to add timed annotations (Events) and associate spans with other traces (Links) using OpenTelemetry.jl. ```APIDOC ## Event and Link ### Description `Event` records a timestamped annotation with attributes on the current span (including structured exception recording). `Link` associates the span with a span from another trace, useful for messaging and batch scenarios. ### Code Examples #### Recording Events and Links ```julia using OpenTelemetrySDK global_tracer_provider(TracerProvider()) with_span("process-message") do # Record a custom timed event push!(Event("message.received"; Symbol("messaging.message_id") => "msg-123")) # Record an exception without rethrowing try error("parse error") catch ex push!(current_span(), ex; is_rethrow_followed = false) span_status!(SPAN_STATUS_ERROR, string(ex)) end # Link to a producer span from another trace producer_ctx = SpanContext (; trace_id = rand(UInt128), span_id = rand(UInt64), is_remote = true, trace_flag = TraceFlag(sampled = true), ) push!(Link(producer_ctx, Dict("messaging.system" => "kafka"))) end ``` ``` -------------------------------- ### Scoped Context Propagation with `current_context` and `with_context` Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Shows how to retrieve the current context and run functions within an augmented context using `with_context`. Nested calls merge context, and the context is restored upon exiting the block. Use `SUPPRESS_INSTRUMENTATION_KEY` to prevent recursive instrumentation. ```julia using OpenTelemetryAPI # Inspect current context ctx = current_context() # Run code in an augmented context my_key = create_key("my-request-id") with_context(; my_key => "req-abc-123") do println(get(current_context(), my_key, nothing)) # => "req-abc-123" # Nested with_context merges with_context(; my_key => "req-xyz-456") do println(get(current_context(), my_key, nothing)) # => "req-xyz-456" end println(get(current_context(), my_key, nothing)) # => "req-abc-123" (restored) end # Suppress instrumentation inside a block (prevents recursive metric recording) with_context(; SUPPRESS_INSTRUMENTATION_KEY => true) do # HTTP calls here will not create new spans end ``` -------------------------------- ### Configure Logger for OTLP HTTP Export Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/Send_Logs_to_Loki_via_OpenTelemetry_Collector/index.md Configures `OtelSimpleLogger` to export logs using `OtlpHttpLogsExporter`. This is the first step to send logs to an OpenTelemetry Collector. ```julia global_logger(OtelSimpleLogger(exporter=OtlpHttpLogsExporter())) ``` -------------------------------- ### Extract context from incoming headers and continue trace Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Extracts trace context from incoming HTTP headers and continues an existing trace within a new span. Requires `extract_context` and `with_context` functions. ```julia using OpenTelemetrySDK using OpenTelemetryAPI incoming_headers = Dict("traceparent" => "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01") remote_ctx = extract_context(incoming_headers) with_context(remote_ctx) do with_span("server-handler") do sc = span_context() println("Continuing trace: ", string(sc.trace_id, base=16, pad=32)) end end ``` -------------------------------- ### Auto-instrument HTTP.jl server and client requests Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Automatically instruments HTTP.jl server requests and client requests with spans and trace context headers. Requires `instrument!(HTTP)` and `uninstrument!(HTTP)`. Ensure OpenTelemetry SDK, exporters, and HTTP.jl are imported. ```julia using OpenTelemetrySDK using OpenTelemetryExporterOtlpProtoHttp using HTTP using Logging global_logger(OtelSimpleLogger(OtlpHttpLogsExporter())) global_tracer_provider(TracerProvider(; span_processor = SimpleSpanProcessor(OtlpHttpTracesExporter()) )) global_meter_provider(MeterProvider()) METRIC_READER = PeriodicMetricReader(MetricReader(OtlpHttpMetricsExporter())) # Activate HTTP instrumentation _, otel_middleware = instrument!(HTTP) function my_handler(req) @info "Handling request" path = req.target HTTP.Response(200, "OK") end router = HTTP.Router(HTTP.Handlers.default404, HTTP.Handlers.default405, otel_middleware) HTTP.register!(router, "GET", "/api/*", my_handler) server = HTTP.serve!(router, "127.0.0.1", 8080) # Each outgoing client request automatically carries traceparent headers for _ in 1:5 HTTP.get("http://127.0.0.1:8080/api/items") end close(server) close(METRIC_READER) uninstrument!(HTTP) # remove patches ``` -------------------------------- ### Set Global Tracer Provider with Default Span Processor Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Traces_in_Jaeger/index.md Initializes the global tracer provider with a default SimpleSpanProcessor that exports spans to the console. ```julia global_tracer_provider(TracerProvider()); ``` -------------------------------- ### Configure Prometheus Exporter Host Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Reconfigures the Prometheus exporter to listen on all available network interfaces (0.0.0.0) to allow external Prometheus services to fetch metrics. Ensure the previous reader is closed to avoid port conflicts. ```julia close(prometheus_reader) # close it first, or you can choose another port to avoid conflict. prometheus_reader = MetricReader(PrometheusExporter(host="0.0.0.0")); ``` -------------------------------- ### W3C Trace Context Propagation Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Implement W3C Trace Context propagation for outgoing requests by injecting the current span context into headers using `inject_context!`. This enables distributed tracing across services. ```julia using OpenTelemetrySDK using OpenTelemetryAPI # The TraceContextTextMapPropagator is auto-registered when OTEL_PROPAGATORS=tracecontext push!(TraceContextTextMapPropagator()) global_tracer_provider(TracerProvider()) # Outgoing request: inject context into headers outgoing_headers = Dict{String,String}() with_span("call-downstream"; kind = SPAN_KIND_CLIENT) do inject_context!(outgoing_headers) println(outgoing_headers["traceparent"]) # e.g. "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" end ``` -------------------------------- ### View for customizing metric aggregation and attribute filtering Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Configure metric aggregation, attribute filtering, and output metric names using View. Views support glob-style instrument name matching and can be registered on MeterProvider. ```julia using OpenTelemetrySDK # Only keep "route" and "method" attributes on request duration; rename the metric duration_view = View("http.server.request_duration_ms"; instrument_name = "http.server.duration", attribute_keys = ("route", "method"), aggregation = HistogramAgg{Float64}(; boundaries = (1.0, 5.0, 10.0, 50.0, 100.0, 500.0, 1000.0), is_record_min = true, is_record_max = true, ), ) # Drop all instruments from a specific meter drop_view = View(; instrument_name = "debug.*", aggregation = DROP) provider = MeterProvider(; views = [duration_view, drop_view]) global_meter_provider(provider) ``` -------------------------------- ### Add More Fruit Metrics Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Record additional fruit metrics with their counts and dimensions after initializing the MetricReader. This allows for observing updated metric values. ```julia c(10; name = "lychee", color = "red") c(8; name = "longan", color = "yellow") c(3; name = "apple", color = "red") ``` -------------------------------- ### OpenTelemetry SDK Span Processors Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/OpenTelemetrySDK.md Provides documentation for the span processor modules within the OpenTelemetry SDK. ```julia ```@autodocs Modules = [OpenTelemetrySDK] Pages = ["span_processor.jl"] Private = false ``` ``` -------------------------------- ### OpenTelemetry SDK Exporters Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/OpenTelemetrySDK.md Provides documentation for the exporter modules within the OpenTelemetry SDK. ```julia ```@autodocs Modules = [OpenTelemetrySDK] Pages = ["exporter.jl"] Private = false ``` ``` -------------------------------- ### Record Multiple Events with Values and Dimensions Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Record multiple events with specified counts and dimensions. This demonstrates how to increment the counter by specific values for different types of fruits and their colors. ```julia c(2; name = "lemon", color = "yellow") c(1; name = "lemon", color = "yellow") c(2; name = "apple", color = "green") c(5; name = "apple", color = "red") c(4; name = "lemon", color = "yellow") ``` -------------------------------- ### Define Resource and InstrumentationScope for telemetry metadata Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Defines `Resource` for service metadata and `InstrumentationScope` for library identification. These are attached to all telemetry signals for filtering and grouping in backends. Requires `OpenTelemetryAPI` and `OpenTelemetrySDK`. ```julia using OpenTelemetryAPI # Resource with service metadata (merges with OTEL_RESOURCE_ATTRIBUTES env var) res = Resource((; Symbol("service.name") => "payment-service", Symbol("service.version") => "2.1.0", Symbol("deployment.environment") => "production", Symbol("host.name") => gethostname(), )) # InstrumentationScope for a library author scope = InstrumentationScope(; name = "MyLibrary.jl", version = v"0.3.1", schema_url = "https://opentelemetry.io/schemas/1.17.0", ) using OpenTelemetrySDK provider = TracerProvider(; resource = res) global_tracer_provider(provider) tracer = Tracer(; instrumentation_scope = scope, provider = provider) with_span("scoped-operation", tracer) do @info "instrumented" end ``` -------------------------------- ### PeriodicMetricReader for scheduled metric exports Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Configure PeriodicMetricReader to export metrics to an OTLP collector at a specified interval. Ensure the OTLP exporter URL is correct. ```julia using OpenTelemetrySDK using OpenTelemetryExporterOtlpProtoHttp global_meter_provider(MeterProvider()) m = Meter("myapp") c = Counter{Int}("events", m) c(100) # One-shot read to console r = MetricReader() r() # Periodic export to OTLP collector every 30 seconds otlp_reader = PeriodicMetricReader( MetricReader(OtlpHttpMetricsExporter(; url = "http://localhost:4318")); export_interval_seconds = 30, export_timeout_seconds = 10, ) # Runs in background; close to stop sleep(5) close(otlp_reader) ``` -------------------------------- ### Attribute Value Types in OpenTelemetry.jl Source: https://context7.com/oolong-dev/opentelemetry.jl/llms.txt Demonstrates how to set various attribute value types (String, Bool, Int64, Float64, Vector) using BoundedAttributes. ```julia span_attrs = BoundedAttributes(Dict{Symbol,Any}()) span_attrs[:tags] = ["web", "checkout"] span_attrs[:latency] = 123.4 span_attrs[:success] = true ``` -------------------------------- ### Instrument HTTP.jl Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/A_Typical_Example_with_HTTP.jl/index.md Integrate OpenTelemetry with HTTP.jl to automatically create spans for requests and record common metrics. This requires injecting hooks into the HTTP package. ```julia using HTTP _, otel_http_middleware = instrument!(HTTP) ``` -------------------------------- ### Define a Counter Instrument Source: https://github.com/oolong-dev/opentelemetry.jl/blob/master/docs/src/tutorials/View_Metrics_in_Prometheus/index.md Create a Counter instrument named 'fruit_counter' associated with a Meter. This instrument will count occurrences, using 'Int' for its value. Common APM systems support Int and Float64. ```julia c = Counter{Int}("fruit_counter", m) ```