diff options
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4ac57d --- /dev/null +++ b/README.md @@ -0,0 +1,128 @@ +# PerfMark + +![PerfMark Hummingbird](doc/perfmark.png "PerfMark") + +PerfMark is a low-overhead, manually-instrumented, tracing library for Java. Users can add the +tracing function calls to their code to see how long each part takes. + +## Features + +* **Very Low Overhead**: When enabled, tracing a function call adds about **70ns**. Tracing is + done in a lock-free, wait-free, thread local buffer, which avoids interfering with your + latency-sensitive code. + +* **Dynamically Enabled**: PerfMark can be enabled or disabled at runtime. When disabled, + PerfMark has *zero overhead*, taking advantage of the JIT compiler to remove the tracing. + +* **Inter-thread Communication**: Existing profilers have difficulty expressing which thread + wakes up and executes work on another thread. PerfMark allows users to express this + relationship explicitly, making for a clear picture of how code flows. + +* **Small Library Size**: The PerfMark tracing API is only *5 KB* in size, and has minimal + dependencies making it easy to include in other projects. If no backend for recording the trace + is present, the library safely disables itself. + +* **Multiple Java Versions**: The PerfMark API supports Java 6, making it easy to include on + older or constrained environments. Additionally, PerfMark includes optimized backends for + Java 6, Java 7, and Java 9. Each of these backends is automatically loaded at runtime + (if possible) and uses advanced JVM features for maximum speed. + +* **Chrome Trace Viewer Integration**: PerfMark can export to the Chrome Trace Event Format, + making it easy to view in your Web Browser. + +## Usage + +To use PerfMark, add the following dependencies to your `build.gradle`: +``` +dependencies { + implementation 'io.perfmark:perfmark-api:0.25.0' + // Only needed for applications, not libraries. + implementation 'io.perfmark:perfmark-traceviewer:0.25.0' +} +``` + +Or in your `pom.xml`: + +``` + <dependency> + <groupId>io.perfmark</groupId> + <artifactId>perfmark-api</artifactId> + <version>0.25.0</version> + </dependency> +``` + +In your code, add the PerfMark tracing calls like so: + +```java +Map<String, Header> parseHeaders(List<String> rawHeaders) { + try (TaskCloseable task = PerfMark.traceTask("Parse HTTP headers")) { + Map<String, String> headers = new HashMap<>(); + for (String rawHeader : rawHeaders) { + Header header = parseHeader(rawHeader); + headers.put(header.name(), header); + } + return headers; + } +} + +``` + +PerfMark can also be used to record asynchronous work: + +```java +Future<Response> buildResponse() { + try (TaskCloseable task = PerfMark.traceTask("Build Response")) { + Link link = PerfMark.linkOut(); + return executor.submit(() -> { + try (TaskCloseable task2 = PerfMark.traceTask("Async Response")) { + PerfMark.linkIn(link); + return new Response(/* ... */); + } + }); + } +} +``` + +To view the traces in your browser, generate the HTML: + +```java + PerfMark.setEnabled(true); + PerfMark.event("My Task"); + TraceEventViewer.writeTraceHtml(); +``` + +The output looks like: + +![PerfMark Hummingbird](doc/screenshot.png "PerfMark") + +## Configuration +PerfMark provides some System Properties that allow controlling how it initializes. These can be set +by providing them as JVM arguments. (e.g. `-Dio.perfmark.PerfMark.startEnabled=true`) + +* `io.perfmark.PerfMark.startEnabled` controls if PerfMark starts enabled. This boolean property + makes it possible to start tracing calls immediately. This is helpful when it's difficult + to invoke `setEnabled()` on PerfMark before task tracing calls have started. + +* `io.perfmark.PerfMark.debug` controls if PerfMark can log initializing steps. This property + exists to disable class loading of the logger package (currently `java.util.logging`). If + the debug property is set, the logger settings still need to be configured to report the logs. + By default, all PerfMark logs use level `FINE` (SLF4J `DEBUG`) or lower, which means that they + usually need additional setup to print. + + In addition to initialization, the debug property controls if other tracing failures can be + logged. When calls involving deferred execution are used (e.g. + `startTask(T, StringFunction<T>)`), the String function provided may throw an exception. In + these cases, the exception is silently ignored. This makes it easy to ensure the start/stop + call parity is maintained. To view these failures, the debug property can be set to log such + problems. As above, the PerfMark logger should be configured as well to report these. + +## Versioning and API Stability + +PerfMark uses Semantic Versioning, and thus will not break existing APIs within a minor version +update. PerfMark may need to disable some functionality, and thus may need to make some tracing +calls become No-ops. In such cases, it will remain safe to call these functions being recorded. + +## Users + +PerfMark was designed originally for [gRPC](https://github.com/grpc/grpc-java). It is also used +by [Zuul](https://github.com/Netflix/zuul). |