From 4b65991be281d11a1dfa9eb283f19964f00e71e4 Mon Sep 17 00:00:00 2001 From: Joshua Moody Date: Fri, 13 Jan 2017 08:29:13 +0100 Subject: [PATCH 1/3] Vendor: remove Lumberjack extensions; not used --- .../Extensions/ContextFilterLogFormatter.h | 65 ----- .../Extensions/ContextFilterLogFormatter.m | 191 ------------- .../Extensions/DispatchQueueLogFormatter.h | 116 -------- .../Extensions/DispatchQueueLogFormatter.m | 251 ------------------ Vendor/CocoaLumberjack/Extensions/README.txt | 7 - 5 files changed, 630 deletions(-) delete mode 100644 Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.h delete mode 100644 Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.m delete mode 100644 Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.h delete mode 100644 Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.m delete mode 100644 Vendor/CocoaLumberjack/Extensions/README.txt diff --git a/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.h b/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.h deleted file mode 100644 index dffc8657..00000000 --- a/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.h +++ /dev/null @@ -1,65 +0,0 @@ -#import -#import "DDLog.h" - -@class ContextFilterLogFormatter; - -/** - * Welcome to Cocoa Lumberjack! - * - * The project page has a wealth of documentation if you have any questions. - * https://github.com/robbiehanson/CocoaLumberjack - * - * If you're new to the project you may wish to read the "Getting Started" page. - * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted - * - * - * This class provides a log formatter that filters log statements from a logging context not on the whitelist. - * - * A log formatter can be added to any logger to format and/or filter its output. - * You can learn more about log formatters here: - * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters - * - * You can learn more about logging context's here: - * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomContext - * - * But here's a quick overview / refresher: - * - * Every log statement has a logging context. - * These come from the underlying logging macros defined in DDLog.h. - * The default logging context is zero. - * You can define multiple logging context's for use in your application. - * For example, logically separate parts of your app each have a different logging context. - * Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context. -**/ -@interface ContextWhitelistFilterLogFormatter : NSObject - -- (id)init; - -- (void)addToWhitelist:(int)loggingContext; -- (void)removeFromWhitelist:(int)loggingContext; - -- (NSArray *)whitelist; - -- (BOOL)isOnWhitelist:(int)loggingContext; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * This class provides a log formatter that filters log statements from a logging context on the blacklist. -**/ -@interface ContextBlacklistFilterLogFormatter : NSObject - -- (id)init; - -- (void)addToBlacklist:(int)loggingContext; -- (void)removeFromBlacklist:(int)loggingContext; - -- (NSArray *)blacklist; - -- (BOOL)isOnBlacklist:(int)loggingContext; - -@end diff --git a/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.m b/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.m deleted file mode 100644 index 9c024acc..00000000 --- a/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.m +++ /dev/null @@ -1,191 +0,0 @@ -#import "ContextFilterLogFormatter.h" -#import - -/** - * Welcome to Cocoa Lumberjack! - * - * The project page has a wealth of documentation if you have any questions. - * https://github.com/robbiehanson/CocoaLumberjack - * - * If you're new to the project you may wish to read the "Getting Started" wiki. - * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted -**/ - -#if ! __has_feature(objc_arc) -#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). -#endif - -@interface LoggingContextSet : NSObject - -- (void)addToSet:(int)loggingContext; -- (void)removeFromSet:(int)loggingContext; - -- (NSArray *)currentSet; - -- (BOOL)isInSet:(int)loggingContext; - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -@implementation ContextWhitelistFilterLogFormatter -{ - LoggingContextSet *contextSet; -} - -- (id)init -{ - if ((self = [super init])) - { - contextSet = [[LoggingContextSet alloc] init]; - } - return self; -} - - -- (void)addToWhitelist:(int)loggingContext -{ - [contextSet addToSet:loggingContext]; -} - -- (void)removeFromWhitelist:(int)loggingContext -{ - [contextSet removeFromSet:loggingContext]; -} - -- (NSArray *)whitelist -{ - return [contextSet currentSet]; -} - -- (BOOL)isOnWhitelist:(int)loggingContext -{ - return [contextSet isInSet:loggingContext]; -} - -- (NSString *)formatLogMessage:(DDLogMessage *)logMessage -{ - if ([self isOnWhitelist:logMessage->logContext]) - return logMessage->logMsg; - else - return nil; -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -@implementation ContextBlacklistFilterLogFormatter -{ - LoggingContextSet *contextSet; -} - -- (id)init -{ - if ((self = [super init])) - { - contextSet = [[LoggingContextSet alloc] init]; - } - return self; -} - - -- (void)addToBlacklist:(int)loggingContext -{ - [contextSet addToSet:loggingContext]; -} - -- (void)removeFromBlacklist:(int)loggingContext -{ - [contextSet removeFromSet:loggingContext]; -} - -- (NSArray *)blacklist -{ - return [contextSet currentSet]; -} - -- (BOOL)isOnBlacklist:(int)loggingContext -{ - return [contextSet isInSet:loggingContext]; -} - -- (NSString *)formatLogMessage:(DDLogMessage *)logMessage -{ - if ([self isOnBlacklist:logMessage->logContext]) - return nil; - else - return logMessage->logMsg; -} - -@end - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -@implementation LoggingContextSet -{ - OSSpinLock lock; - NSMutableSet *set; -} - -- (id)init -{ - if ((self = [super init])) - { - set = [[NSMutableSet alloc] init]; - } - return self; -} - - -- (void)addToSet:(int)loggingContext -{ - OSSpinLockLock(&lock); - { - [set addObject:@(loggingContext)]; - } - OSSpinLockUnlock(&lock); -} - -- (void)removeFromSet:(int)loggingContext -{ - OSSpinLockLock(&lock); - { - [set removeObject:@(loggingContext)]; - } - OSSpinLockUnlock(&lock); -} - -- (NSArray *)currentSet -{ - NSArray *result = nil; - - OSSpinLockLock(&lock); - { - result = [set allObjects]; - } - OSSpinLockUnlock(&lock); - - return result; -} - -- (BOOL)isInSet:(int)loggingContext -{ - BOOL result = NO; - - OSSpinLockLock(&lock); - { - result = [set containsObject:@(loggingContext)]; - } - OSSpinLockUnlock(&lock); - - return result; -} - -@end diff --git a/Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.h b/Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.h deleted file mode 100644 index 9ad8d3f4..00000000 --- a/Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.h +++ /dev/null @@ -1,116 +0,0 @@ -#import -#import -#import "DDLog.h" - - -/** - * Welcome to Cocoa Lumberjack! - * - * The project page has a wealth of documentation if you have any questions. - * https://github.com/robbiehanson/CocoaLumberjack - * - * If you're new to the project you may wish to read the "Getting Started" page. - * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted - * - * - * This class provides a log formatter that prints the dispatch_queue label instead of the mach_thread_id. - * - * A log formatter can be added to any logger to format and/or filter its output. - * You can learn more about log formatters here: - * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters - * - * A typical NSLog (or DDTTYLogger) prints detailed info as [:]. - * For example: - * - * 2011-10-17 20:21:45.435 AppName[19928:5207] Your log message here - * - * Where: - * - 19928 = process id - * - 5207 = thread id (mach_thread_id printed in hex) - * - * When using grand central dispatch (GCD), this information is less useful. - * This is because a single serial dispatch queue may be run on any thread from an internally managed thread pool. - * For example: - * - * 2011-10-17 20:32:31.111 AppName[19954:4d07] Message from my_serial_dispatch_queue - * 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 [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 { -@protected - - NSString *dateFormatString; -} - -/** - * Standard init method. - * Configure using properties as desired. -**/ -- (id)init; - -/** - * The minQueueLength restricts the minimum size of the [detail box]. - * If the minQueueLength is set to 0, there is no restriction. - * - * For example, say a dispatch_queue has a label of "diskIO": - * - * 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 default minQueueLength is 0 (no minimum, so [detail box] won't be padded). - * - * If you want every [detail box] to have the exact same width, - * set both minQueueLength and maxQueueLength to the same value. -**/ -@property (assign) NSUInteger minQueueLength; - -/** - * 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 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 maxQueueLength is 0 (no maximum, so [detail box] won't be truncated). - * - * If you want every [detail box] to have the exact same width, - * set both minQueueLength and maxQueueLength to the same value. -**/ -@property (assign) NSUInteger maxQueueLength; - -/** - * Sometimes queue labels have long names like "com.apple.main-queue", - * but you'd prefer something shorter like simply "main". - * - * This method allows you to set such preferred replacements. - * The above example is set by default. - * - * To remove/undo a previous replacement, invoke this method with nil for the 'shortLabel' parameter. -**/ -- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel; -- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel; - -@end diff --git a/Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.m b/Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.m deleted file mode 100644 index d348f3dc..00000000 --- a/Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.m +++ /dev/null @@ -1,251 +0,0 @@ -#import "DispatchQueueLogFormatter.h" -#import - -/** - * Welcome to Cocoa Lumberjack! - * - * The project page has a wealth of documentation if you have any questions. - * https://github.com/robbiehanson/CocoaLumberjack - * - * If you're new to the project you may wish to read the "Getting Started" wiki. - * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted -**/ - -#if ! __has_feature(objc_arc) -#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). -#endif - - -@implementation DispatchQueueLogFormatter -{ - int32_t atomicLoggerCount; - NSDateFormatter *threadUnsafeDateFormatter; // Use [self stringFromDate] - - OSSpinLock lock; - - NSUInteger _minQueueLength; // _prefix == Only access via atomic property - NSUInteger _maxQueueLength; // _prefix == Only access via atomic property - NSMutableDictionary *_replacements; // _prefix == Only access from within spinlock -} - -- (id)init -{ - if ((self = [super init])) - { - dateFormatString = @"yyyy-MM-dd HH:mm:ss:SSS"; - - atomicLoggerCount = 0; - threadUnsafeDateFormatter = nil; - - _minQueueLength = 0; - _maxQueueLength = 0; - _replacements = [[NSMutableDictionary alloc] init]; - - // Set default replacements: - - [_replacements setObject:@"main" forKey:@"com.apple.main-thread"]; - } - return self; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark Configuration -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -@synthesize minQueueLength = _minQueueLength; -@synthesize maxQueueLength = _maxQueueLength; - -- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel -{ - NSString *result = nil; - - OSSpinLockLock(&lock); - { - result = [_replacements objectForKey:longLabel]; - } - OSSpinLockUnlock(&lock); - - return result; -} - -- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel -{ - OSSpinLockLock(&lock); - { - if (shortLabel) - [_replacements setObject:shortLabel forKey:longLabel]; - else - [_replacements removeObjectForKey:longLabel]; - } - OSSpinLockUnlock(&lock); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark DDLogFormatter -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -- (NSString *)stringFromDate:(NSDate *)date -{ - int32_t loggerCount = OSAtomicAdd32(0, &atomicLoggerCount); - - if (loggerCount <= 1) - { - // Single-threaded mode. - - if (threadUnsafeDateFormatter == nil) - { - threadUnsafeDateFormatter = [[NSDateFormatter alloc] init]; - [threadUnsafeDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; - [threadUnsafeDateFormatter setDateFormat:dateFormatString]; - } - - return [threadUnsafeDateFormatter stringFromDate:date]; - } - else - { - // Multi-threaded mode. - // NSDateFormatter is NOT thread-safe. - - NSString *key = @"DispatchQueueLogFormatter_NSDateFormatter"; - - NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary]; - NSDateFormatter *dateFormatter = [threadDictionary objectForKey:key]; - - if (dateFormatter == nil) - { - dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; - [dateFormatter setDateFormat:dateFormatString]; - - [threadDictionary setObject:dateFormatter forKey:key]; - } - - return [dateFormatter stringFromDate:date]; - } -} - -- (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage -{ - // As per the DDLogFormatter contract, this method is always invoked on the same thread/dispatch_queue - - NSUInteger minQueueLength = self.minQueueLength; - NSUInteger maxQueueLength = self.maxQueueLength; - - // Get the name of the queue, thread, or machID (whichever we are to use). - - NSString *queueThreadLabel = nil; - - BOOL useQueueLabel = YES; - BOOL useThreadName = NO; - - if (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. - - char *names[] = { "com.apple.root.low-priority", - "com.apple.root.default-priority", - "com.apple.root.high-priority", - "com.apple.root.low-overcommit-priority", - "com.apple.root.default-overcommit-priority", - "com.apple.root.high-overcommit-priority" }; - - int length = sizeof(names) / sizeof(char *); - - int i; - for (i = 0; i < length; i++) - { - if (strcmp(logMessage->queueLabel, names[i]) == 0) - { - useQueueLabel = NO; - useThreadName = [logMessage->threadName length] > 0; - break; - } - } - } - else - { - useQueueLabel = NO; - useThreadName = [logMessage->threadName length] > 0; - } - - if (useQueueLabel || useThreadName) - { - NSString *fullLabel; - NSString *abrvLabel; - - if (useQueueLabel) - fullLabel = @(logMessage->queueLabel); - else - fullLabel = logMessage->threadName; - - OSSpinLockLock(&lock); - { - abrvLabel = [_replacements objectForKey:fullLabel]; - } - OSSpinLockUnlock(&lock); - - if (abrvLabel) - queueThreadLabel = abrvLabel; - else - queueThreadLabel = fullLabel; - } - else - { - queueThreadLabel = [NSString stringWithFormat:@"%x", logMessage->machThreadID]; - } - - // Now use the thread label in the output - - NSUInteger labelLength = [queueThreadLabel length]; - - // labelLength > maxQueueLength : truncate - // labelLength < minQueueLength : padding - // : exact - - if ((maxQueueLength > 0) && (labelLength > maxQueueLength)) - { - // Truncate - - return [queueThreadLabel substringToIndex:maxQueueLength]; - } - else if (labelLength < minQueueLength) - { - // Padding - - NSUInteger numSpaces = minQueueLength - labelLength; - - char spaces[numSpaces + 1]; - memset(spaces, ' ', numSpaces); - spaces[numSpaces] = '\0'; - - return [NSString stringWithFormat:@"%@%s", queueThreadLabel, spaces]; - } - else - { - // Exact - - return queueThreadLabel; - } -} - -- (NSString *)formatLogMessage:(DDLogMessage *)logMessage -{ - NSString *timestamp = [self stringFromDate:(logMessage->timestamp)]; - NSString *queueThreadLabel = [self queueThreadLabelForLogMessage:logMessage]; - - return [NSString stringWithFormat:@"%@ [%@] %@", timestamp, queueThreadLabel, logMessage->logMsg]; -} - -- (void)didAddToLogger:(id )logger -{ - OSAtomicIncrement32(&atomicLoggerCount); -} - -- (void)willRemoveFromLogger:(id )logger -{ - OSAtomicDecrement32(&atomicLoggerCount); -} - -@end diff --git a/Vendor/CocoaLumberjack/Extensions/README.txt b/Vendor/CocoaLumberjack/Extensions/README.txt deleted file mode 100644 index eb20e501..00000000 --- a/Vendor/CocoaLumberjack/Extensions/README.txt +++ /dev/null @@ -1,7 +0,0 @@ -This folder contains some sample formatters that may be helpful. - -Feel free to change them, extend them, or use them as the basis for your own custom formatter(s). - -More information about creating your own custom formatters can be found on the wiki: -https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters - From e9929be2dc81cfe3cd5a5e114f13e1b7e49ad73e Mon Sep 17 00:00:00 2001 From: Joshua Moody Date: Fri, 13 Jan 2017 08:32:13 +0100 Subject: [PATCH 2/3] Vendor: update CocoaLumberjack sources: 3.0 * Jan 12 2017 * 1d361a83599948b0110c12946a8cf75a37f295f2 --- DeviceAgent.xcodeproj/project.pbxproj | 158 +- Vendor/CocoaLumberjack/CocoaLumberjack.h | 85 + Vendor/CocoaLumberjack/DDASLLogCapture.h | 41 + Vendor/CocoaLumberjack/DDASLLogCapture.m | 230 ++ Vendor/CocoaLumberjack/DDASLLogger.h | 57 +- Vendor/CocoaLumberjack/DDASLLogger.m | 182 +- .../DDAbstractDatabaseLogger.h | 107 +- .../DDAbstractDatabaseLogger.m | 1179 ++++---- Vendor/CocoaLumberjack/DDAssertMacros.h | 26 + Vendor/CocoaLumberjack/DDFileLogger.h | 480 ++- Vendor/CocoaLumberjack/DDFileLogger.m | 2339 +++++++------- Vendor/CocoaLumberjack/DDLegacyMacros.h | 75 + Vendor/CocoaLumberjack/DDLog+LOGV.h | 83 + Vendor/CocoaLumberjack/DDLog.h | 969 +++--- Vendor/CocoaLumberjack/DDLog.m | 2015 ++++++------ Vendor/CocoaLumberjack/DDLogMacros.h | 101 + Vendor/CocoaLumberjack/DDTTYLogger.h | 211 +- Vendor/CocoaLumberjack/DDTTYLogger.m | 2694 +++++++++-------- 18 files changed, 6271 insertions(+), 4761 deletions(-) create mode 100644 Vendor/CocoaLumberjack/CocoaLumberjack.h create mode 100644 Vendor/CocoaLumberjack/DDASLLogCapture.h create mode 100644 Vendor/CocoaLumberjack/DDASLLogCapture.m mode change 100755 => 100644 Vendor/CocoaLumberjack/DDASLLogger.h mode change 100755 => 100644 Vendor/CocoaLumberjack/DDASLLogger.m create mode 100644 Vendor/CocoaLumberjack/DDAssertMacros.h create mode 100644 Vendor/CocoaLumberjack/DDLegacyMacros.h create mode 100644 Vendor/CocoaLumberjack/DDLog+LOGV.h mode change 100755 => 100644 Vendor/CocoaLumberjack/DDLog.h mode change 100755 => 100644 Vendor/CocoaLumberjack/DDLog.m create mode 100644 Vendor/CocoaLumberjack/DDLogMacros.h mode change 100755 => 100644 Vendor/CocoaLumberjack/DDTTYLogger.h mode change 100755 => 100644 Vendor/CocoaLumberjack/DDTTYLogger.m diff --git a/DeviceAgent.xcodeproj/project.pbxproj b/DeviceAgent.xcodeproj/project.pbxproj index 1c8ddaa9..b52ff293 100644 --- a/DeviceAgent.xcodeproj/project.pbxproj +++ b/DeviceAgent.xcodeproj/project.pbxproj @@ -194,6 +194,29 @@ F549E1A71D5472BA00C4FA36 /* CBXInfoPlist.m in Sources */ = {isa = PBXBuildFile; fileRef = F549E1A31D54723300C4FA36 /* CBXInfoPlist.m */; }; F54B07651DEDB26200C88A8E /* EnvironmentTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = F54B07641DEDB26200C88A8E /* EnvironmentTableController.m */; }; F5536CEE1D737611006B4EA4 /* AlertFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = F5536CED1D737611006B4EA4 /* AlertFactory.m */; }; + F5538B711E28AC7B003EC5F3 /* CocoaLumberjack.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B601E28AC7B003EC5F3 /* CocoaLumberjack.h */; }; + F5538B721E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B611E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.h */; }; + F5538B731E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B621E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.m */; }; + F5538B741E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B621E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.m */; }; + F5538B751E28AC7B003EC5F3 /* DDASLLogCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B631E28AC7B003EC5F3 /* DDASLLogCapture.h */; }; + F5538B761E28AC7B003EC5F3 /* DDASLLogCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B641E28AC7B003EC5F3 /* DDASLLogCapture.m */; }; + F5538B771E28AC7B003EC5F3 /* DDASLLogCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B641E28AC7B003EC5F3 /* DDASLLogCapture.m */; }; + F5538B781E28AC7B003EC5F3 /* DDASLLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B651E28AC7B003EC5F3 /* DDASLLogger.h */; }; + F5538B791E28AC7B003EC5F3 /* DDASLLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B661E28AC7B003EC5F3 /* DDASLLogger.m */; }; + F5538B7A1E28AC7B003EC5F3 /* DDASLLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B661E28AC7B003EC5F3 /* DDASLLogger.m */; }; + F5538B7B1E28AC7B003EC5F3 /* DDAssertMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B671E28AC7B003EC5F3 /* DDAssertMacros.h */; }; + F5538B7C1E28AC7B003EC5F3 /* DDFileLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B681E28AC7B003EC5F3 /* DDFileLogger.h */; }; + F5538B7D1E28AC7B003EC5F3 /* DDFileLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B691E28AC7B003EC5F3 /* DDFileLogger.m */; }; + F5538B7E1E28AC7B003EC5F3 /* DDFileLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B691E28AC7B003EC5F3 /* DDFileLogger.m */; }; + F5538B7F1E28AC7B003EC5F3 /* DDLegacyMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B6A1E28AC7B003EC5F3 /* DDLegacyMacros.h */; }; + F5538B801E28AC7B003EC5F3 /* DDLog.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B6B1E28AC7B003EC5F3 /* DDLog.h */; }; + F5538B811E28AC7B003EC5F3 /* DDLog.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B6C1E28AC7B003EC5F3 /* DDLog.m */; }; + F5538B821E28AC7B003EC5F3 /* DDLog.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B6C1E28AC7B003EC5F3 /* DDLog.m */; }; + F5538B831E28AC7B003EC5F3 /* DDLog+LOGV.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B6D1E28AC7B003EC5F3 /* DDLog+LOGV.h */; }; + F5538B841E28AC7B003EC5F3 /* DDLogMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B6E1E28AC7B003EC5F3 /* DDLogMacros.h */; }; + F5538B851E28AC7B003EC5F3 /* DDTTYLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = F5538B6F1E28AC7B003EC5F3 /* DDTTYLogger.h */; }; + F5538B861E28AC7B003EC5F3 /* DDTTYLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B701E28AC7B003EC5F3 /* DDTTYLogger.m */; }; + F5538B871E28AC7B003EC5F3 /* DDTTYLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F5538B701E28AC7B003EC5F3 /* DDTTYLogger.m */; }; F55B31C61CBE6EEA00DFB13C /* TwoFingerTap.m in Sources */ = {isa = PBXBuildFile; fileRef = F55B31C41CBE6E3800DFB13C /* TwoFingerTap.m */; }; F55B31C71CBE6EEF00DFB13C /* TwoFingerTap.m in Sources */ = {isa = PBXBuildFile; fileRef = F55B31C41CBE6E3800DFB13C /* TwoFingerTap.m */; }; F55F81801C6DD07500A945C8 /* GCDAsyncSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F7FED1C6DD07500A945C8 /* GCDAsyncSocket.h */; }; @@ -234,20 +257,6 @@ F55F81A61C6DD07500A945C8 /* HTTPRedirectResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80181C6DD07500A945C8 /* HTTPRedirectResponse.m */; }; F55F81A71C6DD07500A945C8 /* WebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F80191C6DD07500A945C8 /* WebSocket.h */; }; F55F81A81C6DD07500A945C8 /* WebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F801A1C6DD07500A945C8 /* WebSocket.m */; }; - F55F82301C6DD07500A945C8 /* DDAbstractDatabaseLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F80EC1C6DD07500A945C8 /* DDAbstractDatabaseLogger.h */; }; - F55F82311C6DD07500A945C8 /* DDAbstractDatabaseLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80ED1C6DD07500A945C8 /* DDAbstractDatabaseLogger.m */; }; - F55F82321C6DD07500A945C8 /* DDASLLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F80EE1C6DD07500A945C8 /* DDASLLogger.h */; }; - F55F82331C6DD07500A945C8 /* DDASLLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80EF1C6DD07500A945C8 /* DDASLLogger.m */; }; - F55F82341C6DD07500A945C8 /* DDFileLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F80F01C6DD07500A945C8 /* DDFileLogger.h */; }; - F55F82351C6DD07500A945C8 /* DDFileLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80F11C6DD07500A945C8 /* DDFileLogger.m */; }; - F55F82361C6DD07500A945C8 /* DDLog.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F80F21C6DD07500A945C8 /* DDLog.h */; }; - F55F82371C6DD07500A945C8 /* DDLog.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80F31C6DD07500A945C8 /* DDLog.m */; }; - F55F82381C6DD07500A945C8 /* DDTTYLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F80F41C6DD07500A945C8 /* DDTTYLogger.h */; }; - F55F82391C6DD07500A945C8 /* DDTTYLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80F51C6DD07500A945C8 /* DDTTYLogger.m */; }; - F55F823A1C6DD07500A945C8 /* ContextFilterLogFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F80F71C6DD07500A945C8 /* ContextFilterLogFormatter.h */; }; - F55F823B1C6DD07500A945C8 /* ContextFilterLogFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80F81C6DD07500A945C8 /* ContextFilterLogFormatter.m */; }; - F55F823C1C6DD07500A945C8 /* DispatchQueueLogFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F80F91C6DD07500A945C8 /* DispatchQueueLogFormatter.h */; }; - F55F823D1C6DD07500A945C8 /* DispatchQueueLogFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80FA1C6DD07500A945C8 /* DispatchQueueLogFormatter.m */; }; F55F824E1C6DD07500A945C8 /* HTTPResponseProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F81171C6DD07500A945C8 /* HTTPResponseProxy.h */; }; F55F824F1C6DD07500A945C8 /* HTTPResponseProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F81181C6DD07500A945C8 /* HTTPResponseProxy.m */; }; F55F82501C6DD07500A945C8 /* Route.h in Headers */ = {isa = PBXBuildFile; fileRef = F55F81191C6DD07500A945C8 /* Route.h */; }; @@ -380,13 +389,6 @@ F5B0A1D51CAD4E8A00E056CE /* HTTPFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80161C6DD07500A945C8 /* HTTPFileResponse.m */; }; F5B0A1D61CAD4E8A00E056CE /* HTTPRedirectResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80181C6DD07500A945C8 /* HTTPRedirectResponse.m */; }; F5B0A1D71CAD4E8A00E056CE /* WebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F801A1C6DD07500A945C8 /* WebSocket.m */; }; - F5B0A1D81CAD4E9500E056CE /* DDAbstractDatabaseLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80ED1C6DD07500A945C8 /* DDAbstractDatabaseLogger.m */; }; - F5B0A1D91CAD4E9500E056CE /* DDASLLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80EF1C6DD07500A945C8 /* DDASLLogger.m */; }; - F5B0A1DA1CAD4E9500E056CE /* DDFileLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80F11C6DD07500A945C8 /* DDFileLogger.m */; }; - F5B0A1DB1CAD4E9500E056CE /* DDLog.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80F31C6DD07500A945C8 /* DDLog.m */; }; - F5B0A1DC1CAD4E9500E056CE /* DDTTYLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80F51C6DD07500A945C8 /* DDTTYLogger.m */; }; - F5B0A1DD1CAD4E9B00E056CE /* ContextFilterLogFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80F81C6DD07500A945C8 /* ContextFilterLogFormatter.m */; }; - F5B0A1DE1CAD4E9B00E056CE /* DispatchQueueLogFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F80FA1C6DD07500A945C8 /* DispatchQueueLogFormatter.m */; }; F5B0A1DF1CAD4EA700E056CE /* HTTPResponseProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F81181C6DD07500A945C8 /* HTTPResponseProxy.m */; }; F5B0A1E01CAD4EA700E056CE /* Route.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F811A1C6DD07500A945C8 /* Route.m */; }; F5B0A1E11CAD4EA700E056CE /* RouteRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = F55F811C1C6DD07500A945C8 /* RouteRequest.m */; }; @@ -607,6 +609,23 @@ F54B07641DEDB26200C88A8E /* EnvironmentTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EnvironmentTableController.m; sourceTree = ""; }; F5536CEC1D737611006B4EA4 /* AlertFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = AlertFactory.h; sourceTree = ""; tabWidth = 4; usesTabs = 0; wrapsLines = 1; }; F5536CED1D737611006B4EA4 /* AlertFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = AlertFactory.m; sourceTree = ""; tabWidth = 4; usesTabs = 0; wrapsLines = 1; }; + F5538B601E28AC7B003EC5F3 /* CocoaLumberjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CocoaLumberjack.h; sourceTree = ""; }; + F5538B611E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDAbstractDatabaseLogger.h; sourceTree = ""; }; + F5538B621E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDAbstractDatabaseLogger.m; sourceTree = ""; }; + F5538B631E28AC7B003EC5F3 /* DDASLLogCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDASLLogCapture.h; sourceTree = ""; }; + F5538B641E28AC7B003EC5F3 /* DDASLLogCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDASLLogCapture.m; sourceTree = ""; }; + F5538B651E28AC7B003EC5F3 /* DDASLLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDASLLogger.h; sourceTree = ""; }; + F5538B661E28AC7B003EC5F3 /* DDASLLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDASLLogger.m; sourceTree = ""; }; + F5538B671E28AC7B003EC5F3 /* DDAssertMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDAssertMacros.h; sourceTree = ""; }; + F5538B681E28AC7B003EC5F3 /* DDFileLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDFileLogger.h; sourceTree = ""; }; + F5538B691E28AC7B003EC5F3 /* DDFileLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDFileLogger.m; sourceTree = ""; }; + F5538B6A1E28AC7B003EC5F3 /* DDLegacyMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDLegacyMacros.h; sourceTree = ""; }; + F5538B6B1E28AC7B003EC5F3 /* DDLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDLog.h; sourceTree = ""; }; + F5538B6C1E28AC7B003EC5F3 /* DDLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDLog.m; sourceTree = ""; }; + F5538B6D1E28AC7B003EC5F3 /* DDLog+LOGV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DDLog+LOGV.h"; sourceTree = ""; }; + F5538B6E1E28AC7B003EC5F3 /* DDLogMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDLogMacros.h; sourceTree = ""; }; + F5538B6F1E28AC7B003EC5F3 /* DDTTYLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDTTYLogger.h; sourceTree = ""; }; + F5538B701E28AC7B003EC5F3 /* DDTTYLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDTTYLogger.m; sourceTree = ""; }; F55B31C31CBE6E3800DFB13C /* TwoFingerTap.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = TwoFingerTap.h; path = AutomationActions/Gestures/TwoFingerTap.h; sourceTree = ""; tabWidth = 4; usesTabs = 0; }; F55B31C41CBE6E3800DFB13C /* TwoFingerTap.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = TwoFingerTap.m; path = AutomationActions/Gestures/TwoFingerTap.m; sourceTree = ""; tabWidth = 4; usesTabs = 0; }; F55F7FED1C6DD07500A945C8 /* GCDAsyncSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDAsyncSocket.h; sourceTree = ""; }; @@ -647,20 +666,6 @@ F55F80181C6DD07500A945C8 /* HTTPRedirectResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTTPRedirectResponse.m; sourceTree = ""; }; F55F80191C6DD07500A945C8 /* WebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocket.h; sourceTree = ""; }; F55F801A1C6DD07500A945C8 /* WebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebSocket.m; sourceTree = ""; }; - F55F80EC1C6DD07500A945C8 /* DDAbstractDatabaseLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDAbstractDatabaseLogger.h; sourceTree = ""; }; - F55F80ED1C6DD07500A945C8 /* DDAbstractDatabaseLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDAbstractDatabaseLogger.m; sourceTree = ""; }; - F55F80EE1C6DD07500A945C8 /* DDASLLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDASLLogger.h; sourceTree = ""; }; - F55F80EF1C6DD07500A945C8 /* DDASLLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDASLLogger.m; sourceTree = ""; }; - F55F80F01C6DD07500A945C8 /* DDFileLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDFileLogger.h; sourceTree = ""; }; - F55F80F11C6DD07500A945C8 /* DDFileLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDFileLogger.m; sourceTree = ""; }; - F55F80F21C6DD07500A945C8 /* DDLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDLog.h; sourceTree = ""; }; - F55F80F31C6DD07500A945C8 /* DDLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDLog.m; sourceTree = ""; }; - F55F80F41C6DD07500A945C8 /* DDTTYLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDTTYLogger.h; sourceTree = ""; }; - F55F80F51C6DD07500A945C8 /* DDTTYLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDTTYLogger.m; sourceTree = ""; }; - F55F80F71C6DD07500A945C8 /* ContextFilterLogFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextFilterLogFormatter.h; sourceTree = ""; }; - F55F80F81C6DD07500A945C8 /* ContextFilterLogFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContextFilterLogFormatter.m; sourceTree = ""; }; - F55F80F91C6DD07500A945C8 /* DispatchQueueLogFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DispatchQueueLogFormatter.h; sourceTree = ""; }; - F55F80FA1C6DD07500A945C8 /* DispatchQueueLogFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DispatchQueueLogFormatter.m; sourceTree = ""; }; F55F81171C6DD07500A945C8 /* HTTPResponseProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPResponseProxy.h; sourceTree = ""; }; F55F81181C6DD07500A945C8 /* HTTPResponseProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTTPResponseProxy.m; sourceTree = ""; }; F55F81191C6DD07500A945C8 /* Route.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Route.h; sourceTree = ""; }; @@ -1302,32 +1307,27 @@ F55F80EA1C6DD07500A945C8 /* CocoaLumberjack */ = { isa = PBXGroup; children = ( - F55F80EC1C6DD07500A945C8 /* DDAbstractDatabaseLogger.h */, - F55F80ED1C6DD07500A945C8 /* DDAbstractDatabaseLogger.m */, - F55F80EE1C6DD07500A945C8 /* DDASLLogger.h */, - F55F80EF1C6DD07500A945C8 /* DDASLLogger.m */, - F55F80F01C6DD07500A945C8 /* DDFileLogger.h */, - F55F80F11C6DD07500A945C8 /* DDFileLogger.m */, - F55F80F21C6DD07500A945C8 /* DDLog.h */, - F55F80F31C6DD07500A945C8 /* DDLog.m */, - F55F80F41C6DD07500A945C8 /* DDTTYLogger.h */, - F55F80F51C6DD07500A945C8 /* DDTTYLogger.m */, - F55F80F61C6DD07500A945C8 /* Extensions */, + F5538B601E28AC7B003EC5F3 /* CocoaLumberjack.h */, + F5538B611E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.h */, + F5538B621E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.m */, + F5538B631E28AC7B003EC5F3 /* DDASLLogCapture.h */, + F5538B641E28AC7B003EC5F3 /* DDASLLogCapture.m */, + F5538B651E28AC7B003EC5F3 /* DDASLLogger.h */, + F5538B661E28AC7B003EC5F3 /* DDASLLogger.m */, + F5538B671E28AC7B003EC5F3 /* DDAssertMacros.h */, + F5538B681E28AC7B003EC5F3 /* DDFileLogger.h */, + F5538B691E28AC7B003EC5F3 /* DDFileLogger.m */, + F5538B6A1E28AC7B003EC5F3 /* DDLegacyMacros.h */, + F5538B6B1E28AC7B003EC5F3 /* DDLog.h */, + F5538B6C1E28AC7B003EC5F3 /* DDLog.m */, + F5538B6D1E28AC7B003EC5F3 /* DDLog+LOGV.h */, + F5538B6E1E28AC7B003EC5F3 /* DDLogMacros.h */, + F5538B6F1E28AC7B003EC5F3 /* DDTTYLogger.h */, + F5538B701E28AC7B003EC5F3 /* DDTTYLogger.m */, ); path = CocoaLumberjack; sourceTree = ""; }; - F55F80F61C6DD07500A945C8 /* Extensions */ = { - isa = PBXGroup; - children = ( - F55F80F71C6DD07500A945C8 /* ContextFilterLogFormatter.h */, - F55F80F81C6DD07500A945C8 /* ContextFilterLogFormatter.m */, - F55F80F91C6DD07500A945C8 /* DispatchQueueLogFormatter.h */, - F55F80FA1C6DD07500A945C8 /* DispatchQueueLogFormatter.m */, - ); - path = Extensions; - sourceTree = ""; - }; F55F80FC1C6DD07500A945C8 /* RoutingHTTPServer */ = { isa = PBXGroup; children = ( @@ -2014,6 +2014,7 @@ F55F818F1C6DD07500A945C8 /* HTTPLogging.h in Headers */, 89C5F3671C9C5BC20093A018 /* InvalidArgumentException.h in Headers */, F55F819F1C6DD07500A945C8 /* HTTPDynamicFileResponse.h in Headers */, + F5538B711E28AC7B003EC5F3 /* CocoaLumberjack.h in Headers */, F55F818D1C6DD07500A945C8 /* HTTPConnection.h in Headers */, F55F81991C6DD07500A945C8 /* MultipartMessageHeaderField.h in Headers */, 89B951A11CF5B297007FD0AB /* QuerySpecifierByType.h in Headers */, @@ -2023,24 +2024,27 @@ F55F81801C6DD07500A945C8 /* GCDAsyncSocket.h in Headers */, 89C5F35E1C9C51680093A018 /* Query.h in Headers */, F55F81931C6DD07500A945C8 /* HTTPServer.h in Headers */, + F5538B7F1E28AC7B003EC5F3 /* DDLegacyMacros.h in Headers */, F55F82541C6DD07500A945C8 /* RouteResponse.h in Headers */, F55F81A51C6DD07500A945C8 /* HTTPRedirectResponse.h in Headers */, 899696E51CB46C0100BB42E2 /* CoordinateQueryConfiguration.h in Headers */, F59E94751D153ECF00A873C1 /* XCUIApplication+DeviceAgentAdditions.h in Headers */, F55F824E1C6DD07500A945C8 /* HTTPResponseProxy.h in Headers */, - F55F823A1C6DD07500A945C8 /* ContextFilterLogFormatter.h in Headers */, 899696C41CB3360900BB42E2 /* Pinch.h in Headers */, 896586821CEB9B9800E8329C /* QueryFactory.h in Headers */, F55F81901C6DD07500A945C8 /* HTTPMessage.h in Headers */, 89512BDF1CA095D20027D61E /* DeviceEventRoutes.h in Headers */, 89512BDB1C9EEC3C0027D61E /* Drag.h in Headers */, 89D537F71CA1DF8500F62E09 /* QuerySpecifier.h in Headers */, + F5538B851E28AC7B003EC5F3 /* DDTTYLogger.h in Headers */, + F5538B781E28AC7B003EC5F3 /* DDASLLogger.h in Headers */, 89D538151CA351F400F62E09 /* QuerySpecifierByIndex.h in Headers */, 896C7C771D19AE990017CE08 /* ClearText.h in Headers */, F55F81A11C6DD07500A945C8 /* HTTPErrorResponse.h in Headers */, F5870B3F1CF0BEFF00B3376C /* CBXTouchEvent.h in Headers */, 899696D31CB44D9B00BB42E2 /* GestureConfiguration.h in Headers */, 896C7C721D18AA800017CE08 /* ClearTextIn.h in Headers */, + F5538B7C1E28AC7B003EC5F3 /* DDFileLogger.h in Headers */, 89D538031CA20DB800F62E09 /* QuerySpecifierByText.h in Headers */, F5FEA0B81D747CCD00B5EF42 /* UIDevice+Wifi_IP.h in Headers */, F55F81851C6DD07500A945C8 /* DDData.h in Headers */, @@ -2048,17 +2052,17 @@ F55F82561C6DD07500A945C8 /* RoutingConnection.h in Headers */, 899696C91CB356BF00BB42E2 /* QueryConfiguration.h in Headers */, 899696FA1CB5BA4600BB42E2 /* CoordinateQuery.h in Headers */, - F55F823C1C6DD07500A945C8 /* DispatchQueueLogFormatter.h in Headers */, 899696FF1CB5C93400BB42E2 /* QuerySpecifierByCoordinate.h in Headers */, F55F81921C6DD07500A945C8 /* HTTPResponse.h in Headers */, + F5538B831E28AC7B003EC5F3 /* DDLog+LOGV.h in Headers */, F55F818B1C6DD07500A945C8 /* HTTPAuthenticationRequest.h in Headers */, F55F81891C6DD07500A945C8 /* DDRange.h in Headers */, 89D5381D1CA359B200F62E09 /* QuerySpecifierByPropertyLike.h in Headers */, - F55F82321C6DD07500A945C8 /* DDASLLogger.h in Headers */, 89D5380C1CA32AE900F62E09 /* FBElement.h in Headers */, 899696EA1CB5857C00BB42E2 /* JSONKeyValidator.h in Headers */, 89C5F35A1C9B9C850093A018 /* Gesture.h in Headers */, 89D537FB1CA2020700F62E09 /* QuerySpecifierById.h in Headers */, + F5538B841E28AC7B003EC5F3 /* DDLogMacros.h in Headers */, F55F81A71C6DD07500A945C8 /* WebSocket.h in Headers */, 89D537FF1CA2090500F62E09 /* QuerySpecifierFactory.h in Headers */, 899696F51CB5B8C300BB42E2 /* Coordinate.h in Headers */, @@ -2068,22 +2072,22 @@ F55F81951C6DD07500A945C8 /* MultipartFormDataParser.h in Headers */, 89D538191CA3551600F62E09 /* QuerySpecifierByProperty.h in Headers */, F5366D9E1DE6CC2900E7C765 /* TextInputFirstResponderProvider.h in Headers */, - F55F82361C6DD07500A945C8 /* DDLog.h in Headers */, 89D538081CA32AB000F62E09 /* XCUIElement+WebDriverAttributes.h in Headers */, - F55F82341C6DD07500A945C8 /* DDFileLogger.h in Headers */, - F55F82301C6DD07500A945C8 /* DDAbstractDatabaseLogger.h in Headers */, 89F6BF8B1CBC4BDD0088269C /* Rotate.h in Headers */, + F5538B7B1E28AC7B003EC5F3 /* DDAssertMacros.h in Headers */, F5870B421CF0BEFF00B3376C /* TouchPath.h in Headers */, + F5538B751E28AC7B003EC5F3 /* DDASLLogCapture.h in Headers */, F55F82501C6DD07500A945C8 /* Route.h in Headers */, + F5538B801E28AC7B003EC5F3 /* DDLog.h in Headers */, 89C5F3501C9A60E70093A018 /* Testmanagerd.h in Headers */, F55F819B1C6DD07500A945C8 /* HTTPAsyncFileResponse.h in Headers */, + F5538B721E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.h in Headers */, 89C5F3561C9B9B690093A018 /* CBXTypedefs.h in Headers */, 89C5F3541C9A66E10093A018 /* NSXPCConnection.h in Headers */, F55F81871C6DD07500A945C8 /* DDNumber.h in Headers */, 89C5F36B1C9C912F0093A018 /* GestureFactory.h in Headers */, F55F82581C6DD07500A945C8 /* RoutingHTTPServer.h in Headers */, 899697051CB5D5CF00BB42E2 /* Gesture+Options.h in Headers */, - F55F82381C6DD07500A945C8 /* DDTTYLogger.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2455,19 +2459,17 @@ F55F81861C6DD07500A945C8 /* DDData.m in Sources */, 8965867D1CEB961300E8329C /* QueryConfigurationFactory.m in Sources */, F55F840F1C6E437100A945C8 /* UndefinedRoutes.m in Sources */, + F5538B791E28AC7B003EC5F3 /* DDASLLogger.m in Sources */, 89D538041CA20DB800F62E09 /* QuerySpecifierByText.m in Sources */, 899696BB1CADF84B00BB42E2 /* EnterText.m in Sources */, F55F824F1C6DD07500A945C8 /* HTTPResponseProxy.m in Sources */, - F55F82311C6DD07500A945C8 /* DDAbstractDatabaseLogger.m in Sources */, F55F840E1C6E437100A945C8 /* SessionRoutes.m in Sources */, 89D5380D1CA32AE900F62E09 /* FBElement.m in Sources */, F5A14DE61E02CF84001A0037 /* CBLSApplicationWorkspace.m in Sources */, - F55F82331C6DD07500A945C8 /* DDASLLogger.m in Sources */, F55F82591C6DD07500A945C8 /* RoutingHTTPServer.m in Sources */, 89C5F3701C9E32440093A018 /* DoubleTap.m in Sources */, 89D538001CA2090500F62E09 /* QuerySpecifierFactory.m in Sources */, 896C7C731D18AA800017CE08 /* ClearTextIn.m in Sources */, - F55F823B1C6DD07500A945C8 /* ContextFilterLogFormatter.m in Sources */, 899696DA1CB45FFC00BB42E2 /* ActionConfiguration.m in Sources */, 899696F11CB5880F00BB42E2 /* AutomationAction.m in Sources */, F55F81A81C6DD07500A945C8 /* WebSocket.m in Sources */, @@ -2480,6 +2482,7 @@ F55F840C1C6E437100A945C8 /* MetaRoutes.m in Sources */, F5041F4C1E092D30000B3E3E /* XCTestPrivateSymbols.m in Sources */, F55F818E1C6DD07500A945C8 /* HTTPConnection.m in Sources */, + F5538B7D1E28AC7B003EC5F3 /* DDFileLogger.m in Sources */, 89D538111CA34CBE00F62E09 /* QuerySpecifierByTextLike.m in Sources */, F519E0FF1D79E336003A84B0 /* FBFailureProofTestCase.m in Sources */, 89331D321CC50447003C2E59 /* ThreadUtils.m in Sources */, @@ -2492,6 +2495,7 @@ 89C5F36C1C9C912F0093A018 /* GestureFactory.m in Sources */, F55F819A1C6DD07500A945C8 /* MultipartMessageHeaderField.m in Sources */, F55F84131C6E438200A945C8 /* ElementNotFoundException.m in Sources */, + F5538B761E28AC7B003EC5F3 /* DDASLLogCapture.m in Sources */, F55F81A21C6DD07500A945C8 /* HTTPErrorResponse.m in Sources */, F55F84151C6E438800A945C8 /* Application.m in Sources */, 899696F61CB5B8C300BB42E2 /* Coordinate.m in Sources */, @@ -2499,16 +2503,16 @@ F55F819C1C6DD07500A945C8 /* HTTPAsyncFileResponse.m in Sources */, F55F818C1C6DD07500A945C8 /* HTTPAuthenticationRequest.m in Sources */, 896C7C781D19AE990017CE08 /* ClearText.m in Sources */, - F55F82391C6DD07500A945C8 /* DDTTYLogger.m in Sources */, 89C5F3681C9C5BC20093A018 /* InvalidArgumentException.m in Sources */, F55F84091C6E436500A945C8 /* CBXRoute.m in Sources */, F55F81911C6DD07500A945C8 /* HTTPMessage.m in Sources */, - F55F82351C6DD07500A945C8 /* DDFileLogger.m in Sources */, 89F6BF8C1CBC4BDD0088269C /* Rotate.m in Sources */, 899696D41CB44D9B00BB42E2 /* GestureConfiguration.m in Sources */, 899696EB1CB5857C00BB42E2 /* JSONKeyValidator.m in Sources */, F55F81981C6DD07500A945C8 /* MultipartMessageHeader.m in Sources */, F5041F4A1E092D27000B3E3E /* XCUIElement+FBIsVisible.m in Sources */, + F5538B811E28AC7B003EC5F3 /* DDLog.m in Sources */, + F5538B861E28AC7B003EC5F3 /* DDTTYLogger.m in Sources */, 899697061CB5D5CF00BB42E2 /* Gesture+Options.m in Sources */, 89C5F35F1C9C51680093A018 /* Query.m in Sources */, F55F84121C6E438200A945C8 /* CBXException.m in Sources */, @@ -2518,7 +2522,6 @@ 899696E61CB46C0100BB42E2 /* CoordinateQueryConfiguration.m in Sources */, F5DED0401D7634AB00563648 /* SpringBoardAlert.m in Sources */, F5FEA0B51D7478CF00B5EF42 /* SpringBoardAlerts.m in Sources */, - F55F82371C6DD07500A945C8 /* DDLog.m in Sources */, 89C5F35B1C9B9C850093A018 /* Gesture.m in Sources */, 89C5F3641C9C58BD0093A018 /* Touch.m in Sources */, 89512BE01CA095D20027D61E /* DeviceEventRoutes.m in Sources */, @@ -2537,6 +2540,7 @@ F59E94761D153ECF00A873C1 /* XCUIApplication+DeviceAgentAdditions.m in Sources */, F55F84171C6E438800A945C8 /* Application+Queries.m in Sources */, F55F840B1C6E437100A945C8 /* HealthRoutes.m in Sources */, + F5538B731E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.m in Sources */, F55F81961C6DD07500A945C8 /* MultipartFormDataParser.m in Sources */, F55B31C61CBE6EEA00DFB13C /* TwoFingerTap.m in Sources */, F55F81A41C6DD07500A945C8 /* HTTPFileResponse.m in Sources */, @@ -2545,7 +2549,6 @@ 89D538161CA351F400F62E09 /* QuerySpecifierByIndex.m in Sources */, 89B951A21CF5B297007FD0AB /* QuerySpecifierByType.m in Sources */, F5870B401CF0BEFF00B3376C /* CBXTouchEvent.m in Sources */, - F55F823D1C6DD07500A945C8 /* DispatchQueueLogFormatter.m in Sources */, F549E1A61D5472B900C4FA36 /* CBXInfoPlist.m in Sources */, 899696C01CB2F22000BB42E2 /* EnterTextIn.m in Sources */, ); @@ -2615,9 +2618,9 @@ F5B0A1AB1CAD4E2700E056CE /* DoubleTap.m in Sources */, F5B0A1B41CAD4E2700E056CE /* QuerySpecifierByProperty.m in Sources */, 899696EC1CB5857C00BB42E2 /* JSONKeyValidator.m in Sources */, - F5B0A1DE1CAD4E9B00E056CE /* DispatchQueueLogFormatter.m in Sources */, 899696D51CB44D9B00BB42E2 /* GestureConfiguration.m in Sources */, F5FEA0BA1D747CCD00B5EF42 /* UIDevice+Wifi_IP.m in Sources */, + F5538B741E28AC7B003EC5F3 /* DDAbstractDatabaseLogger.m in Sources */, F5B0A1D11CAD4E8A00E056CE /* HTTPAsyncFileResponse.m in Sources */, 899696BC1CADF85B00BB42E2 /* EnterText.m in Sources */, F52C9D871DA7E60300DAFC75 /* DragTest.m in Sources */, @@ -2628,7 +2631,6 @@ F5B0A1D31CAD4E8A00E056CE /* HTTPDynamicFileResponse.m in Sources */, F58D28031D4F947F000FF6C0 /* Gestures+OptionsTests.m in Sources */, F5A14DE71E02CF84001A0037 /* CBLSApplicationWorkspace.m in Sources */, - F5B0A1DB1CAD4E9500E056CE /* DDLog.m in Sources */, F5B0A1D71CAD4E8A00E056CE /* WebSocket.m in Sources */, F5B0A1BF1CAD4E4600E056CE /* HealthRoutes.m in Sources */, F5B0A1AF1CAD4E2700E056CE /* QuerySpecifierFactory.m in Sources */, @@ -2649,17 +2651,15 @@ 896586841CEB9B9800E8329C /* QueryFactory.m in Sources */, F58D280C1D4F947F000FF6C0 /* QueryTests.m in Sources */, F5B0A1B11CAD4E2700E056CE /* QuerySpecifierByText.m in Sources */, - F5B0A1DC1CAD4E9500E056CE /* DDTTYLogger.m in Sources */, F5366DA01DE6CC2900E7C765 /* TextInputFirstResponderProvider.m in Sources */, F5B0A1A31CAD4DE800E056CE /* FBElement.m in Sources */, F5B0A1A71CAD4E2700E056CE /* GestureFactory.m in Sources */, F5B0A1B91CAD4E3A00E056CE /* CBXException.m in Sources */, - F5B0A1D91CAD4E9500E056CE /* DDASLLogger.m in Sources */, + F5538B7E1E28AC7B003EC5F3 /* DDFileLogger.m in Sources */, F5B0A1C41CAD4E4600E056CE /* DeviceEventRoutes.m in Sources */, F549E1A51D5472B100C4FA36 /* CBXInfoPlistTest.m in Sources */, 899696E71CB46C0100BB42E2 /* CoordinateQueryConfiguration.m in Sources */, F5B0A1DF1CAD4EA700E056CE /* HTTPResponseProxy.m in Sources */, - F5B0A1DA1CAD4E9500E056CE /* DDFileLogger.m in Sources */, F5B0A1B81CAD4E3300E056CE /* Application+Queries.m in Sources */, F58D280D1D4F947F000FF6C0 /* CBXiOSVersionInlinesTest.m in Sources */, F5B0A1B71CAD4E3300E056CE /* Application.m in Sources */, @@ -2670,8 +2670,8 @@ F58D28011D4F947F000FF6C0 /* QueryConfigurationTests.m in Sources */, F5870B411CF0BEFF00B3376C /* CBXTouchEvent.m in Sources */, F5B0A1BD1CAD4E4600E056CE /* CBXRoute.m in Sources */, + F5538B821E28AC7B003EC5F3 /* DDLog.m in Sources */, 899696C11CB2F22000BB42E2 /* EnterTextIn.m in Sources */, - F5B0A1DD1CAD4E9B00E056CE /* ContextFilterLogFormatter.m in Sources */, F5B0A1BA1CAD4E3A00E056CE /* ElementNotFoundException.m in Sources */, 899696F71CB5B8C300BB42E2 /* Coordinate.m in Sources */, F5B0A1D21CAD4E8A00E056CE /* HTTPDataResponse.m in Sources */, @@ -2687,6 +2687,7 @@ F52975BF1D4FB1FA009094D5 /* CBXUITestServerTest.m in Sources */, F5B0A1AD1CAD4E2700E056CE /* Query.m in Sources */, F5B0A1B31CAD4E2700E056CE /* QuerySpecifierByIndex.m in Sources */, + F5538B771E28AC7B003EC5F3 /* DDASLLogCapture.m in Sources */, F5B0A1A61CAD4DFA00E056CE /* CBXCUITestServer.m in Sources */, F58D28091D4F947F000FF6C0 /* CoordinateQueryTests.m in Sources */, F5B0A1E21CAD4EA700E056CE /* RouteResponse.m in Sources */, @@ -2705,11 +2706,11 @@ F58D27FF1D4F947F000FF6C0 /* CoordinateQueryConfigurationTests.m in Sources */, F5B0A1E01CAD4EA700E056CE /* Route.m in Sources */, F5B0A1E11CAD4EA700E056CE /* RouteRequest.m in Sources */, + F5538B7A1E28AC7B003EC5F3 /* DDASLLogger.m in Sources */, F5B0A1C91CAD4E6B00E056CE /* DDRange.m in Sources */, F5B0A1C51CAD4E4B00E056CE /* JSONUtils.m in Sources */, F5B0A1AA1CAD4E2700E056CE /* Touch.m in Sources */, F5B0A1B61CAD4E2F00E056CE /* Testmanagerd.m in Sources */, - F5B0A1D81CAD4E9500E056CE /* DDAbstractDatabaseLogger.m in Sources */, F5B0A1D41CAD4E8A00E056CE /* HTTPErrorResponse.m in Sources */, F5963ECC1D5F3F0C002F9304 /* JSONUtilsTest.m in Sources */, F59E94771D153ECF00A873C1 /* XCUIApplication+DeviceAgentAdditions.m in Sources */, @@ -2723,6 +2724,7 @@ F5B0A1B21CAD4E2700E056CE /* QuerySpecifierByTextLike.m in Sources */, F549E1A71D5472BA00C4FA36 /* CBXInfoPlist.m in Sources */, F5B0A1C61CAD4E6400E056CE /* GCDAsyncSocket.m in Sources */, + F5538B871E28AC7B003EC5F3 /* DDTTYLogger.m in Sources */, F5B0A1CE1CAD4E7F00E056CE /* MultipartFormDataParser.m in Sources */, F5B0A1C81CAD4E6B00E056CE /* DDNumber.m in Sources */, F58D28051D4F947F000FF6C0 /* TouchPathTests.m in Sources */, diff --git a/Vendor/CocoaLumberjack/CocoaLumberjack.h b/Vendor/CocoaLumberjack/CocoaLumberjack.h new file mode 100644 index 00000000..581dc324 --- /dev/null +++ b/Vendor/CocoaLumberjack/CocoaLumberjack.h @@ -0,0 +1,85 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2016, 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. + +/** + * Welcome to CocoaLumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/CocoaLumberjack/CocoaLumberjack + * + * If you're new to the project you may wish to read "Getting Started" at: + * Documentation/GettingStarted.md + * + * Otherwise, here is a quick refresher. + * There are three steps to using the macros: + * + * Step 1: + * Import the header in your implementation or prefix file: + * + * #import + * + * Step 2: + * Define your logging level in your implementation file: + * + * // Log levels: off, error, warn, info, verbose + * static const DDLogLevel ddLogLevel = DDLogLevelVerbose; + * + * Step 2 [3rd party frameworks]: + * + * Define your LOG_LEVEL_DEF to a different variable/function than ddLogLevel: + * + * // #undef LOG_LEVEL_DEF // Undefine first only if needed + * #define LOG_LEVEL_DEF myLibLogLevel + * + * Define your logging level in your implementation file: + * + * // Log levels: off, error, warn, info, verbose + * static const DDLogLevel myLibLogLevel = DDLogLevelVerbose; + * + * Step 3: + * Replace your NSLog statements with DDLog statements according to the severity of the message. + * + * NSLog(@"Fatal error, no dohickey found!"); -> DDLogError(@"Fatal error, no dohickey found!"); + * + * DDLog works exactly the same as NSLog. + * This means you can pass it multiple variables just like NSLog. + **/ + +#import + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +// Core +#import "DDLog.h" + +// Main macros +#import "DDLogMacros.h" +#import "DDAssertMacros.h" + +// Capture ASL +#import "DDASLLogCapture.h" + +// Loggers +#import "DDTTYLogger.h" +#import "DDASLLogger.h" +#import "DDFileLogger.h" + +// CLI +#if __has_include("CLIColor.h") && TARGET_OS_OSX +#import "CLIColor.h" +#endif diff --git a/Vendor/CocoaLumberjack/DDASLLogCapture.h b/Vendor/CocoaLumberjack/DDASLLogCapture.h new file mode 100644 index 00000000..64d83703 --- /dev/null +++ b/Vendor/CocoaLumberjack/DDASLLogCapture.h @@ -0,0 +1,41 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2016, 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. + +#import "DDASLLogger.h" + +@protocol DDLogger; + +/** + * This class provides the ability to capture the ASL (Apple System Logs) + */ +@interface DDASLLogCapture : NSObject + +/** + * Start capturing logs + */ ++ (void)start; + +/** + * Stop capturing logs + */ ++ (void)stop; + +/** + * The current capture level. + * @note Default log level: DDLogLevelVerbose (i.e. capture all ASL messages). + */ +@property (class) DDLogLevel captureLevel; + +@end diff --git a/Vendor/CocoaLumberjack/DDASLLogCapture.m b/Vendor/CocoaLumberjack/DDASLLogCapture.m new file mode 100644 index 00000000..4341d6df --- /dev/null +++ b/Vendor/CocoaLumberjack/DDASLLogCapture.m @@ -0,0 +1,230 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2016, 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. + +#import "DDASLLogCapture.h" + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +#import "DDLog.h" + +#include +#include +#include +#include + +static BOOL _cancel = YES; +static DDLogLevel _captureLevel = DDLogLevelVerbose; + +#ifdef __IPHONE_8_0 + #define DDASL_IOS_PIVOT_VERSION __IPHONE_8_0 +#endif +#ifdef __MAC_10_10 + #define DDASL_OSX_PIVOT_VERSION __MAC_10_10 +#endif + +@implementation DDASLLogCapture + +static aslmsg (*dd_asl_next)(aslresponse obj); +static void (*dd_asl_release)(aslresponse obj); + ++ (void)initialize +{ + #if (defined(DDASL_IOS_PIVOT_VERSION) && __IPHONE_OS_VERSION_MAX_ALLOWED >= DDASL_IOS_PIVOT_VERSION) || (defined(DDASL_OSX_PIVOT_VERSION) && __MAC_OS_X_VERSION_MAX_ALLOWED >= DDASL_OSX_PIVOT_VERSION) + #if __IPHONE_OS_VERSION_MIN_REQUIRED < DDASL_IOS_PIVOT_VERSION || __MAC_OS_X_VERSION_MIN_REQUIRED < DDASL_OSX_PIVOT_VERSION + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + // Building on falsely advertised SDK, targeting deprecated API + dd_asl_next = &aslresponse_next; + dd_asl_release = &aslresponse_free; + #pragma GCC diagnostic pop + #else + // Building on lastest, correct SDK, targeting latest API + dd_asl_next = &asl_next; + dd_asl_release = &asl_release; + #endif + #else + // Building on old SDKs, targeting deprecated API + dd_asl_next = &aslresponse_next; + dd_asl_release = &aslresponse_free; + #endif +} + ++ (void)start { + // Ignore subsequent calls + if (!_cancel) { + return; + } + + _cancel = NO; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { + [self captureAslLogs]; + }); +} + ++ (void)stop { + _cancel = YES; +} + ++ (DDLogLevel)captureLevel { + return _captureLevel; +} + ++ (void)setCaptureLevel:(DDLogLevel)level { + _captureLevel = level; +} + +#pragma mark - Private methods + ++ (void)configureAslQuery:(aslmsg)query { + const char param[] = "7"; // ASL_LEVEL_DEBUG, which is everything. We'll rely on regular DDlog log level to filter + + asl_set_query(query, ASL_KEY_LEVEL, param, ASL_QUERY_OP_LESS_EQUAL | ASL_QUERY_OP_NUMERIC); + + // Don't retrieve logs from our own DDASLLogger + asl_set_query(query, kDDASLKeyDDLog, kDDASLDDLogValue, ASL_QUERY_OP_NOT_EQUAL); + +#if !TARGET_OS_IPHONE || TARGET_SIMULATOR + int processId = [[NSProcessInfo processInfo] processIdentifier]; + char pid[16]; + sprintf(pid, "%d", processId); + asl_set_query(query, ASL_KEY_PID, pid, ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_NUMERIC); +#endif +} + ++ (void)aslMessageReceived:(aslmsg)msg { + const char* messageCString = asl_get( msg, ASL_KEY_MSG ); + if ( messageCString == NULL ) + return; + + int flag; + BOOL async; + + const char* levelCString = asl_get(msg, ASL_KEY_LEVEL); + switch (levelCString? atoi(levelCString) : 0) { + // By default all NSLog's with a ASL_LEVEL_WARNING level + case ASL_LEVEL_EMERG : + case ASL_LEVEL_ALERT : + case ASL_LEVEL_CRIT : flag = DDLogFlagError; async = NO; break; + case ASL_LEVEL_ERR : flag = DDLogFlagWarning; async = YES; break; + case ASL_LEVEL_WARNING : flag = DDLogFlagInfo; async = YES; break; + case ASL_LEVEL_NOTICE : flag = DDLogFlagDebug; async = YES; break; + case ASL_LEVEL_INFO : + case ASL_LEVEL_DEBUG : + default : flag = DDLogFlagVerbose; async = YES; break; + } + + if (!(_captureLevel & flag)) { + return; + } + + // NSString * sender = [NSString stringWithCString:asl_get(msg, ASL_KEY_SENDER) encoding:NSUTF8StringEncoding]; + NSString *message = @(messageCString); + + const char* secondsCString = asl_get( msg, ASL_KEY_TIME ); + const char* nanoCString = asl_get( msg, ASL_KEY_TIME_NSEC ); + NSTimeInterval seconds = secondsCString ? strtod(secondsCString, NULL) : [NSDate timeIntervalSinceReferenceDate] - NSTimeIntervalSince1970; + double nanoSeconds = nanoCString? strtod(nanoCString, NULL) : 0; + NSTimeInterval totalSeconds = seconds + (nanoSeconds / 1e9); + + NSDate *timeStamp = [NSDate dateWithTimeIntervalSince1970:totalSeconds]; + + DDLogMessage *logMessage = [[DDLogMessage alloc]initWithMessage:message + level:_captureLevel + flag:flag + context:0 + file:@"DDASLLogCapture" + function:0 + line:0 + tag:nil + options:0 + timestamp:timeStamp]; + + [DDLog log:async message:logMessage]; +} + ++ (void)captureAslLogs { + @autoreleasepool + { + /* + We use ASL_KEY_MSG_ID to see each message once, but there's no + obvious way to get the "next" ID. To bootstrap the process, we'll + search by timestamp until we've seen a message. + */ + + struct timeval timeval = { + .tv_sec = 0 + }; + gettimeofday(&timeval, NULL); + unsigned long long startTime = timeval.tv_sec; + __block unsigned long long lastSeenID = 0; + + /* + syslogd posts kNotifyASLDBUpdate (com.apple.system.logger.message) + through the notify API when it saves messages to the ASL database. + There is some coalescing - currently it is sent at most twice per + second - but there is no documented guarantee about this. In any + case, there may be multiple messages per notification. + + Notify notifications don't carry any payload, so we need to search + for the messages. + */ + int notifyToken = 0; // Can be used to unregister with notify_cancel(). + notify_register_dispatch(kNotifyASLDBUpdate, ¬ifyToken, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(int token) + { + // At least one message has been posted; build a search query. + @autoreleasepool + { + aslmsg query = asl_new(ASL_TYPE_QUERY); + char stringValue[64]; + + if (lastSeenID > 0) { + snprintf(stringValue, sizeof stringValue, "%llu", lastSeenID); + asl_set_query(query, ASL_KEY_MSG_ID, stringValue, ASL_QUERY_OP_GREATER | ASL_QUERY_OP_NUMERIC); + } else { + snprintf(stringValue, sizeof stringValue, "%llu", startTime); + asl_set_query(query, ASL_KEY_TIME, stringValue, ASL_QUERY_OP_GREATER_EQUAL | ASL_QUERY_OP_NUMERIC); + } + + [self configureAslQuery:query]; + + // Iterate over new messages. + aslmsg msg; + aslresponse response = asl_search(NULL, query); + + while ((msg = dd_asl_next(response))) + { + [self aslMessageReceived:msg]; + + // Keep track of which messages we've seen. + lastSeenID = atoll(asl_get(msg, ASL_KEY_MSG_ID)); + } + dd_asl_release(response); + asl_free(query); + + if (_cancel) { + notify_cancel(token); + return; + } + + } + }); + } +} + +@end diff --git a/Vendor/CocoaLumberjack/DDASLLogger.h b/Vendor/CocoaLumberjack/DDASLLogger.h old mode 100755 new mode 100644 index 0f2e9633..046636df --- a/Vendor/CocoaLumberjack/DDASLLogger.h +++ b/Vendor/CocoaLumberjack/DDASLLogger.h @@ -1,37 +1,54 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2016, 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. + #import -#import + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif #import "DDLog.h" +// Custom key set on messages sent to ASL +extern const char* const kDDASLKeyDDLog; + +// Value set for kDDASLKeyDDLog +extern const char* const kDDASLDDLogValue; + /** - * Welcome to Cocoa Lumberjack! - * - * The project page has a wealth of documentation if you have any questions. - * https://github.com/robbiehanson/CocoaLumberjack - * - * If you're new to the project you may wish to read the "Getting Started" wiki. - * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted - * - * * This class provides a logger for the Apple System Log facility. - * + * * As described in the "Getting Started" page, - * the traditional NSLog() function directs it's output to two places: - * + * the traditional NSLog() function directs its output to two places: + * * - Apple System Log * - StdErr (if stderr is a TTY) so log statements show up in Xcode console - * + * * To duplicate NSLog() functionality you can simply add this logger and a tty logger. * However, if you instead choose to use file logging (for faster performance), * you may choose to use a file logger and a tty logger. -**/ - + **/ @interface DDASLLogger : DDAbstractLogger -{ - aslclient client; -} -+ (DDASLLogger *)sharedInstance; +/** + * Singleton method + * + * @return the shared instance + */ +@property (class, readonly, strong) DDASLLogger *sharedInstance; // Inherited from DDAbstractLogger diff --git a/Vendor/CocoaLumberjack/DDASLLogger.m b/Vendor/CocoaLumberjack/DDASLLogger.m old mode 100755 new mode 100644 index 0c35f2fc..a189d136 --- a/Vendor/CocoaLumberjack/DDASLLogger.m +++ b/Vendor/CocoaLumberjack/DDASLLogger.m @@ -1,99 +1,121 @@ -#import "DDASLLogger.h" - -#import +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2016, 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. -/** - * Welcome to Cocoa Lumberjack! - * - * The project page has a wealth of documentation if you have any questions. - * https://github.com/robbiehanson/CocoaLumberjack - * - * If you're new to the project you may wish to read the "Getting Started" wiki. - * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted -**/ +#import "DDASLLogger.h" +#import -#if ! __has_feature(objc_arc) -#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). #endif +const char* const kDDASLKeyDDLog = "DDLog"; -@implementation DDASLLogger +const char* const kDDASLDDLogValue = "1"; static DDASLLogger *sharedInstance; -/** - * The runtime sends initialize to each class in a program exactly one time just before the class, - * or any class that inherits from it, is sent its first message from within the program. (Thus the - * method may never be invoked if the class is not used.) The runtime sends the initialize message to - * classes in a thread-safe manner. Superclasses receive this message before their subclasses. - * - * This method may also be called directly (assumably by accident), hence the safety mechanism. -**/ -+ (void)initialize -{ - static BOOL initialized = NO; - if (!initialized) - { - initialized = YES; - - sharedInstance = [[DDASLLogger alloc] init]; - } +@interface DDASLLogger () { + aslclient _client; } -+ (DDASLLogger *)sharedInstance -{ - return sharedInstance; +@end + + +@implementation DDASLLogger + ++ (instancetype)sharedInstance { + static dispatch_once_t DDASLLoggerOnceToken; + + dispatch_once(&DDASLLoggerOnceToken, ^{ + sharedInstance = [[[self class] alloc] init]; + }); + + return sharedInstance; } -- (id)init -{ - if (sharedInstance != nil) - { - return nil; - } - - if ((self = [super init])) - { - // A default asl client is provided for the main thread, - // but background threads need to create their own client. - - client = asl_open(NULL, "com.apple.console", 0); - } - return self; +- (instancetype)init { + if (sharedInstance != nil) { + return nil; + } + + if ((self = [super init])) { + // A default asl client is provided for the main thread, + // but background threads need to create their own client. + + _client = asl_open(NULL, "com.apple.console", 0); + } + + return self; } -- (void)logMessage:(DDLogMessage *)logMessage -{ - NSString *logMsg = logMessage->logMsg; - - if (formatter) - { - logMsg = [formatter formatLogMessage:logMessage]; - } - - if (logMsg) - { - const char *msg = [logMsg UTF8String]; - - int aslLogLevel; - switch (logMessage->logFlag) - { - // Note: By default ASL will filter anything above level 5 (Notice). - // So our mappings shouldn't go above that level. - - case LOG_FLAG_ERROR : aslLogLevel = ASL_LEVEL_CRIT; break; - case LOG_FLAG_WARN : aslLogLevel = ASL_LEVEL_ERR; break; - case LOG_FLAG_INFO : aslLogLevel = ASL_LEVEL_WARNING; break; - default : aslLogLevel = ASL_LEVEL_NOTICE; break; - } - - asl_log(client, NULL, aslLogLevel, "%s", msg); - } +- (void)logMessage:(DDLogMessage *)logMessage { + // Skip captured log messages + if ([logMessage->_fileName isEqualToString:@"DDASLLogCapture"]) { + return; + } + + NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message; + + if (message) { + const char *msg = [message UTF8String]; + + size_t aslLogLevel; + switch (logMessage->_flag) { + // Note: By default ASL will filter anything above level 5 (Notice). + // So our mappings shouldn't go above that level. + case DDLogFlagError : aslLogLevel = ASL_LEVEL_CRIT; break; + case DDLogFlagWarning : aslLogLevel = ASL_LEVEL_ERR; break; + case DDLogFlagInfo : aslLogLevel = ASL_LEVEL_WARNING; break; // Regular NSLog's level + case DDLogFlagDebug : + case DDLogFlagVerbose : + default : aslLogLevel = ASL_LEVEL_NOTICE; break; + } + + static char const *const level_strings[] = { "0", "1", "2", "3", "4", "5", "6", "7" }; + + // NSLog uses the current euid to set the ASL_KEY_READ_UID. + uid_t const readUID = geteuid(); + + char readUIDString[16]; +#ifndef NS_BLOCK_ASSERTIONS + int l = snprintf(readUIDString, sizeof(readUIDString), "%d", readUID); +#else + snprintf(readUIDString, sizeof(readUIDString), "%d", readUID); +#endif + + NSAssert(l < sizeof(readUIDString), + @"Formatted euid is too long."); + NSAssert(aslLogLevel < (sizeof(level_strings) / sizeof(level_strings[0])), + @"Unhandled ASL log level."); + + aslmsg m = asl_new(ASL_TYPE_MSG); + if (m != NULL) { + if (asl_set(m, ASL_KEY_LEVEL, level_strings[aslLogLevel]) == 0 && + asl_set(m, ASL_KEY_MSG, msg) == 0 && + asl_set(m, ASL_KEY_READ_UID, readUIDString) == 0 && + asl_set(m, kDDASLKeyDDLog, kDDASLDDLogValue) == 0) { + asl_send(_client, m); + } + asl_free(m); + } + //TODO handle asl_* failures non-silently? + } } -- (NSString *)loggerName -{ - return @"cocoa.lumberjack.aslLogger"; +- (NSString *)loggerName { + return @"cocoa.lumberjack.aslLogger"; } @end diff --git a/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.h b/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.h index 436234e2..208bb223 100644 --- a/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.h +++ b/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.h @@ -1,102 +1,123 @@ -#import +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2016, 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 #import "DDLog.h" /** - * Welcome to Cocoa Lumberjack! - * - * The project page has a wealth of documentation if you have any questions. - * https://github.com/robbiehanson/CocoaLumberjack - * - * If you're new to the project you may wish to read the "Getting Started" wiki. - * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted - * - * * This class provides an abstract implementation of a database logger. - * + * * That is, it provides the base implementation for a database logger to build atop of. * All that is needed for a concrete database logger is to extend this class * and override the methods in the implementation file that are prefixed with "db_". -**/ - + **/ @interface DDAbstractDatabaseLogger : DDAbstractLogger { + @protected - NSUInteger saveThreshold; - NSTimeInterval saveInterval; - NSTimeInterval maxAge; - NSTimeInterval deleteInterval; - BOOL deleteOnEverySave; - - BOOL saveTimerSuspended; - NSUInteger unsavedCount; - dispatch_time_t unsavedTime; - dispatch_source_t saveTimer; - dispatch_time_t lastDeleteTime; - dispatch_source_t deleteTimer; + NSUInteger _saveThreshold; + NSTimeInterval _saveInterval; + NSTimeInterval _maxAge; + NSTimeInterval _deleteInterval; + BOOL _deleteOnEverySave; + + BOOL _saveTimerSuspended; + NSUInteger _unsavedCount; + dispatch_time_t _unsavedTime; + dispatch_source_t _saveTimer; + dispatch_time_t _lastDeleteTime; + dispatch_source_t _deleteTimer; } /** * Specifies how often to save the data to disk. * Since saving is an expensive operation (disk io) it is not done after every log statement. * These properties allow you to configure how/when the logger saves to disk. - * + * * A save is done when either (whichever happens first): - * + * * - The number of unsaved log entries reaches saveThreshold * - The amount of time since the oldest unsaved log entry was created reaches saveInterval - * + * * You can optionally disable the saveThreshold by setting it to zero. * If you disable the saveThreshold you are entirely dependent on the saveInterval. - * + * * You can optionally disable the saveInterval by setting it to zero (or a negative value). * If you disable the saveInterval you are entirely dependent on the saveThreshold. - * + * * It's not wise to disable both saveThreshold and saveInterval. - * + * * The default saveThreshold is 500. * The default saveInterval is 60 seconds. -**/ + **/ @property (assign, readwrite) NSUInteger saveThreshold; + +/** + * See the description for the `saveThreshold` property + */ @property (assign, readwrite) NSTimeInterval saveInterval; /** * It is likely you don't want the log entries to persist forever. * Doing so would allow the database to grow infinitely large over time. - * + * * The maxAge property provides a way to specify how old a log statement can get * before it should get deleted from the database. - * + * * The deleteInterval specifies how often to sweep for old log entries. * Since deleting is an expensive operation (disk io) is is done on a fixed interval. - * + * * An alternative to the deleteInterval is the deleteOnEverySave option. * This specifies that old log entries should be deleted during every save operation. - * + * * You can optionally disable the maxAge by setting it to zero (or a negative value). * If you disable the maxAge then old log statements are not deleted. - * + * * You can optionally disable the deleteInterval by setting it to zero (or a negative value). - * + * * If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted. - * + * * It's not wise to enable both deleteInterval and deleteOnEverySave. - * + * * The default maxAge is 7 days. * The default deleteInterval is 5 minutes. * The default deleteOnEverySave is NO. -**/ + **/ @property (assign, readwrite) NSTimeInterval maxAge; + +/** + * See the description for the `maxAge` property + */ @property (assign, readwrite) NSTimeInterval deleteInterval; + +/** + * See the description for the `maxAge` property + */ @property (assign, readwrite) BOOL deleteOnEverySave; /** * Forces a save of any pending log entries (flushes log entries to disk). -**/ + **/ - (void)savePendingLogEntries; /** * Removes any log entries that are older than maxAge. -**/ + **/ - (void)deleteOldLogEntries; @end diff --git a/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.m b/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.m index c7366a69..0200f7cf 100644 --- a/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.m +++ b/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.m @@ -1,727 +1,660 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2016, 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. + #import "DDAbstractDatabaseLogger.h" #import -/** - * Welcome to Cocoa Lumberjack! - * - * The project page has a wealth of documentation if you have any questions. - * https://github.com/robbiehanson/CocoaLumberjack - * - * If you're new to the project you may wish to read the "Getting Started" wiki. - * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted -**/ - -#if ! __has_feature(objc_arc) -#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). #endif @interface DDAbstractDatabaseLogger () + - (void)destroySaveTimer; - (void)destroyDeleteTimer; + @end #pragma mark - @implementation DDAbstractDatabaseLogger -- (id)init -{ - if ((self = [super init])) - { - saveThreshold = 500; - saveInterval = 60; // 60 seconds - maxAge = (60 * 60 * 24 * 7); // 7 days - deleteInterval = (60 * 5); // 5 minutes - } - return self; +- (instancetype)init { + if ((self = [super init])) { + _saveThreshold = 500; + _saveInterval = 60; // 60 seconds + _maxAge = (60 * 60 * 24 * 7); // 7 days + _deleteInterval = (60 * 5); // 5 minutes + } + + return self; } -- (void)dealloc -{ - [self destroySaveTimer]; - [self destroyDeleteTimer]; - +- (void)dealloc { + [self destroySaveTimer]; + [self destroyDeleteTimer]; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Override Me //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- (BOOL)db_log:(DDLogMessage *)logMessage -{ - // Override me and add your implementation. - // - // Return YES if an item was added to the buffer. - // Return NO if the logMessage was ignored. - - return NO; +- (BOOL)db_log:(DDLogMessage *)logMessage { + // Override me and add your implementation. + // + // Return YES if an item was added to the buffer. + // Return NO if the logMessage was ignored. + + return NO; } -- (void)db_save -{ - // Override me and add your implementation. +- (void)db_save { + // Override me and add your implementation. } -- (void)db_delete -{ - // Override me and add your implementation. +- (void)db_delete { + // Override me and add your implementation. } -- (void)db_saveAndDelete -{ - // Override me and add your implementation. +- (void)db_saveAndDelete { + // Override me and add your implementation. } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Private API //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)performSaveAndSuspendSaveTimer -{ - if (unsavedCount > 0) - { - if (deleteOnEverySave) - [self db_saveAndDelete]; - else - [self db_save]; - } - - unsavedCount = 0; - unsavedTime = 0; - - if (saveTimer && !saveTimerSuspended) - { - dispatch_suspend(saveTimer); - saveTimerSuspended = YES; - } +- (void)performSaveAndSuspendSaveTimer { + if (_unsavedCount > 0) { + if (_deleteOnEverySave) { + [self db_saveAndDelete]; + } else { + [self db_save]; + } + } + + _unsavedCount = 0; + _unsavedTime = 0; + + if (_saveTimer && !_saveTimerSuspended) { + dispatch_suspend(_saveTimer); + _saveTimerSuspended = YES; + } } -- (void)performDelete -{ - if (maxAge > 0.0) - { - [self db_delete]; - - lastDeleteTime = dispatch_time(DISPATCH_TIME_NOW, 0); - } +- (void)performDelete { + if (_maxAge > 0.0) { + [self db_delete]; + + _lastDeleteTime = dispatch_time(DISPATCH_TIME_NOW, 0); + } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Timers //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)destroySaveTimer -{ - if (saveTimer) - { - dispatch_source_cancel(saveTimer); - if (saveTimerSuspended) - { - // Must resume a timer before releasing it (or it will crash) - dispatch_resume(saveTimer); - saveTimerSuspended = NO; - } - #if !OS_OBJECT_USE_OBJC - dispatch_release(saveTimer); - #endif - saveTimer = NULL; - } -} +- (void)destroySaveTimer { + if (_saveTimer) { + dispatch_source_cancel(_saveTimer); -- (void)updateAndResumeSaveTimer -{ - if ((saveTimer != NULL) && (saveInterval > 0.0) && (unsavedTime > 0.0)) - { - uint64_t interval = (uint64_t)(saveInterval * NSEC_PER_SEC); - dispatch_time_t startTime = dispatch_time(unsavedTime, interval); - - dispatch_source_set_timer(saveTimer, startTime, interval, 1.0); - - if (saveTimerSuspended) - { - dispatch_resume(saveTimer); - saveTimerSuspended = NO; - } - } + if (_saveTimerSuspended) { + // Must resume a timer before releasing it (or it will crash) + dispatch_resume(_saveTimer); + _saveTimerSuspended = NO; + } + + #if !OS_OBJECT_USE_OBJC + dispatch_release(_saveTimer); + #endif + _saveTimer = NULL; + } } -- (void)createSuspendedSaveTimer -{ - if ((saveTimer == NULL) && (saveInterval > 0.0)) - { - saveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, loggerQueue); - - dispatch_source_set_event_handler(saveTimer, ^{ @autoreleasepool { - - [self performSaveAndSuspendSaveTimer]; - - }}); - - saveTimerSuspended = YES; - } +- (void)updateAndResumeSaveTimer { + if ((_saveTimer != NULL) && (_saveInterval > 0.0) && (_unsavedTime > 0.0)) { + uint64_t interval = (uint64_t)(_saveInterval * NSEC_PER_SEC); + dispatch_time_t startTime = dispatch_time(_unsavedTime, interval); + + dispatch_source_set_timer(_saveTimer, startTime, interval, 1.0); + + if (_saveTimerSuspended) { + dispatch_resume(_saveTimer); + _saveTimerSuspended = NO; + } + } } -- (void)destroyDeleteTimer -{ - if (deleteTimer) - { - dispatch_source_cancel(deleteTimer); - #if !OS_OBJECT_USE_OBJC - dispatch_release(deleteTimer); - #endif - deleteTimer = NULL; - } +- (void)createSuspendedSaveTimer { + if ((_saveTimer == NULL) && (_saveInterval > 0.0)) { + _saveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.loggerQueue); + + dispatch_source_set_event_handler(_saveTimer, ^{ @autoreleasepool { + [self performSaveAndSuspendSaveTimer]; + } }); + + _saveTimerSuspended = YES; + } } -- (void)updateDeleteTimer -{ - if ((deleteTimer != NULL) && (deleteInterval > 0.0) && (maxAge > 0.0)) - { - uint64_t interval = (uint64_t)(deleteInterval * NSEC_PER_SEC); - dispatch_time_t startTime; - - if (lastDeleteTime > 0) - startTime = dispatch_time(lastDeleteTime, interval); - else - startTime = dispatch_time(DISPATCH_TIME_NOW, interval); - - dispatch_source_set_timer(deleteTimer, startTime, interval, 1.0); - } +- (void)destroyDeleteTimer { + if (_deleteTimer) { + dispatch_source_cancel(_deleteTimer); + #if !OS_OBJECT_USE_OBJC + dispatch_release(_deleteTimer); + #endif + _deleteTimer = NULL; + } } -- (void)createAndStartDeleteTimer -{ - if ((deleteTimer == NULL) && (deleteInterval > 0.0) && (maxAge > 0.0)) - { - deleteTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, loggerQueue); +- (void)updateDeleteTimer { + if ((_deleteTimer != NULL) && (_deleteInterval > 0.0) && (_maxAge > 0.0)) { + uint64_t interval = (uint64_t)(_deleteInterval * NSEC_PER_SEC); + dispatch_time_t startTime; - if (deleteTimer != NULL) { - dispatch_source_set_event_handler(deleteTimer, ^{ @autoreleasepool { + if (_lastDeleteTime > 0) { + startTime = dispatch_time(_lastDeleteTime, interval); + } else { + startTime = dispatch_time(DISPATCH_TIME_NOW, interval); + } + + dispatch_source_set_timer(_deleteTimer, startTime, interval, 1.0); + } +} - [self performDelete]; +- (void)createAndStartDeleteTimer { + if ((_deleteTimer == NULL) && (_deleteInterval > 0.0) && (_maxAge > 0.0)) { + _deleteTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.loggerQueue); - }}); + if (_deleteTimer != NULL) { + dispatch_source_set_event_handler(_deleteTimer, ^{ @autoreleasepool { + [self performDelete]; + } }); [self updateDeleteTimer]; - - dispatch_resume(deleteTimer); + + if (_deleteTimer != NULL) { + dispatch_resume(_deleteTimer); + } } - } + } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Configuration //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- (NSUInteger)saveThreshold -{ - // The design of this method is taken from the DDAbstractLogger implementation. - // For extensive documentation please refer to the DDAbstractLogger implementation. - - // Note: The internal implementation MUST access the colorsEnabled variable directly, - // This method is designed explicitly for external access. - // - // Using "self." syntax to go through this method will cause immediate deadlock. - // This is the intended result. Fix it by accessing the ivar directly. - // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. - - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); - - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - - __block NSUInteger result; - - dispatch_sync(globalLoggingQueue, ^{ - dispatch_sync(loggerQueue, ^{ - result = saveThreshold; - }); - }); - - return result; +- (NSUInteger)saveThreshold { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSUInteger result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = _saveThreshold; + }); + }); + + return result; } -- (void)setSaveThreshold:(NSUInteger)threshold -{ - dispatch_block_t block = ^{ @autoreleasepool { - - if (saveThreshold != threshold) - { - saveThreshold = threshold; - - // Since the saveThreshold has changed, - // we check to see if the current unsavedCount has surpassed the new threshold. - // - // If it has, we immediately save the log. - - if ((unsavedCount >= saveThreshold) && (saveThreshold > 0)) - { - [self performSaveAndSuspendSaveTimer]; - } - } - }}; - - // The design of the setter logic below is taken from the DDAbstractLogger implementation. - // For documentation please refer to the DDAbstractLogger implementation. - - if ([self isOnInternalLoggerQueue]) - { - block(); - } - else - { - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - - dispatch_async(globalLoggingQueue, ^{ - dispatch_async(loggerQueue, block); - }); - } +- (void)setSaveThreshold:(NSUInteger)threshold { + dispatch_block_t block = ^{ + @autoreleasepool { + if (_saveThreshold != threshold) { + _saveThreshold = threshold; + + // Since the saveThreshold has changed, + // we check to see if the current unsavedCount has surpassed the new threshold. + // + // If it has, we immediately save the log. + + if ((_unsavedCount >= _saveThreshold) && (_saveThreshold > 0)) { + [self performSaveAndSuspendSaveTimer]; + } + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } } -- (NSTimeInterval)saveInterval -{ - // The design of this method is taken from the DDAbstractLogger implementation. - // For extensive documentation please refer to the DDAbstractLogger implementation. - - // Note: The internal implementation MUST access the colorsEnabled variable directly, - // This method is designed explicitly for external access. - // - // Using "self." syntax to go through this method will cause immediate deadlock. - // This is the intended result. Fix it by accessing the ivar directly. - // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. - - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); - - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - - __block NSTimeInterval result; - - dispatch_sync(globalLoggingQueue, ^{ - dispatch_sync(loggerQueue, ^{ - result = saveInterval; - }); - }); - - return result; +- (NSTimeInterval)saveInterval { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSTimeInterval result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = _saveInterval; + }); + }); + + return result; } -- (void)setSaveInterval:(NSTimeInterval)interval -{ - dispatch_block_t block = ^{ @autoreleasepool { - - // C99 recommended floating point comparison macro - // Read: isLessThanOrGreaterThan(floatA, floatB) - - if (/* saveInterval != interval */ islessgreater(saveInterval, interval)) - { - saveInterval = interval; - - // There are several cases we need to handle here. - // - // 1. If the saveInterval was previously enabled and it just got disabled, - // then we need to stop the saveTimer. (And we might as well release it.) - // - // 2. If the saveInterval was previously disabled and it just got enabled, - // then we need to setup the saveTimer. (Plus we might need to do an immediate save.) - // - // 3. If the saveInterval increased, then we need to reset the timer so that it fires at the later date. - // - // 4. If the saveInterval decreased, then we need to reset the timer so that it fires at an earlier date. - // (Plus we might need to do an immediate save.) - - if (saveInterval > 0.0) - { - if (saveTimer == NULL) - { - // Handles #2 - // - // Since the saveTimer uses the unsavedTime to calculate it's first fireDate, - // if a save is needed the timer will fire immediately. - - [self createSuspendedSaveTimer]; - [self updateAndResumeSaveTimer]; - } - else - { - // Handles #3 - // Handles #4 - // - // Since the saveTimer uses the unsavedTime to calculate it's first fireDate, - // if a save is needed the timer will fire immediately. - - [self updateAndResumeSaveTimer]; - } - } - else if (saveTimer) - { - // Handles #1 - - [self destroySaveTimer]; - } - } - }}; - - // The design of the setter logic below is taken from the DDAbstractLogger implementation. - // For documentation please refer to the DDAbstractLogger implementation. - - if ([self isOnInternalLoggerQueue]) - { - block(); - } - else - { - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - - dispatch_async(globalLoggingQueue, ^{ - dispatch_async(loggerQueue, block); - }); - } +- (void)setSaveInterval:(NSTimeInterval)interval { + dispatch_block_t block = ^{ + @autoreleasepool { + // C99 recommended floating point comparison macro + // Read: isLessThanOrGreaterThan(floatA, floatB) + + if (/* saveInterval != interval */ islessgreater(_saveInterval, interval)) { + _saveInterval = interval; + + // There are several cases we need to handle here. + // + // 1. If the saveInterval was previously enabled and it just got disabled, + // then we need to stop the saveTimer. (And we might as well release it.) + // + // 2. If the saveInterval was previously disabled and it just got enabled, + // then we need to setup the saveTimer. (Plus we might need to do an immediate save.) + // + // 3. If the saveInterval increased, then we need to reset the timer so that it fires at the later date. + // + // 4. If the saveInterval decreased, then we need to reset the timer so that it fires at an earlier date. + // (Plus we might need to do an immediate save.) + + if (_saveInterval > 0.0) { + if (_saveTimer == NULL) { + // Handles #2 + // + // Since the saveTimer uses the unsavedTime to calculate it's first fireDate, + // if a save is needed the timer will fire immediately. + + [self createSuspendedSaveTimer]; + [self updateAndResumeSaveTimer]; + } else { + // Handles #3 + // Handles #4 + // + // Since the saveTimer uses the unsavedTime to calculate it's first fireDate, + // if a save is needed the timer will fire immediately. + + [self updateAndResumeSaveTimer]; + } + } else if (_saveTimer) { + // Handles #1 + + [self destroySaveTimer]; + } + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } } -- (NSTimeInterval)maxAge -{ - // The design of this method is taken from the DDAbstractLogger implementation. - // For extensive documentation please refer to the DDAbstractLogger implementation. - - // Note: The internal implementation MUST access the colorsEnabled variable directly, - // This method is designed explicitly for external access. - // - // Using "self." syntax to go through this method will cause immediate deadlock. - // This is the intended result. Fix it by accessing the ivar directly. - // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. - - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); - - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - - __block NSTimeInterval result; - - dispatch_sync(globalLoggingQueue, ^{ - dispatch_sync(loggerQueue, ^{ - result = maxAge; - }); - }); - - return result; +- (NSTimeInterval)maxAge { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSTimeInterval result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = _maxAge; + }); + }); + + return result; } -- (void)setMaxAge:(NSTimeInterval)interval -{ - dispatch_block_t block = ^{ @autoreleasepool { - - // C99 recommended floating point comparison macro - // Read: isLessThanOrGreaterThan(floatA, floatB) - - if (/* maxAge != interval */ islessgreater(maxAge, interval)) - { - NSTimeInterval oldMaxAge = maxAge; - NSTimeInterval newMaxAge = interval; - - maxAge = interval; - - // There are several cases we need to handle here. - // - // 1. If the maxAge was previously enabled and it just got disabled, - // then we need to stop the deleteTimer. (And we might as well release it.) - // - // 2. If the maxAge was previously disabled and it just got enabled, - // then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.) - // - // 3. If the maxAge was increased, - // then we don't need to do anything. - // - // 4. If the maxAge was decreased, - // then we should do an immediate delete. - - BOOL shouldDeleteNow = NO; - - if (oldMaxAge > 0.0) - { - if (newMaxAge <= 0.0) - { - // Handles #1 - - [self destroyDeleteTimer]; - } - else if (oldMaxAge > newMaxAge) - { - // Handles #4 - shouldDeleteNow = YES; - } - } - else if (newMaxAge > 0.0) - { - // Handles #2 - shouldDeleteNow = YES; - } - - if (shouldDeleteNow) - { - [self performDelete]; - - if (deleteTimer) - [self updateDeleteTimer]; - else - [self createAndStartDeleteTimer]; - } - } - }}; - - // The design of the setter logic below is taken from the DDAbstractLogger implementation. - // For documentation please refer to the DDAbstractLogger implementation. - - if ([self isOnInternalLoggerQueue]) - { - block(); - } - else - { - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - - dispatch_async(globalLoggingQueue, ^{ - dispatch_async(loggerQueue, block); - }); - } +- (void)setMaxAge:(NSTimeInterval)interval { + dispatch_block_t block = ^{ + @autoreleasepool { + // C99 recommended floating point comparison macro + // Read: isLessThanOrGreaterThan(floatA, floatB) + + if (/* maxAge != interval */ islessgreater(_maxAge, interval)) { + NSTimeInterval oldMaxAge = _maxAge; + NSTimeInterval newMaxAge = interval; + + _maxAge = interval; + + // There are several cases we need to handle here. + // + // 1. If the maxAge was previously enabled and it just got disabled, + // then we need to stop the deleteTimer. (And we might as well release it.) + // + // 2. If the maxAge was previously disabled and it just got enabled, + // then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.) + // + // 3. If the maxAge was increased, + // then we don't need to do anything. + // + // 4. If the maxAge was decreased, + // then we should do an immediate delete. + + BOOL shouldDeleteNow = NO; + + if (oldMaxAge > 0.0) { + if (newMaxAge <= 0.0) { + // Handles #1 + + [self destroyDeleteTimer]; + } else if (oldMaxAge > newMaxAge) { + // Handles #4 + shouldDeleteNow = YES; + } + } else if (newMaxAge > 0.0) { + // Handles #2 + shouldDeleteNow = YES; + } + + if (shouldDeleteNow) { + [self performDelete]; + + if (_deleteTimer) { + [self updateDeleteTimer]; + } else { + [self createAndStartDeleteTimer]; + } + } + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } } -- (NSTimeInterval)deleteInterval -{ - // The design of this method is taken from the DDAbstractLogger implementation. - // For extensive documentation please refer to the DDAbstractLogger implementation. - - // Note: The internal implementation MUST access the colorsEnabled variable directly, - // This method is designed explicitly for external access. - // - // Using "self." syntax to go through this method will cause immediate deadlock. - // This is the intended result. Fix it by accessing the ivar directly. - // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. - - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); - - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - - __block NSTimeInterval result; - - dispatch_sync(globalLoggingQueue, ^{ - dispatch_sync(loggerQueue, ^{ - result = deleteInterval; - }); - }); - - return result; +- (NSTimeInterval)deleteInterval { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSTimeInterval result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = _deleteInterval; + }); + }); + + return result; } -- (void)setDeleteInterval:(NSTimeInterval)interval -{ - dispatch_block_t block = ^{ @autoreleasepool { - - // C99 recommended floating point comparison macro - // Read: isLessThanOrGreaterThan(floatA, floatB) - - if (/* deleteInterval != interval */ islessgreater(deleteInterval, interval)) - { - deleteInterval = interval; - - // There are several cases we need to handle here. - // - // 1. If the deleteInterval was previously enabled and it just got disabled, - // then we need to stop the deleteTimer. (And we might as well release it.) - // - // 2. If the deleteInterval was previously disabled and it just got enabled, - // then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.) - // - // 3. If the deleteInterval increased, then we need to reset the timer so that it fires at the later date. - // - // 4. If the deleteInterval decreased, then we need to reset the timer so that it fires at an earlier date. - // (Plus we might need to do an immediate delete.) - - if (deleteInterval > 0.0) - { - if (deleteTimer == NULL) - { - // Handles #2 - // - // Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate, - // if a delete is needed the timer will fire immediately. - - [self createAndStartDeleteTimer]; - } - else - { - // Handles #3 - // Handles #4 - // - // Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate, - // if a save is needed the timer will fire immediately. - - [self updateDeleteTimer]; - } - } - else if (deleteTimer) - { - // Handles #1 - - [self destroyDeleteTimer]; - } - } - }}; - - // The design of the setter logic below is taken from the DDAbstractLogger implementation. - // For documentation please refer to the DDAbstractLogger implementation. - - if ([self isOnInternalLoggerQueue]) - { - block(); - } - else - { - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - - dispatch_async(globalLoggingQueue, ^{ - dispatch_async(loggerQueue, block); - }); - } +- (void)setDeleteInterval:(NSTimeInterval)interval { + dispatch_block_t block = ^{ + @autoreleasepool { + // C99 recommended floating point comparison macro + // Read: isLessThanOrGreaterThan(floatA, floatB) + + if (/* deleteInterval != interval */ islessgreater(_deleteInterval, interval)) { + _deleteInterval = interval; + + // There are several cases we need to handle here. + // + // 1. If the deleteInterval was previously enabled and it just got disabled, + // then we need to stop the deleteTimer. (And we might as well release it.) + // + // 2. If the deleteInterval was previously disabled and it just got enabled, + // then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.) + // + // 3. If the deleteInterval increased, then we need to reset the timer so that it fires at the later date. + // + // 4. If the deleteInterval decreased, then we need to reset the timer so that it fires at an earlier date. + // (Plus we might need to do an immediate delete.) + + if (_deleteInterval > 0.0) { + if (_deleteTimer == NULL) { + // Handles #2 + // + // Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate, + // if a delete is needed the timer will fire immediately. + + [self createAndStartDeleteTimer]; + } else { + // Handles #3 + // Handles #4 + // + // Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate, + // if a save is needed the timer will fire immediately. + + [self updateDeleteTimer]; + } + } else if (_deleteTimer) { + // Handles #1 + + [self destroyDeleteTimer]; + } + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } } -- (BOOL)deleteOnEverySave -{ - // The design of this method is taken from the DDAbstractLogger implementation. - // For extensive documentation please refer to the DDAbstractLogger implementation. - - // Note: The internal implementation MUST access the colorsEnabled variable directly, - // This method is designed explicitly for external access. - // - // Using "self." syntax to go through this method will cause immediate deadlock. - // This is the intended result. Fix it by accessing the ivar directly. - // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. - - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); - - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - - __block BOOL result; - - dispatch_sync(globalLoggingQueue, ^{ - dispatch_sync(loggerQueue, ^{ - result = deleteOnEverySave; - }); - }); - - return result; +- (BOOL)deleteOnEverySave { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block BOOL result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = _deleteOnEverySave; + }); + }); + + return result; } -- (void)setDeleteOnEverySave:(BOOL)flag -{ - dispatch_block_t block = ^{ - - deleteOnEverySave = flag; - }; - - // The design of the setter logic below is taken from the DDAbstractLogger implementation. - // For documentation please refer to the DDAbstractLogger implementation. - - if ([self isOnInternalLoggerQueue]) - { - block(); - } - else - { - dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; - NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); - - dispatch_async(globalLoggingQueue, ^{ - dispatch_async(loggerQueue, block); - }); - } +- (void)setDeleteOnEverySave:(BOOL)flag { + dispatch_block_t block = ^{ + _deleteOnEverySave = flag; + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Public API //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)savePendingLogEntries -{ - dispatch_block_t block = ^{ @autoreleasepool { - - [self performSaveAndSuspendSaveTimer]; - }}; - - if ([self isOnInternalLoggerQueue]) - block(); - else - dispatch_async(loggerQueue, block); +- (void)savePendingLogEntries { + dispatch_block_t block = ^{ + @autoreleasepool { + [self performSaveAndSuspendSaveTimer]; + } + }; + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_async(self.loggerQueue, block); + } } -- (void)deleteOldLogEntries -{ - dispatch_block_t block = ^{ @autoreleasepool { - - [self performDelete]; - }}; - - if ([self isOnInternalLoggerQueue]) - block(); - else - dispatch_async(loggerQueue, block); +- (void)deleteOldLogEntries { + dispatch_block_t block = ^{ + @autoreleasepool { + [self performDelete]; + } + }; + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_async(self.loggerQueue, block); + } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark DDLogger //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)didAddLogger -{ - // If you override me be sure to invoke [super didAddLogger]; - - [self createSuspendedSaveTimer]; - - [self createAndStartDeleteTimer]; +- (void)didAddLogger { + // If you override me be sure to invoke [super didAddLogger]; + + [self createSuspendedSaveTimer]; + + [self createAndStartDeleteTimer]; } -- (void)willRemoveLogger -{ - // If you override me be sure to invoke [super willRemoveLogger]; - - [self performSaveAndSuspendSaveTimer]; - - [self destroySaveTimer]; - [self destroyDeleteTimer]; +- (void)willRemoveLogger { + // If you override me be sure to invoke [super willRemoveLogger]; + + [self performSaveAndSuspendSaveTimer]; + + [self destroySaveTimer]; + [self destroyDeleteTimer]; } -- (void)logMessage:(DDLogMessage *)logMessage -{ - if ([self db_log:logMessage]) - { - BOOL firstUnsavedEntry = (++unsavedCount == 1); - - if ((unsavedCount >= saveThreshold) && (saveThreshold > 0)) - { - [self performSaveAndSuspendSaveTimer]; - } - else if (firstUnsavedEntry) - { - unsavedTime = dispatch_time(DISPATCH_TIME_NOW, 0); - [self updateAndResumeSaveTimer]; - } - } +- (void)logMessage:(DDLogMessage *)logMessage { + if ([self db_log:logMessage]) { + BOOL firstUnsavedEntry = (++_unsavedCount == 1); + + if ((_unsavedCount >= _saveThreshold) && (_saveThreshold > 0)) { + [self performSaveAndSuspendSaveTimer]; + } else if (firstUnsavedEntry) { + _unsavedTime = dispatch_time(DISPATCH_TIME_NOW, 0); + [self updateAndResumeSaveTimer]; + } + } } -- (void)flush -{ - // This method is invoked by DDLog's flushLog method. - // - // It is called automatically when the application quits, - // or if the developer invokes DDLog's flushLog method prior to crashing or something. - - [self performSaveAndSuspendSaveTimer]; +- (void)flush { + // This method is invoked by DDLog's flushLog method. + // + // It is called automatically when the application quits, + // or if the developer invokes DDLog's flushLog method prior to crashing or something. + + [self performSaveAndSuspendSaveTimer]; } @end diff --git a/Vendor/CocoaLumberjack/DDAssertMacros.h b/Vendor/CocoaLumberjack/DDAssertMacros.h new file mode 100644 index 00000000..7678a9c1 --- /dev/null +++ b/Vendor/CocoaLumberjack/DDAssertMacros.h @@ -0,0 +1,26 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2016, 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. + +/** + * NSAsset replacement that will output a log message even when assertions are disabled. + **/ +#define DDAssert(condition, frmt, ...) \ + if (!(condition)) { \ + NSString *description = [NSString stringWithFormat:frmt, ## __VA_ARGS__]; \ + DDLogError(@"%@", description); \ + NSAssert(NO, description); \ + } +#define DDAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %s", #condition) + diff --git a/Vendor/CocoaLumberjack/DDFileLogger.h b/Vendor/CocoaLumberjack/DDFileLogger.h index 5af63764..37300c7b 100644 --- a/Vendor/CocoaLumberjack/DDFileLogger.h +++ b/Vendor/CocoaLumberjack/DDFileLogger.h @@ -1,61 +1,74 @@ -#import +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2016, 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 + #import "DDLog.h" @class DDLogFileInfo; /** - * Welcome to Cocoa Lumberjack! - * - * The project page has a wealth of documentation if you have any questions. - * https://github.com/robbiehanson/CocoaLumberjack - * - * If you're new to the project you may wish to read the "Getting Started" wiki. - * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted - * - * * This class provides a logger to write log statements to a file. -**/ + **/ // Default configuration and safety/sanity values. -// -// maximumFileSize -> DEFAULT_LOG_MAX_FILE_SIZE -// rollingFrequency -> DEFAULT_LOG_ROLLING_FREQUENCY -// maximumNumberOfLogFiles -> DEFAULT_LOG_MAX_NUM_LOG_FILES -// +// +// maximumFileSize -> kDDDefaultLogMaxFileSize +// rollingFrequency -> kDDDefaultLogRollingFrequency +// maximumNumberOfLogFiles -> kDDDefaultLogMaxNumLogFiles +// logFilesDiskQuota -> kDDDefaultLogFilesDiskQuota +// // You should carefully consider the proper configuration values for your application. -#define DEFAULT_LOG_MAX_FILE_SIZE (1024 * 1024) // 1 MB -#define DEFAULT_LOG_ROLLING_FREQUENCY (60 * 60 * 24) // 24 Hours -#define DEFAULT_LOG_MAX_NUM_LOG_FILES (5) // 5 Files +extern unsigned long long const kDDDefaultLogMaxFileSize; +extern NSTimeInterval const kDDDefaultLogRollingFrequency; +extern NSUInteger const kDDDefaultLogMaxNumLogFiles; +extern unsigned long long const kDDDefaultLogFilesDiskQuota; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// The LogFileManager protocol is designed to allow you to control all aspects of your log files. -// -// The primary purpose of this is to allow you to do something with the log files after they have been rolled. -// Perhaps you want to compress them to save disk space. -// Perhaps you want to upload them to an FTP server. -// Perhaps you want to run some analytics on the file. -// -// A default LogFileManager is, of course, provided. -// The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property. -// -// This protocol provides various methods to fetch the list of log files. -// -// There are two variants: sorted and unsorted. -// If sorting is not necessary, the unsorted variant is obviously faster. -// The sorted variant will return an array sorted by when the log files were created, -// with the most recently created log file at index 0, and the oldest log file at the end of the array. -// -// You can fetch only the log file paths (full path including name), log file names (name only), -// or an array of DDLogFileInfo objects. -// The DDLogFileInfo class is documented below, and provides a handy wrapper that -// gives you easy access to various file attributes such as the creation date or the file size. - +/** + * The LogFileManager protocol is designed to allow you to control all aspects of your log files. + * + * The primary purpose of this is to allow you to do something with the log files after they have been rolled. + * Perhaps you want to compress them to save disk space. + * Perhaps you want to upload them to an FTP server. + * Perhaps you want to run some analytics on the file. + * + * A default LogFileManager is, of course, provided. + * The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property. + * + * This protocol provides various methods to fetch the list of log files. + * + * There are two variants: sorted and unsorted. + * If sorting is not necessary, the unsorted variant is obviously faster. + * The sorted variant will return an array sorted by when the log files were created, + * with the most recently created log file at index 0, and the oldest log file at the end of the array. + * + * You can fetch only the log file paths (full path including name), log file names (name only), + * or an array of `DDLogFileInfo` objects. + * The `DDLogFileInfo` class is documented below, and provides a handy wrapper that + * gives you easy access to various file attributes such as the creation date or the file size. + */ @protocol DDLogFileManager @required @@ -66,33 +79,86 @@ * For example, if this property is set to 3, * then the LogFileManager will only keep 3 archived log files (plus the current active log file) on disk. * Once the active log file is rolled/archived, then the oldest of the existing 3 rolled/archived log files is deleted. - * - * You may optionally disable deleting old/rolled/archived log files by setting this property to zero. -**/ -@property (readwrite, assign) NSUInteger maximumNumberOfLogFiles; + * + * You may optionally disable this option by setting it to zero. + **/ +@property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles; + +/** + * The maximum space that logs can take. On rolling logfile all old logfiles that exceed logFilesDiskQuota will + * be deleted. + * + * You may optionally disable this option by setting it to zero. + **/ +@property (readwrite, assign, atomic) unsigned long long logFilesDiskQuota; // Public methods -- (NSString *)logsDirectory; +/** + * Returns the logs directory (path) + */ +@property (nonatomic, readonly, copy) NSString *logsDirectory; + +/** + * Returns an array of `NSString` objects, + * each of which is the filePath to an existing log file on disk. + **/ +@property (nonatomic, readonly, strong) NSArray *unsortedLogFilePaths; + +/** + * Returns an array of `NSString` objects, + * each of which is the fileName of an existing log file on disk. + **/ +@property (nonatomic, readonly, strong) NSArray *unsortedLogFileNames; + +/** + * Returns an array of `DDLogFileInfo` objects, + * each representing an existing log file on disk, + * and containing important information about the log file such as it's modification date and size. + **/ +@property (nonatomic, readonly, strong) NSArray *unsortedLogFileInfos; + +/** + * Just like the `unsortedLogFilePaths` method, but sorts the array. + * The items in the array are sorted by creation date. + * The first item in the array will be the most recently created log file. + **/ +@property (nonatomic, readonly, strong) NSArray *sortedLogFilePaths; -- (NSArray *)unsortedLogFilePaths; -- (NSArray *)unsortedLogFileNames; -- (NSArray *)unsortedLogFileInfos; +/** + * Just like the `unsortedLogFileNames` method, but sorts the array. + * The items in the array are sorted by creation date. + * The first item in the array will be the most recently created log file. + **/ +@property (nonatomic, readonly, strong) NSArray *sortedLogFileNames; -- (NSArray *)sortedLogFilePaths; -- (NSArray *)sortedLogFileNames; -- (NSArray *)sortedLogFileInfos; +/** + * Just like the `unsortedLogFileInfos` method, but sorts the array. + * The items in the array are sorted by creation date. + * The first item in the array will be the most recently created log file. + **/ +@property (nonatomic, readonly, strong) NSArray *sortedLogFileInfos; // Private methods (only to be used by DDFileLogger) +/** + * Generates a new unique log file path, and creates the corresponding log file. + **/ - (NSString *)createNewLogFile; @optional // Notifications from DDFileLogger -- (void)didArchiveLogFile:(NSString *)logFilePath; -- (void)didRollAndArchiveLogFile:(NSString *)logFilePath; +/** + * Called when a log file was archieved + */ +- (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:)); + +/** + * Called when the roll action was executed and the log was archieved + */ +- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:)); @end @@ -102,41 +168,102 @@ /** * 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/. - * On iPhone, this is in ~/Library/Caches/Logs. - * - * Log files are named "log-.txt", - * where uuid is a 6 character hexadecimal consisting of the set [0123456789ABCDEF]. - * - * Archived log files are automatically deleted according to the maximumNumberOfLogFiles property. -**/ + * On Mac, this is in `~/Library/Logs/`. + * On iPhone, this is in `~/Library/Caches/Logs`. + * + * Log files are named `"