From 410aab8cb14675d6cca57823cd845197e9a2bfb7 Mon Sep 17 00:00:00 2001 From: David Friedel Date: Fri, 26 Dec 2025 11:32:00 +0000 Subject: [PATCH] Add log_message, get_breadcrumbs, and enable_debug_logging features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add log_message(level, title, message?, data?) for structured logging with title - Add log_message_async() async variant - Add get_breadcrumbs() public method to retrieve current breadcrumbs - Add clear_breadcrumbs() method to clear all breadcrumbs - Add enable_debug_logging global flag and set_debug_logging() function - 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 --- src/irontelemetry/client.py | 67 ++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/src/irontelemetry/client.py b/src/irontelemetry/client.py index af72ab6..0c822e7 100644 --- a/src/irontelemetry/client.py +++ b/src/irontelemetry/client.py @@ -25,6 +25,16 @@ from .types import ( User, ) +# Global debug logging flag. When enabled, all IronTelemetry clients +# will output debug information to the console. +enable_debug_logging: bool = False + + +def set_debug_logging(enabled: bool) -> None: + """Enable or disable global debug logging for all TelemetryClient instances.""" + global enable_debug_logging + enable_debug_logging = enabled + class TelemetryClient: """Main IronTelemetry client class.""" @@ -49,7 +59,7 @@ class TelemetryClient: self._user: Optional[User] = None self._current_journey: Optional[Journey] = None - if self._options.debug: + if self._options.debug or enable_debug_logging: print(f"[IronTelemetry] Initialized with DSN: {self._options.dsn}") def capture_exception( @@ -98,6 +108,45 @@ class TelemetryClient: event = self._create_event(level, message) return await self._send_event_async(event) + def log_message( + self, + level: SeverityLevel, + title: str, + message: Optional[str] = None, + data: Optional[Dict[str, Any]] = None, + ) -> SendResult: + """Log a structured message with title, message, and optional data. + + Useful for structured logging that differentiates the log title from its details. + + Args: + level: The severity level of the log + title: A short, descriptive title for the log entry + message: Optional detailed message + data: Optional additional data to attach to the log + """ + full_message = f"{title}: {message}" if message else title + event = self._create_event(level, full_message) + event.extra["logTitle"] = title + if data: + event.extra["logData"] = data + return self._send_event(event) + + async def log_message_async( + self, + level: SeverityLevel, + title: str, + message: Optional[str] = None, + data: Optional[Dict[str, Any]] = None, + ) -> SendResult: + """Log a structured message asynchronously.""" + full_message = f"{title}: {message}" if message else title + event = self._create_event(level, full_message) + event.extra["logTitle"] = title + if data: + event.extra["logData"] = data + return await self._send_event_async(event) + def add_breadcrumb( self, message: str, @@ -108,6 +157,14 @@ class TelemetryClient: """Add a breadcrumb.""" self._breadcrumbs.add(message, category, level, data) + def get_breadcrumbs(self) -> List[Breadcrumb]: + """Get a copy of the current breadcrumbs list.""" + return self._breadcrumbs.get_all() + + def clear_breadcrumbs(self) -> None: + """Clear all breadcrumbs.""" + self._breadcrumbs.clear() + def set_user( self, id: str, @@ -194,7 +251,7 @@ class TelemetryClient: """Send an event.""" # Check sample rate if random.random() > self._options.sample_rate: - if self._options.debug: + if self._options.debug or enable_debug_logging: print("[IronTelemetry] Event dropped due to sample rate") return SendResult(success=True, event_id=event.event_id) @@ -202,7 +259,7 @@ class TelemetryClient: if self._options.before_send: result = self._options.before_send(event) if result is None: - if self._options.debug: + if self._options.debug or enable_debug_logging: print("[IronTelemetry] Event dropped by before_send hook") return SendResult(success=True, event_id=event.event_id) event = result @@ -225,7 +282,7 @@ class TelemetryClient: """Send an event asynchronously.""" # Check sample rate if random.random() > self._options.sample_rate: - if self._options.debug: + if self._options.debug or enable_debug_logging: print("[IronTelemetry] Event dropped due to sample rate") return SendResult(success=True, event_id=event.event_id) @@ -233,7 +290,7 @@ class TelemetryClient: if self._options.before_send: result = self._options.before_send(event) if result is None: - if self._options.debug: + if self._options.debug or enable_debug_logging: print("[IronTelemetry] Event dropped by before_send hook") return SendResult(success=True, event_id=event.event_id) event = result