git clone https://github.com/steffan-westcott/clj-otel.git
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.
Clone clj-otel
repository
To clone this repository, run the following command :
git clone https://github.com/steffan-westcott/clj-otel.git
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.
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
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
.
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.
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
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:
Start REPL with chosen aliases in examples/auto-sdk-config/deps.edn
In the REPL, load namespace example.auto-sdk-config
This will create a single span named squaring
with an event my event
.
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
To start and exercise the Ring middleware example with combined automatic and manual instrumentation:
Start first REPL with chosen aliases in examples/auto-instrument-agent/middleware/word-length-service/deps.edn
In the first REPL, load namespace example.auto-instrument-agent.middleware.word-length-service
.
This starts a word-length-service
server on port 8081.
Start second REPL with chosen aliases in examples/auto-instrument-agent/middleware/sentence-summary-service/deps.edn
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)
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
To start and exercise the Pedestal interceptor example with combined automatic and manual instrumentation:
Start first REPL with chosen aliases in examples/auto-instrument-agent/interceptor/planet-service/deps.edn
In the first REPL, load namespace example.auto-instrument-agent.interceptor.planet-service
.
This starts a planet-service
server on port 8081.
Start second REPL with chosen aliases in examples/auto-instrument-agent/interceptor/solar-system-service/deps.edn
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)
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
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
To start and exercise the Ring middleware example with manual instrumentation:
Start first REPL with chosen aliases in examples/manual-instrument/middleware/random-word-service/deps.edn
In the first REPL, load namespace example.manual-instrument.middleware.random-word-service
.
This starts a random-word-service
server on port 8081.
Start second REPL with chosen aliases in examples/manual-instrument/middleware/puzzle-service/deps.edn
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)
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
To start and exercise the Pedestal interceptor example with manual instrumentation:
Start first REPL with chosen aliases in examples/manual-instrument/interceptor/sum-service/deps.edn
In the first REPL, load namespace example.manual-instrument.interceptor.sum-service
.
This starts a sum-service
server on port 8081.
Start second REPL with chosen aliases in examples/manual-instrument/interceptor/average-service/deps.edn
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)
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
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:
Start REPL with chosen aliases in examples/programmatic-sdk-config/deps.edn
In the REPL, load namespace example.programmatic-sdk-config
Edit and redefine function init-otel!
to configure the SDK as desired.
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