Skip to content

Commit

Permalink
File rolling based on size or time may optionally be disabled now.
Browse files Browse the repository at this point in the history
  • Loading branch information
robbiehanson committed Mar 20, 2012
1 parent 8c53ba7 commit bd66c48
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 81 deletions.
134 changes: 74 additions & 60 deletions Lumberjack/DDFileLogger.h
Expand Up @@ -92,18 +92,19 @@
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Default log file manager.
//
// All log files are placed inside the logsDirectory.
// If a specific logsDirectory isn't specified, the default directory is used.
// On Mac, this is in ~/Library/Logs/<Application Name>.
// On iPhone, this is in ~/Library/Caches/Logs.
//
// Log files are named "log-<uuid>.txt",
// where uuid is a 6 character hexadecimal consisting of the set [0123456789ABCDEF].
//
// Archived log files are automatically deleted according to the maximumNumberOfLogFiles property.

/**
* Default log file manager.
*
* All log files are placed inside the logsDirectory.
* If a specific logsDirectory isn't specified, the default directory is used.
* On Mac, this is in ~/Library/Logs/<Application Name>.
* On iPhone, this is in ~/Library/Caches/Logs.
*
* Log files are named "log-<uuid>.txt",
* where uuid is a 6 character hexadecimal consisting of the set [0123456789ABCDEF].
*
* Archived log files are automatically deleted according to the maximumNumberOfLogFiles property.
**/
@interface DDLogFileManagerDefault : NSObject <DDLogFileManager>
{
NSUInteger maximumNumberOfLogFiles;
Expand All @@ -119,15 +120,16 @@
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Most users will want file log messages to be prepended with the date and time.
// Rather than forcing the majority of users to write their own formatter,
// we will supply a logical default formatter.
// Users can easily replace this formatter with their own by invoking the setLogFormatter method.
// It can also be removed by calling setLogFormatter, and passing a nil parameter.
//
// In addition to the convenience of having a logical default formatter,
// it will also provide a template that makes it easy for developers to copy and change.

/**
* Most users will want file log messages to be prepended with the date and time.
* Rather than forcing the majority of users to write their own formatter,
* we will supply a logical default formatter.
* Users can easily replace this formatter with their own by invoking the setLogFormatter method.
* It can also be removed by calling setLogFormatter, and passing a nil parameter.
*
* In addition to the convenience of having a logical default formatter,
* it will also provide a template that makes it easy for developers to copy and change.
**/
@interface DDLogFileFormatterDefault : NSObject <DDLogFormatter>
{
NSDateFormatter *dateFormatter;
Expand Down Expand Up @@ -155,35 +157,46 @@
- (id)init;
- (id)initWithLogFileManager:(id <DDLogFileManager>)logFileManager;

// Configuration
//
// maximumFileSize:
// The approximate maximum size to allow log files to grow.
// If a log file is larger than this value after a write,
// 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.
//
// 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.
//
// logFileManager
// Allows you to retrieve the list of log files,
// and configure the maximum number of archived log files to keep.

/**
* Log File Rolling:
*
* maximumFileSize:
* The approximate maximum size 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.
*
* 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;

@property (readwrite, assign) NSTimeInterval rollingFrequency;

/**
* 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 <DDLogFileManager> logFileManager;


Expand All @@ -202,19 +215,20 @@
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// DDLogFileInfo is a simple class that provides access to various file attributes.
// It provides good performance as it only fetches the information if requested,
// and it caches the information to prevent duplicate fetches.
//
// It was designed to provide quick snapshots of the current state of log files,
// and to help sort log files in an array.
//
// This class does not monitor the files, or update it's cached attribute values if the file changes on disk.
// This is not what the class was designed for.
//
// If you absolutely must get updated values,
// you can invoke the reset method which will clear the cache.

/**
* DDLogFileInfo is a simple class that provides access to various file attributes.
* It provides good performance as it only fetches the information if requested,
* and it caches the information to prevent duplicate fetches.
*
* It was designed to provide quick snapshots of the current state of log files,
* and to help sort log files in an array.
*
* This class does not monitor the files, or update it's cached attribute values if the file changes on disk.
* This is not what the class was designed for.
*
* If you absolutely must get updated values,
* you can invoke the reset method which will clear the cache.
**/
@interface DDLogFileInfo : NSObject
{
__strong NSString *filePath;
Expand Down
21 changes: 12 additions & 9 deletions Lumberjack/DDFileLogger.m
Expand Up @@ -606,7 +606,7 @@ - (void)scheduleTimerToRollLogFileDueToAge
rollingTimer = NULL;
}

if (currentLogFileInfo == nil)
if (currentLogFileInfo == nil || rollingFrequency <= 0.0)
{
return;
}
Expand Down Expand Up @@ -697,7 +697,7 @@ - (void)rollLogFileNow

- (void)maybeRollLogFileDueToAge
{
if (currentLogFileInfo.age >= rollingFrequency)
if (rollingFrequency > 0.0 && currentLogFileInfo.age >= rollingFrequency)
{
NSLogVerbose(@"DDFileLogger: Rolling log file due to age...");

Expand All @@ -714,16 +714,19 @@ - (void)maybeRollLogFileDueToSize
// This method is called from logMessage.
// Keep it FAST.

unsigned long long fileSize = [currentLogFileHandle offsetInFile];

// Note: Use direct access to maximumFileSize variable.
// We specifically wrote our own getter/setter method to allow us to do this (for performance reasons).

if (fileSize >= maximumFileSize) // YES, we are using direct access. Read note above.
if (maximumFileSize > 0)
{
NSLogVerbose(@"DDFileLogger: Rolling log file due to size...");
unsigned long long fileSize = [currentLogFileHandle offsetInFile];

[self rollLogFileNow];
if (fileSize >= maximumFileSize)
{
NSLogVerbose(@"DDFileLogger: Rolling log file due to size (%qu)...", fileSize);

[self rollLogFileNow];
}
}
}

Expand Down Expand Up @@ -756,12 +759,12 @@ - (DDLogFileInfo *)currentLogFileInfo
useExistingLogFile = NO;
shouldArchiveMostRecent = NO;
}
else if (mostRecentLogFileInfo.fileSize >= maximumFileSize)
else if (maximumFileSize > 0 && mostRecentLogFileInfo.fileSize >= maximumFileSize)
{
useExistingLogFile = NO;
shouldArchiveMostRecent = YES;
}
else if (mostRecentLogFileInfo.age >= rollingFrequency)
else if (rollingFrequency > 0.0 && mostRecentLogFileInfo.age >= rollingFrequency)
{
useExistingLogFile = NO;
shouldArchiveMostRecent = YES;
Expand Down
25 changes: 13 additions & 12 deletions Lumberjack/DDLog.h
Expand Up @@ -435,14 +435,15 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
NSString *methodName;
}

// The initializer is somewhat reserved for internal use.
// However, if you find need to manually create logMessage objects,
// there is one thing you should be aware of.
// The initializer expects the file and function parameters to be string literals.
// That is, it expects the given strings to exist for the duration of the object's lifetime,
// and it expects the given strings to be immutable.
// In other words, it does not copy these strings, it simply points to them.

/**
* The initializer is somewhat reserved for internal use.
* However, if you find need to manually create logMessage objects, there is one thing you should be aware of:
*
* The initializer expects the file and function parameters to be string literals.
* That is, it expects the given strings to exist for the duration of the object's lifetime,
* and it expects the given strings to be immutable.
* In other words, it does not copy these strings, it simply points to them.
**/
- (id)initWithLogMsg:(NSString *)logMsg
level:(int)logLevel
flag:(int)logFlag
Expand All @@ -456,18 +457,18 @@ NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
* Returns the threadID as it appears in NSLog.
* That is, it is a hexadecimal value which is calculated from the machThreadID.
**/
- (NSString *)threadID;
@property (nonatomic, readonly) NSString *threadID;

/**
* Convenience method to get just the file name, as the file variable is generally the full file path.
* Convenience property to get just the file name, as the file variable is generally the full file path.
* This method does not include the file extension, which is generally unwanted for logging purposes.
**/
- (NSString *)fileName;
@property (nonatomic, readonly) NSString *fileName;

/**
* Returns the function variable in NSString form.
**/
- (NSString *)methodName;
@property (nonatomic, readonly) NSString *methodName;

@end

Expand Down

0 comments on commit bd66c48

Please sign in to comment.