TLog is a powerful, lightweight, and easy-to-use logging library for Swift applications. It provides multiple output destinations, customizable formatting, and enterprise-grade features while maintaining simplicity and performance.
- โ Multiple Log Levels: trace, debug, info, warning, error, critical
- โ Multiple Destinations: Console, File, OSLog, Network, Memory
- โ Thread-Safe: All operations are performed on dedicated queues
- โ File Rotation: Automatic log file rotation with size limits
- โ Customizable Formatting: Configure timestamp, emoji, category display
- โ Zero Dependencies: Pure Swift implementation
- โ Backward Compatible: Drop-in replacement for TLog 1.x
- ๐ Log Rotation: Automatic file rotation with configurable size and count limits
- ๐ฑ OSLog Integration: Native iOS logging system integration
- ๐จ Emoji Support: Visual log level indicators
- ๐ Category System: Organize logs by functional areas
- ๐ฏ Filtering: Per-destination log level filtering
- ๐งต Thread Safety: Concurrent logging without blocking
- ๐ Privacy Protection: Built-in sensitive data redaction
- ๐ Analytics: Real-time log statistics and monitoring
- ๐ก๏ธ Circuit Breaker: Network destination protection
- โก Async Support: Modern Swift concurrency integration
- Open your project in Xcode
- Go to File โ Add Package Dependencies
- Enter the repository URL:
https://github.com/fanta1ty/TLog.git
- Choose version
2.0.0
or "Up to Next Major Version" - Click Add Package
Add TLog to your Package.swift
dependencies:
// swift-tools-version: 5.5
import PackageDescription
let package = Package(
name: "YourProject",
dependencies: [
.package(url: "https://github.com/fanta1ty/TLog.git", from: "2.0.0")
],
targets: [
.target(
name: "YourTarget",
dependencies: ["TLog"]
),
]
)
Then run:
swift package update
# Podfile
platform :ios, '12.0'
use_frameworks!
target 'YourApp' do
pod 'TLog', '~> 2.0'
end
# Install CocoaPods (if not already installed)
sudo gem install cocoapods
# Install TLog
pod install
# Open workspace (not .xcodeproj)
open YourApp.xcworkspace
import TLog
Add to your Cartfile
:
github "fanta1ty/TLog" ~> 2.0
Then run:
carthage update --platform iOS
- Download the source code from GitHub releases
- Copy the
Sources/TLog
directory into your project - Add the files to your Xcode project
import TLog
// Simple logging (same as TLog 1.x)
TLog.debug("Debug message")
TLog.info("Info message")
TLog.warning("Warning message")
TLog.error("Error message")
// Enable/disable logging
TLog.isLoggingEnabled = true
import TLog
// Get the shared logger instance
let logger = TLog.shared
// Configure global settings
logger.minimumLevel = .info
logger.defaultCategory = "MyApp"
// Enable file logging
logger.enableFileLogging(fileName: "myapp.log")
// Log with categories
logger.info("User logged in", category: "AUTH")
logger.error("Database connection failed", category: "DATABASE")
logger.debug("API response received", category: "NETWORK")
TLog supports six log levels in hierarchical order:
Level | Description | Use Case | Production |
---|---|---|---|
trace ๐ | Finest level of detail | Method entry/exit, detailed flow | โ |
debug ๐ | Debugging information | Variable values, state changes | โ |
info โน๏ธ | General information | Application lifecycle, major events | โ |
warning |
Potentially harmful situations | Deprecated API usage, fallback scenarios | โ |
error โ | Error events | Handled exceptions, failed operations | โ |
critical ๐ฅ | Very severe errors | System failures, data corruption | โ |
// Method tracing (development only)
logger.trace("โ processUserData")
logger.trace("โ processUserData completed")
// Debug information
logger.debug("API Response", metadata: [
"status_code": .stringConvertible(200),
"response_time": .stringConvertible(1.2)
])
// Important events
logger.info("User login successful", metadata: [
"user_id": .string("12345"),
"login_method": .string("oauth")
])
// Potential issues
logger.warning("API response time high", metadata: [
"response_time": .stringConvertible(5.2),
"threshold": .stringConvertible(3.0)
])
// Handled errors
logger.error("Payment processing failed", metadata: [
"error_code": .string("CARD_DECLINED"),
"amount": .stringConvertible(99.99)
])
// Critical system issues
logger.critical("Database connection lost", metadata: [
"connection_attempts": .stringConvertible(3),
"last_error": .string("Connection timeout")
])
Outputs formatted logs to the console with emoji and color support.
// Configure console formatting
logger.configureConsole(
showEmojis: true,
showTimestamp: true,
showCategory: true,
showLocation: true,
showThreadInfo: true,
colorOutput: true
)
Output Example:
14:32:18.742 โน๏ธ [INFO] [AUTH] [main] <LoginViewController.swift:45> User authentication successful
Writes logs to files with automatic rotation.
// Enable file logging with custom settings
logger.enableFileLogging(fileName: "app.log")
// Or configure manually
let fileDestination = FileDestination(fileName: "custom.log")
fileDestination.maxFileSize = 5 * 1024 * 1024 // 5MB
fileDestination.maxFiles = 10
fileDestination.compressionEnabled = true
logger.addDestination(fileDestination)
Features:
- Automatic file rotation when size limit is reached
- Configurable number of archived files
- Thread-safe file operations
- Logs stored in app's Documents/Logs directory
- Optional compression for archived files
Sends logs to remote servers with advanced features.
// Basic network logging
logger.enableNetworkLogging(
endpoint: URL(string: "https://logs.myapp.com/api")!,
authToken: "your-auth-token",
minimumLevel: .error
)
// Advanced configuration
let networkConfig = NetworkConfiguration(
endpoint: URL(string: "https://logs.myapp.com/api")!,
httpMethod: .POST,
format: .json,
batchSize: 20,
flushInterval: 30.0,
authToken: "bearer-token",
customHeaders: ["X-App-Version": "1.0.0"],
enableGzip: true,
retryPolicy: RetryPolicy(maxRetries: 3, baseDelay: 1.0)
)
let networkDestination = NetworkDestination(
configuration: networkConfig,
enableCircuitBreaker: true
)
logger.addDestination(networkDestination)
Features:
- Multiple HTTP methods (GET, POST, PUT, PATCH, DELETE)
- Various formats (JSON, JSON Lines, Plain Text, Custom)
- Batching and automatic flushing
- Authentication support
- Custom headers
- Gzip compression
- Circuit breaker protection
- Retry logic with exponential backoff
Stores logs in memory for testing and debugging.
// Enable memory logging
logger.enableMemoryLogging(maxMessages: 1000)
// Access stored messages
let memoryDest = logger.getMemoryDestination()
let allMessages = memoryDest?.getAllMessages()
let errorMessages = memoryDest?.getMessages(for: .error)
let networkLogs = memoryDest?.getMessages(for: "NETWORK")
Integrates with Apple's unified logging system.
if #available(iOS 10.0, *) {
let osLogDestination = OSLogDestination(
subsystem: "com.myapp.logger",
category: "network"
)
logger.addDestination(osLogDestination)
}
Create custom destinations by implementing the LogDestination
protocol:
class SlackDestination: LogDestination {
var isEnabled: Bool = true
var minimumLevel: LogLevel = .error
var filters: [LogFilter] = []
var formatter: LogFormatter?
private let webhookURL: URL
init(webhookURL: URL) {
self.webhookURL = webhookURL
}
func write(_ message: LogMessage) {
guard isEnabled && message.level >= minimumLevel else { return }
guard filters.allSatisfy({ $0.shouldLog(message) }) else { return }
let slackMessage = [
"text": formatter?.format(message) ?? message.formattedMessage,
"channel": "#alerts",
"username": "TLog Bot"
]
// Send to Slack webhook
sendToSlack(slackMessage)
}
private func sendToSlack(_ message: [String: Any]) {
// Implementation for sending to Slack
}
}
// Add custom destination
logger.addDestination(SlackDestination(webhookURL: slackWebhookURL))
private func setupLogging() {
let logger = TLog.shared
#if DEBUG
// ๐ ๏ธ Development Environment
logger.configure(for: .development)
logger.enableMemoryLogging(maxMessages: 1000)
logger.configureConsole(
showEmojis: true,
showTimestamp: true,
showThreadInfo: true,
colorOutput: true
)
#elseif STAGING
// ๐งช Staging Environment
logger.configure(for: .staging)
logger.enableFileLogging(fileName: "staging.log")
logger.enableNetworkLogging(
endpoint: URL(string: "https://staging-logs.myapp.com/api")!,
authToken: "staging-auth-token",
minimumLevel: .info
)
#else
// ๐ญ Production Environment
logger.configure(for: .production)
logger.enablePrivacyProtection() // ๐ Protect user data
logger.enableFileLogging(fileName: "production.log")
logger.enableHealthMonitoring() // ๐ฉบ Monitor logging health
// Send critical errors to monitoring service
logger.enableRobustNetworkLogging(
endpoint: URL(string: "https://logs.myapp.com/api/errors")!,
authToken: "prod-auth-token",
minimumLevel: .error,
enableCircuitBreaker: true
)
#endif
// ๐ Global metadata for all logs
logger.globalMetadata = [
"app_version": .string(Bundle.main.appVersion),
"user_id": .string(currentUserID),
"session_id": .string(UUID().uuidString)
]
}
// Add filters
logger.addGlobalFilter(LogFilters.category(["NETWORK", "DATABASE"]))
logger.addGlobalFilter(LogFilters.rateLimit(maxMessages: 100, per: 60.0))
logger.addGlobalFilter(LogFilters.contains("ERROR"))
// Enable privacy protection
var privacySettings = PrivacySettings()
privacySettings.enableDataRedaction = true
privacySettings.enableEmailRedaction = true
privacySettings.enableIPRedaction = true
logger.enablePrivacyProtection(settings: privacySettings)
Platform | Minimum Version | Notes |
---|---|---|
iOS | 12.0+ | Full feature support |
macOS | 10.14+ | Full feature support |
tvOS | 12.0+ | Console and file logging |
watchOS | 5.0+ | Console logging only |
TLog is fully thread-safe:
- All logging operations use dedicated concurrent queues
- File operations are serialized to prevent corruption
- No blocking of the main thread
- Safe to use from any thread or queue
// Safe to call from any thread
DispatchQueue.global().async {
TLog.info("Background thread log")
}
DispatchQueue.main.async {
TLog.info("Main thread log")
}
TLog is designed for high performance:
- Minimal overhead for disabled log levels
- Asynchronous writing to destinations
- Efficient string formatting
- Memory-conscious design
Benchmarks (iPhone 12 Pro, Release build):
- 1M debug logs (disabled): ~0.1 seconds
- 100K info logs (enabled): ~2.3 seconds
- File logging overhead: ~5% additional time
// Enable performance monitoring
logger.isPerformanceMonitoringEnabled = true
// Check performance metrics
let metrics = logger.performanceMetrics
print("Average log time: \(metrics.averageLogTime * 1000)ms")
print("Messages by level: \(metrics.messagesByLevel)")
TLog 2.0 is backward compatible with 1.x. Existing code works without changes:
// TLog 1.x code works as-is
TLog.debug("Debug message")
TLog.info("Info message")
TLog.error("Error message")
TLog.isLoggingEnabled = false
// But you can now use enhanced features
TLog.shared.enableFileLogging()
TLog.shared.minimumLevel = .warning
- โ
Replace
TLog.verbose()
withTLog.trace()
for semantic clarity - โ
Replace
TLog.server()
withTLog.info(category: "SERVER")
- โ Consider using metadata instead of string interpolation
- โ Set up environment-based configuration
- โ Enable privacy protection for production
// Instance methods with metadata support
func trace(_ message: String, metadata: LogMetadata = [:], category: String? = nil)
func debug(_ message: String, metadata: LogMetadata = [:], category: String? = nil)
func info(_ message: String, metadata: LogMetadata = [:], category: String? = nil)
func warning(_ message: String, metadata: LogMetadata = [:], category: String? = nil)
func error(_ message: String, metadata: LogMetadata = [:], category: String? = nil)
func critical(_ message: String, metadata: LogMetadata = [:], category: String? = nil)
// Static methods (backward compatibility)
static func debug(_ message: String)
static func info(_ message: String)
static func warning(_ message: String)
static func error(_ message: String)
static func verbose(_ message: String) // Maps to trace
static func server(_ message: String) // Maps to info with "SERVER" category
// Async methods (iOS 13+)
func traceAsync(_ message: String, metadata: LogMetadata = [:], category: String? = nil) async
func debugAsync(_ message: String, metadata: LogMetadata = [:], category: String? = nil) async
// ... other async methods
// Convenience methods
func error(_ error: Error, message: String = "Error occurred", category: String? = nil)
func time<T>(_ operation: String, category: String? = nil, block: () throws -> T) rethrows -> T
func timeAsync<T>(_ operation: String, category: String? = nil, block: () async throws -> T) async rethrows -> T
func configure(for environment: Environment)
func configure(with configuration: TLogConfiguration)
func addDestination(_ destination: LogDestination)
func removeAllDestinations()
func enableFileLogging(fileName: String = "app.log")
func enableNetworkLogging(endpoint: URL, authToken: String? = nil, minimumLevel: LogLevel = .error)
func enableMemoryLogging(maxMessages: Int = 1000)
func enablePrivacyProtection(settings: PrivacySettings = PrivacySettings())
func enableHealthMonitoring()
func configureConsole(showEmojis: Bool, showTimestamp: Bool, ...)
import XCTest
@testable import MyApp
import TLog
class MyAppTests: XCTestCase {
override func setUp() {
super.setUp()
// Configure TLog for testing
TLog.shared.configureForTesting()
}
override func tearDown() {
// Clear logs after each test
TLog.shared.getMemoryDestination()?.clear()
super.tearDown()
}
func testUserLogin() {
// Your test code
performUserLogin()
// Verify logging
let memoryDest = TLog.shared.getMemoryDestination()!
let logs = memoryDest.getAllMessages()
XCTAssertTrue(logs.contains { $0.message.contains("User login") })
XCTAssertEqual(memoryDest.getMessages(for: "AUTH").count, 2)
}
}
We welcome contributions! Please see our Contributing Guidelines for details.
# Clone repository
git clone https://github.com/fanta1ty/TLog.git
cd TLog
# Open in Xcode
open Package.swift
# Or build with Swift Package Manager
swift build
swift test
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Write tests for your changes
- Ensure all tests pass (
swift test
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
TLog is available under the MIT license. See the LICENSE file for more info.
- Original TLog library concept
- Swift community for logging best practices
- Apple's OSLog for system integration patterns
- Contributors and beta testers
- ๐ง Email: [email protected]
- ๐ Issues: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
- ๐ Documentation: API Reference
- ๐ Changelog: CHANGELOG.md
- SwiftUI log viewer component
- Structured logging improvements
- More built-in formatters
- Enhanced privacy controls
- macOS app for log analysis
- Cloud logging service integration
- Machine learning log analysis
- Advanced filtering DSL
Made with โค๏ธ by fanta1ty
import TLog
// Simple logging (same as TLog 1.x)
TLog.debug("Debug message")
TLog.info("Info message")
TLog.warning("Warning message")
TLog.error("Error message")
// Enable/disable logging
TLog.isLoggingEnabled = true
import TLog
// Get the shared logger instance
let logger = TLog.shared
// Configure global settings
logger.minimumLevel = .info
logger.defaultCategory = "MyApp"
// Enable file logging
logger.enableFileLogging(fileName: "myapp.log")
// Log with categories
logger.info("User logged in", category: "AUTH")
logger.error("Database connection failed", category: "DATABASE")
logger.debug("API response received", category: "NETWORK")
TLog supports six log levels in hierarchical order:
Level | Description | Use Case |
---|---|---|
trace ๐ | Finest level of detail | Method entry/exit, detailed flow |
debug ๐ | Debugging information | Variable values, state changes |
info โน๏ธ | General information | Application lifecycle, major events |
warning |
Potentially harmful situations | Deprecated API usage, fallback scenarios |
error โ | Error events | Handled exceptions, failed operations |
critical ๐ฅ | Very severe errors | System failures, data corruption |
Outputs formatted logs to the console with emoji and color support.
// Configure console formatting
logger.configureConsole(
showEmojis: true,
showTimestamp: true,
showCategory: true,
showLocation: true
)
Output Example:
14:32:18.742 โน๏ธ [INFO] [AUTH] <LoginViewController.swift:45> User authentication successful
Writes logs to files with automatic rotation.
// Enable file logging with custom settings
let fileDestination = FileDestination(fileName: "app.log")
fileDestination.maxFileSize = 5 * 1024 * 1024 // 5MB
fileDestination.maxFiles = 10
logger.addDestination(fileDestination)
Features:
- Automatic file rotation when size limit is reached
- Configurable number of archived files
- Thread-safe file operations
- Logs stored in app's Documents/Logs directory
Integrates with Apple's unified logging system.
if #available(iOS 10.0, *) {
let osLogDestination = OSLogDestination(
subsystem: "com.myapp.logger",
category: "network"
)
logger.addDestination(osLogDestination)
}
Create custom destinations by implementing the LogDestination
protocol:
class NetworkDestination: LogDestination {
var isEnabled: Bool = true
var minimumLevel: LogLevel = .error
func write(_ message: LogMessage) {
// Send logs to remote server
sendToServer(message)
}
private func sendToServer(_ message: LogMessage) {
// Implementation for sending logs to server
}
}
// Add custom destination
logger.addDestination(NetworkDestination())
let logger = TLog.shared
// Set minimum log level
logger.minimumLevel = .warning
// Set default category
logger.defaultCategory = "MyApp"
// Enable/disable all logging
logger.isEnabled = true
// Configure specific destinations
for destination in logger.destinations {
if let console = destination as? ConsoleDestination {
console.minimumLevel = .debug
console.showEmojis = false
}
if let file = destination as? FileDestination {
file.minimumLevel = .info
file.maxFileSize = 2 * 1024 * 1024 // 2MB
}
}
Platform | Minimum Version | Notes |
---|---|---|
iOS | 12.0+ | Full feature support |
macOS | 10.14+ | Full feature support |
tvOS | 12.0+ | Console and file logging |
watchOS | 5.0+ | Console logging only |
TLog is fully thread-safe:
- All logging operations use dedicated concurrent queues
- File operations are serialized to prevent corruption
- No blocking of the main thread
- Safe to use from any thread or queue
TLog is designed for high performance:
- Minimal overhead for disabled log levels
- Asynchronous writing to destinations
- Efficient string formatting
- Memory-conscious design
Benchmarks (iPhone 12 Pro, Release build):
- 1M debug logs (disabled): ~0.1 seconds
- 100K info logs (enabled): ~2.3 seconds
- File logging overhead: ~5% additional time
TLog 2.0 is backward compatible with 1.x. Existing code works without changes:
// TLog 1.x code works as-is
TLog.debug("Debug message")
TLog.info("Info message")
TLog.error("Error message")
TLog.isLoggingEnabled = false
// But you can now use enhanced features
TLog.shared.enableFileLogging()
TLog.shared.minimumLevel = .warning
// Instance methods
func trace(_ message: String, category: String? = nil)
func debug(_ message: String, category: String? = nil)
func info(_ message: String, category: String? = nil)
func warning(_ message: String, category: String? = nil)
func error(_ message: String, category: String? = nil)
func critical(_ message: String, category: String? = nil)
// Static methods (backward compatibility)
static func debug(_ message: String)
static func info(_ message: String)
static func warning(_ message: String)
static func error(_ message: String)
static func verbose(_ message: String) // Maps to trace
static func server(_ message: String) // Maps to info with "SERVER" category
func addDestination(_ destination: LogDestination)
func removeAllDestinations()
func enableFileLogging(fileName: String = "app.log")
func configureConsole(showEmojis: Bool, showTimestamp: Bool, ...)
func getLogFileURL() -> URL?
We welcome contributions! Please see our Contributing Guidelines for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
TLog is available under the MIT license. See the LICENSE file for more info.
- Original TLog library concept
- Swift community for logging best practices
- Apple's OSLog for system integration patterns
- ๐ง Email: [email protected]
- ๐ Issues: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions