vOOice/VoiceInk/Utilities/AppLogger.swift
Deborah Mangan d798a99994 docs: Add QOL improvements documentation and source files
This commit provides comprehensive documentation and source files for 5 critical quality of life improvements:

1. Recording duration indicator with real-time timer
2. Enhanced status display with visual feedback
3. Visible cancel button during recording
4. Keyboard shortcut cheat sheet (Cmd+?)
5. Structured logging system (AppLogger)

Included Files:
- Complete source files for new features
- Step-by-step application guide
- Detailed technical documentation
- Full analysis with 40+ improvement ideas

See APPLYING_QOL_IMPROVEMENTS.md for instructions on how to apply these improvements to the codebase.

All changes are backward compatible with no breaking changes.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2025-11-03 11:39:30 +10:00

171 lines
5.4 KiB
Swift
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
import OSLog
/// Centralized logging system for VoiceLink Community
///
/// Provides structured, categorized logging with consistent formatting across the application.
/// Uses OSLog for performance and integration with macOS Console.app.
///
/// ## Usage
/// ```swift
/// AppLogger.transcription.info("Starting transcription for \(audioURL.lastPathComponent)")
/// AppLogger.audio.error("Failed to configure audio device: \(error)")
/// ```
struct AppLogger {
private init() {}
// MARK: - Subsystem
private static let subsystem = Bundle.main.bundleIdentifier ?? "com.tmm22.voicelinkcommunity"
// MARK: - Category Loggers
/// Logger for transcription operations
///
/// Use for:
/// - Starting/stopping transcription
/// - Model loading/unloading
/// - Transcription results
/// - Transcription errors
static let transcription = Logger(subsystem: subsystem, category: "Transcription")
/// Logger for audio operations
///
/// Use for:
/// - Audio device configuration
/// - Recording start/stop
/// - Audio level monitoring
/// - Audio file operations
static let audio = Logger(subsystem: subsystem, category: "Audio")
/// Logger for Power Mode operations
///
/// Use for:
/// - Power Mode activation/deactivation
/// - Configuration application
/// - App/URL detection
/// - Session management
static let powerMode = Logger(subsystem: subsystem, category: "PowerMode")
/// Logger for AI enhancement operations
///
/// Use for:
/// - AI provider communication
/// - Enhancement requests/responses
/// - Prompt processing
/// - Context capture
static let ai = Logger(subsystem: subsystem, category: "AI")
/// Logger for UI operations
///
/// Use for:
/// - Window management
/// - View lifecycle
/// - User interactions
/// - UI state changes
static let ui = Logger(subsystem: subsystem, category: "UI")
/// Logger for network operations
///
/// Use for:
/// - API requests/responses
/// - Network errors
/// - TTS provider calls
/// - Cloud transcription
static let network = Logger(subsystem: subsystem, category: "Network")
/// Logger for storage operations
///
/// Use for:
/// - SwiftData operations
/// - File I/O
/// - Keychain access
/// - UserDefaults
static let storage = Logger(subsystem: subsystem, category: "Storage")
/// Logger for general application lifecycle
///
/// Use for:
/// - App launch/termination
/// - Initialization
/// - Configuration
/// - Critical errors
static let app = Logger(subsystem: subsystem, category: "App")
// MARK: - Convenience Methods
/// Log a transcription event
static func logTranscription(_ message: String, level: OSLogType = .info, file: String = #file, function: String = #function, line: Int = #line) {
log(message, logger: transcription, level: level, file: file, function: function, line: line)
}
/// Log an audio event
static func logAudio(_ message: String, level: OSLogType = .info, file: String = #file, function: String = #function, line: Int = #line) {
log(message, logger: audio, level: level, file: file, function: function, line: line)
}
/// Log a Power Mode event
static func logPowerMode(_ message: String, level: OSLogType = .info, file: String = #file, function: String = #function, line: Int = #line) {
log(message, logger: powerMode, level: level, file: file, function: function, line: line)
}
/// Log an AI enhancement event
static func logAI(_ message: String, level: OSLogType = .info, file: String = #file, function: String = #function, line: Int = #line) {
log(message, logger: ai, level: level, file: file, function: function, line: line)
}
// MARK: - Private Helpers
private static func log(_ message: String, logger: Logger, level: OSLogType, file: String, function: String, line: Int) {
let fileName = URL(fileURLWithPath: file).lastPathComponent
let context = "[\(fileName):\(line) \(function)]"
switch level {
case .debug:
logger.debug("\(context) \(message)")
case .info:
logger.info("\(context) \(message)")
case .error:
logger.error("\(context) \(message)")
case .fault:
logger.fault("\(context) \(message)")
default:
logger.log("\(context) \(message)")
}
}
}
// MARK: - OSLogType Extension
extension OSLogType {
/// Human-readable description of log level
var description: String {
switch self {
case .debug: return "DEBUG"
case .info: return "INFO"
case .error: return "ERROR"
case .fault: return "FAULT"
default: return "LOG"
}
}
}
// MARK: - Migration Helpers
#if DEBUG
/// Helper to identify print statements that should be migrated to AppLogger
///
/// Usage in development:
/// ```swift
/// // Instead of:
/// print("🎙 Recording started")
///
/// // Use:
/// AppLogger.audio.info("Recording started")
/// ```
@available(*, deprecated, message: "Use AppLogger instead")
func debugPrint(_ items: Any..., separator: String = " ", terminator: String = "\n") {
Swift.print("⚠️ [DEPRECATED] Use AppLogger:", items, separator: separator, terminator: terminator)
}
#endif