Distributed tracing is a critical piece of application observability. But instrumenting your applications with traces is not always easy.
Whether you are an SRE or a developer, you need application observability. But you might not prefer to instrument code. That is where the Wavefront Tracing Agent for Java comes in handy, as it provides application observability without needing any code change. The Tracing Agent consists of a Java SpecialAgent and a Wavefront Tracer Plugin. The Java Special Agent alters your application’s bytecode to automatically instrument open-source components (such as Java Web Servlet, HttpClient, and Spring) with OpenTracing traces. The Wavefront Tracer Plugin processes and sends these traces to Wavefront. By attaching the Tracing Agent to your application, you will be able to visualize traces, span logs, and RED metrics in Wavefront without having to write any code. Unlike traditional APM agents, the Wavefront Tracing Agent for Java is OpenTracing compliant.
Using the Tracing Agent
Let’s walk through the steps needed to attach the Tracing Agent to your application and start sending traces to Wavefront. Say you have a BeachShirts application that has a Shopping service that you would like to instrument, and that the service is contained in shopping.jar.
- Navigate to the directory that holds shopping.jar.
- Download the latest version of the Java SpecialAgent to your directory. At the time of writing, the latest version is 1.5.0.
wget -O opentracing-specialagent-1.5.0.jar "http://central.maven.org/maven2/io/opentracing/contrib/specialagent/opentracing-specialagent/1.5.0/opentracing-specialagent-1.5.0.jar"
Any version of the SpecialAgent starting from 1.4.1 comes packaged with the Wavefront Tracer Plugin and will therefore work.
- Create a tracer.properties file in your directory. This file is used to configure your Wavefront Tracer instance for reporting (via either direct ingestion or Wavefront proxy) and for tags specific to your application. You can use the following as a template for your tracer.properties file:
# Required application tags wf.application=beachshirts-via-agent wf.service=shopping # Optional application tags wf.cluster=us-west-2 wf.shard=primary wf.customTags=location,Palo Alto,env,prod # If reporting via direct ingestion: wf.reportingMechanism=direct wf.server=<INSERT_WF_SERVER> wf.token=<INSERT_WF_TOKEN> # If reporting via Wavefront proxy: #wf.reportingMechanism=proxy #wf.proxyHost<INSERT_WF_PROXY_HOSTNAME> #wf.proxyMetricsPort=2878 #wf.proxyDistributionsPort=2878 #wf.proxyTracingPort=30000
You can reference the configuration properties here.
- Statically attach the SpecialAgent to your service and enable the Wavefront Tracer Plugin at startup:
java -javaagent:opentracing-specialagent-1.5.0.jar -Dsa.tracer=wavefront -jar shopping.jar
With that, you are now running an instrumented version of your Shopping service, and you should begin to see traces and metrics for your service in Wavefront.
Let’s say that your BeachShirts application has another service called Styling that is contained in styling.jar. We can use the same approach to instrument this service as well. If you are running both services on a single machine, you do not need to download multiple versions of the SpecialAgent JAR. Just make sure to specify the full path of your JARs in your command as needed.
As an alternative to using a tracer.properties file, you can specify Wavefront configuration properties as command-line arguments. You can even use a combination of a properties file and command-line arguments. For instance, you could reuse the same tracer.properties file from above for Styling but override the service name in the command line. Just run the following command from the same directory as above:
java -javaagent:opentracing-specialagent-1.5.0.jar -Dsa.tracer=wavefront -Dwf.service=styling -jar <INSERT_STYLING_JAR_PATH>
Let’s say that your BeachShirts application consists of a third and final service called Delivery. Still, this service is already running. You do not want to disrupt its operation by restarting it to attach the Tracing Agent statically. So instead, you can dynamically attach the Tracing Agent to your running service.
To do so, first, run jps to find the process identifier (PID) of your running service. Then dynamically attach the Tracing Agent to the process by issuing one of the following commands depending on the version of JDK that is installed.
For JDK 8:
java -Xbootclasspath/a:$JAVA_HOME/lib/tools.jar -Dsa.tracer=wavefront -Dwf.service=delivery -jar opentracing-specialagent-1.5.0.jar <INSERT_PID>
For JDK 9+:
java -Dsa.tracer=wavefront -Dwf.service=delivery -jar opentracing-specialagent-1.5.0.jar <INSERT_PID>
Agent vs. SDKs
Now you might be wondering whether you should use the Tracing Agent or Wavefront SDKs to instrument your application for tracing. The Tracing Agent is incredibly easy to get started with because it requires no additional code, and it instruments a vast number of open-source Java components. For more advanced users, Wavefront’s Java SDKs provide enhanced tracing support for Jersey, JAX-RS, and gRPC that includes more descriptive operation names, more configuration options, and better performance due to the overhead that comes with running a Java agent. Both provide you with out-of-the-box JVM and RED metrics. And both allow you to further instrument your proprietary code with OpenTracing spans, although for the Tracing Agent, you can only do so if you use static attach.
|Wavefront Tracing Agent||Wavefront SDKs|
|No code to write||Better performance|
|Support for numerous third-library libraries||Enhanced support for select third-party libraries (with more descriptive span names, error-tag propagation, and advanced configuration options)|
|OpenTracing support for Java||OpenTracing support for Java, C#, Python, Go|
Agent + SDKs
It is even possible to take a hybrid approach where you use the Tracing Agent to instrument some services and SDKs to instrument other services within your application.
For example, let’s say that you would like to continue to use the Tracing Agent for your Styling and Delivery services because they use components (like AWS or OkHttp) that would not get automatically instrumented by Wavefront SDKs. But you would like to instrument your Shopping service, which uses a Jersey-compliant framework, with the Wavefront Jersey SDK to get more descriptive span names. Because both the Tracing Agent and the SDK are OpenTracing-compliant, your span contexts will still be propagated correctly, and your traces will be fully intact. So when you instrument your Shopping service with the SDK instead of the Tracing Agent, you would see traces similar to the following:
This trace looks very similar to the trace displayed further above, but notice that the server-side span for the Shopping service now includes the Jersey resource class and method (ShoppingWebResource.orderShirts), providing you with a better idea of what the span, and the trace as a whole, represents at a glance.
This hybrid approach allows you to choose the best solution for each of your services based on the respective benefits of the Tracing Agent and the SDKs. And if you have services written in C#, Python, or Go, you can also integrate those services into your traces using Wavefront’s language-specific SDK offerings.
The Wavefront Tracing Agent presents an extremely easy way to instrument your Java application with OpenTracing, offering automated instrumentation and compatibility with a large number of third-party libraries. It provides you with out-of-the-box traces, RED metrics, JVM metrics, and span logs in Wavefront that give critical insights into your application’s performance. It is quick and easy to use, so give it a try!Get Started with Wavefront Follow @WavefrontHQ
The post Wavefront Introduces Java Tracing Agent Delivering Out-of-the-Box Application Observability appeared first on Wavefront by VMware.
About the AuthorMore Content by Han Zhang