// Software License Agreement (BSD License) // // Copyright (c) 2010-2023, Deusty, LLC // All rights reserved. // // Redistribution and use of this software in source and binary forms, // with or without modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // * Neither the name of Deusty nor the names of its contributors may be used // to endorse or promote products derived from this software without specific // prior written permission of Deusty, LLC. // Disable legacy macros #ifndef DD_LEGACY_MACROS #define DD_LEGACY_MACROS 0 #endif #ifndef DD_NSLOG_LEVEL #define DD_NSLOG_LEVEL 2 #endif #import "DDLog.h" #import "DDFileLogger.h" #import "DDLogFileInfo.h" #import "DDLogFileManager.h" #import "DDLogFileManagerDefault.h" #import "DDLogFileFormatterDefault.h" #define NSLogError(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 1) NSLog((frmt), ##__VA_ARGS__); } while(0) #define NSLogWarn(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 2) NSLog((frmt), ##__VA_ARGS__); } while(0) #define NSLogInfo(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 3) NSLog((frmt), ##__VA_ARGS__); } while(0) #define NSLogDebug(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 4) NSLog((frmt), ##__VA_ARGS__); } while(0) #define NSLogVerbose(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 5) NSLog((frmt), ##__VA_ARGS__); } while(0) NS_ASSUME_NONNULL_BEGIN /** * This class provides a logger to write log statements to a file. **/ // Default configuration and safety/sanity values. // // maximumFileSize -> kDDDefaultLogMaxFileSize // rollingFrequency -> kDDDefaultLogRollingFrequency // maximumNumberOfLogFiles -> kDDDefaultLogMaxNumLogFiles // logFilesDiskQuota -> kDDDefaultLogFilesDiskQuota // // You should carefully consider the proper configuration values for your application. extern unsigned long long const kDDDefaultLogMaxFileSize; extern NSTimeInterval const kDDDefaultLogRollingFrequency; extern NSUInteger const kDDDefaultLogMaxNumLogFiles; extern unsigned long long const kDDDefaultLogFilesDiskQuota; /** * The standard implementation for a file logger */ @interface DDFileLogger : DDAbstractLogger /** * Designated initializer, requires a `DDLogFileManager` instance. * A global queue w/ default priority is used to run callbacks. * If needed, specify queue using `initWithLogFileManager:completionQueue:`. */ - (instancetype)initWithLogFileManager:(id )logFileManager logfileFormatter:(nullable DDLogFileFormatterDefault *)logfileFormatter; /** * Designated initializer, requires a `DDLogFileManager` instance. * The completionQueue is used to execute `didArchiveLogFile:wasRolled:`, * and the callback in `rollLogFileWithCompletionBlock:`. * If nil, a global queue w/ default priority is used. */ - (instancetype)initWithLogFileManager:(id )logFileManager logfileFormatter:(nullable DDLogFileFormatterDefault *)logfileFormatter completionQueue:(nullable dispatch_queue_t)dispatchQueue NS_DESIGNATED_INITIALIZER; /** * Deprecated. Use `willLogMessage:` */ - (void)willLogMessage __attribute__((deprecated("Use -willLogMessage:"))) NS_REQUIRES_SUPER; /** * Deprecated. Use `didLogMessage:` */ - (void)didLogMessage __attribute__((deprecated("Use -didLogMessage:"))) NS_REQUIRES_SUPER; /** * Called when the logger is about to write message. Call super before your implementation. */ - (void)willLogMessage:(DDLogFileInfo *)logFileInfo NS_REQUIRES_SUPER; /** * Called when the logger wrote message. Call super after your implementation. */ - (void)didLogMessage:(DDLogFileInfo *)logFileInfo NS_REQUIRES_SUPER; /** * Writes all in-memory log data to the permanent storage. Call super before your implementation. * Don't call this method directly, instead use the `[DDLog flushLog]` to ensure all log messages are included in flush. */ - (void)flush NS_REQUIRES_SUPER; /** * Called when the logger checks archive or not current log file. * Override this method to extend standard behavior. By default returns NO. * This is executed directly on the logger's internal queue, so keep processing light! */ - (BOOL)shouldArchiveRecentLogFileInfo:(DDLogFileInfo *)recentLogFileInfo; /** * Log File Rolling: * * `maximumFileSize`: * The approximate maximum size (in bytes) to allow log files to grow. * If a log file is larger than this value after a log statement is appended, * then the log file is rolled. * * `rollingFrequency` * How often to roll the log file. * The frequency is given as an `NSTimeInterval`, which is a double that specifies the interval in seconds. * Once the log file gets to be this old, it is rolled. * * `doNotReuseLogFiles` * When set, will always create a new log file at application launch. * * Both the `maximumFileSize` and the `rollingFrequency` are used to manage rolling. * Whichever occurs first will cause the log file to be rolled. * * For example: * The `rollingFrequency` is 24 hours, * but the log file surpasses the `maximumFileSize` after only 20 hours. * The log file will be rolled at that 20 hour mark. * A new log file will be created, and the 24 hour timer will be restarted. * * You may optionally disable rolling due to filesize by setting `maximumFileSize` to zero. * If you do so, rolling is based solely on `rollingFrequency`. * * You may optionally disable rolling due to time by setting `rollingFrequency` to zero (or any non-positive number). * If you do so, rolling is based solely on `maximumFileSize`. * * If you disable both `maximumFileSize` and `rollingFrequency`, then the log file won't ever be rolled. * This is strongly discouraged. **/ @property (readwrite, assign) unsigned long long maximumFileSize; /** * See description for `maximumFileSize` */ @property (readwrite, assign) NSTimeInterval rollingFrequency; /** * See description for `maximumFileSize` */ @property (readwrite, assign, atomic) BOOL doNotReuseLogFiles; /** * The DDLogFileManager instance can be used to retrieve the list of log files, * and configure the maximum number of archived log files to keep. * * @see DDLogFileManager.maximumNumberOfLogFiles **/ @property (strong, nonatomic, readonly) id logFileManager; /** * When using a custom formatter you can set the `logMessage` method not to append * `\n` character after each output. This allows for some greater flexibility with * custom formatters. Default value is YES. **/ @property (nonatomic, readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters; /** * You can optionally force the current log file to be rolled with this method. * CompletionBlock will be called on main queue. */ - (void)rollLogFileWithCompletionBlock:(nullable void (^)(void))completionBlock NS_SWIFT_NAME(rollLogFile(withCompletion:)); /** * Method is deprecated. * @deprecated Use `rollLogFileWithCompletionBlock:` method instead. */ - (void)rollLogFile __attribute__((deprecated("Use -rollLogFileWithCompletionBlock:"))); - (void)logData:(NSData *)data; // Will assert if used outside logger's queue. - (void)lt_logData:(NSData *)data; - (nullable NSData *)lt_dataForMessage:(DDLogMessage *)message; // Inherited from DDAbstractLogger // - (id )logFormatter; // - (void)setLogFormatter:(id )formatter; /** * Returns the log file that should be used. * If there is an existing log file that is suitable, * within the constraints of `maximumFileSize` and `rollingFrequency`, then it is returned. * * Otherwise a new file is created and returned. If this failes, `NULL` is returned. **/ @property (nonatomic, nullable, readonly, strong) DDLogFileInfo *currentLogFileInfo; @end NS_ASSUME_NONNULL_END