Dice app for java (#2625)

Co-authored-by: Mateusz Rzeszutek <mrzeszutek@splunk.com>
Co-authored-by: Phillip Carter <pcarter@fastmail.com>
This commit is contained in:
Severin Neumann 2023-04-26 04:33:11 +02:00 committed by GitHub
parent 28a1670271
commit d373aa84f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 188 additions and 106 deletions

View File

@ -1,138 +1,221 @@
---
title: Getting Started
description: Get telemetry from a client-server app in less than 5 minutes!
spelling: cSpell:ignore helloworld javaagent
spelling: cSpell:ignore helloworld javaagent springframework autoreconfigure
spelling: cSpell:ignore rolldice aarch Nanos darwin autoconfigure webmvc
weight: 1
---
In this page, you'll learn how to set up and get tracing telemetry from a simple
hello-world client-server example.
This page will show you how to get started with OpenTelemetry in Java.
You'll work with gRPC's [Java Quick start example][], which uses gRPC to
communicate between the client and server. You can work through this page even
if you aren't familiar with gRPC.
You will learn how you can instrument a simple java application automatically,
in such a way that traces, metrics and logs are emitted to the console.
## Get and run the example
## Prerequisites
First, get and run the hello-world example without instrumentation:
Ensure that you have the following installed locally:
1. [Get the example code.][]
2. [Run the example:][] you should see the client output "Hello world".
3. Stop the server before proceeding, if it is still running.
- Java JDK
- [Gradle](https://gradle.org/)
## Run the instrumented example
## Example Application
The following example uses a basic spring boot application.
### Dependencies
Create a folder called `java-simple` and within that folder, create a file
called `build.gradle.kts` with the following content:
```kotlin
plugins {
id("java")
id("org.springframework.boot") version "3.0.6"
id("io.spring.dependency-management") version "1.1.0"
}
sourceSets {
main {
java.setSrcDirs(setOf("."))
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
}
```
### Code
In that same folder, create a file called `DiceApplication.java` and add the
following code to the file:
```java
package otel;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.Banner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DiceApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(DiceApplication.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
}
```
Create another file called `RollController.java` and add the following code to
the file:
```java
package otel;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RollController {
private static final Logger logger = LoggerFactory.getLogger(RollController.class);
@GetMapping("/rolldice")
public String index(@RequestParam("player") Optional<String> player) {
int result = this.getRandomNumber(1, 6);
if (player.isPresent()) {
logger.info("{} is rolling the dice: {}", player.get(), result);
} else {
logger.info("Anonymous player is rolling the dice: {}", result);
}
return Integer.toString(result);
}
public int getRandomNumber(int min, int max) {
return ThreadLocalRandom.current().nextInt(min, max + 1);
}
}
```
To test the application, build and run it:
```console
gradle assemble
java -jar ./build/libs/java-simple.jar
```
## Instrumentation
Next, you'll use a [Java agent to automatically instrument](../automatic) the
client and server at launch time. While you can [configure the Java agent][] in
a number of ways, the steps below use environment variables.
application at launch time. While you can [configure the Java agent][] in a
number of ways, the steps below use environment variables.
1. Download [opentelemetry-javaagent.jar][] from [Releases][] of the
`opentelemetry-java-instrumentation` repo. The JAR file contains the agent
and all automatic instrumentation packages.
{{% alert color="info" %}}<i class="fas fa-edit"></i> Take note of the path
to the JAR file.{{% /alert %}}
2. Set and export variables that specify the Java agent JAR and a [console
exporter][], using a notation suitable for your shell/terminal environment
&mdash; we illustrate a notation for bash-like shells:
1. Download [opentelemetry-javaagent.jar][] from [Releases][] of the
`opentelemetry-java-instrumentation` repo. The JAR file contains the agent
and all automatic instrumentation packages:
```console
$ export JAVA_OPTS="-javaagent:PATH/TO/opentelemetry-javaagent.jar"
$ export OTEL_TRACES_EXPORTER=logging
$ export OTEL_METRICS_EXPORTER=logging
```
```console
curl -L -O https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
```
{{% alert title="Important" color="warning" %}}Replace `PATH/TO` above, with
your path to the JAR.{{% /alert %}}
{{% alert color="info" %}}<i class="fas fa-edit"></i> Take note of the path
to the JAR file.{{% /alert %}}
3. Run the **server** as a background process. For example, for bash-like
shells run:
2. Set and export variables that specify the Java agent JAR and a [console
exporter][], using a notation suitable for your shell/terminal environment
&mdash; we illustrate a notation for bash-like shells:
```console
$ ./build/install/examples/bin/hello-world-server &
[otel.javaagent 2022-03-19 13:38:16:712 +0000] [main] INFO io.opentelemetry.javaagent.tooling.VersionLogger - opentelemetry-javaagent - version: 1.12.0
Mar 19, 2022 1:38:18 PM io.grpc.examples.helloworld.HelloWorldServer start
...
```
```console
$ export JAVA_TOOL_OPTIONS="-javaagent:PATH/TO/opentelemetry-javaagent.jar" \
OTEL_TRACES_EXPORTER=logging \
OTEL_METRICS_EXPORTER=logging \
OTEL_LOGS_EXPORTER=logging
```
Note the output from the `otel.javaagent`.
{{% alert title="Important" color="warning" %}}Replace `PATH/TO` above, with
your path to the JAR.{{% /alert %}}
4. From the _same_ terminal, run the **client**:
3. Run your **application** once again:
```console
$ ./build/install/examples/bin/hello-world-client
[otel.javaagent 2022-03-19 13:38:48:462 +0000] [main] INFO io.opentelemetry.javaagent.tooling.VersionLogger - opentelemetry-javaagent - version: 1.12.0
Mar 19, 2022 1:38:50 PM io.grpc.examples.helloworld.HelloWorldClient greet
INFO: Will try to greet world ...
[Trace output elided -- see below for details]
Mar 19, 2022 1:38:51 PM io.grpc.examples.helloworld.HelloWorldClient greet
INFO: Greeting: Hello world
```
```console
$ java -jar ./build/libs/java-simple.jar
...
```
5. Stop the server process. For example, for bash-like shells run:
Note the output from the `otel.javaagent`.
```console
$ jobs
[1]+ Running ./build/install/examples/bin/hello-world-server &
$ kill %1
...
*** server shut down
```
4. From _another_ terminal, send a request using `curl`:
At step 4, you should have seen trace output from the server and client that
looks something like this (trace output is line-wrapped for convenience):
```console
$ curl localhost:8080/rolldice
```
5. Stop the server process. For example, for bash-like shells run:
At step 4, you should have seen trace & log output from the server and client
that looks something like this (trace output is line-wrapped for convenience):
```sh
[otel.javaagent 2022-03-19 13:38:51:310 +0000] [grpc-default-executor-0] INFO
io.opentelemetry.exporter.logging.LoggingSpanExporter -
'helloworld.Greeter/SayHello' : 150407692a813ceb4e9f49a02c8b1fd0
ee15310978e6f6d3 SERVER [tracer: io.opentelemetry.grpc-1.6:1.12.0]
AttributesMap{data={net.transport=ip_tcp, rpc.grpc.status_code=0,
rpc.service=helloworld.Greeter, thread.id=16, rpc.method=SayHello,
rpc.system=grpc, net.peer.ip=127.0.0.1, thread.name=grpc-default-executor-0,
net.peer.port=44186}, capacity=128, totalAddedValues=9}
[otel.javaagent 2022-03-19 13:38:51:368 +0000] [main] INFO
io.opentelemetry.exporter.logging.LoggingSpanExporter -
'helloworld.Greeter/SayHello' : 150407692a813ceb4e9f49a02c8b1fd0
6ed56cd008f241c5 CLIENT [tracer: io.opentelemetry.grpc-1.6:1.12.0]
AttributesMap{data={net.transport=ip_tcp, net.peer.name=localhost,
rpc.grpc.status_code=0, rpc.service=helloworld.Greeter, thread.id=1,
rpc.method=SayHello, rpc.system=grpc, thread.name=main, net.peer.port=50051},
capacity=128, totalAddedValues=9}
[otel.javaagent 2023-04-24 17:33:54:567 +0200] [http-nio-8080-exec-1] INFO
io.opentelemetry.exporter.logging.LoggingSpanExporter - 'RollController.index' :
70c2f04ec863a956e9af975ba0d983ee 7fd145f5cda13625 INTERNAL [tracer:
io.opentelemetry.spring-webmvc-6.0:1.25.0-alpha] AttributesMap{data=
{thread.id=39, thread.name=http-nio-8080-exec-1}, capacity=128,
totalAddedValues=2}
[otel.javaagent 2023-04-24 17:33:54:568 +0200] [http-nio-8080-exec-1] INFO
io.opentelemetry.exporter.logging.LoggingSpanExporter - 'GET /rolldice' :
70c2f04ec863a956e9af975ba0d983ee 647ad186ad53eccf SERVER [tracer:
io.opentelemetry.tomcat-10.0:1.25.0-alpha] AttributesMap{
data={user_agent.original=curl/7.87.0, net.host.name=localhost,
net.transport=ip_tcp, http.target=/rolldice, net.sock.peer.addr=127.0.0.1,
thread.name=http-nio-8080-exec-1, net.sock.peer.port=53422,
http.route=/rolldice, net.sock.host.addr=127.0.0.1, thread.id=39,
net.protocol.name=http, http.status_code=200, http.scheme=http,
net.protocol.version=1.1, http.response_content_length=1,
net.host.port=8080, http.method=GET}, capacity=128, totalAddedValues=17}
```
At step 5, when stopping the server, you should see an output of all the metrics
collected (metrics output is line-wrapped and shortened for convenience):
```sh
[otel.javaagent 2022-10-18 10:12:12:650 +0200] [Thread-0] INFO
[otel.javaagent 2023-04-24 17:34:25:347 +0200] [PeriodicMetricReader-1] INFO
io.opentelemetry.exporter.logging.LoggingMetricExporter - Received a collection
of 15 metrics for export.
[otel.javaagent 2022-10-18 10:12:12:651 +0200] [Thread-0] INFO
of 19 metrics for export.
[otel.javaagent 2023-04-24 17:34:25:347 +0200] [PeriodicMetricReader-1] INFO
io.opentelemetry.exporter.logging.LoggingMetricExporter - metric:
ImmutableMetricData{resource=Resource{...},
instrumentationScopeInfo=InstrumentationScopeInfo{...},
name=rpc.server.duration, description=The duration of an inbound RPC invocation,
unit=ms, type=HISTOGRAM,
data=ImmutableHistogramData{aggregationTemporality=CUMULATIVE,
points=[ImmutableHistogramPointData{getStartEpochNanos=1666080515038517000,
getEpochNanos=1666080732649264000, getAttributes={net.host.name="localhost",
net.transport="ip_tcp", rpc.grpc.status_code=0, rpc.method="SayHello",
rpc.service="helloworld.Greeter", rpc.system="grpc"}, getSum=20.300248000000003,
getCount=12, hasMin=true, getMin=0.278541, hasMax=true, getMax=16.563833,
getBoundaries=[5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0,
2500.0, 5000.0, 7500.0, 10000.0], getCounts=[11, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0], getExemplars=[ImmutableDoubleExemplarData{filteredAttributes={},
epochNanos=1666080530527597000,
spanContext=ImmutableSpanContext{traceId=f60e0940793cb1dc95bcb86e4668a548,
spanId=9737452b2e78e75f, traceFlags=01,
traceState=ArrayBasedTraceState{entries=[]}, remote=false, valid=true},
value=0.278541}, ImmutableDoubleExemplarData{filteredAttributes={},
epochNanos=1666080519431994000,
spanContext=ImmutableSpanContext{traceId=723ace62b22b2db3bc8323be279e0e55,
spanId=44159949946521e7, traceFlags=01,
traceState=ArrayBasedTraceState{entries=[]}, remote=false, valid=true},
value=16.563833}]}]}}
ImmutableMetricData{resource=Resource{schemaUrl=
https://opentelemetry.io/schemas/1.19.0, attributes={host.arch="aarch64",
host.name="OPENTELEMETRY", os.description="Mac OS X 13.3.1", os.type="darwin",
process.command_args=[/bin/java, -jar, java-simple.jar],
process.executable.path="/bin/java", process.pid=64497,
process.runtime.description="Homebrew OpenJDK 64-Bit Server VM 20",
process.runtime.name="OpenJDK Runtime Environment",
process.runtime.version="20", service.name="java-simple",
telemetry.auto.version="1.25.0", telemetry.sdk.language="java",
telemetry.sdk.name="opentelemetry", telemetry.sdk.version="1.25.0"}},
instrumentationScopeInfo=InstrumentationScopeInfo{name=io.opentelemetry.runtime-metrics,
version=1.25.0, schemaUrl=null, attributes={}},
name=process.runtime.jvm.buffer.limit, description=Total capacity of the buffers
in this pool, unit=By, type=LONG_SUM, data=ImmutableSumData{points=
[ImmutableLongPointData{startEpochNanos=1682350405319221000,
epochNanos=1682350465326752000, attributes=
{pool="mapped - 'non-volatile memory'"}, value=0, exemplars=[]},
ImmutableLongPointData{startEpochNanos=1682350405319221000,
epochNanos=1682350465326752000, attributes={pool="mapped"},
value=0, exemplars=[]},
ImmutableLongPointData{startEpochNanos=1682350405319221000,
epochNanos=1682350465326752000, attributes={pool="direct"},
value=8192, exemplars=[]}], monotonic=false, aggregationTemporality=CUMULATIVE}}
...
```
@ -152,13 +235,8 @@ For more:
https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#logging-exporter
[exporter]:
https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#exporters
[get the example code.]:
https://grpc.io/docs/languages/java/quickstart/#get-the-example-code
[java quick start example]: https://grpc.io/docs/languages/java/quickstart/
[manual instrumentation]: ../manual
[opentelemetry-javaagent.jar]:
https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
[releases]:
https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases
[run the example:]:
https://grpc.io/docs/languages/java/quickstart/#run-the-example

View File

@ -2683,6 +2683,10 @@
"StatusCode": 200,
"LastSeen": "2023-02-15T21:26:16.922966-05:00"
},
"https://gradle.org/": {
"StatusCode": 206,
"LastSeen": "2023-04-24T17:44:10.474433+02:00"
},
"https://grafana.com/": {
"StatusCode": 200,
"LastSeen": "2023-02-15T21:24:27.889758-05:00"