k9-mail/core/logging/README.md

206 lines
5 KiB
Markdown
Raw Normal View History

2025-11-22 13:56:56 +01:00
# Thunderbird Core Logging Module
This module provides a flexible and extensible logging system for Thunderbird for Android.
## Architecture
The logging system is organized into several modules:
- **api**: Core interfaces and classes
- **impl-console**: Console logging implementation
- **impl-composite**: Composite logging (multiple sinks)
- **impl-legacy**: Legacy logging system compatibility
- **testing**: Testing utilities
### Core Components
```mermaid
classDiagram
class Logger {
+verbose(tag, throwable, message: () -> LogMessage)
+debug(tag, throwable, message: () -> LogMessage)
+info(tag, throwable, message: () -> LogMessage)
+warn(tag, throwable, message: () -> LogMessage)
+error(tag, throwable, message: () -> LogMessage)
}
class DefaultLogger {
-sink: LogSink
-clock: Clock
}
class LogSink {
+level: LogLevel
+canLog(level): boolean
+log(event: LogEvent)
}
class LogEvent {
+level: LogLevel
+tag: LogTag?
+message: LogMessage
+throwable: Throwable?
+timestamp: Long
}
class LogLevel {
VERBOSE
DEBUG
INFO
WARN
ERROR
}
Logger <|-- DefaultLogger
DefaultLogger --> LogSink
LogSink --> LogEvent
LogSink --> LogLevel
LogEvent --> LogLevel
```
### Implementation Modules
```mermaid
classDiagram
class LogSink {
+level: LogLevel
+canLog(level): boolean
+log(event: LogEvent)
}
class ConsoleLogSink {
+level: LogLevel
}
class CompositeLogSink {
+level: LogLevel
-manager: LogSinkManager
}
LogSink <|-- ConsoleLogSink
LogSink <|-- CompositeLogSink
CompositeLogSink --> LogSinkManager
class LogSinkManager {
+getAll(): List<LogSink>
+add(sink: LogSink)
+addAll(sinks: List<LogSink>)
+remove(sink: LogSink)
+removeAll()
}
class DefaultLogSinkManager {
-sinks: MutableList<LogSink>
}
LogSinkManager <|-- DefaultLogSinkManager
```
## Getting Started
### Basic Setup
To start using the logging system, you need to:
1. Add the necessary dependencies to your module's build.gradle.kts file
2. Create a LogSink
3. Create a Logger
4. Start logging!
### Basic Logging
```kotlin
// Create a log sink
val sink = ConsoleLogSink(LogLevel.DEBUG)
// Create a logger
val logger = DefaultLogger(sink)
// Log messages
logger.debug(tag = "MyTag") { "Debug message" }
logger.info { "Info message" }
logger.warn { "Warning message" }
logger.error(throwable = exception) { "Error message with exception" }
```
Note that the message parameter is a lambda that returns a String. This allows for lazy evaluation of the message, which can improve performance when the log level is set to filter out certain messages.
### Composite Logging (Multiple Sinks)
If you want to send logs to multiple destinations, use the CompositeLogSink:
```kotlin
// Create log sinks
val consoleSink = ConsoleLogSink(LogLevel.INFO)
val otherSink = YourCustomLogSink(LogLevel.DEBUG)
// Create a composite sink
val compositeSink = CompositeLogSink(
level = LogLevel.DEBUG,
sinks = listOf(
consoleSink,
otherSink
)
)
// Create a logger
val logger = DefaultLogger(compositeSink)
// Log messages (will go to both sinks if level is appropriate)
logger.debug { "This goes only to otherSink if its level is DEBUG or lower" }
logger.info { "This goes to both sinks if their levels are INFO or lower" }
```
## Creating Custom Log Sinks
You can create your own log sink by implementing the LogSink interface:
```kotlin
class MyCustomLogSink(
override val level: LogLevel,
// Add any other parameters you need
) : LogSink {
override fun log(event: LogEvent) {
// Implement your custom logging logic here
// For example, send logs to a remote server, write to a database, etc.
val formattedMessage = "${event.timestamp} [${event.level}] ${event.tag ?: ""}: ${event.message}"
// Handle the throwable if present
event.throwable?.let {
// Process the throwable
}
// Send or store the log message
}
}
```
## Best Practices
### Log Levels
Use appropriate log levels for different types of messages:
- **VERBOSE**: Detailed information, typically useful only for debugging
- **DEBUG**: Debugging information, useful during development
- **INFO**: General information about application operation
- **WARN**: Potential issues that aren't errors but might need attention
- **ERROR**: Errors and exceptions that should be investigated
## Troubleshooting
### Common Issues
1. **No logs appearing**:
- Check that the log level of your sink is appropriate for the messages you're logging
- Verify that your logger is properly initialized
### Debugging the Logging System
To debug issues with the logging system itself:
1. Create a simple ConsoleLogSink with VERBOSE level
2. Log test messages at different levels
3. Check if messages appear as expected