Liking cljdoc? Tell your friends :D

Examples

Running the examples

These instructions assume a Unix-like environment, with docker-compose to spin up backend instances and curl to issue HTTP requests. All examples use deps.edn for project configuration.

  1. Clone clj-otel repository

    To clone this repository, run the following command :

    git clone https://github.com/steffan-westcott/clj-otel.git
  2. Get OpenTelemetry instrumentation agent JAR

    Before running any of the examples, the file opentelemetry-javaagent.jar must be downloaded and placed in the examples directory. See the releases page for notes and download links.

  3. Start OpenTelemetry Collector and telemetry backend instances

    docker-compose.yaml is a Docker Compose configuration file that can be used to spin up OpenTelemetry Collector, Jaeger, Zipkin and Prometheus instances. The Collector config in file otel-collector-config.yaml is set to forward trace data to Jaeger and Zipkin, while metrics data is forwarded to Prometheus.

    To start the instances, run the following command in the examples directory :

    docker-compose up -d
  4. Load and exercise example

    Select an example from the overview below and follow the notes on starting and exercising the application or services. See the choice of aliases in the deps.edn file to configure telemetry export to an OpenTelemetry Collector or backend of your choice. For example, in examples/auto-sdk-config, to export trace data to the Collector using gRPC with Netty transport, start a REPL with aliases otel, traces-collector-grpc, metrics-none and grpc-netty.

  5. View telemetry data in backend(s)

    • Jaeger : Navigate to http://localhost:16686/search then select an option in the Service dropdown and click the Find Traces button.

    • Zipkin : Navigate to http://localhost:9411/zipkin/ then select search options under the cog icon and click the Run Query button.

    • Prometheus : Navigate to http://localhost:9090/graph then enter a metric name in the expression in the search bar, or click the Open metrics explorer button and select a metric.

  6. Stop OpenTelemetry Collector and telemetry backend instances

    To stop the OpenTelemetry Collector and telemetry backend instances, run the following command in the examples directory :

    docker-compose down -v

Examples overview

Manually instrumented application run with autoconfigured SDK

  • Simplest example; small standalone application

  • Project directory examples/auto-sdk-config

  • Manual instrumentation only, no automatic instrumentation

  • Runs with autoconfigured OpenTelemetry SDK

To start and exercise the application:

  1. Start REPL with chosen aliases in examples/auto-sdk-config/deps.edn

  2. In the REPL, load namespace example.auto-sdk-config

    This will create a single span named squaring with an event my event.

Microservices run with combined automatic and manual instrumentation

  • Two dependent microservices; One microservice has a choice of synchronous and asynchronous implementations

  • Project directories for Ring middleware example in examples/auto-instrument-agent/middleware

  • Project directories for Pedestal interceptors example in examples/auto-instrument-agent/interceptor

  • A combination of automatic and manual instrumentation

  • Runs with OpenTelemetry instrumentation agent

Ring middleware example

To start and exercise the Ring middleware example with combined automatic and manual instrumentation:

  1. Start first REPL with chosen aliases in examples/auto-instrument-agent/middleware/word-length-service/deps.edn

  2. In the first REPL, load namespace example.auto-instrument-agent.middleware.word-length-service. This starts a word-length-service server on port 8081.

  3. Start second REPL with chosen aliases in examples/auto-instrument-agent/middleware/sentence-summary-service/deps.edn

  4. In the second REPL, load one of the following namespaces to start a sentence-summary-service server on port 8080:

    • example.auto-instrument-agent.middleware.sentence-summary-service (synchronous example)

    • example.auto-instrument-agent.middleware.sentence-summary-service-bound-async (asynchronous example using bound context)

    • example.auto-instrument-agent.middleware.sentence-summary-service-explicit-async (asynchronous example using explicit context)

  5. Send an HTTP request to exercise the servers:

    curl -X GET "http://localhost:8080/summary?sentence=Clojure+and+OpenTelemetry"
    # {:word-count 3, :shortest-length 3, :longest-length 13}

    Simulate a downstream 5xx server error by including the word boom in the request:

    curl -X GET "http://localhost:8080/summary?sentence=Things+went+boom"
    # 500 HTTP response

    Simulate a downstream 4xx client error by including the word problem in the request:

    curl -X GET "http://localhost:8080/summary?sentence=User+problem"
    # 400 HTTP response

Pedestal interceptor example

To start and exercise the Pedestal interceptor example with combined automatic and manual instrumentation:

  1. Start first REPL with chosen aliases in examples/auto-instrument-agent/interceptor/planet-service/deps.edn

  2. In the first REPL, load namespace example.auto-instrument-agent.interceptor.planet-service. This starts a planet-service server on port 8081.

  3. Start second REPL with chosen aliases in examples/auto-instrument-agent/interceptor/solar-system-service/deps.edn

  4. In the second REPL, load one of the following namespaces to start a solar-system-service server on port 8080:

    • example.auto-instrument-agent.interceptor.solar-system-service (synchronous example)

    • example.auto-instrument-agent.interceptor.solar-system-service-bound-async (asynchronous example using bound context)

    • example.auto-instrument-agent.interceptor.solar-system-service-explicit-async (asynchronous example using explicit context)

  5. Send an HTTP request to exercise the servers:

    curl -X GET "http://localhost:8080/statistics?planet=jupiter"
    # The planet Jupiter has diameter 142984.0km and gravity 23.1m/s^2.

    Simulate a downstream 5xx server error by requesting data on Saturn:

    curl -X GET "http://localhost:8080/statistics?planet=saturn"
    # 500 HTTP response

    Simulate a downstream 4xx client error by requesting data on Pluto:

    curl -X GET "http://localhost:8080/statistics?planet=pluto"
    # 400 HTTP response

Microservices run with manual instrumentation only

  • Two dependent microservices; One microservice has a choice of synchronous and asynchronous implementations

  • Project directories for Ring middleware example in examples/manual-instrument/middleware

  • Project directories for Pedestal interceptors example in examples/manual-instrument/interceptor

  • Manual instrumentation only, no automatic instrumentation

  • Runs with autoconfigured OpenTelemetry SDK

Ring middleware example

To start and exercise the Ring middleware example with manual instrumentation:

  1. Start first REPL with chosen aliases in examples/manual-instrument/middleware/random-word-service/deps.edn

  2. In the first REPL, load namespace example.manual-instrument.middleware.random-word-service. This starts a random-word-service server on port 8081.

  3. Start second REPL with chosen aliases in examples/manual-instrument/middleware/puzzle-service/deps.edn

  4. In the second REPL, load one of the following namespaces to start a puzzle-service server on port 8080:

    • example.manual-instrument.middleware.puzzle-service (synchronous example)

    • example.manual-instrument.middleware.puzzle-service-bound-async (asynchronous example using bound context)

    • example.manual-instrument.middleware.puzzle-service-explicit-async (asynchronous example using explicit context)

  5. Send an HTTP request to exercise the servers:

    curl -X GET "http://localhost:8080/puzzle?types=verb,noun,adjective,noun"
    # reac abt mixde fgrso

    Simulate a downstream 5xx server error by including the word type fault in the request:

    curl -X GET "http://localhost:8080/puzzle?types=noun,fault,verb"
    # 500 HTTP response

    Simulate a downstream 4xx client error by including an unknown word type in the request:

    curl -X GET "http://localhost:8080/puzzle?types=bogus,noun"
    # 400 HTTP response

Pedestal interceptor example

To start and exercise the Pedestal interceptor example with manual instrumentation:

  1. Start first REPL with chosen aliases in examples/manual-instrument/interceptor/sum-service/deps.edn

  2. In the first REPL, load namespace example.manual-instrument.interceptor.sum-service. This starts a sum-service server on port 8081.

  3. Start second REPL with chosen aliases in examples/manual-instrument/interceptor/average-service/deps.edn

  4. In the second REPL, load one of the following namespaces to start an average-service server on port 8080:

    • example.manual-instrument.interceptor.average-service (synchronous example)

    • example.manual-instrument.interceptor.average-service-bound-async (asynchronous example using bound context)

    • example.manual-instrument.interceptor.average-service-explicit-async (asynchronous example using explicit context)

  5. Send an HTTP request to exercise the servers:

    curl -X GET "http://localhost:8080/average?nums=1,2,3,4"
    # {:odds 2.0, :evens 3.0}

    Simulate a downstream 5xx server error by using odd numbers that add to 13:

    curl -X GET "http://localhost:8080/average?nums=1,2,3,4,9"
    # 500 HTTP response

    Simulate a downstream 4xx client error by giving first number 0:

    curl -X GET "http://localhost:8080/average?nums=0,1,2"
    # 400 HTTP response

Manually instrumented application run with programmatic SDK configuration

  • Small standalone application

  • Project directory examples/programmatic-sdk-config

  • Manual instrumentation only, no automatic instrumentation

  • Runs with programmatically configured OpenTelemetry SDK

To start and exercise the application:

  1. Start REPL with chosen aliases in examples/programmatic-sdk-config/deps.edn

  2. In the REPL, load namespace example.programmatic-sdk-config

  3. Edit and redefine function init-otel! to configure the SDK as desired.

  4. In the REPL, evaluate the following forms to initialise the SDK, exercise an instrumented function, then close the SDK:

    (init-otel!)
    (square 7)
    (close-otel!)
    init-otel! may be evaluated once only.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close