Fork me on GitHub

Instrumentation

There are four ways to instrument your own application / library code if desired.

Instrumentation UI

The easiest way to get started with instrumenting your code is to run Glowroot and use its Instrumentation UI, which will help you autocomplete your way to instrumenting your code. Plus, you can apply the instrumentation you create directly in the UI and it will re-transform your existing bytecode on the fly so you can test out your new instrumentation immediately.

Check out the Instrumentation UI on the live demo site https://demo.glowroot.org/config/instrumentation?new, or better, fire up Glowroot on your own application and try it out there!

Agent API

The Agent API is for direct use by application code.

To use the Agent API, your application should only depend on the small Agent API jar file:

<dependency>
  <groupId>org.glowroot</groupId>
  <artifactId>glowroot-agent-api</artifactId>
  <version>0.14.0</version>
</dependency>

The Agent API has a built in empty stub implementation which is used if it doesn't find the Glowroot agent present at runtime.

You can then annotate your application code to provide Glowroot with additional details, e.g.

@Instrumentation.Timer("process invoice")
void processInvoice(Invoice invoice) {
    ...
}

Another annotation example:

@Instrumentation.TraceEntry(message = "process invoice: {{0.invoiceNumber}}",
                       timer = "process invoice")
void processInvoice(Invoice invoice) {
    ...
}

There is also the org.glowroot.agent.api.Glowroot class which contains static methods to further annotate your application transactions/requests, e.g. you can use to provide your own transaction name (which is used for display and aggregation purposes):

void processInvoice(Invoice invoice) {
    Glowroot.setTransactionName("Process Invoice");
    ...
}

For more details see the Agent API Javadoc.

JSON-only Plugin

The easiest way to author a JSON-only plugin is to build your instrumentation in the Instrumentation UI and then hit the 'Export all' button (see https://demo.glowroot.org/config/instrumentation-list). This will generate the JSON instrumentation definition(s) that you can paste into your JSON-only plugin, e.g.

{
  "name": "My Application Plugin",
  "id": "myapp",
  "instrumentation": [
    {
      "className": "com.example.myapp.InvoiceService",
      "methodName": "processInvoice",
      "methodParameterTypes": [
        "com.example.myapp.Invoice"
      ],
      "captureKind": "trace-entry",
      "timerName": "process invoice",
      "traceEntryMessageTemplate": "process invoice: {{0.invoiceNumber}}"
    }
  ]
}

To install a purely JSON-defined plugin, simply drop the json file into glowroot/plugins and restart your JVM.

Plugin API

For more complex plugins you can use the Plugin API. For example, the same instrumentation from above can be written using the Plugin API like this:

package com.example.myplugin;

import org.glowroot.agent.plugin.api.*;
import org.glowroot.agent.plugin.api.weaving.*;

public class InvoiceAspect {

    // Glowroot will inject this interface into com.example.myapp.Invoice's interface list
    // so that the plugin can access it regardless of what class loader loads com.example.myapp.Invoice
    @Shim("com.example.myapp.Invoice")
    public interface Invoice {
        String getInvoiceNumber();
    }

    @Pointcut(className = "com.example.myapp.InvoiceService", methodName = "processInvoice",
            methodParameterTypes = {"com.example.myapp.Invoice"}, timerName = "process invoice")
    public static class ProcessInvoiceAdvice {

        private static final TimerName timer = Agent.getTimerName(ProcessInvoiceAdvice.class);

        @OnBefore
        public static TraceEntry onBefore(ThreadContext context, @BindParameter Invoice invoice) {
            return context.startTraceEntry(
                    MessageSupplier.create("process invoice: {}", invoice.getInvoiceNumber()), timer);
        }

        @OnReturn
        public static void onReturn(@BindTraveler TraceEntry traceEntry) {
            traceEntry.end();
        }

        @OnThrow
        public static void onThrow(@BindThrowable Throwable throwable,
                @BindTraveler TraceEntry traceEntry) {
            traceEntry.endWithError(throwable);
        }
    }
}

and accompanying glowroot.plugin.json file:

{
  "name": "My Application Plugin",
  "id": "myapp",
  "aspects": [
    "com.example.myplugin.InvoiceAspect"
  ]
}

To install the above plugin, build a jar file with your plugin class files and the glowroot.plugin.json file and drop the resulting jar file into glowroot/plugins (and restart your JVM).

For more details see the Plugin API Javadoc.

Also, all of the core plugins are written using the Plugin API, so can be good sources of inspiration for what is possible https://github.com/glowroot/glowroot/tree/master/agent/plugins.