Production-safe dynamic tracing and diagnostics for Java applications—attach to live JVMs with no restart or recompilation.
Java
5,995
1,508 commits
updated Oct 12, 2026
Safe, dynamic tracing for Java applications
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
BTrace 3.0 runs on Java 8–27+. 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 < 17 will be removed in the next major release (4.0). See the migration guide for details on upgrading from BTrace 2.x and the 3.0.0 release notes for everything that changed.
# Install via JBang (easiest)
curl -Ls https://sh.jbang.dev | bash -s - app setup
# Add the BTrace JBang catalog (one time)
jbang catalog add --name btraceio https://raw.githubusercontent.com/btraceio/jbang-catalog/main/jbang-catalog.json
# Trace slow methods in your running app
jbang btrace@btraceio -n 'com.myapp.*::* @return if duration>100ms { print method, duration }' $(pgrep -f myapp)
Method timing:
btrace -n 'java.sql.Statement::execute* @return { print method, duration }' <PID>
Exception tracking:
btrace -n 'java.lang.Exception::<init> @return { print self, stack(5) }' <PID>
Custom probes:
@BTrace public class Trace {
@OnMethod(clazz = "com.example.OrderService", method = "checkout")
public static void onCheckout(@Self Object self, @Duration long ns) {
println("checkout: " + str(ns / 1_000_000) + "ms");
}
}
See the Oneliner Guide for complete syntax.
# JBang (recommended - zero installation)
jbang catalog add --name btraceio https://raw.githubusercontent.com/btraceio/jbang-catalog/main/jbang-catalog.json
jbang btrace@btraceio <PID> script.java
# SDKMan
sdk install btrace
# Manual download (assets are versioned: btrace-v<version>-bin.tar.gz)
BTRACE_VERSION=3.0.0
curl -LO https://github.com/btraceio/btrace/releases/download/v${BTRACE_VERSION}/btrace-v${BTRACE_VERSION}-bin.tar.gz
See Installation Guide for Docker, package managers, and more options.
| Resource | Description |
|---|---|
| Quick Reference | Cheat sheet for experienced users |
| Getting Started | Step-by-step first trace tutorial |
| Full Tutorial | Complete walkthrough of all features |
| Oneliners | DTrace-style quick probes |
| Extensions | StatsD, custom integrations |
| Documentation Hub | All docs and guides |
git clone https://github.com/btraceio/btrace.git
cd btrace
./gradlew :btrace-dist:build
See CLAUDE.md for development setup and architecture.
Get help: Slack · GitHub Issues
Tips:
GRADLE_OPTS="-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false"../gradlew :btrace-runtime:test./gradlew :btrace-core:test./gradlew :btrace-compiler:test./gradlew :btrace-agent:test./gradlew test -PupdateTestData.Integration tests (optional):
./gradlew --no-daemon integration-tests:test
These may exercise privileged extensions. If you run into permission denials, provide a policy file and pass it to the test JVMs via -Dbtrace.permissions=/path/to/permissions.properties.
Use JBang to run BTrace without manual installation:
# Install JBang (one time)
curl -Ls https://sh.jbang.dev | bash -s - app setup
# Use BTrace immediately (replace <version> with desired version, e.g., 3.0.0)
jbang io.btrace:btrace:<version> <PID> <script.java>
# After first run, use shorter alias
jbang btrace <PID> <script.java>
Note: Replace <version> 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.
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
# 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 ghcr.io/btraceio/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:
ghcr.io/btraceio/btrace:latest - Debian-based (~25MB)ghcr.io/btraceio/btrace:latest-alpine - Alpine-based (~15MB)ghcr.io/btraceio/btrace:latest-distroless - Distroless (~10MB)See docker/README.md for complete Docker documentation.
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 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=<profile> 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.mddocs/architecture/provided-style-extensions.mddocs/examples/README.mdAs a last resort (discouraged), you may append a single jar to the system classpath: -Dbtrace.system.appendJar=/abs/path/lib.jar -Dbtrace.trusted=true.
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:
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.
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:
@entry, @return, @errorprint, count, time, stackif duration>NUMBERms, if args[N]==VALUE*, ?) and regex (/pattern/)See Oneliner Guide for complete syntax and examples.
For comprehensive documentation, tutorials, and guides:
BTrace supports extensions (like StatsdExtension) that provide additional functionality. Extensions require explicit permissions for security:
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 <zip|dir> prints extension id, version, services, and whether it’s privileged.btracex policy print|set [--policy-file <path>|--home|--classpath <outDir>] 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.
-javaagent:btrace.jar=...,grant=NETWORK,THREADS,grantAll=false-javaagent:btrace.jar=...,allowExtensions=btrace-statsd,my-metrics,denyExtensions=legacy-foo-Dbtrace.permissions=/path/to/permissions.properties or ~/.btrace/permissions.properties.See docs/PermissionPolicy.md for details and examples.
btracex inspect (with no args) opens an interactive view of installed extensions.? (default), + (allowed), - (denied).default / allowed / denied and the full path.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
? → + (confirm) → - → +; only c clears to default)c (removes extension id from both allow and deny lists)e (opens a dialog with required permissions and risk descriptions)/ (filter by id or path)s (choose column; repeat to toggle asc/desc)m (enter mode), then Up/Down to resize; press Esc or m again to exit? / qFat 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):
Contributions are accepted under the Apache License 2.0. See CONTRIBUTING.md for the workflow and expectations.
See CLAUDE.md for detailed development guidelines and project architecture.
Apache License 2.0. See LICENSE.
Credits: Built with ASM, JCTools, hppcrt. Optimized with JProfiler.
(top 24 of 35)
141 followers · starred Sep 2021
268 followers · starred Nov 2014
2,079 followers · starred Dec 2025
423 followers · starred Aug 2025
Production-safe dynamic tracing and diagnostics for Java applications—attach to live JVMs with no restart or recompilation.
Java
5,995
1,508 commits
updated Oct 12, 2026
Safe, dynamic tracing for Java applications
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
BTrace 3.0 runs on Java 8–27+. 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 < 17 will be removed in the next major release (4.0). See the migration guide for details on upgrading from BTrace 2.x and the 3.0.0 release notes for everything that changed.
# Install via JBang (easiest)
curl -Ls https://sh.jbang.dev | bash -s - app setup
# Add the BTrace JBang catalog (one time)
jbang catalog add --name btraceio https://raw.githubusercontent.com/btraceio/jbang-catalog/main/jbang-catalog.json
# Trace slow methods in your running app
jbang btrace@btraceio -n 'com.myapp.*::* @return if duration>100ms { print method, duration }' $(pgrep -f myapp)
Method timing:
btrace -n 'java.sql.Statement::execute* @return { print method, duration }' <PID>
Exception tracking:
btrace -n 'java.lang.Exception::<init> @return { print self, stack(5) }' <PID>
Custom probes:
@BTrace public class Trace {
@OnMethod(clazz = "com.example.OrderService", method = "checkout")
public static void onCheckout(@Self Object self, @Duration long ns) {
println("checkout: " + str(ns / 1_000_000) + "ms");
}
}
See the Oneliner Guide for complete syntax.
# JBang (recommended - zero installation)
jbang catalog add --name btraceio https://raw.githubusercontent.com/btraceio/jbang-catalog/main/jbang-catalog.json
jbang btrace@btraceio <PID> script.java
# SDKMan
sdk install btrace
# Manual download (assets are versioned: btrace-v<version>-bin.tar.gz)
BTRACE_VERSION=3.0.0
curl -LO https://github.com/btraceio/btrace/releases/download/v${BTRACE_VERSION}/btrace-v${BTRACE_VERSION}-bin.tar.gz
See Installation Guide for Docker, package managers, and more options.
| Resource | Description |
|---|---|
| Quick Reference | Cheat sheet for experienced users |
| Getting Started | Step-by-step first trace tutorial |
| Full Tutorial | Complete walkthrough of all features |
| Oneliners | DTrace-style quick probes |
| Extensions | StatsD, custom integrations |
| Documentation Hub | All docs and guides |
git clone https://github.com/btraceio/btrace.git
cd btrace
./gradlew :btrace-dist:build
See CLAUDE.md for development setup and architecture.
Get help: Slack · GitHub Issues
Tips:
GRADLE_OPTS="-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false"../gradlew :btrace-runtime:test./gradlew :btrace-core:test./gradlew :btrace-compiler:test./gradlew :btrace-agent:test./gradlew test -PupdateTestData.Integration tests (optional):
./gradlew --no-daemon integration-tests:test
These may exercise privileged extensions. If you run into permission denials, provide a policy file and pass it to the test JVMs via -Dbtrace.permissions=/path/to/permissions.properties.
Use JBang to run BTrace without manual installation:
# Install JBang (one time)
curl -Ls https://sh.jbang.dev | bash -s - app setup
# Use BTrace immediately (replace <version> with desired version, e.g., 3.0.0)
jbang io.btrace:btrace:<version> <PID> <script.java>
# After first run, use shorter alias
jbang btrace <PID> <script.java>
Note: Replace <version> 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.
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
# 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 ghcr.io/btraceio/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:
ghcr.io/btraceio/btrace:latest - Debian-based (~25MB)ghcr.io/btraceio/btrace:latest-alpine - Alpine-based (~15MB)ghcr.io/btraceio/btrace:latest-distroless - Distroless (~10MB)See docker/README.md for complete Docker documentation.
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 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=<profile> 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.mddocs/architecture/provided-style-extensions.mddocs/examples/README.mdAs a last resort (discouraged), you may append a single jar to the system classpath: -Dbtrace.system.appendJar=/abs/path/lib.jar -Dbtrace.trusted=true.
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:
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.
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:
@entry, @return, @errorprint, count, time, stackif duration>NUMBERms, if args[N]==VALUE*, ?) and regex (/pattern/)See Oneliner Guide for complete syntax and examples.
For comprehensive documentation, tutorials, and guides:
BTrace supports extensions (like StatsdExtension) that provide additional functionality. Extensions require explicit permissions for security:
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 <zip|dir> prints extension id, version, services, and whether it’s privileged.btracex policy print|set [--policy-file <path>|--home|--classpath <outDir>] 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.
-javaagent:btrace.jar=...,grant=NETWORK,THREADS,grantAll=false-javaagent:btrace.jar=...,allowExtensions=btrace-statsd,my-metrics,denyExtensions=legacy-foo-Dbtrace.permissions=/path/to/permissions.properties or ~/.btrace/permissions.properties.See docs/PermissionPolicy.md for details and examples.
btracex inspect (with no args) opens an interactive view of installed extensions.? (default), + (allowed), - (denied).default / allowed / denied and the full path.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
? → + (confirm) → - → +; only c clears to default)c (removes extension id from both allow and deny lists)e (opens a dialog with required permissions and risk descriptions)/ (filter by id or path)s (choose column; repeat to toggle asc/desc)m (enter mode), then Up/Down to resize; press Esc or m again to exit? / qFat 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):
Contributions are accepted under the Apache License 2.0. See CONTRIBUTING.md for the workflow and expectations.
See CLAUDE.md for detailed development guidelines and project architecture.
Apache License 2.0. See LICENSE.
Credits: Built with ASM, JCTools, hppcrt. Optimized with JProfiler.
(top 24 of 35)
141 followers · starred Sep 2021
268 followers · starred Nov 2014
2,079 followers · starred Dec 2025
423 followers · starred Aug 2025