btrace is a free, open source monitoring & observability project written in Java and released under Apache-2.0. It has 5,997 GitHub stars, 953 forks and 6 open issues, and was last pushed 2 hours ago. On this registry it ranks #79 of 270 tracked projects in Monitoring & Observability, with 5 head-to-head comparisons available. It gained 2 stars over the last 30 tracked days.

What is btrace?

What it is

BTrace is an open-source dynamic tracing and diagnostics tool for Java applications, distributed under the Apache-2.0 license and maintained in the Java and JVM ecosystem. It works by attaching to a running Java Virtual Machine and dynamically instrumenting bytecode at runtime, injecting tracing code into classes that are already loaded. The project sits in the Infrastructure & Operations / Monitoring & Observability category and carries the topics tracing, observability, diagnostics, profiling, bytecode-instrumentation, runtime-instrumentation, java-agent and dtrace.

The concrete problem it solves is the cost of restarting or rebuilding a Java service in order to understand its runtime behaviour. Instead of redeploying an application with added logging, or reproducing a fault in a staging environment, BTrace lets an operator attach to the live JVM and observe method entry and exit, timings, field access and allocations without a restart and without recompilation. The README describes the model as production-safe: scripts pass through verification so that a trace script cannot crash the application being traced. The project has been public for roughly twelve years, with 5,995 stars, 956 forks and 6 open issues at the time of writing.

Key capabilities

  • Dynamic instrumentation of running JVMs with no restart and no recompilation.
  • Script verification that keeps a submitted trace from crashing the target application.
  • Probes for method entry and exit, timings, field access and allocations.
  • Bytecode injection designed for low overhead and minimal performance impact.
  • DTrace-style oneliner probes, for example matching java.sql.Statement::execute* with an @return action that prints the method and its duration.
  • Custom probe classes written against annotations such as @BTrace, @OnMethod, @Self and @Duration.
  • Extension support for integrations such as StatsD and other custom extension points.

Who uses it and how

  • Operators attach to a live JVM to measure method duration, as in the documented oneliner that prints method and duration for java.sql.Statement::execute*.
  • Engineers track exceptions at runtime by tracing java.lang.Exception and printing the instance together with stack(5).
  • Teams write custom @BTrace classes, such as one targeting com.example.OrderService.checkout, to print timing in milliseconds for a specific method.
  • Developers write oneliner probes for quick DTrace-style investigation without authoring a full script.
  • Integrators build extensions, including StatsD reporting, against the
project readme (upstream, from github) — read inline

BTrace

Safe, dynamic tracing for Java applications

CI Release codecov

BTrace dynamically instruments running Java applications to inject tracing code at runtime. No restarts. No recompilation. Production-safe.

Quick links: Quick Reference · Step-by-Step Tutorial


Why BTrace?

  • Zero downtime - Attach to running JVMs without restart
  • Production safe - Verified scripts can't crash your application
  • Flexible probes - Method entry/exit, timings, field access, allocations
  • Low overhead - Bytecode injection with minimal performance impact

Supported Java Versions

BTrace 3.0 runs on Java 8–25+. Running BTrace against a JVM older than Java 17 is deprecated: it continues to work throughout 3.x but emits a deprecation warning. Support for Java with the desired BTrace version (e.g.,3.0.0`). See releases for available versions.

Extensions: The published artifact bundles the default extensions, so scripts that inject services such as MetricsService or PrinterService work under jbang with nothing extra to install.

Benefits: Zero installation, automatic version management, works everywhere (Windows/macOS/Linux/containers), perfect for CI/CD.

Agent JAR: The client automatically discovers the masked agent JAR (btrace.jar) on its classpath — no extraction step is needed. If you want to use the agent JAR directly (e.g., with -javaagent), find it in the Maven local repository after the first jbang run:

# ~/.m2/repository/io/btrace/btrace/<version>/btrace-<version>.jar

For launch-time use, review the startup-mode security boundary. Use noServer=true for startup scripts that do not need later client connections; BTrace 3.0 does not support an unauthenticated remote prepared-mode endpoint.

See Getting Started Guide for complete JBang documentation and examples.

Binary Distribution

Download: Get the latest release from the release page

# Extract the archive
tar -xzf btrace-*.tar.gz
# or
unzip btrace-*.zip

# Set environment variables (optional but recommended)
export BTRACE_HOME=/path/to/btrace
export PATH=$BTRACE_HOME/bin:$PATH
Package Installation
# RPM-based systems
sudo rpm -i btrace-*.rpm

# Debian-based systems
sudo dpkg -i btrace-*.deb

Docker images:

# Copy BTrace into your application image
FROM btrace/btrace:latest AS btrace
FROM bellsoft/liberica-openjdk-debian:11-cds

COPY --from=btrace /opt/btrace /opt/btrace
ENV BTRACE_HOME=/opt/btrace PATH="${PATH}:${BTRACE_HOME}/bin"

# Your application...

Available variants:

  • btrace/btrace:latest - Debian-based (~25MB)
  • btrace/btrace:latest-alpine - Alpine-based (~15MB)
  • btrace/btrace:latest-distroless - Distroless (~10MB)

See docker/README.md for complete Docker documentation.

Quick Start

With JBang (no installation required):

# Attach to running application
jbang btrace <PID> <trace_script.java>

With installed BTrace:

# Attach to running application
btrace <PID> <trace_script.java>

# Compile BTrace script
btracec <trace_script.java>

# Launch application with BTrace agent
btracer <compiled_script.class> <java-application-and-args>

Extensions and Removed libs/profiles

Extensions add functionality via a stable API on bootstrap and an isolated implementation. See the extension development guide and examples.

Note: The legacy libs/profiles mechanism has been removed. Passing libs= logs an error and loads nothing, so custom classes that used to arrive that way will no longer resolve. Package integrations as extensions and use provided-style class loading patterns (object hand-off + TCCL). For migration guidance and examples, see:

  • docs/architecture/migrating-from-libs-profiles.md
  • docs/architecture/provided-style-extensions.md
  • docs/examples/README.md

As a last resort (discouraged), you may append a single jar to the system classpath: -Dbtrace.system.appendJar=/abs/path/lib.jar -Dbtrace.trusted=true.

Fat Agent JAR (Single-JAR Deployment)

For environments where managing multiple JARs is impractical (Spark, Hadoop, Kubernetes), BTrace provides a fat agent JAR with embedded extensions:

# Build fat agent with the default extensions
./gradlew :btrace-dist:fatAgentJar

# Build with specific extensions only
./gradlew :btrace-dist:fatAgentJar -PembedExtensions=btrace-metrics,btrace-statsd

# Use the fat agent
java -javaagent:btrace-agent-fat.jar <your-app>

The fat agent JAR includes:

  • All agent and boot classes
  • Embedded extension API classes (bootstrap)
  • Embedded extension impl classes (runtime-loaded)
  • Extension metadata for auto-discovery

For custom fat agent builds, use the Gradle plugin:

plugins {
    id 'io.btrace.fat-agent'
}

btraceFatAgent {
    embedExtensions {
        // BTrace bundles extension packages in its distribution's extensions/ directory.
        file('/path/to/btrace-metrics-3.0.0-extension.zip')
        project(':my-custom-extension')
    }
}

See Fat Agent Plugin Architecture and Gradle Plugin README for details.

Oneliner Quick Examples

BTrace now supports DTrace-style oneliners for quick debugging without writing full Java scripts:

# Trace method entry with arguments
btrace -n 'javax.swing.*::setText @entry { print method, args }' <PID>

# Find slow database queries (>100ms)
btrace -n 'java.sql.Statement::execute* @return if duration>100ms { print method, duration }' <PID>

# Count method invocations
btrace -n 'java.util.HashMap::get @entry { count }' <PID>

# Print stack trace on OutOfMemoryError
btrace -n 'java.lang.OutOfMemoryError::<init> @return { stack(10) }' <PID>

Supported features:

  • Locations: @entry, @return, @error
  • Actions: print, count, time, stack
  • Filters: if duration>NUMBERms, if args[N]==VALUE
  • Patterns: Wildcards (*, ?) and regex (/pattern/)

See Oneliner Guide for complete syntax and examples.

Documentation

For comprehensive documentation, tutorials, and guides:

Extensions and Permissions

BTrace supports extensions (like StatsdExtension) that provide additional functionality. Extensions require explicit permissions for security:

  • Default permissions (always granted): MESSAGING, AGGREGATION, JFR_EVENTS, PROFILING
  • Standard permissions (granted unless denied): FILE_READ, SYSTEM_PROPS, THREAD_INFO, MEMORY_INFO
  • Privileged permissions (require explicit grant): FILE_WRITE, NETWORK, THREADS, NATIVE, EXEC, REFLECTION, CLASSLOADER, UNLIMITED_MEMORY

Permissions are enforced based on extension/service descriptors and agent grants specified at attach-time.

Privileged permissions are granted via agent options (there is no client-side flag), e.g. when starting the target with the agent:

java -javaagent:btrace.jar=grant=NETWORK,THREADS ... MainClass

or persistently via a policy file (see PermissionPolicy).

If extensions fail to load, use -le to troubleshoot:

btrace -le <PID>

See the Tutorial for detailed documentation.

Extensions CLI: use btracex to inspect and manage extensions and the simplified permission policy:

  • btracex inspect prints extension id, version, services, and whether it’s privileged.
  • btracex policy print|set [--policy-file |--home|--classpath ] edits allowExtensions, denyExtensions, allowPrivileged.
  • btracex list shows installed extensions; btracex install accepts a local extension package or separately published third-party Maven coordinates. BTrace-built packages are supplied in the distribution's extensions/ directory, not as individual Maven artifacts.

Note: Extension “required permissions” are informational and help operators assess risk. Implementation linking is controlled by per‑extension allow/deny lists and the allowPrivileged flag; when blocked, APIs remain available and SHIMs are used so probes continue safely.

Agent Policy and Allow/Deny Lists
  • Launch-time policy can be set via agent args (operator-controlled):
    • -javaagent:btrace.jar=...,grant=NETWORK,THREADS,grantAll=false
    • -javaagent:btrace.jar=...,allowExtensions=btrace-statsd,my-metrics,denyExtensions=legacy-foo
  • Optional policy file (process-local): -Dbtrace.permissions=/path/to/permissions.properties or ~/.btrace/permissions.properties.
  • When an extension impl is blocked, the API remains on bootstrap so SHIMs can be generated.

See docs/PermissionPolicy.md for details and examples.

btracex TUI (interactive)
  • Launch: btracex inspect (with no args) opens an interactive view of installed extensions.
  • Header: shows current policy file path and the list of scanned repositories.
  • Table: columns State, Id, Version. State uses compact symbols: ? (default), + (allowed), - (denied).
  • Details: selection updates automatically; shows the full-word state: default / allowed / denied and the full path.
  • Legend: a short legend under the table maps the state symbols.

The TUI provides a keyboard-driven, terminal-based view for browsing installed extensions and toggling their allow/deny state without editing the policy file by hand.

Keys

  • Navigate: Arrow keys, PageUp/PageDown, Home/End
  • Toggle state: space (flows ? → + (confirm) → - → +; only c clears to default)
  • Clear: c (removes extension id from both allow and deny lists)
  • Explain privileges: e (opens a dialog with required permissions and risk descriptions)
  • Filter: / (filter by id or path)
  • Sort: s (choose column; repeat to toggle asc/desc)
  • Adjust split: m (enter mode), then Up/Down to resize; press Esc or m again to exit
  • Help / Quit: ? / q

Maven Integration

Fat Agent Plugin: The unpublished in-repository Maven fat-agent module was removed for 3.0.0 because it cannot consume the published 3.0 extension layout safely. Use the io.btrace.fat-agent Gradle plugin documented above.

Script Compilation Plugin (external repo):

  • Compilation of BTrace scripts during the build process
  • BTrace Project Archetype for quick project setup

Contributing

Important: Pull requests can only be accepted from signers of the Oracle Contributor Agreement.

Development

See CLAUDE.md for detailed development guidelines and project architecture.

Community

License

Apache License 2.0. See LICENSE.


Credits: Built with ASM, JCTools, hppcrt. Optimized with JProfiler.

Frequently asked questions

Is btrace free to use?

btrace is open source under the Apache-2.0 licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does btrace do?

Production-safe dynamic tracing and diagnostics for Java applications—attach to live JVMs with no restart or recompilation.

What is btrace written in?

btrace is primarily written in Java. Its source is publicly available at https://github.com/btraceio/btrace, and it has 5,997 GitHub stars.