From d2b6a3cef5efa9aad5f05f7c84b6b012d08e2ca8 Mon Sep 17 00:00:00 2001 From: Aleksandar Petrov <8142643+aleks-p@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:07:35 -0400 Subject: [PATCH] Update java examples with latest SDKs (#3812) * Update java span-profiles example with latest SDKs * Bump java SDK version in a few more examples, improve docs further (cherry picked from commit 0d3898b10200ee5e56542c57d362a574d8d5d7b9) --- .../configure-client/language-sdks/java.md | 4 ++-- .../dotnet-span-profiles.md | 2 +- .../trace-span-profiles/go-span-profiles.md | 2 +- .../trace-span-profiles/java-span-profiles.md | 11 +++++---- .../python-span-profiles.md | 2 +- .../trace-span-profiles/ruby-span-profiles.md | 2 +- .../java/fib/Dockerfile | 2 +- .../java/rideshare/Dockerfile | 2 +- .../java/rideshare/build.gradle.kts | 2 +- .../java/simple/Dockerfile | 2 +- examples/tracing/java/Dockerfile | 5 ++-- examples/tracing/java/README.md | 14 +++++------ examples/tracing/java/build.gradle.kts | 2 ++ examples/tracing/java/docker-compose.yml | 1 - .../main/java/org/example/rideshare/Main.java | 4 ++++ .../org/example/rideshare/OrderService.java | 24 +++++++++++-------- 16 files changed, 46 insertions(+), 35 deletions(-) diff --git a/docs/sources/configure-client/language-sdks/java.md b/docs/sources/configure-client/language-sdks/java.md index a055dc882f..cfa737075e 100644 --- a/docs/sources/configure-client/language-sdks/java.md +++ b/docs/sources/configure-client/language-sdks/java.md @@ -51,12 +51,12 @@ First, add the Pyroscope dependency: io.pyroscope agent - 0.15.2 + 0.16.0 ``` ```gradle -implementation("io.pyroscope:agent:0.15.2") +implementation("io.pyroscope:agent:0.16.0") ``` {{< /code >}} diff --git a/docs/sources/configure-client/trace-span-profiles/dotnet-span-profiles.md b/docs/sources/configure-client/trace-span-profiles/dotnet-span-profiles.md index 8d0320a29d..75591779f6 100644 --- a/docs/sources/configure-client/trace-span-profiles/dotnet-span-profiles.md +++ b/docs/sources/configure-client/trace-span-profiles/dotnet-span-profiles.md @@ -7,7 +7,7 @@ weight: 103 # Span profiles with Traces to profiles for .NET -Span Profiles represents a shift in profiling methodology. +Span Profiles represent a shift in profiling methodology. Traditional continuous profiling provides an application-wide view over fixed intervals. In contrast, Span Profiles delivers focused, dynamic analysis on specific execution scopes within applications, such as individual requests or specific trace spans. diff --git a/docs/sources/configure-client/trace-span-profiles/go-span-profiles.md b/docs/sources/configure-client/trace-span-profiles/go-span-profiles.md index 7ccd47814e..a072f9a632 100644 --- a/docs/sources/configure-client/trace-span-profiles/go-span-profiles.md +++ b/docs/sources/configure-client/trace-span-profiles/go-span-profiles.md @@ -10,7 +10,7 @@ weight: 100 # Span profiles with Traces to profiles for Go -Span Profiles represents a major shift in profiling methodology, enabling deeper analysis of both tracing and profiling data. +Span Profiles represent a major shift in profiling methodology, enabling deeper analysis of both tracing and profiling data. Traditional continuous profiling provides an application-wide view over fixed intervals. In contrast, Span Profiles delivers focused, dynamic analysis on specific execution scopes within applications, such as individual requests or specific trace spans. diff --git a/docs/sources/configure-client/trace-span-profiles/java-span-profiles.md b/docs/sources/configure-client/trace-span-profiles/java-span-profiles.md index 5263ebae3d..27d5a9ec79 100644 --- a/docs/sources/configure-client/trace-span-profiles/java-span-profiles.md +++ b/docs/sources/configure-client/trace-span-profiles/java-span-profiles.md @@ -7,7 +7,7 @@ weight: 101 # Span profiles with Traces to profiles for Java -Span Profiles represents a major shift in profiling methodology, enabling deeper analysis of both tracing and profiling data. +Span Profiles represent a major shift in profiling methodology, enabling deeper analysis of both tracing and profiling data. Traditional continuous profiling provides an application-wide view over fixed intervals. In contrast, Span Profiles delivers focused, dynamic analysis on specific execution scopes within applications, such as individual requests or specific trace spans. @@ -40,7 +40,8 @@ Your applications must be instrumented for profiling and tracing before you can ## Configure the otel-profiling-java package -To start collecting Span Profiles for your Java application, you need to include [otel-profiling-java](https://github.com/pyroscope-io/otel-profiling-java) as an extension to your application. +To start collecting Span Profiles for your Java application, you need to include [otel-profiling-java](https://github.com/pyroscope-io/otel-profiling-java) as an extension +for the [OTel Java agent](https://opentelemetry.io/docs/zero-code/java/agent/). Assuming you have this sample application Docker image: @@ -61,7 +62,7 @@ EXPOSE 5000 ## Add required libararies ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.17.0/opentelemetry-javaagent.jar opentelemetry-javaagent.jar -ADD https://repo1.maven.org/maven2/io/pyroscope/otel/0.10.1.11/otel-0.10.1.11.jar pyroscope-otel.jar +ADD https://repo1.maven.org/maven2/io/pyroscope/otel/0.11.0/otel-0.11.0.jar pyroscope-otel.jar ENV PYROSCOPE_APPLICATION_NAME=my-app ENV PYROSCOPE_FORMAT=jfr @@ -83,14 +84,14 @@ ENV PYROSCOPE_SERVER_ADDRESS=http://localhost:4040 # ENV PYROSCOPE_BASIC_AUTH_USER=123 ## Grafana Cloud Username # ENV PYROSCOPE_BASIC_AUTH_PASSWORD=glc_secret ## Grafana Cloud Password / API Token -## Add the pyroscope and the opentelemetry java-agents +## Add the opentelemetry java agent CMD ["java", "-Dserver.port=5000", "-javaagent:./opentelemetry-javaagent.jar", "-jar", "./my-app.jar" ] ``` ### Available configuration options | Flag | Description | Default | -| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| | `otel.pyroscope.start.profiling` | Boolean flag to start PyroscopeAgent. Set to false if you want to start the PyroscopeAgent manually. | `true` | | `otel.pyroscope.root.span.only` | Boolean flag. When enabled, the tracer will annotate only the first span created locally (the root span), but the profile will include samples of all the nested spans. This may be helpful in case if the trace consists of multiple spans shorter than 10ms and profiler can't collect and annotate samples properly. | `true` | | `otel.pyroscope.add.span.name` | Boolean flag. Controls whether the span name added to profile labels. | `true` | diff --git a/docs/sources/configure-client/trace-span-profiles/python-span-profiles.md b/docs/sources/configure-client/trace-span-profiles/python-span-profiles.md index efe470a176..0efb17a680 100644 --- a/docs/sources/configure-client/trace-span-profiles/python-span-profiles.md +++ b/docs/sources/configure-client/trace-span-profiles/python-span-profiles.md @@ -7,7 +7,7 @@ weight: 104 # Span profiles with Traces to profiles for Python -Span Profiles represents a major shift in profiling methodology, enabling deeper analysis of both tracing and profiling data. +Span Profiles represent a major shift in profiling methodology, enabling deeper analysis of both tracing and profiling data. Traditional continuous profiling provides an application-wide view over fixed intervals. In contrast, Span Profiles delivers focused, dynamic analysis on specific execution scopes within applications, such as individual requests or specific trace spans. diff --git a/docs/sources/configure-client/trace-span-profiles/ruby-span-profiles.md b/docs/sources/configure-client/trace-span-profiles/ruby-span-profiles.md index 402481ae8f..4ab7f6afcf 100644 --- a/docs/sources/configure-client/trace-span-profiles/ruby-span-profiles.md +++ b/docs/sources/configure-client/trace-span-profiles/ruby-span-profiles.md @@ -7,7 +7,7 @@ weight: 102 # Span profiles with Traces to profiles for Ruby -Span Profiles represents a major shift in profiling methodology, enabling deeper analysis of both tracing and profiling data. +Span Profiles represent a major shift in profiling methodology, enabling deeper analysis of both tracing and profiling data. Traditional continuous profiling provides an application-wide view over fixed intervals. In contrast, Span Profiles delivers focused, dynamic analysis on specific execution scopes within applications, such as individual requests or specific trace spans. diff --git a/examples/language-sdk-instrumentation/java/fib/Dockerfile b/examples/language-sdk-instrumentation/java/fib/Dockerfile index b7b334fab1..9fbe636e93 100644 --- a/examples/language-sdk-instrumentation/java/fib/Dockerfile +++ b/examples/language-sdk-instrumentation/java/fib/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /opt/app RUN apt-get update && apt-get install ca-certificates -y && update-ca-certificates && apt-get install -y git -ADD https://github.com/grafana/pyroscope-java/releases/download/v0.15.2/pyroscope.jar /opt/app/pyroscope.jar +ADD https://github.com/grafana/pyroscope-java/releases/download/v0.16.0/pyroscope.jar /opt/app/pyroscope.jar COPY Main.java ./ diff --git a/examples/language-sdk-instrumentation/java/rideshare/Dockerfile b/examples/language-sdk-instrumentation/java/rideshare/Dockerfile index d307d7a4cb..39ff829ae5 100644 --- a/examples/language-sdk-instrumentation/java/rideshare/Dockerfile +++ b/examples/language-sdk-instrumentation/java/rideshare/Dockerfile @@ -37,6 +37,6 @@ COPY --from=builder /opt/app/build/libs/rideshare-1.0-SNAPSHOT.jar /opt/app/buil WORKDIR /opt/app -ADD https://github.com/grafana/pyroscope-java/releases/download/v0.15.2/pyroscope.jar /opt/app/pyroscope.jar +ADD https://github.com/grafana/pyroscope-java/releases/download/v0.16.0/pyroscope.jar /opt/app/pyroscope.jar CMD sh -c "exec java -Dserver.port=${RIDESHARE_LISTEN_PORT} -javaagent:pyroscope.jar -jar ./build/libs/rideshare-1.0-SNAPSHOT.jar" diff --git a/examples/language-sdk-instrumentation/java/rideshare/build.gradle.kts b/examples/language-sdk-instrumentation/java/rideshare/build.gradle.kts index de7719422b..40f4d1d681 100644 --- a/examples/language-sdk-instrumentation/java/rideshare/build.gradle.kts +++ b/examples/language-sdk-instrumentation/java/rideshare/build.gradle.kts @@ -12,7 +12,7 @@ repositories { } dependencies { - implementation("io.pyroscope:agent:0.15.2") + implementation("io.pyroscope:agent:0.16.0") implementation("org.springframework.boot:spring-boot-starter-web") testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2") diff --git a/examples/language-sdk-instrumentation/java/simple/Dockerfile b/examples/language-sdk-instrumentation/java/simple/Dockerfile index 562ca4a0a3..66abb42b76 100644 --- a/examples/language-sdk-instrumentation/java/simple/Dockerfile +++ b/examples/language-sdk-instrumentation/java/simple/Dockerfile @@ -2,7 +2,7 @@ FROM openjdk:11.0.11-jdk WORKDIR /opt/app -ADD https://github.com/grafana/pyroscope-java/releases/download/v0.15.2/pyroscope.jar /opt/app/pyroscope.jar +ADD https://github.com/grafana/pyroscope-java/releases/download/v0.16.0/pyroscope.jar /opt/app/pyroscope.jar COPY Main.java ./Main.java RUN javac Main.java diff --git a/examples/tracing/java/Dockerfile b/examples/tracing/java/Dockerfile index df828062b5..468da6d5d0 100644 --- a/examples/tracing/java/Dockerfile +++ b/examples/tracing/java/Dockerfile @@ -42,8 +42,9 @@ COPY --from=builder /opt/app/build/libs/rideshare-1.0-SNAPSHOT.jar /opt/app/buil WORKDIR /opt/app ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.17.0/opentelemetry-javaagent.jar opentelemetry-javaagent.jar -ADD https://repo1.maven.org/maven2/io/pyroscope/otel/0.10.1.11/otel-0.10.1.11.jar pyroscope-otel.jar +ADD https://repo1.maven.org/maven2/io/pyroscope/agent/0.16.0/agent-0.16.0.jar pyroscope.jar +ADD https://repo1.maven.org/maven2/io/pyroscope/otel/0.11.0/otel-0.11.0.jar pyroscope-otel.jar EXPOSE 5000 -CMD ["java", "-Dserver.port=5000", "-javaagent:./opentelemetry-javaagent.jar", "-jar", "./build/libs/rideshare-1.0-SNAPSHOT.jar" ] +CMD ["java", "-Dserver.port=5000", "-javaagent:./pyroscope.jar", "-javaagent:./opentelemetry-javaagent.jar", "-jar", "./build/libs/rideshare-1.0-SNAPSHOT.jar" ] diff --git a/examples/tracing/java/README.md b/examples/tracing/java/README.md index 7bc0b64e61..59b5107731 100644 --- a/examples/tracing/java/README.md +++ b/examples/tracing/java/README.md @@ -7,34 +7,34 @@ The docker compose consists of: - Grafana The `rideshare` app generate traces and profiling data that should be available in Grafana. -Pyroscope and Tempo datasources are provisioned automatically. +Datasources for Pyroscope and Tempo are provisioned automatically. ### Build and run The project can be run locally with the following commands: ```shell -# Pull latest pyroscope and grafana images: +# (optionally) pull latest pyroscope and grafana images: docker pull grafana/pyroscope:latest docker pull grafana/grafana:latest -docker compose up +# build and run the example +docker compose up --build ``` -Navigate to the [Explore page](http://localhost:3000/explore?schemaVersion=1&panes=%7B%22yM9%22:%7B%22datasource%22:%22tempo%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22datasource%22:%7B%22type%22:%22tempo%22,%22uid%22:%22tempo%22%7D,%22queryType%22:%22traceqlSearch%22,%22limit%22:20,%22tableType%22:%22traces%22,%22filters%22:%5B%7B%22id%22:%22e73a615e%22,%22operator%22:%22%3D%22,%22scope%22:%22span%22%7D,%7B%22id%22:%22service-name%22,%22tag%22:%22service.name%22,%22operator%22:%22%3D%22,%22scope%22:%22resource%22,%22value%22:%5B%22ride-sharing-app%22%5D,%22valueType%22:%22string%22%7D%5D%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D%7D&orgId=1), select a trace and click on a span that has a linked profile: +Navigate to the [Explore page](http://localhost:3000/explore?schemaVersion=1&panes=%7B%22f36%22:%7B%22datasource%22:%22tempo%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22datasource%22:%7B%22type%22:%22tempo%22,%22uid%22:%22tempo%22%7D,%22queryType%22:%22traceqlSearch%22,%22limit%22:20,%22tableType%22:%22traces%22,%22filters%22:%5B%7B%22id%22:%22e73a615e%22,%22operator%22:%22%3D%22,%22scope%22:%22span%22%7D,%7B%22id%22:%22service-name%22,%22tag%22:%22service.name%22,%22operator%22:%22%3D%22,%22scope%22:%22resource%22,%22value%22:%5B%22rideshare.java.push.app%22%5D,%22valueType%22:%22string%22%7D%5D%7D%5D,%22range%22:%7B%22from%22:%22now-15m%22,%22to%22:%22now%22%7D%7D%7D&orgId=1), select a trace and click on a span that has a linked profile: ![image](https://github.com/grafana/otel-profiling-go/assets/12090599/31e33cd1-818b-4116-b952-c9ec7b1fb593) By default, only the root span gets labeled (the first span created locally): such spans are marked with the _link_ icon -and have `pyroscope.profile.id` attribute set to the corresponding span ID. +and have the `pyroscope.profile.id` attribute set to the corresponding span ID. Please note that presence of the attribute does not necessarily indicate that the span has a profile: stack trace samples might not be collected, if the utilized CPU time is less than the sample interval (10ms). ### Instrumentation -- `rideshare` demo application instrumented with OpenTelemetry: [OTel integration](https://github.com/grafana/otel-profiling-java) -- `pyroscope` itself is instrumented with `opentracing-go` SDK and [`spanprofiler`](https://github.com/grafana/dskit/tree/main/spanprofiler) for profiling integration. +The `rideshare` demo application is instrumented with OpenTelemetry: [OTel integration](https://github.com/grafana/otel-profiling-java) ### Grafana Tempo configuration diff --git a/examples/tracing/java/build.gradle.kts b/examples/tracing/java/build.gradle.kts index 0e4a9d1a63..bd5b9d9263 100644 --- a/examples/tracing/java/build.gradle.kts +++ b/examples/tracing/java/build.gradle.kts @@ -12,6 +12,8 @@ repositories { } dependencies { + implementation("io.pyroscope:agent:0.16.0") + implementation("org.springframework.boot:spring-boot-starter-web") testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2") diff --git a/examples/tracing/java/docker-compose.yml b/examples/tracing/java/docker-compose.yml index 2830ff692a..266fc909a6 100644 --- a/examples/tracing/java/docker-compose.yml +++ b/examples/tracing/java/docker-compose.yml @@ -17,7 +17,6 @@ services: OTEL_TRACES_SAMPLER: always_on OTEL_PROPAGATORS: tracecontext REGION: us-east - PYROSCOPE_LABELS: region=us-east PYROSCOPE_SERVER_ADDRESS: http://pyroscope:4040 build: context: . diff --git a/examples/tracing/java/src/main/java/org/example/rideshare/Main.java b/examples/tracing/java/src/main/java/org/example/rideshare/Main.java index 1004e1ad49..389d694b90 100644 --- a/examples/tracing/java/src/main/java/org/example/rideshare/Main.java +++ b/examples/tracing/java/src/main/java/org/example/rideshare/Main.java @@ -1,5 +1,6 @@ package org.example.rideshare; +import io.pyroscope.labels.Pyroscope; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -8,6 +9,9 @@ @SpringBootApplication public class Main { public static void main(String[] args) { + Pyroscope.setStaticLabels(Map.of( + "region", System.getenv("REGION"), + "hostname", System.getenv("HOSTNAME"))); SpringApplication.run(Main.class, args); } } diff --git a/examples/tracing/java/src/main/java/org/example/rideshare/OrderService.java b/examples/tracing/java/src/main/java/org/example/rideshare/OrderService.java index 34a5f49408..40620c5e83 100644 --- a/examples/tracing/java/src/main/java/org/example/rideshare/OrderService.java +++ b/examples/tracing/java/src/main/java/org/example/rideshare/OrderService.java @@ -1,5 +1,7 @@ package org.example.rideshare; +import io.pyroscope.labels.LabelsSet; +import io.pyroscope.labels.Pyroscope; import org.springframework.stereotype.Service; import java.time.Duration; @@ -14,16 +16,18 @@ public class OrderService { public static final Duration OP_DURATION = Duration.of(200, ChronoUnit.MILLIS); public synchronized void findNearestVehicle(int searchRadius, String vehicle) { - AtomicLong i = new AtomicLong(); - Instant end = Instant.now() - .plus(OP_DURATION.multipliedBy(searchRadius)); - while (Instant.now().compareTo(end) <= 0) { - i.incrementAndGet(); - } - - if (vehicle.equals("car")) { - checkDriverAvailability(searchRadius); - } + Pyroscope.LabelsWrapper.run(new LabelsSet("vehicle", vehicle), () -> { + AtomicLong i = new AtomicLong(); + Instant end = Instant.now() + .plus(OP_DURATION.multipliedBy(searchRadius)); + while (Instant.now().compareTo(end) <= 0) { + i.incrementAndGet(); + } + + if (vehicle.equals("car")) { + checkDriverAvailability(searchRadius); + } + }); } private void checkDriverAvailability(int searchRadius) {