Skip to content

raghavtech/distributed_trace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Flow – Lightweight Java Distributed Tracing Agent

Flow is a lightweight Java agent that captures end-to-end distributed execution traces of Java applications running on servlet containers (for example, Tomcat).

It is designed primarily for performance analysts and engineers to understand where time is spent inside and across services, not for generic logging or metrics collection.

Flow instruments applications at runtime using Byte Buddy and produces hierarchical, distributed traces that show:

  • Request entry points
  • Method execution paths
  • Cross-service HTTP calls
  • Time spent at each node and layer

Why Flow?

Modern enterprise applications are:

  • Highly concurrent
  • Distributed across multiple JVMs and nodes
  • Composed of many internal and external service calls

Traditional logs and metrics cannot answer questions like:

  • Where exactly did this request spend time?
  • Which downstream service caused the slowdown?
  • How did this request flow across nodes?

Flow answers these questions by capturing distributed traces that follow a request across JVMs and services.

Key Capabilities

HTTP and Method Tracing

  • HTTP request tracing for servlet-based applications
  • Method-level spans with parent and child relationships

Distributed Tracing

  • Distributed tracing across services
  • W3C Trace Context (traceparent) propagation
  • Works across nodes and JVMs

Apache HttpClient Instrumentation

  • Automatically creates client spans
  • Injects trace context into outbound HTTP requests

Low Overhead Design

  • Bytecode instrumentation only
  • No blocking I/O on the request path

Configurable Instrumentation

  • Selectively trace specific classes or patterns
  • No recompilation required for configuration changes

Architecture Overview

┌────────────┐
│   Browser  │
└─────┬──────┘
      │
      ▼
┌──────────────┐        traceparent        ┌──────────────┐
│  Service A   │ ────────────────────────▶ │  Service B   │
│  (Node A)    │                           │  (Node B)    │
│              │                           │              │
│  SERVER span │                           │  SERVER span │
│  CLIENT span │                           │              │
└──────────────┘                           └──────────────┘

Each request produces a distributed trace graph spanning:

  • Multiple methods
  • Multiple threads
  • Multiple JVMs

How It Works

Inbound HTTP Requests

  • Agent intercepts the servlet filter chain
  • Extracts or creates trace context
  • Starts a root SERVER span

Internal Execution

  • Selected application methods are instrumented
  • Nested spans are created automatically

Outbound HTTP Calls

  • Apache HttpClient is instrumented
  • CLIENT spans are created
  • Trace context is injected via the traceparent header

Downstream Services

  • Extract trace context
  • Continue the same distributed trace

Installation

Build the Agent

mvn clean package

This produces:

target/flow-agent-<version>.jar

Run with Java Agent

Add the agent to your JVM startup:

-javaagent:/path/to/flow-agent.jar

Example (Tomcat):

export JAVA_OPTS="-javaagent:/opt/flow/flow-agent.jar"
catalina.sh run

Configuration

Instrumentation is controlled via a properties file packaged in the agent:

src/main/resources/flow-agent.properties

Example:

trace.classes=com.example.employee.servlet.EmployeeServlet,
              com.example.employee.service.EmployeeService,
              com.example.employee.dao.EmployeeDao

trace.regex=.*Service.*,.*Dao.*

This allows adding or removing traced classes without rebuilding the agent.

Output

The agent produces hierarchical trace data that can be:

  • Logged (development)
  • Exported to a collector (future)
  • Visualized as call trees, flame graphs, or service flow diagrams

Example Trace Structure (with Timing)

POST /employees                               11.36 ms
 └─ LoginFilter.doFilter()                    11.26 ms
     └─ EmployeeServlet.service()             11.12 ms
         └─ EmployeeService.updateEmployee()  10.61 ms
             └─ EmployeeDao.updateEmployee()   8.36 ms

Current Status

  • ✅ HTTP inbound tracing (Tomcat)
  • ✅ Method-level spans
  • ✅ Distributed tracing across services
  • ✅ Apache HttpClient support
  • 🚧 Trace exporting and visualization (in progress)
  • 🚧 Async execution propagation (planned)
  • 🚧 Sampling and scale optimizations (planned)

Design Goals

  • Correct distributed traces first
  • Minimal runtime overhead
  • Clear execution flow for performance analysts
  • Extensible architecture for future backends

Non-Goals

  • Full APM replacement
  • Log aggregation
  • Metrics-only monitoring

Flow is focused on execution flow and performance analysis, not general observability.

License

MIT License (or your preferred license)

Contributing

Contributions, design discussions, and performance insights are welcome. Please open an issue or submit a pull request.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages