Subversion Repositories Mobile Apps.GyroMouse

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #import <Foundation/Foundation.h>
  2. #import "DDLog.h"
  3.  
  4. @class DDLogFileInfo;
  5.  
  6. /**
  7.  * Welcome to Cocoa Lumberjack!
  8.  *
  9.  * The project page has a wealth of documentation if you have any questions.
  10.  * https://github.com/CocoaLumberjack/CocoaLumberjack
  11.  *
  12.  * If you're new to the project you may wish to read the "Getting Started" wiki.
  13.  * https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
  14.  *
  15.  *
  16.  * This class provides a logger to write log statements to a file.
  17. **/
  18.  
  19.  
  20. // Default configuration and safety/sanity values.
  21. //
  22. // maximumFileSize         -> DEFAULT_LOG_MAX_FILE_SIZE
  23. // rollingFrequency        -> DEFAULT_LOG_ROLLING_FREQUENCY
  24. // maximumNumberOfLogFiles -> DEFAULT_LOG_MAX_NUM_LOG_FILES
  25. //
  26. // You should carefully consider the proper configuration values for your application.
  27.  
  28. #define DEFAULT_LOG_MAX_FILE_SIZE     (1024 * 1024)   //  1 MB
  29. #define DEFAULT_LOG_ROLLING_FREQUENCY (60 * 60 * 24)  // 24 Hours
  30. #define DEFAULT_LOG_MAX_NUM_LOG_FILES (5)             //  5 Files
  31.  
  32.  
  33. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  34. #pragma mark -
  35. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  36.  
  37. // The LogFileManager protocol is designed to allow you to control all aspects of your log files.
  38. //
  39. // The primary purpose of this is to allow you to do something with the log files after they have been rolled.
  40. // Perhaps you want to compress them to save disk space.
  41. // Perhaps you want to upload them to an FTP server.
  42. // Perhaps you want to run some analytics on the file.
  43. //
  44. // A default LogFileManager is, of course, provided.
  45. // The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property.
  46. //
  47. // This protocol provides various methods to fetch the list of log files.
  48. //
  49. // There are two variants: sorted and unsorted.
  50. // If sorting is not necessary, the unsorted variant is obviously faster.
  51. // The sorted variant will return an array sorted by when the log files were created,
  52. // with the most recently created log file at index 0, and the oldest log file at the end of the array.
  53. //
  54. // You can fetch only the log file paths (full path including name), log file names (name only),
  55. // or an array of DDLogFileInfo objects.
  56. // The DDLogFileInfo class is documented below, and provides a handy wrapper that
  57. // gives you easy access to various file attributes such as the creation date or the file size.
  58.  
  59. @protocol DDLogFileManager <NSObject>
  60. @required
  61.  
  62. // Public properties
  63.  
  64. /**
  65.  * The maximum number of archived log files to keep on disk.
  66.  * For example, if this property is set to 3,
  67.  * then the LogFileManager will only keep 3 archived log files (plus the current active log file) on disk.
  68.  * Once the active log file is rolled/archived, then the oldest of the existing 3 rolled/archived log files is deleted.
  69.  *
  70.  * You may optionally disable deleting old/rolled/archived log files by setting this property to zero.
  71. **/
  72. @property (readwrite, assign) NSUInteger maximumNumberOfLogFiles;
  73.  
  74. // Public methods
  75.  
  76. - (NSString *)logsDirectory;
  77.  
  78. - (NSArray *)unsortedLogFilePaths;
  79. - (NSArray *)unsortedLogFileNames;
  80. - (NSArray *)unsortedLogFileInfos;
  81.  
  82. - (NSArray *)sortedLogFilePaths;
  83. - (NSArray *)sortedLogFileNames;
  84. - (NSArray *)sortedLogFileInfos;
  85.  
  86. // Private methods (only to be used by DDFileLogger)
  87.  
  88. - (NSString *)createNewLogFile;
  89.  
  90. @optional
  91.  
  92. // Notifications from DDFileLogger
  93.  
  94. - (void)didArchiveLogFile:(NSString *)logFilePath;
  95. - (void)didRollAndArchiveLogFile:(NSString *)logFilePath;
  96.  
  97. @end
  98.  
  99. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  100. #pragma mark -
  101. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  102.  
  103. /**
  104.  * Default log file manager.
  105.  *
  106.  * All log files are placed inside the logsDirectory.
  107.  * If a specific logsDirectory isn't specified, the default directory is used.
  108.  * On Mac, this is in ~/Library/Logs/<Application Name>.
  109.  * On iPhone, this is in ~/Library/Caches/Logs.
  110.  *
  111.  * Log files are named "<app name> <date> <time>.log"
  112.  * Example: MobileSafari 2013-12-03 17-14.log
  113.  *
  114.  * Archived log files are automatically deleted according to the maximumNumberOfLogFiles property.
  115. **/
  116. @interface DDLogFileManagerDefault : NSObject <DDLogFileManager>
  117. {
  118.     NSUInteger maximumNumberOfLogFiles;
  119.     NSString *_logsDirectory;
  120. }
  121.  
  122. - (id)init;
  123. - (instancetype)initWithLogsDirectory:(NSString *)logsDirectory;
  124.  
  125. /* Inherited from DDLogFileManager protocol:
  126.  
  127. @property (readwrite, assign) NSUInteger maximumNumberOfLogFiles;
  128.  
  129. - (NSString *)logsDirectory;
  130.  
  131. - (NSArray *)unsortedLogFilePaths;
  132. - (NSArray *)unsortedLogFileNames;
  133. - (NSArray *)unsortedLogFileInfos;
  134.  
  135. - (NSArray *)sortedLogFilePaths;
  136. - (NSArray *)sortedLogFileNames;
  137. - (NSArray *)sortedLogFileInfos;
  138.  
  139. */
  140.  
  141. @end
  142.  
  143. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  144. #pragma mark -
  145. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  146.  
  147. /**
  148.  * Most users will want file log messages to be prepended with the date and time.
  149.  * Rather than forcing the majority of users to write their own formatter,
  150.  * we will supply a logical default formatter.
  151.  * Users can easily replace this formatter with their own by invoking the setLogFormatter method.
  152.  * It can also be removed by calling setLogFormatter, and passing a nil parameter.
  153.  *
  154.  * In addition to the convenience of having a logical default formatter,
  155.  * it will also provide a template that makes it easy for developers to copy and change.
  156. **/
  157. @interface DDLogFileFormatterDefault : NSObject <DDLogFormatter>
  158. {
  159.     NSDateFormatter *dateFormatter;
  160. }
  161.  
  162. - (id)init;
  163. - (instancetype)initWithDateFormatter:(NSDateFormatter *)dateFormatter;
  164.  
  165. @end
  166.  
  167. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  168. #pragma mark -
  169. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  170.  
  171. @interface DDFileLogger : DDAbstractLogger <DDLogger>
  172. {
  173.     __strong id <DDLogFileManager> logFileManager;
  174.    
  175.     DDLogFileInfo *currentLogFileInfo;
  176.     NSFileHandle *currentLogFileHandle;
  177.    
  178.     dispatch_source_t currentLogFileVnode;
  179.     dispatch_source_t rollingTimer;
  180.    
  181.     unsigned long long maximumFileSize;
  182.     NSTimeInterval rollingFrequency;
  183. }
  184.  
  185. - (id)init;
  186. - (instancetype)initWithLogFileManager:(id <DDLogFileManager>)logFileManager;
  187.  
  188. /**
  189.  * Log File Rolling:
  190.  *
  191.  * maximumFileSize:
  192.  *   The approximate maximum size to allow log files to grow.
  193.  *   If a log file is larger than this value after a log statement is appended,
  194.  *   then the log file is rolled.
  195.  *
  196.  * rollingFrequency
  197.  *   How often to roll the log file.
  198.  *   The frequency is given as an NSTimeInterval, which is a double that specifies the interval in seconds.
  199.  *   Once the log file gets to be this old, it is rolled.
  200.  *
  201.  * Both the maximumFileSize and the rollingFrequency are used to manage rolling.
  202.  * Whichever occurs first will cause the log file to be rolled.
  203.  *
  204.  * For example:
  205.  * The rollingFrequency is 24 hours,
  206.  * but the log file surpasses the maximumFileSize after only 20 hours.
  207.  * The log file will be rolled at that 20 hour mark.
  208.  * A new log file will be created, and the 24 hour timer will be restarted.
  209.  *
  210.  * You may optionally disable rolling due to filesize by setting maximumFileSize to zero.
  211.  * If you do so, rolling is based solely on rollingFrequency.
  212.  *
  213.  * You may optionally disable rolling due to time by setting rollingFrequency to zero (or any non-positive number).
  214.  * If you do so, rolling is based solely on maximumFileSize.
  215.  *
  216.  * If you disable both maximumFileSize and rollingFrequency, then the log file won't ever be rolled.
  217.  * This is strongly discouraged.
  218. **/
  219. @property (readwrite, assign) unsigned long long maximumFileSize;
  220. @property (readwrite, assign) NSTimeInterval rollingFrequency;
  221.  
  222. /**
  223.  * The DDLogFileManager instance can be used to retrieve the list of log files,
  224.  * and configure the maximum number of archived log files to keep.
  225.  *
  226.  * @see DDLogFileManager.maximumNumberOfLogFiles
  227. **/
  228. @property (strong, nonatomic, readonly) id <DDLogFileManager> logFileManager;
  229.  
  230.  
  231. // You can optionally force the current log file to be rolled with this method.
  232. // CompletionBlock will be called on main queue.
  233.  
  234. - (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock;
  235.  
  236. // Method is deprecated. Use rollLogFileWithCompletionBlock: method instead.
  237.  
  238. - (void)rollLogFile __attribute((deprecated));
  239.  
  240. // Inherited from DDAbstractLogger
  241.  
  242. // - (id <DDLogFormatter>)logFormatter;
  243. // - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
  244.  
  245. @end
  246.  
  247. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  248. #pragma mark -
  249. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  250.  
  251. /**
  252.  * DDLogFileInfo is a simple class that provides access to various file attributes.
  253.  * It provides good performance as it only fetches the information if requested,
  254.  * and it caches the information to prevent duplicate fetches.
  255.  *
  256.  * It was designed to provide quick snapshots of the current state of log files,
  257.  * and to help sort log files in an array.
  258.  *
  259.  * This class does not monitor the files, or update it's cached attribute values if the file changes on disk.
  260.  * This is not what the class was designed for.
  261.  *
  262.  * If you absolutely must get updated values,
  263.  * you can invoke the reset method which will clear the cache.
  264. **/
  265. @interface DDLogFileInfo : NSObject
  266. {
  267.     __strong NSString *filePath;
  268.     __strong NSString *fileName;
  269.    
  270.     __strong NSDictionary *fileAttributes;
  271.    
  272.     __strong NSDate *creationDate;
  273.     __strong NSDate *modificationDate;
  274.    
  275.     unsigned long long fileSize;
  276. }
  277.  
  278. @property (strong, nonatomic, readonly) NSString *filePath;
  279. @property (strong, nonatomic, readonly) NSString *fileName;
  280.  
  281. @property (strong, nonatomic, readonly) NSDictionary *fileAttributes;
  282.  
  283. @property (strong, nonatomic, readonly) NSDate *creationDate;
  284. @property (strong, nonatomic, readonly) NSDate *modificationDate;
  285.  
  286. @property (nonatomic, readonly) unsigned long long fileSize;
  287.  
  288. @property (nonatomic, readonly) NSTimeInterval age;
  289.  
  290. @property (nonatomic, readwrite) BOOL isArchived;
  291.  
  292. + (instancetype)logFileWithPath:(NSString *)filePath;
  293.  
  294. - (instancetype)initWithFilePath:(NSString *)filePath;
  295.  
  296. - (void)reset;
  297. - (void)renameFile:(NSString *)newFileName;
  298.  
  299. #if TARGET_IPHONE_SIMULATOR
  300.  
  301. // So here's the situation.
  302. // Extended attributes are perfect for what we're trying to do here (marking files as archived).
  303. // This is exactly what extended attributes were designed for.
  304. //
  305. // But Apple screws us over on the simulator.
  306. // Everytime you build-and-go, they copy the application into a new folder on the hard drive,
  307. // and as part of the process they strip extended attributes from our log files.
  308. // Normally, a copy of a file preserves extended attributes.
  309. // So obviously Apple has gone to great lengths to piss us off.
  310. //
  311. // Thus we use a slightly different tactic for marking log files as archived in the simulator.
  312. // That way it "just works" and there's no confusion when testing.
  313. //
  314. // The difference in method names is indicative of the difference in functionality.
  315. // On the simulator we add an attribute by appending a filename extension.
  316. //
  317. // For example:
  318. // log-ABC123.txt -> log-ABC123.archived.txt
  319.  
  320. - (BOOL)hasExtensionAttributeWithName:(NSString *)attrName;
  321.  
  322. - (void)addExtensionAttributeWithName:(NSString *)attrName;
  323. - (void)removeExtensionAttributeWithName:(NSString *)attrName;
  324.  
  325. #else
  326.  
  327. // Normal use of extended attributes used everywhere else,
  328. // such as on Macs and on iPhone devices.
  329.  
  330. - (BOOL)hasExtendedAttributeWithName:(NSString *)attrName;
  331.  
  332. - (void)addExtendedAttributeWithName:(NSString *)attrName;
  333. - (void)removeExtendedAttributeWithName:(NSString *)attrName;
  334.  
  335. #endif
  336.  
  337. - (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another;
  338. - (NSComparisonResult)reverseCompareByModificationDate:(DDLogFileInfo *)another;
  339.  
  340. @end
  341.