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 | 13.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
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?
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: thinhnguyen12389@gmail.com
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions