Add logMessage, getBreadcrumbs, and enableDebugLogging features

- 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 <noreply@anthropic.com>
This commit is contained in:
David Friedel 2025-12-26 11:32:01 +00:00
parent 087bdd0bbe
commit 57cd6577a5
1 changed files with 61 additions and 3 deletions

View File

@ -1,6 +1,7 @@
package com.ironservices.telemetry; package com.ironservices.telemetry;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -10,6 +11,12 @@ import java.util.concurrent.ThreadLocalRandom;
* The main IronTelemetry client. * The main IronTelemetry client.
*/ */
public class TelemetryClient implements AutoCloseable { 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 TelemetryOptions options;
private final ParsedDSN parsedDSN; private final ParsedDSN parsedDSN;
private final Transport transport; private final Transport transport;
@ -40,7 +47,7 @@ public class TelemetryClient implements AutoCloseable {
this.tags = new HashMap<>(); this.tags = new HashMap<>();
this.extra = new HashMap<>(); this.extra = new HashMap<>();
if (options.isDebug()) { if (options.isDebug() || enableDebugLogging) {
System.out.println("[IronTelemetry] Initialized with DSN: " + parsedDSN.getApiBaseUrl()); System.out.println("[IronTelemetry] Initialized with DSN: " + parsedDSN.getApiBaseUrl());
} }
} }
@ -87,6 +94,50 @@ public class TelemetryClient implements AutoCloseable {
return CompletableFuture.supplyAsync(() -> captureMessage(message, level)); 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<String, Object> 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<SendResult> logMessageAsync(SeverityLevel level, String title, String message, Map<String, Object> data) {
return CompletableFuture.supplyAsync(() -> logMessage(level, title, message, data));
}
/** /**
* Add a breadcrumb. * Add a breadcrumb.
*/ */
@ -115,6 +166,13 @@ public class TelemetryClient implements AutoCloseable {
breadcrumbs.add(breadcrumb); breadcrumbs.add(breadcrumb);
} }
/**
* Get a copy of the current breadcrumbs list.
*/
public List<Breadcrumb> getBreadcrumbs() {
return breadcrumbs.getAll();
}
/** /**
* Set the user context. * Set the user context.
*/ */
@ -240,7 +298,7 @@ public class TelemetryClient implements AutoCloseable {
private SendResult sendEvent(TelemetryEvent event) { private SendResult sendEvent(TelemetryEvent event) {
// Check sample rate // Check sample rate
if (options.getSampleRate() < 1.0 && ThreadLocalRandom.current().nextDouble() > options.getSampleRate()) { 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()); System.out.println("[IronTelemetry] Event sampled out: " + event.getEventId());
} }
return SendResult.success(event.getEventId()); return SendResult.success(event.getEventId());
@ -250,7 +308,7 @@ public class TelemetryClient implements AutoCloseable {
if (options.getBeforeSend() != null) { if (options.getBeforeSend() != null) {
event = options.getBeforeSend().apply(event); event = options.getBeforeSend().apply(event);
if (event == null) { if (event == null) {
if (options.isDebug()) { if (options.isDebug() || enableDebugLogging) {
System.out.println("[IronTelemetry] Event dropped by beforeSend hook"); System.out.println("[IronTelemetry] Event dropped by beforeSend hook");
} }
return SendResult.success(null); return SendResult.success(null);