Skip to content

Latest commit

 

History

History
174 lines (123 loc) · 4.56 KB

File metadata and controls

174 lines (123 loc) · 4.56 KB

JLogPointAgent

Java agent for dynamic logging

Overview

jlogpoint is a lightweight Java agent that you can attach to a running JVM to dynamically inject "log points" into specific methods without requiring application restart. It uses Byte Buddy for safe bytecode manipulation and retransformation.

Features

  • 🔍 Introspect loaded classes and methods - Browse all classes loaded in the JVM
  • 🎯 Dynamic log point injection - Add logging to any method on-the-fly
  • 🔄 Safe retransformation - Uses Byte Buddy for reliable bytecode manipulation
  • 🚀 No restart required - Attach to running JVMs
  • 📊 Method entry/exit logging - Track method calls, arguments, and return values

Requirements

  • Compiler: JDK 25
  • Target Compatibility: Java 17+
  • Build System: Maven
  • Testing: JUnit 5 (Jupiter)

Building

mvn clean package

This will create a shaded JAR with all dependencies at:

target/jlogpoint-1.0.0-SNAPSHOT.jar

Usage

Option 1: Start JVM with agent

java -javaagent:target/jlogpoint-1.0.0-SNAPSHOT.jar -jar your-application.jar

Option 2: Attach to running JVM

eu.ndsk.jlogpoint.infra.LogPointManager;

// Get the agent's log point manager
LogPointManager manager = eu.ndsk.jlogpoint.infra.JLogPointAgent.getLogPointManager();

// Add a log point to a specific method
manager.

    addLogPoint(
    "com.example.MyClass",     // Class name
        "myMethod",                 // Method name
        "Custom log message"        // Log message
    );

    // List all active log points
    Map<String, LogPoint> activeLogPoints = manager.getActiveLogPoints();

// Remove a log point
manager.

    removeLogPoint("com.example.MyClass","myMethod");

Class Introspection

import eu.ndsk.jlogpoint.infra.ClassIntrospector;

ClassIntrospector introspector = new ClassIntrospector(
    JLogPointAgent.getInstrumentation()
);

// Find classes by pattern
List<ClassInfo> classes = introspector.findClasses("com.example");

// Get methods for a specific class
List<MethodInfo> methods = introspector.getMethodsForClass("com.example.MyClass");

Project Structure

jlogpoint/
├── src/main/java/de/ndsk/jlogpoint/
│   ├── JLogPointAgent.java         # Agent entry point
│   ├── LogPointManager.java        # Manages log points and instrumentation
│   ├── LogPointAdvice.java         # Byte Buddy advice for logging
│   └── ClassIntrospector.java      # Class/method introspection utilities
├── src/test/java/de/ndsk/jlogpoint/
│   ├── LogPointManagerTest.java    # Unit tests
│   └── ClassIntrospectorTest.java  # Unit tests
└── pom.xml                          # Maven configuration

How It Works

  1. Agent Initialization: When attached, the agent registers with the JVM's Instrumentation API
  2. Log Point Registration: When you call addLogPoint(), the manager:
    • Locates the target class in loaded classes
    • Creates a Byte Buddy transformation
    • Applies LogPointAdvice to inject logging code
    • Retransforms the class on-the-fly
  3. Method Execution: When the instrumented method runs:
    • Entry advice logs method name and arguments
    • Exit advice logs return values or exceptions

Testing

Run tests with:

mvn test

Dependencies

  • Byte Buddy 1.14.18 - Bytecode manipulation
  • JUnit 5.10.2 - Testing framework

License

See LICENSE file for details.

Example Output

When a log point is active, you'll see output like:

[LOGPOINT ENTER] com.example.MyClass#myMethod | Args: [arg1, arg2]
[LOGPOINT EXIT] com.example.MyClass#myMethod | Return: result value

Advanced Usage

Custom Log Messages

manager.addLogPoint(
    "com.example.Service",
    "processData",
    "Processing data with arguments: ${args}"
);

Monitoring All Methods in a Class

Iterate through methods and add log points:

ClassIntrospector introspector = new ClassIntrospector(
    JLogPointAgent.getInstrumentation()
);

List<MethodInfo> methods = introspector.getMethodsForClass("com.example.MyClass");
for (MethodInfo method : methods) {
    manager.addLogPoint("com.example.MyClass", method.getName(), "Monitoring: " + method.getName());
}

Limitations

  • Cannot instrument native methods
  • Some system classes may be restricted
  • Retransformation has a small performance overhead
  • Log points persist until explicitly removed or JVM restart

Contributing

Contributions are welcome! Please ensure tests pass before submitting PRs.