Agent Skills: GuicedEE Telemetry

OpenTelemetry distributed tracing for GuicedEE using Guice AOP and OTLP exporters: @Trace and @SpanAttribute annotations, automatic span creation, Uni-aware span lifecycle, call-scope span propagation, @TelemetryOptions configuration, OTLP HTTP export to Tempo/Jaeger, in-memory exporters for testing, Log4j2 OpenTelemetry appender, and environment variable overrides. Use when adding distributed tracing, configuring OpenTelemetry, or instrumenting methods with spans.

UncategorizedID: GuicedEE/ai-rules/guicedee-telemetry

Install this agent skill to your local

pnpm dlx add-skill https://github.com/GuicedEE/ai-rules/tree/HEAD/skills/.system/guicedee-telemetry

Skill Files

Browse the full folder contents for guicedee-telemetry.

Download Skill

Loading file tree…

skills/.system/guicedee-telemetry/SKILL.md

Skill Metadata

Name
guicedee-telemetry
Description
"OpenTelemetry distributed tracing for GuicedEE using Guice AOP and OTLP exporters: @Trace and @SpanAttribute annotations, automatic span creation, Uni-aware span lifecycle, call-scope span propagation, @TelemetryOptions configuration, OTLP HTTP export to Tempo/Jaeger, in-memory exporters for testing, Log4j2 OpenTelemetry appender, and environment variable overrides. Use when adding distributed tracing, configuring OpenTelemetry, or instrumenting methods with spans."

GuicedEE Telemetry

OpenTelemetry distributed tracing for GuicedEE using Guice AOP and OTLP exporters.

Core Concept

Annotate your classes and methods with @Trace and @SpanAttribute — the framework builds an OpenTelemetrySdk at startup, binds a TraceMethodInterceptor via Guice AOP, and exports spans and logs to any OTLP-compatible backend (Tempo, Jaeger, etc.) automatically.

Required Flow

  1. Add com.guicedee:guiced-telemetry dependency.
  2. Configure telemetry:
    @TelemetryOptions(
        serviceName = "my-service",
        otlpEndpoint = "http://localhost:4318",
        serviceVersion = "1.0.0",
        deploymentEnvironment = "production"
    )
    public class MyAppConfig {}
    

    Per-signal endpoints & automatic sub-paths. otlpEndpoint is treated as a base URL — the configurator appends the correct signal sub-path (/v1/traces, /v1/logs) automatically when it is missing, so http://localhost:4318 and http://localhost:4318/v1/traces both work.

    Tempo/Jaeger are traces-only. Sending OTLP logs to a traces backend yields HTTP 404 on /v1/logs. You have two correct options:

    • Disable log export: @TelemetryOptions(exportLogs = false) (no log exporter, logger provider, or OTel Log4j2 appender is registered). Ship logs to Loki out-of-band (Grafana Alloy / Promtail).
    • Point logs at a logs backend: set logsEndpoint (and optionally tracesEndpoint) to send each signal to a different collector, e.g. tracesEndpoint = "http://tempo:4318/v1/traces", logsEndpoint = "http://loki:3100/otlp/v1/logs".

    Standard OTel env vars are honoured too: OTEL_EXPORTER_OTLP_ENDPOINT (base, sub-path appended), OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / OTEL_EXPORTER_OTLP_LOGS_ENDPOINT (full URLs, used verbatim).

  3. Annotate methods to trace:
    @Trace("place-order")
    public void placeOrder(@SpanAttribute("order.id") String orderId,
                           @SpanAttribute("order.amount") double amount) {
        // span is created automatically
    }
    
    @Trace
    @SpanAttribute("result")
    public String processPayment(String paymentId) {
        return "success"; // return value recorded as "result" attribute
    }
    
  4. Configure module-info.java:
    module my.app {
        requires com.guicedee.telemetry;
        opens my.app.services to com.google.guice;
    }
    
  5. Bootstrap GuicedEE — tracing starts automatically:
    IGuiceContext.registerModuleForScanning.add("my.app");
    IGuiceContext.instance().inject();
    

Tracing Annotations

@Trace

Creates an OpenTelemetry span around a method invocation.

  • Custom name: @Trace("fetch-users")
  • Default name: ClassName.methodName
  • Class-level: traces all methods in the class

@SpanAttribute

Records method parameters or return values as span attributes.

  • Supported types: String, Boolean, Long, Double, Integer, Float
  • Complex objects serialized to JSON via Jackson

Uni support

When a @Trace method returns a Mutiny Uni, the span remains open until the Uni completes or fails.

Span propagation

Parent spans are propagated through GuicedEE's CallScoper. Nested @Trace methods create child spans automatically.

Configuration

@TelemetryOptions annotation

| Attribute | Purpose | |---|---| | enabled | Enable/disable tracing | | serviceName | OpenTelemetry service name | | otlpEndpoint | OTLP HTTP base endpoint (signal sub-path appended automatically) | | tracesEndpoint | Optional full URL for spans (used verbatim); derives from base when blank | | logsEndpoint | Optional full URL for logs (used verbatim); point at a logs backend, not Tempo | | exportLogs | Set false for traces-only backends (Tempo) to skip OTLP log export entirely | | serviceVersion | Service version resource attribute | | deploymentEnvironment | Deployment environment attribute | | useInMemoryExporters | In-memory exporters for unit testing | | configureLogs | Enable Log4j2 OpenTelemetry appender | | maxBatchSize | Batch span processor max batch size |

Environment variable overrides

Every @TelemetryOptions attribute can be overridden via system properties or environment variables.

Startup Flow

IGuiceContext.instance().inject()
 └─ TelemetryPreStartup (scans for @TelemetryOptions)
     └─ OpenTelemetrySDKConfigurator.initialize()
         ├─ Build Resource (service.name, version, environment, host)
         ├─ Create OTLP HTTP exporters (spans + logs)
         ├─ Build SdkTracerProvider + SdkLoggerProvider
         ├─ Set GlobalOpenTelemetry
         └─ Register shutdown hook
 └─ TraceModule (binds TraceMethodInterceptor for @Trace)

Testing

Use in-memory exporters for unit tests:

@TelemetryOptions(useInMemoryExporters = true)
public class TestConfig {}

Access InMemorySpanExporter and InMemoryLogRecordExporter to assert on captured spans.

Non-Negotiable Constraints

  • Module must requires com.guicedee.telemetry;.
  • Traced classes must be in packages opened to com.google.guice.
  • Guice AOP requires non-final, non-private methods for interception.
  • The telemetry module is registered automatically — no provides needed.
  • A JVM shutdown hook flushes pending spans automatically.