Skip to content

Commit

Permalink
Adding threadName to DDLogMessage. Improving DispatchQueueLogFormatte…
Browse files Browse the repository at this point in the history
…r (now supports NSThreadName).
  • Loading branch information
robbiehanson committed Nov 17, 2011
1 parent 222fc43 commit 528df37
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 131 deletions.
1 change: 1 addition & 0 deletions Lumberjack/DDLog.h
Expand Up @@ -421,6 +421,7 @@ NSString *ExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
int lineNumber;
mach_port_t machThreadID;
char *queueLabel;
NSString *threadName;

// The private variables below are only calculated if needed.
// You should use the public methods to access this information.
Expand Down
4 changes: 3 additions & 1 deletion Lumberjack/DDLog.m
Expand Up @@ -786,6 +786,8 @@ - (id)initWithLogMsg:(NSString *)msg
strncpy(queueLabel, label, labelLength);
queueLabel[labelLength] = 0;
}

threadName = [[NSThread currentThread] name];
}
return self;
}
Expand All @@ -802,7 +804,7 @@ - (NSString *)threadID

- (NSString *)fileName
{
if (fileName == nil)
if (fileName == nil && file != NULL)
{
fileName = ExtractFileNameWithoutExtension(file, NO);
}
Expand Down
62 changes: 30 additions & 32 deletions Lumberjack/Extensions/DispatchQueueLogFormatter.h
Expand Up @@ -35,62 +35,60 @@
* 2011-10-17 20:32:31.112 AppName[19954:5207] Message from my_serial_dispatch_queue
* 2011-10-17 20:32:31.113 AppName[19954:2c55] Message from my_serial_dispatch_queue
*
* This formatter allows you to replace the standard detail info with the dispatch_queue name.
* This formatter allows you to replace the standard [box:info] with the dispatch_queue name.
* For example:
*
* 2011-10-17 20:32:31.111 AppName[img-scaling] Message from my_serial_dispatch_queue
* 2011-10-17 20:32:31.112 AppName[img-scaling] Message from my_serial_dispatch_queue
* 2011-10-17 20:32:31.113 AppName[img-scaling] Message from my_serial_dispatch_queue
*
* If the dispatch_queue doesn't have a set name, then it falls back to the thread name.
* If the current thread doesn't have a set name, then it falls back to the mach_thread_id in hex (like normal).
*
* Note: If manually creating your own background threads (via NSThread/alloc/init or NSThread/detachNeThread),
* you can use [[NSThread currentThread] setName:(NSString *)].
**/
@interface DispatchQueueLogFormatter : NSObject <DDLogFormatter>

/**
* Standard init method.
*
* @see queueLength
* @see rightAlign
* Configure using properties as desired.
**/
- (id)init;

/**
* The queueLength is simply the number of characters that will be inside the [detail box].
* For example:
* The minQueueLength restricts the minimum size of the [detail box].
* If the minQueueLength is set to 0, there is no restriction.
*
* Say a dispatch_queue has a label of "diskIO".
* If the queueLength is 4: [disk]
* If the queueLength is 5: [diskI]
* If the queueLength is 6: [diskIO]
* If the queueLength is 7: [diskIO ]
* If the queueLength is 8: [diskIO ]
* For example, say a dispatch_queue has a label of "diskIO":
*
* The default queueLength is 6.
* If the minQueueLength is 0: [diskIO]
* If the minQueueLength is 4: [diskIO]
* If the minQueueLength is 5: [diskIO]
* If the minQueueLength is 6: [diskIO]
* If the minQueueLength is 7: [diskIO ]
* If the minQueueLength is 8: [diskIO ]
*
* The output will also be influenced by the rightAlign property.
* The default minQueueLength is 0 (no minimum, so [detail box] won't be padded).
**/
@property (assign) int queueLength;
@property (assign) NSUInteger minQueueLength;

/**
* The rightAlign property allows you to specify whether the detail info should be
* left or right aligned within the [detail box].
*
* The maxQueueLength restricts the number of characters that will be inside the [detail box].
* If the maxQueueLength is 0, there is no restriction.
* For example:
* Say a dispatch_queue has a label of "diskIO".
*
* If leftAlign and queueLength is 4: [disk]
* If leftAlign and queueLength is 5: [diskI]
* If leftAlign and queueLength is 6: [diskIO]
* If leftAlign and queueLength is 7: [diskIO ]
* If leftAlign and queueLength is 8: [diskIO ]
*
* If rightAlign and queueLength is 4: [skIO]
* If rightAlign and queueLength is 5: [iskIO]
* If rightAlign and queueLength is 6: [diskIO]
* If rightAlign and queueLength is 7: [ diskIO]
* If rightAlign and queueLength is 8: [ diskIO]
* Say a dispatch_queue has a label of "diskIO". (standardizedQueueLength==NO)
* If the maxQueueLength is 0: [diskIO]
* If the maxQueueLength is 4: [disk]
* If the maxQueueLength is 5: [diskI]
* If the maxQueueLength is 6: [diskIO]
* If the maxQueueLength is 7: [diskIO]
* If the maxQueueLength is 8: [diskIO]
*
* The default is leftAlignment.
* The default maxQueueLength is 0 (no maximum, so [thread box] queue names won't be truncated).
**/
@property (assign) BOOL rightAlign;
@property (assign) NSUInteger maxQueueLength;

/**
* Sometimes queue labels have long names like "com.apple.main-queue",
Expand Down
169 changes: 73 additions & 96 deletions Lumberjack/Extensions/DispatchQueueLogFormatter.m
Expand Up @@ -15,18 +15,14 @@
#warning This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag.
#endif

#define DEFAULT_QUEUE_LENGTH 6
#define MIN_QUEUE_LENGTH 4
#define MAX_QUEUE_LENGTH 35


@implementation DispatchQueueLogFormatter
{
OSSpinLock lock;
NSDateFormatter *dateFormatter;

int _queueLength; // _prefix == Only access from within spinlock
BOOL _rightAlign; // _prefix == Only access from within spinlock
NSUInteger _minQueueLength; // _prefix == Only access via atomic property
NSUInteger _maxQueueLength; // _prefix == Only access via atomic property
NSMutableDictionary *_replacements; // _prefix == Only access from within spinlock
}

Expand All @@ -38,8 +34,8 @@ - (id)init
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss:SSS"];

_queueLength = DEFAULT_QUEUE_LENGTH;
_rightAlign = NO;
_minQueueLength = 0;
_maxQueueLength = 0;
_replacements = [[NSMutableDictionary alloc] init];

// Set default replacements:
Expand All @@ -54,57 +50,8 @@ - (id)init
#pragma mark Configuration
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

- (int)queueLength
{
int result = 0;

OSSpinLockLock(&lock);
{
result = _queueLength;
}
OSSpinLockUnlock(&lock);

return result;
}

- (void)setQueueLength:(int)newQueueLength
{
OSSpinLockLock(&lock);
{
if (newQueueLength > MAX_QUEUE_LENGTH) {
_queueLength = MAX_QUEUE_LENGTH;
}
else if (newQueueLength < MIN_QUEUE_LENGTH) {
_queueLength = MIN_QUEUE_LENGTH;
}
else {
_queueLength = newQueueLength;
}
}
OSSpinLockUnlock(&lock);
}

- (BOOL)rightAlign
{
BOOL result = NO;

OSSpinLockLock(&lock);
{
result = _rightAlign;
}
OSSpinLockUnlock(&lock);

return result;
}

- (void)setRightAlign:(BOOL)newRightAlign
{
OSSpinLockLock(&lock);
{
_rightAlign = newRightAlign;
}
OSSpinLockUnlock(&lock);
}
@synthesize minQueueLength = _minQueueLength;
@synthesize maxQueueLength = _maxQueueLength;

- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel
{
Expand Down Expand Up @@ -139,73 +86,103 @@ - (NSString *)formatLogMessage:(DDLogMessage *)logMessage
{
// As per the DDLogFormatter contract, this method is always invoked on the same thread/dispatch_queue

int queueLength = 0;
BOOL rightAlign = NO;

NSString *timestamp = [dateFormatter stringFromDate:(logMessage->timestamp)];
NSString *label;

NSUInteger minQueueLength = self.minQueueLength;
NSUInteger maxQueueLength = self.maxQueueLength;

// Get the name of the queue, thread, or machID (whichever we are to use).

NSString *threadLabel = nil;

BOOL useQueueLabel = YES;
BOOL useThreadName = NO;

if (logMessage->queueLabel)
{
NSString *longLabel = [NSString stringWithUTF8String:logMessage->queueLabel];
// If you manually create a thread, it's dispatch_queue will have one of the thread names below.
// Since all such threads have the same name, we'd prefer to use the threadName or the machThreadID.

NSString *shortLabel = nil;
char *names[] = { "com.apple.root.low-overcommit-priority",
"com.apple.root.default-overcommit-priority",
"com.apple.root.high-overcommit-priority" };

OSSpinLockLock(&lock);
int i;
for (i = 0; i < sizeof(names); i++)
{
queueLength = _queueLength;
rightAlign = _rightAlign;

shortLabel = [_replacements objectForKey:longLabel];
if (strcmp(logMessage->queueLabel, names[1]) == 0)
{
useQueueLabel = NO;
useThreadName = [logMessage->threadName length] > 0;
break;
}
}
OSSpinLockUnlock(&lock);

if (shortLabel)
label = shortLabel;
else
label = longLabel;
}
else
{
label = [NSString stringWithFormat:@"%x", logMessage->machThreadID];
useQueueLabel = NO;
useThreadName = [logMessage->threadName length] > 0;
}

if (useQueueLabel || useThreadName)
{
NSString *fullLabel;
NSString *abrvLabel;

if (useQueueLabel)
fullLabel = [NSString stringWithUTF8String:logMessage->queueLabel];
else
fullLabel = logMessage->threadName;

OSSpinLockLock(&lock);
{
queueLength = _queueLength;
rightAlign = _rightAlign;
abrvLabel = [_replacements objectForKey:fullLabel];
}
OSSpinLockUnlock(&lock);

if (abrvLabel)
threadLabel = abrvLabel;
else
threadLabel = fullLabel;
}
else
{
threadLabel = [NSString stringWithFormat:@"%x", logMessage->machThreadID];
}

// Now use the thread label in the output

int labelLength = (int)[label length];
NSUInteger labelLength = [threadLabel length];

if (labelLength == queueLength)
{
return [NSString stringWithFormat:@"%@ [%@] %@", timestamp, label, logMessage->logMsg];
}
else if (labelLength > queueLength)
// labelLength > maxQueueLength : truncate
// labelLength < minQueueLength : padding
// : exact

if ((maxQueueLength > 0) && (labelLength > maxQueueLength))
{
NSString *subLabel;
if (rightAlign)
subLabel = [label substringFromIndex:(labelLength - queueLength)];
else
subLabel = [label substringToIndex:queueLength];
// Truncate

NSString *subLabel = [threadLabel substringToIndex:maxQueueLength];

return [NSString stringWithFormat:@"%@ [%@] %@", timestamp, subLabel, logMessage->logMsg];
}
else
else if (labelLength < minQueueLength)
{
int numSpaces = queueLength - labelLength;
// Padding

NSUInteger numSpaces = maxQueueLength - labelLength;

char spaces[numSpaces + 1];
memset(spaces, ' ', numSpaces);
spaces[numSpaces] = '\0';

if (rightAlign)
return [NSString stringWithFormat:@"%@ [%s%@] %@", timestamp, spaces, label, logMessage->logMsg];
else
return [NSString stringWithFormat:@"%@ [%@%s] %@", timestamp, label, spaces, logMessage->logMsg];
return [NSString stringWithFormat:@"%@ [%@%s] %@", timestamp, threadLabel, spaces, logMessage->logMsg];
}
else
{
// Exact

return [NSString stringWithFormat:@"%@ [%@] %@", timestamp, threadLabel, logMessage->logMsg];
}
}

Expand Down
20 changes: 18 additions & 2 deletions Xcode/DispatchQueueLogger/DispatchQueueLogger/AppDelegate.m
Expand Up @@ -23,8 +23,8 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
// Log statements *AFTER* DispatchQueueLogFormatter

DispatchQueueLogFormatter *formatter = [[DispatchQueueLogFormatter alloc] init];
formatter.queueLength = 17;
formatter.rightAlign = NO;
formatter.minQueueLength = 4;
formatter.maxQueueLength = 0;

[formatter setReplacementString:@"main" forQueueLabel:@"com.apple.main-thread"];
[formatter setReplacementString:@"global-background" forQueueLabel:@"com.apple.root.background-priority"];
Expand Down Expand Up @@ -86,6 +86,22 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
dispatch_async(dgq, blockD);
dispatch_async(hgq, blockD);
}

[NSThread detachNewThreadSelector:@selector(backgroundThread:) toTarget:self withObject:nil];
}

- (void)backgroundThread:(id)ignore
{
@autoreleasepool {

[[NSThread currentThread] setName:@"MyBgThread"];

int i;
for (i = 0; i < 5; i++)
{
DDLogVerbose(@"Some log statement");
}
}
}

@end

0 comments on commit 528df37

Please sign in to comment.