From 57cd6577a5e048eaf129bd52a9fabbcd18960e57 Mon Sep 17 00:00:00 2001 From: David Friedel Date: Fri, 26 Dec 2025 11:32:01 +0000 Subject: [PATCH] Add logMessage, getBreadcrumbs, and enableDebugLogging features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add logMessage(level, title, message?, data?) for structured logging with title - Add logMessageAsync() async variant - Add getBreadcrumbs() public method to retrieve current breadcrumbs - Add static enableDebugLogging field for global debug output control - Update all debug logging to respect the global debug flag 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../telemetry/TelemetryClient.java | 64 ++++++++++++++++++- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/ironservices/telemetry/TelemetryClient.java b/src/main/java/com/ironservices/telemetry/TelemetryClient.java index ce426bb..0c97868 100644 --- a/src/main/java/com/ironservices/telemetry/TelemetryClient.java +++ b/src/main/java/com/ironservices/telemetry/TelemetryClient.java @@ -1,6 +1,7 @@ package com.ironservices.telemetry; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -10,6 +11,12 @@ import java.util.concurrent.ThreadLocalRandom; * The main IronTelemetry client. */ public class TelemetryClient implements AutoCloseable { + + /** + * Global debug logging flag. When enabled, all IronTelemetry clients + * will output debug information to stdout. + */ + public static volatile boolean enableDebugLogging = false; private final TelemetryOptions options; private final ParsedDSN parsedDSN; private final Transport transport; @@ -40,7 +47,7 @@ public class TelemetryClient implements AutoCloseable { this.tags = new HashMap<>(); this.extra = new HashMap<>(); - if (options.isDebug()) { + if (options.isDebug() || enableDebugLogging) { System.out.println("[IronTelemetry] Initialized with DSN: " + parsedDSN.getApiBaseUrl()); } } @@ -87,6 +94,50 @@ public class TelemetryClient implements AutoCloseable { return CompletableFuture.supplyAsync(() -> captureMessage(message, level)); } + /** + * Log a structured message with title, message, and optional data. + * Useful for structured logging that differentiates the log title from its details. + * + * @param level The severity level of the log + * @param title A short, descriptive title for the log entry + * @param message Optional detailed message (can be null) + * @param data Optional additional data to attach to the log (can be null) + */ + public SendResult logMessage(SeverityLevel level, String title, String message, Map data) { + String fullMessage = (message != null && !message.isEmpty()) ? title + ": " + message : title; + TelemetryEvent event = createEvent(level, fullMessage); + + synchronized (lock) { + event.getExtra().put("logTitle", title); + if (data != null) { + event.getExtra().put("logData", data); + } + } + + return sendEvent(event); + } + + /** + * Log a structured message with title and message. + */ + public SendResult logMessage(SeverityLevel level, String title, String message) { + return logMessage(level, title, message, null); + } + + /** + * Log a structured message with title only. + */ + public SendResult logMessage(SeverityLevel level, String title) { + return logMessage(level, title, null, null); + } + + /** + * Log a structured message asynchronously. + */ + public CompletableFuture logMessageAsync(SeverityLevel level, String title, String message, Map data) { + return CompletableFuture.supplyAsync(() -> logMessage(level, title, message, data)); + } + /** * Add a breadcrumb. */ @@ -115,6 +166,13 @@ public class TelemetryClient implements AutoCloseable { breadcrumbs.add(breadcrumb); } + /** + * Get a copy of the current breadcrumbs list. + */ + public List getBreadcrumbs() { + return breadcrumbs.getAll(); + } + /** * Set the user context. */ @@ -240,7 +298,7 @@ public class TelemetryClient implements AutoCloseable { private SendResult sendEvent(TelemetryEvent event) { // Check sample rate if (options.getSampleRate() < 1.0 && ThreadLocalRandom.current().nextDouble() > options.getSampleRate()) { - if (options.isDebug()) { + if (options.isDebug() || enableDebugLogging) { System.out.println("[IronTelemetry] Event sampled out: " + event.getEventId()); } return SendResult.success(event.getEventId()); @@ -250,7 +308,7 @@ public class TelemetryClient implements AutoCloseable { if (options.getBeforeSend() != null) { event = options.getBeforeSend().apply(event); if (event == null) { - if (options.isDebug()) { + if (options.isDebug() || enableDebugLogging) { System.out.println("[IronTelemetry] Event dropped by beforeSend hook"); } return SendResult.success(null);