BTrace
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
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.mddocs/architecture/provided-style-extensions.mddocs/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:
- BTrace Documentation Hub - Complete documentation index with learning paths, quick reference, troubleshooting, and more
- Getting Started Guide - Get up and running in 5 minutes
- BTrace Wiki - External wiki with additional resources
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 inspectprints extension id, version, services, and whether it’s privileged.btracex policy print|set [--policy-file |--home|--classpath ]editsallowExtensions,denyExtensions,allowPrivileged.btracex listshows installed extensions;btracex installaccepts a local extension package or separately published third-party Maven coordinates. BTrace-built packages are supplied in the distribution'sextensions/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.propertiesor~/.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/deniedand 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) → - → +; onlycclears 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; pressEscormagain 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
- Slack: btrace.slack.com
- Gitter: gitter.im/btraceio/btrace
- Issues: GitHub Issues
License
Apache License 2.0. See LICENSE.
Credits: Built with ASM, JCTools, hppcrt. Optimized with JProfiler.