init
This commit is contained in:
57
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/CLI/CLIColor.m
generated
Normal file
57
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/CLI/CLIColor.m
generated
Normal file
@@ -0,0 +1,57 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
|
||||
#import <CocoaLumberjack/CLIColor.h>
|
||||
|
||||
@interface CLIColor () {
|
||||
CGFloat _red, _green, _blue, _alpha;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation CLIColor
|
||||
|
||||
+ (instancetype)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha {
|
||||
CLIColor *color = [CLIColor new];
|
||||
color->_red = red;
|
||||
color->_green = green;
|
||||
color->_blue = blue;
|
||||
color->_alpha = alpha;
|
||||
return color;
|
||||
}
|
||||
|
||||
- (void)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha {
|
||||
if (red) {
|
||||
*red = _red;
|
||||
}
|
||||
if (green) {
|
||||
*green = _green;
|
||||
}
|
||||
if (blue) {
|
||||
*blue = _blue;
|
||||
}
|
||||
if (alpha) {
|
||||
*alpha = _alpha;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
205
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogCapture.m
generated
Normal file
205
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogCapture.m
generated
Normal file
@@ -0,0 +1,205 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <TargetConditionals.h>
|
||||
|
||||
#if !TARGET_OS_WATCH
|
||||
|
||||
#include <asl.h>
|
||||
#include <notify.h>
|
||||
#include <notify_keys.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#import <CocoaLumberjack/DDASLLogCapture.h>
|
||||
|
||||
// Disable legacy macros
|
||||
#ifndef DD_LEGACY_MACROS
|
||||
#define DD_LEGACY_MACROS 0
|
||||
#endif
|
||||
|
||||
static BOOL _cancel = YES;
|
||||
static DDLogLevel _captureLevel = DDLogLevelVerbose;
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
|
||||
@implementation DDASLLogCapture
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
+ (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 || (defined(TARGET_SIMULATOR) && TARGET_SIMULATOR)
|
||||
int processId = [[NSProcessInfo processInfo] processIdentifier];
|
||||
char pid[16];
|
||||
snprintf(pid, sizeof(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;
|
||||
|
||||
DDLogFlag 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:nil
|
||||
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 = (unsigned long long)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 = asl_next(response)))
|
||||
{
|
||||
[self aslMessageReceived:msg];
|
||||
|
||||
// Keep track of which messages we've seen.
|
||||
lastSeenID = (unsigned long long)atoll(asl_get(msg, ASL_KEY_MSG_ID));
|
||||
}
|
||||
asl_release(response);
|
||||
asl_free(query);
|
||||
|
||||
if (_cancel) {
|
||||
notify_cancel(token);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
133
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogger.m
generated
Normal file
133
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogger.m
generated
Normal file
@@ -0,0 +1,133 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <TargetConditionals.h>
|
||||
|
||||
#if !TARGET_OS_WATCH
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
#import <asl.h>
|
||||
|
||||
#import <CocoaLumberjack/DDASLLogger.h>
|
||||
|
||||
const char* const kDDASLKeyDDLog = "DDLog";
|
||||
const char* const kDDASLDDLogValue = "1";
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
static DDASLLogger *sharedInstance;
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
@interface DDASLLogger () {
|
||||
aslclient _client;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
|
||||
@implementation DDASLLogger
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static dispatch_once_t DDASLLoggerOnceToken;
|
||||
|
||||
dispatch_once(&DDASLLoggerOnceToken, ^{
|
||||
sharedInstance = [[[self class] alloc] init];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (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;
|
||||
}
|
||||
|
||||
- (DDLoggerName)loggerName {
|
||||
return DDLoggerNameASL;
|
||||
}
|
||||
|
||||
- (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
|
||||
size_t l = (size_t)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?
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
683
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDAbstractDatabaseLogger.m
generated
Normal file
683
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDAbstractDatabaseLogger.m
generated
Normal file
@@ -0,0 +1,683 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
#import <CocoaLumberjack/DDAbstractDatabaseLogger.h>
|
||||
|
||||
@interface DDAbstractDatabaseLogger ()
|
||||
|
||||
- (void)destroySaveTimer;
|
||||
- (void)updateAndResumeSaveTimer;
|
||||
- (void)createSuspendedSaveTimer;
|
||||
- (void)destroyDeleteTimer;
|
||||
- (void)updateDeleteTimer;
|
||||
- (void)createAndStartDeleteTimer;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation DDAbstractDatabaseLogger
|
||||
|
||||
- (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];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Override Me
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (BOOL)db_log:(__unused 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_delete {
|
||||
// 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 != NULL && _saveTimerSuspended == 0) {
|
||||
dispatch_suspend(_saveTimer);
|
||||
_saveTimerSuspended = 1;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)performDelete {
|
||||
if (_maxAge > 0.0) {
|
||||
[self db_delete];
|
||||
|
||||
_lastDeleteTime = dispatch_time(DISPATCH_TIME_NOW, 0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Timers
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)destroySaveTimer {
|
||||
if (_saveTimer != NULL) {
|
||||
dispatch_source_cancel(_saveTimer);
|
||||
|
||||
// Must activate a timer before releasing it (or it will crash)
|
||||
if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) {
|
||||
if (_saveTimerSuspended < 0) {
|
||||
dispatch_activate(_saveTimer);
|
||||
} else if (_saveTimerSuspended > 0) {
|
||||
dispatch_resume(_saveTimer);
|
||||
}
|
||||
} else {
|
||||
if (_saveTimerSuspended != 0) {
|
||||
dispatch_resume(_saveTimer);
|
||||
}
|
||||
}
|
||||
|
||||
#if !OS_OBJECT_USE_OBJC
|
||||
dispatch_release(_saveTimer);
|
||||
#endif
|
||||
_saveTimer = NULL;
|
||||
_saveTimerSuspended = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateAndResumeSaveTimer {
|
||||
if ((_saveTimer != NULL) && (_saveInterval > 0.0) && (_unsavedTime > 0)) {
|
||||
uint64_t interval = (uint64_t)(_saveInterval * (NSTimeInterval) NSEC_PER_SEC);
|
||||
dispatch_time_t startTime = dispatch_time(_unsavedTime, (int64_t)interval);
|
||||
|
||||
dispatch_source_set_timer(_saveTimer, startTime, interval, 1ull * NSEC_PER_SEC);
|
||||
|
||||
if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) {
|
||||
if (_saveTimerSuspended < 0) {
|
||||
dispatch_activate(_saveTimer);
|
||||
_saveTimerSuspended = 0;
|
||||
} else if (_saveTimerSuspended > 0) {
|
||||
dispatch_resume(_saveTimer);
|
||||
_saveTimerSuspended = 0;
|
||||
}
|
||||
} else {
|
||||
if (_saveTimerSuspended != 0) {
|
||||
dispatch_resume(_saveTimer);
|
||||
_saveTimerSuspended = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (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 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)destroyDeleteTimer {
|
||||
if (_deleteTimer != NULL) {
|
||||
dispatch_source_cancel(_deleteTimer);
|
||||
#if !OS_OBJECT_USE_OBJC
|
||||
dispatch_release(_deleteTimer);
|
||||
#endif
|
||||
_deleteTimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateDeleteTimer {
|
||||
if ((_deleteTimer != NULL) && (_deleteInterval > 0.0) && (_maxAge > 0.0)) {
|
||||
int64_t interval = (int64_t)(_deleteInterval * (NSTimeInterval) 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, (uint64_t)interval, 1ull * NSEC_PER_SEC);
|
||||
}
|
||||
}
|
||||
|
||||
- (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];
|
||||
|
||||
// We are sure that -updateDeleteTimer did call dispatch_source_set_timer()
|
||||
// since it has the same guards on _deleteInterval and _maxAge
|
||||
if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *))
|
||||
dispatch_activate(_deleteTimer);
|
||||
else
|
||||
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(self.loggerQueue, ^{
|
||||
result = self->_saveThreshold;
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setSaveThreshold:(NSUInteger)threshold {
|
||||
dispatch_block_t block = ^{
|
||||
@autoreleasepool {
|
||||
if (self->_saveThreshold != threshold) {
|
||||
self->_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 ((self->_unsavedCount >= self->_saveThreshold) && (self->_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(self.loggerQueue, ^{
|
||||
result = self->_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(self->_saveInterval, interval)) {
|
||||
self->_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 (self->_saveInterval > 0.0) {
|
||||
if (self->_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 (self->_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(self.loggerQueue, ^{
|
||||
result = self->_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(self->_maxAge, interval)) {
|
||||
NSTimeInterval oldMaxAge = self->_maxAge;
|
||||
NSTimeInterval newMaxAge = interval;
|
||||
|
||||
self->_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 (self->_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(self.loggerQueue, ^{
|
||||
result = self->_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(self->_deleteInterval, interval)) {
|
||||
self->_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 (self->_deleteInterval > 0.0) {
|
||||
if (self->_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 (self->_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(self.loggerQueue, ^{
|
||||
result = self->_deleteOnEverySave;
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setDeleteOnEverySave:(BOOL)flag {
|
||||
dispatch_block_t block = ^{
|
||||
self->_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(self.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)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)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
|
||||
31
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger+Internal.h
generated
Normal file
31
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger+Internal.h
generated
Normal file
@@ -0,0 +1,31 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDFileLogger.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DDFileLogger (Internal)
|
||||
|
||||
- (void)logData:(NSData *)data;
|
||||
|
||||
// Will assert if used outside logger's queue.
|
||||
- (void)lt_logData:(NSData *)data;
|
||||
|
||||
- (nullable NSData *)lt_dataForMessage:(DDLogMessage *)message;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
1820
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger.m
generated
Normal file
1820
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger.m
generated
Normal file
File diff suppressed because it is too large
Load Diff
1308
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLog.m
generated
Normal file
1308
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLog.m
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLoggerNames.m
generated
Normal file
21
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLoggerNames.m
generated
Normal file
@@ -0,0 +1,21 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDLoggerNames.h>
|
||||
|
||||
DDLoggerName const DDLoggerNameASL = @"cocoa.lumberjack.aslLogger";
|
||||
DDLoggerName const DDLoggerNameTTY = @"cocoa.lumberjack.ttyLogger";
|
||||
DDLoggerName const DDLoggerNameOS = @"cocoa.lumberjack.osLogger";
|
||||
DDLoggerName const DDLoggerNameFile = @"cocoa.lumberjack.fileLogger";
|
||||
119
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDOSLogger.m
generated
Normal file
119
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDOSLogger.m
generated
Normal file
@@ -0,0 +1,119 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <os/log.h>
|
||||
|
||||
#import <CocoaLumberjack/DDOSLogger.h>
|
||||
|
||||
@interface DDOSLogger () {
|
||||
NSString *_subsystem;
|
||||
NSString *_category;
|
||||
}
|
||||
|
||||
@property (copy, nonatomic, readonly, nullable) NSString *subsystem;
|
||||
@property (copy, nonatomic, readonly, nullable) NSString *category;
|
||||
@property (strong, nonatomic, readwrite, nonnull) os_log_t logger;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DDOSLogger
|
||||
|
||||
@synthesize subsystem = _subsystem;
|
||||
@synthesize category = _category;
|
||||
|
||||
#pragma mark - Initialization
|
||||
|
||||
/**
|
||||
* Assertion
|
||||
* Swift: (String, String)?
|
||||
*/
|
||||
- (instancetype)initWithSubsystem:(NSString *)subsystem category:(NSString *)category {
|
||||
NSAssert((subsystem == nil) == (category == nil), @"Either both subsystem and category or neither should be nil.");
|
||||
if (self = [super init]) {
|
||||
_subsystem = [subsystem copy];
|
||||
_category = [category copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
|
||||
static DDOSLogger *sharedInstance;
|
||||
|
||||
- (instancetype)init {
|
||||
return [self initWithSubsystem:nil category:nil];
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static dispatch_once_t DDOSLoggerOnceToken;
|
||||
|
||||
dispatch_once(&DDOSLoggerOnceToken, ^{
|
||||
sharedInstance = [[[self class] alloc] init];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
#pragma mark - os_log
|
||||
|
||||
- (os_log_t)getLogger {
|
||||
if (self.subsystem == nil || self.category == nil) {
|
||||
return OS_LOG_DEFAULT;
|
||||
}
|
||||
return os_log_create(self.subsystem.UTF8String, self.category.UTF8String);
|
||||
}
|
||||
|
||||
- (os_log_t)logger {
|
||||
if (_logger == nil) {
|
||||
_logger = [self getLogger];
|
||||
}
|
||||
return _logger;
|
||||
}
|
||||
|
||||
#pragma mark - DDLogger
|
||||
|
||||
- (DDLoggerName)loggerName {
|
||||
return DDLoggerNameOS;
|
||||
}
|
||||
|
||||
- (void)logMessage:(DDLogMessage *)logMessage {
|
||||
// Skip captured log messages
|
||||
if ([logMessage->_fileName isEqualToString:@"DDASLLogCapture"]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) {
|
||||
NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
|
||||
if (message != nil) {
|
||||
const char *msg = [message UTF8String];
|
||||
__auto_type logger = [self logger];
|
||||
switch (logMessage->_flag) {
|
||||
case DDLogFlagError :
|
||||
os_log_error(logger, "%{public}s", msg);
|
||||
break;
|
||||
case DDLogFlagWarning:
|
||||
case DDLogFlagInfo :
|
||||
os_log_info(logger, "%{public}s", msg);
|
||||
break;
|
||||
case DDLogFlagDebug :
|
||||
case DDLogFlagVerbose:
|
||||
default :
|
||||
os_log_debug(logger, "%{public}s", msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
1494
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDTTYLogger.m
generated
Normal file
1494
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDTTYLogger.m
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDContextFilterLogFormatter+Deprecated.h>
|
||||
|
||||
@implementation DDContextAllowlistFilterLogFormatter (Deprecated)
|
||||
|
||||
- (void)addToWhitelist:(NSInteger)loggingContext {
|
||||
[self addToAllowlist:loggingContext];
|
||||
}
|
||||
|
||||
- (void)removeFromWhitelist:(NSInteger)loggingContext {
|
||||
[self removeFromAllowlist:loggingContext];
|
||||
}
|
||||
|
||||
- (NSArray *)whitelist {
|
||||
return [self allowlist];
|
||||
}
|
||||
|
||||
- (BOOL)isOnWhitelist:(NSInteger)loggingContext {
|
||||
return [self isOnAllowlist:loggingContext];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation DDContextDenylistFilterLogFormatter (Deprecated)
|
||||
|
||||
- (void)addToBlacklist:(NSInteger)loggingContext {
|
||||
[self addToDenylist:loggingContext];
|
||||
}
|
||||
|
||||
- (void)removeFromBlacklist:(NSInteger)loggingContext {
|
||||
[self removeFromDenylist:loggingContext];
|
||||
}
|
||||
|
||||
- (NSArray *)blacklist {
|
||||
return [self denylist];
|
||||
}
|
||||
|
||||
- (BOOL)isOnBlacklist:(NSInteger)loggingContext {
|
||||
return [self isOnDenylist:loggingContext];
|
||||
}
|
||||
|
||||
@end
|
||||
185
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDContextFilterLogFormatter.m
generated
Executable file
185
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDContextFilterLogFormatter.m
generated
Executable file
@@ -0,0 +1,185 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
#import <pthread/pthread.h>
|
||||
|
||||
#import <CocoaLumberjack/DDContextFilterLogFormatter.h>
|
||||
|
||||
@interface DDLoggingContextSet : NSObject
|
||||
|
||||
@property (readonly, copy, nonnull) NSArray *currentSet;
|
||||
|
||||
- (void)addToSet:(NSInteger)loggingContext;
|
||||
- (void)removeFromSet:(NSInteger)loggingContext;
|
||||
|
||||
- (BOOL)isInSet:(NSInteger)loggingContext;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDContextAllowlistFilterLogFormatter () {
|
||||
DDLoggingContextSet *_contextSet;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation DDContextAllowlistFilterLogFormatter
|
||||
|
||||
- (instancetype)init {
|
||||
if ((self = [super init])) {
|
||||
_contextSet = [[DDLoggingContextSet alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addToAllowlist:(NSInteger)loggingContext {
|
||||
[_contextSet addToSet:loggingContext];
|
||||
}
|
||||
|
||||
- (void)removeFromAllowlist:(NSInteger)loggingContext {
|
||||
[_contextSet removeFromSet:loggingContext];
|
||||
}
|
||||
|
||||
- (NSArray *)allowlist {
|
||||
return [_contextSet currentSet];
|
||||
}
|
||||
|
||||
- (BOOL)isOnAllowlist:(NSInteger)loggingContext {
|
||||
return [_contextSet isInSet:loggingContext];
|
||||
}
|
||||
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
|
||||
if ([self isOnAllowlist:logMessage->_context]) {
|
||||
return logMessage->_message;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface DDContextDenylistFilterLogFormatter () {
|
||||
DDLoggingContextSet *_contextSet;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation DDContextDenylistFilterLogFormatter
|
||||
|
||||
- (instancetype)init {
|
||||
if ((self = [super init])) {
|
||||
_contextSet = [[DDLoggingContextSet alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addToDenylist:(NSInteger)loggingContext {
|
||||
[_contextSet addToSet:loggingContext];
|
||||
}
|
||||
|
||||
- (void)removeFromDenylist:(NSInteger)loggingContext {
|
||||
[_contextSet removeFromSet:loggingContext];
|
||||
}
|
||||
|
||||
- (NSArray *)denylist {
|
||||
return [_contextSet currentSet];
|
||||
}
|
||||
|
||||
- (BOOL)isOnDenylist:(NSInteger)loggingContext {
|
||||
return [_contextSet isInSet:loggingContext];
|
||||
}
|
||||
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
|
||||
if ([self isOnDenylist:logMessage->_context]) {
|
||||
return nil;
|
||||
} else {
|
||||
return logMessage->_message;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDLoggingContextSet () {
|
||||
pthread_mutex_t _mutex;
|
||||
NSMutableSet *_set;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation DDLoggingContextSet
|
||||
|
||||
- (instancetype)init {
|
||||
if ((self = [super init])) {
|
||||
_set = [[NSMutableSet alloc] init];
|
||||
pthread_mutex_init(&_mutex, NULL);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
}
|
||||
|
||||
- (void)addToSet:(NSInteger)loggingContext {
|
||||
pthread_mutex_lock(&_mutex);
|
||||
{
|
||||
[_set addObject:@(loggingContext)];
|
||||
}
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
|
||||
- (void)removeFromSet:(NSInteger)loggingContext {
|
||||
pthread_mutex_lock(&_mutex);
|
||||
{
|
||||
[_set removeObject:@(loggingContext)];
|
||||
}
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
|
||||
- (NSArray *)currentSet {
|
||||
NSArray *result = nil;
|
||||
|
||||
pthread_mutex_lock(&_mutex);
|
||||
{
|
||||
result = [_set allObjects];
|
||||
}
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (BOOL)isInSet:(NSInteger)loggingContext {
|
||||
BOOL result = NO;
|
||||
|
||||
pthread_mutex_lock(&_mutex);
|
||||
{
|
||||
result = [_set containsObject:@(loggingContext)];
|
||||
}
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
269
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDDispatchQueueLogFormatter.m
generated
Executable file
269
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDDispatchQueueLogFormatter.m
generated
Executable file
@@ -0,0 +1,269 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
#import <pthread/pthread.h>
|
||||
#import <stdatomic.h>
|
||||
#import <sys/qos.h>
|
||||
|
||||
#import <CocoaLumberjack/DDDispatchQueueLogFormatter.h>
|
||||
|
||||
DDQualityOfServiceName const DDQualityOfServiceUserInteractive = @"UI";
|
||||
DDQualityOfServiceName const DDQualityOfServiceUserInitiated = @"IN";
|
||||
DDQualityOfServiceName const DDQualityOfServiceDefault = @"DF";
|
||||
DDQualityOfServiceName const DDQualityOfServiceUtility = @"UT";
|
||||
DDQualityOfServiceName const DDQualityOfServiceBackground = @"BG";
|
||||
DDQualityOfServiceName const DDQualityOfServiceUnspecified = @"UN";
|
||||
|
||||
static DDQualityOfServiceName _qos_name(NSUInteger qos) {
|
||||
switch ((qos_class_t) qos) {
|
||||
case QOS_CLASS_USER_INTERACTIVE: return DDQualityOfServiceUserInteractive;
|
||||
case QOS_CLASS_USER_INITIATED: return DDQualityOfServiceUserInitiated;
|
||||
case QOS_CLASS_DEFAULT: return DDQualityOfServiceDefault;
|
||||
case QOS_CLASS_UTILITY: return DDQualityOfServiceUtility;
|
||||
case QOS_CLASS_BACKGROUND: return DDQualityOfServiceBackground;
|
||||
default: return DDQualityOfServiceUnspecified;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - DDDispatchQueueLogFormatter
|
||||
|
||||
@interface DDDispatchQueueLogFormatter () {
|
||||
NSDateFormatter *_dateFormatter; // Use [self stringFromDate]
|
||||
|
||||
pthread_mutex_t _mutex;
|
||||
|
||||
NSUInteger _minQueueLength; // _prefix == Only access via atomic property
|
||||
NSUInteger _maxQueueLength; // _prefix == Only access via atomic property
|
||||
NSMutableDictionary *_replacements; // _prefix == Only access from within spinlock
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation DDDispatchQueueLogFormatter
|
||||
|
||||
- (instancetype)init {
|
||||
if ((self = [super init])) {
|
||||
_dateFormatter = [self createDateFormatter];
|
||||
|
||||
pthread_mutex_init(&_mutex, NULL);
|
||||
_replacements = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// Set default replacements:
|
||||
_replacements[@"com.apple.main-thread"] = @"main";
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithMode:(DDDispatchQueueLogFormatterMode)mode {
|
||||
return [self init];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Configuration
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@synthesize minQueueLength = _minQueueLength;
|
||||
@synthesize maxQueueLength = _maxQueueLength;
|
||||
|
||||
- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel {
|
||||
NSString *result = nil;
|
||||
|
||||
pthread_mutex_lock(&_mutex);
|
||||
{
|
||||
result = _replacements[longLabel];
|
||||
}
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel {
|
||||
pthread_mutex_lock(&_mutex);
|
||||
{
|
||||
if (shortLabel) {
|
||||
_replacements[longLabel] = shortLabel;
|
||||
} else {
|
||||
[_replacements removeObjectForKey:longLabel];
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark DDLogFormatter
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (NSDateFormatter *)createDateFormatter {
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
[self configureDateFormatter:formatter];
|
||||
return formatter;
|
||||
}
|
||||
|
||||
- (void)configureDateFormatter:(NSDateFormatter *)dateFormatter {
|
||||
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
|
||||
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss:SSS"];
|
||||
[dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
|
||||
[dateFormatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]];
|
||||
}
|
||||
|
||||
- (NSString *)stringFromDate:(NSDate *)date {
|
||||
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.
|
||||
|
||||
NSArray *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",
|
||||
@"com.apple.root.default-qos.overcommit"
|
||||
];
|
||||
|
||||
for (NSString * name in names) {
|
||||
if ([logMessage->_queueLabel isEqualToString:name]) {
|
||||
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;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&_mutex);
|
||||
{
|
||||
abrvLabel = _replacements[fullLabel];
|
||||
}
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
|
||||
if (abrvLabel) {
|
||||
queueThreadLabel = abrvLabel;
|
||||
} else {
|
||||
queueThreadLabel = fullLabel;
|
||||
}
|
||||
} else {
|
||||
queueThreadLabel = logMessage->_threadID;
|
||||
}
|
||||
|
||||
// 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:@"%@ [%@ (QOS:%@)] %@", timestamp, queueThreadLabel, _qos_name(logMessage->_qos), logMessage->_message];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - DDAtomicCounter
|
||||
|
||||
@interface DDAtomicCounter() {
|
||||
atomic_int_fast32_t _value;
|
||||
}
|
||||
@end
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
|
||||
@implementation DDAtomicCounter
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
- (instancetype)initWithDefaultValue:(int32_t)defaultValue {
|
||||
if ((self = [super init])) {
|
||||
atomic_init(&_value, defaultValue);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (int32_t)value {
|
||||
return atomic_load_explicit(&_value, memory_order_relaxed);
|
||||
}
|
||||
|
||||
- (int32_t)increment {
|
||||
int32_t old = atomic_fetch_add_explicit(&_value, 1, memory_order_relaxed);
|
||||
return (old + 1);
|
||||
}
|
||||
|
||||
- (int32_t)decrement {
|
||||
int32_t old = atomic_fetch_sub_explicit(&_value, 1, memory_order_relaxed);
|
||||
return (old - 1);
|
||||
}
|
||||
|
||||
@end
|
||||
204
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDFileLogger+Buffering.m
generated
Normal file
204
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDFileLogger+Buffering.m
generated
Normal file
@@ -0,0 +1,204 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <sys/mount.h>
|
||||
|
||||
#import <CocoaLumberjack/DDFileLogger+Buffering.h>
|
||||
#import "../DDFileLogger+Internal.h"
|
||||
|
||||
static const NSUInteger kDDDefaultBufferSize = 4096; // 4 kB, block f_bsize on iphone7
|
||||
static const NSUInteger kDDMaxBufferSize = 1048576; // ~1 mB, f_iosize on iphone7
|
||||
|
||||
// Reads attributes from base file system to determine buffer size.
|
||||
// see statfs in sys/mount.h for descriptions of f_iosize and f_bsize.
|
||||
// f_bsize == "default", and f_iosize == "max"
|
||||
static inline NSUInteger p_DDGetDefaultBufferSizeBytesMax(const BOOL max) {
|
||||
struct statfs *mountedFileSystems = NULL;
|
||||
int count = getmntinfo(&mountedFileSystems, 0);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
struct statfs mounted = mountedFileSystems[i];
|
||||
const char *name = mounted.f_mntonname;
|
||||
|
||||
// We can use 2 as max here, since any length > 1 will fail the if-statement.
|
||||
if (strnlen(name, 2) == 1 && *name == '/') {
|
||||
return max ? (NSUInteger)mounted.f_iosize : (NSUInteger)mounted.f_bsize;
|
||||
}
|
||||
}
|
||||
|
||||
return max ? kDDMaxBufferSize : kDDDefaultBufferSize;
|
||||
}
|
||||
|
||||
static NSUInteger DDGetMaxBufferSizeBytes() {
|
||||
static NSUInteger maxBufferSize = 0;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
maxBufferSize = p_DDGetDefaultBufferSizeBytesMax(YES);
|
||||
});
|
||||
return maxBufferSize;
|
||||
}
|
||||
|
||||
static NSUInteger DDGetDefaultBufferSizeBytes() {
|
||||
static NSUInteger defaultBufferSize = 0;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
defaultBufferSize = p_DDGetDefaultBufferSizeBytesMax(NO);
|
||||
});
|
||||
return defaultBufferSize;
|
||||
}
|
||||
|
||||
@interface DDBufferedProxy : NSProxy
|
||||
|
||||
@property (nonatomic) DDFileLogger *fileLogger;
|
||||
@property (nonatomic) NSOutputStream *buffer;
|
||||
|
||||
@property (nonatomic) NSUInteger maxBufferSizeBytes;
|
||||
@property (nonatomic) NSUInteger currentBufferSizeBytes;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DDBufferedProxy
|
||||
|
||||
- (instancetype)initWithFileLogger:(DDFileLogger *)fileLogger {
|
||||
_fileLogger = fileLogger;
|
||||
_maxBufferSizeBytes = DDGetDefaultBufferSizeBytes();
|
||||
[self flushBuffer];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
dispatch_block_t block = ^{
|
||||
[self lt_sendBufferedDataToFileLogger];
|
||||
self.fileLogger = nil;
|
||||
};
|
||||
|
||||
if ([self->_fileLogger isOnInternalLoggerQueue]) {
|
||||
block();
|
||||
} else {
|
||||
dispatch_sync(self->_fileLogger.loggerQueue, block);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Buffering
|
||||
|
||||
- (void)flushBuffer {
|
||||
[_buffer close];
|
||||
_buffer = [NSOutputStream outputStreamToMemory];
|
||||
[_buffer open];
|
||||
_currentBufferSizeBytes = 0;
|
||||
}
|
||||
|
||||
- (void)lt_sendBufferedDataToFileLogger {
|
||||
NSData *data = [_buffer propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
|
||||
[_fileLogger lt_logData:data];
|
||||
[self flushBuffer];
|
||||
}
|
||||
|
||||
#pragma mark - Logging
|
||||
|
||||
- (void)logMessage:(DDLogMessage *)logMessage {
|
||||
// Don't need to check for isOnInternalLoggerQueue, -lt_dataForMessage: will do it for us.
|
||||
NSData *data = [_fileLogger lt_dataForMessage:logMessage];
|
||||
|
||||
if (data.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
[data enumerateByteRangesUsingBlock:^(const void * __nonnull bytes, NSRange byteRange, BOOL * __nonnull __unused stop) {
|
||||
NSUInteger bytesLength = byteRange.length;
|
||||
#ifdef NS_BLOCK_ASSERTIONS
|
||||
__unused
|
||||
#endif
|
||||
NSInteger written = [_buffer write:bytes maxLength:bytesLength];
|
||||
NSAssert(written > 0 && (NSUInteger)written == bytesLength, @"Failed to write to memory buffer.");
|
||||
|
||||
_currentBufferSizeBytes += bytesLength;
|
||||
|
||||
if (_currentBufferSizeBytes >= _maxBufferSizeBytes) {
|
||||
[self lt_sendBufferedDataToFileLogger];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)flush {
|
||||
// This method is public.
|
||||
// We need to execute the rolling on our logging thread/queue.
|
||||
|
||||
dispatch_block_t block = ^{
|
||||
@autoreleasepool {
|
||||
[self lt_sendBufferedDataToFileLogger];
|
||||
[self.fileLogger flush];
|
||||
}
|
||||
};
|
||||
|
||||
// The design of this method is taken from the DDAbstractLogger implementation.
|
||||
// For extensive documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
if ([self.fileLogger isOnInternalLoggerQueue]) {
|
||||
block();
|
||||
} else {
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
NSAssert(![self.fileLogger isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
|
||||
dispatch_sync(globalLoggingQueue, ^{
|
||||
dispatch_sync(self.fileLogger.loggerQueue, block);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setMaxBufferSizeBytes:(NSUInteger)newBufferSizeBytes {
|
||||
_maxBufferSizeBytes = MIN(newBufferSizeBytes, DDGetMaxBufferSizeBytes());
|
||||
}
|
||||
|
||||
#pragma mark - Wrapping
|
||||
|
||||
- (DDFileLogger *)wrapWithBuffer {
|
||||
return (DDFileLogger *)self;
|
||||
}
|
||||
|
||||
- (DDFileLogger *)unwrapFromBuffer {
|
||||
return (DDFileLogger *)self.fileLogger;
|
||||
}
|
||||
|
||||
#pragma mark - NSProxy
|
||||
|
||||
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
|
||||
return [self.fileLogger methodSignatureForSelector:sel];
|
||||
}
|
||||
|
||||
- (BOOL)respondsToSelector:(SEL)aSelector {
|
||||
return [self.fileLogger respondsToSelector:aSelector];
|
||||
}
|
||||
|
||||
- (void)forwardInvocation:(NSInvocation *)invocation {
|
||||
[invocation invokeWithTarget:self.fileLogger];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation DDFileLogger (Buffering)
|
||||
|
||||
- (instancetype)wrapWithBuffer {
|
||||
return (DDFileLogger *)[[DDBufferedProxy alloc] initWithFileLogger:self];
|
||||
}
|
||||
|
||||
- (instancetype)unwrapFromBuffer {
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
111
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDMultiFormatter.m
generated
Normal file
111
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDMultiFormatter.m
generated
Normal file
@@ -0,0 +1,111 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
#import <CocoaLumberjack/DDMultiFormatter.h>
|
||||
|
||||
@interface DDMultiFormatter () {
|
||||
dispatch_queue_t _queue;
|
||||
NSMutableArray *_formatters;
|
||||
}
|
||||
|
||||
- (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation DDMultiFormatter
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_queue = dispatch_queue_create("cocoa.lumberjack.multiformatter", DISPATCH_QUEUE_CONCURRENT);
|
||||
_formatters = [NSMutableArray new];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark Processing
|
||||
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
|
||||
__block NSString *line = logMessage->_message;
|
||||
|
||||
dispatch_sync(_queue, ^{
|
||||
for (id<DDLogFormatter> formatter in self->_formatters) {
|
||||
DDLogMessage *message = [self logMessageForLine:line originalMessage:logMessage];
|
||||
line = [formatter formatLogMessage:message];
|
||||
|
||||
if (!line) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
- (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message {
|
||||
DDLogMessage *newMessage = [message copy];
|
||||
|
||||
newMessage->_message = line;
|
||||
return newMessage;
|
||||
}
|
||||
|
||||
#pragma mark Formatters
|
||||
|
||||
- (NSArray *)formatters {
|
||||
__block NSArray *formatters;
|
||||
|
||||
dispatch_sync(_queue, ^{
|
||||
formatters = [self->_formatters copy];
|
||||
});
|
||||
|
||||
return formatters;
|
||||
}
|
||||
|
||||
- (void)addFormatter:(id<DDLogFormatter>)formatter {
|
||||
dispatch_barrier_async(_queue, ^{
|
||||
[self->_formatters addObject:formatter];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)removeFormatter:(id<DDLogFormatter>)formatter {
|
||||
dispatch_barrier_async(_queue, ^{
|
||||
[self->_formatters removeObject:formatter];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)removeAllFormatters {
|
||||
dispatch_barrier_async(_queue, ^{
|
||||
[self->_formatters removeAllObjects];
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)isFormattingWithFormatter:(id<DDLogFormatter>)formatter {
|
||||
__block BOOL hasFormatter;
|
||||
|
||||
dispatch_sync(_queue, ^{
|
||||
hasFormatter = [self->_formatters containsObject:formatter];
|
||||
});
|
||||
|
||||
return hasFormatter;
|
||||
}
|
||||
|
||||
@end
|
||||
104
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/CocoaLumberjack.h
generated
Normal file
104
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/CocoaLumberjack.h
generated
Normal file
@@ -0,0 +1,104 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/CocoaLumberjack.h>
|
||||
*
|
||||
* 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 <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for CocoaLumberjack.
|
||||
FOUNDATION_EXPORT double CocoaLumberjackVersionNumber;
|
||||
|
||||
//! Project version string for CocoaLumberjack.
|
||||
FOUNDATION_EXPORT const unsigned char CocoaLumberjackVersionString[];
|
||||
|
||||
// Disable legacy macros
|
||||
#ifndef DD_LEGACY_MACROS
|
||||
#define DD_LEGACY_MACROS 0
|
||||
#endif
|
||||
|
||||
// Core
|
||||
#import <CocoaLumberjack/DDLog.h>
|
||||
|
||||
// Main macros
|
||||
#import <CocoaLumberjack/DDLogMacros.h>
|
||||
#import <CocoaLumberjack/DDAssertMacros.h>
|
||||
|
||||
// Capture ASL
|
||||
#import <CocoaLumberjack/DDASLLogCapture.h>
|
||||
|
||||
// Loggers
|
||||
#import <CocoaLumberjack/DDLoggerNames.h>
|
||||
|
||||
#import <CocoaLumberjack/DDTTYLogger.h>
|
||||
#import <CocoaLumberjack/DDASLLogger.h>
|
||||
#import <CocoaLumberjack/DDFileLogger.h>
|
||||
#import <CocoaLumberjack/DDOSLogger.h>
|
||||
|
||||
// Extensions
|
||||
#import <CocoaLumberjack/DDContextFilterLogFormatter.h>
|
||||
#import <CocoaLumberjack/DDContextFilterLogFormatter+Deprecated.h>
|
||||
#import <CocoaLumberjack/DDDispatchQueueLogFormatter.h>
|
||||
#import <CocoaLumberjack/DDMultiFormatter.h>
|
||||
#import <CocoaLumberjack/DDFileLogger+Buffering.h>
|
||||
|
||||
// CLI
|
||||
#import <CocoaLumberjack/CLIColor.h>
|
||||
|
||||
// etc
|
||||
#import <CocoaLumberjack/DDAbstractDatabaseLogger.h>
|
||||
#import <CocoaLumberjack/DDLog+LOGV.h>
|
||||
#import <CocoaLumberjack/DDLegacyMacros.h>
|
||||
75
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/DDLegacyMacros.h
generated
Normal file
75
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/DDLegacyMacros.h
generated
Normal file
@@ -0,0 +1,75 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
/**
|
||||
* Legacy macros used for 1.9.x backwards compatibility.
|
||||
*
|
||||
* Imported by default when importing a DDLog.h directly and DD_LEGACY_MACROS is not defined and set to 0.
|
||||
**/
|
||||
#if DD_LEGACY_MACROS
|
||||
|
||||
#warning CocoaLumberjack 1.9.x legacy macros enabled. \
|
||||
Disable legacy macros by importing CocoaLumberjack.h or DDLogMacros.h instead of DDLog.h or add `#define DD_LEGACY_MACROS 0` before importing DDLog.h.
|
||||
|
||||
#ifndef LOG_LEVEL_DEF
|
||||
#define LOG_LEVEL_DEF ddLogLevel
|
||||
#endif
|
||||
|
||||
#define LOG_FLAG_ERROR DDLogFlagError
|
||||
#define LOG_FLAG_WARN DDLogFlagWarning
|
||||
#define LOG_FLAG_INFO DDLogFlagInfo
|
||||
#define LOG_FLAG_DEBUG DDLogFlagDebug
|
||||
#define LOG_FLAG_VERBOSE DDLogFlagVerbose
|
||||
|
||||
#define LOG_LEVEL_OFF DDLogLevelOff
|
||||
#define LOG_LEVEL_ERROR DDLogLevelError
|
||||
#define LOG_LEVEL_WARN DDLogLevelWarning
|
||||
#define LOG_LEVEL_INFO DDLogLevelInfo
|
||||
#define LOG_LEVEL_DEBUG DDLogLevelDebug
|
||||
#define LOG_LEVEL_VERBOSE DDLogLevelVerbose
|
||||
#define LOG_LEVEL_ALL DDLogLevelAll
|
||||
|
||||
#define LOG_ASYNC_ENABLED YES
|
||||
|
||||
#define LOG_ASYNC_ERROR ( NO && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_WARN (YES && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_INFO (YES && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_DEBUG (YES && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_VERBOSE (YES && LOG_ASYNC_ENABLED)
|
||||
|
||||
#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
|
||||
[DDLog log : isAsynchronous \
|
||||
level : lvl \
|
||||
flag : flg \
|
||||
context : ctx \
|
||||
file : __FILE__ \
|
||||
function : fnct \
|
||||
line : __LINE__ \
|
||||
tag : atag \
|
||||
format : (frmt), ## __VA_ARGS__]
|
||||
|
||||
#define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \
|
||||
do { if((lvl & flg) != 0) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0)
|
||||
|
||||
#define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \
|
||||
LOG_MAYBE(async, lvl, flg, ctx, __PRETTY_FUNCTION__, frmt, ## __VA_ARGS__)
|
||||
|
||||
#define DDLogError(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_ERROR, LOG_LEVEL_DEF, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogWarn(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_WARN, LOG_LEVEL_DEF, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogInfo(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_INFO, LOG_LEVEL_DEF, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogDebug(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_DEBUG, LOG_LEVEL_DEF, LOG_FLAG_DEBUG, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogVerbose(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_VERBOSE, LOG_LEVEL_DEF, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__)
|
||||
|
||||
#endif
|
||||
54
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/CLIColor.h
generated
Normal file
54
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/CLIColor.h
generated
Normal file
@@ -0,0 +1,54 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* This class represents an NSColor replacement for CLI projects that don't link with AppKit
|
||||
**/
|
||||
@interface CLIColor : NSObject
|
||||
|
||||
/**
|
||||
* Convenience method for creating a `CLIColor` instance from RGBA params
|
||||
*
|
||||
* @param red red channel, between 0 and 1
|
||||
* @param green green channel, between 0 and 1
|
||||
* @param blue blue channel, between 0 and 1
|
||||
* @param alpha alpha channel, between 0 and 1
|
||||
*/
|
||||
+ (instancetype)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
|
||||
|
||||
/**
|
||||
* Get the RGBA components from a `CLIColor`
|
||||
*
|
||||
* @param red red channel, between 0 and 1
|
||||
* @param green green channel, between 0 and 1
|
||||
* @param blue blue channel, between 0 and 1
|
||||
* @param alpha alpha channel, between 0 and 1
|
||||
*/
|
||||
- (void)getRed:(nullable CGFloat *)red green:(nullable CGFloat *)green blue:(nullable CGFloat *)blue alpha:(nullable CGFloat *)alpha NS_SWIFT_NAME(get(red:green:blue:alpha:));
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
46
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogCapture.h
generated
Normal file
46
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogCapture.h
generated
Normal file
@@ -0,0 +1,46 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDASLLogger.h>
|
||||
|
||||
@protocol DDLogger;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* This class provides the ability to capture the ASL (Apple System Logs)
|
||||
*/
|
||||
API_DEPRECATED("Use DDOSLogger instead", macosx(10.4,10.12), ios(2.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0))
|
||||
@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
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
63
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogger.h
generated
Normal file
63
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogger.h
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <Foundation/Foundation.h>
|
||||
|
||||
// Disable legacy macros
|
||||
#ifndef DD_LEGACY_MACROS
|
||||
#define DD_LEGACY_MACROS 0
|
||||
#endif
|
||||
|
||||
#import <CocoaLumberjack/DDLog.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// Custom key set on messages sent to ASL
|
||||
extern const char* const kDDASLKeyDDLog;
|
||||
|
||||
// Value set for kDDASLKeyDDLog
|
||||
extern const char* const kDDASLDDLogValue;
|
||||
|
||||
/**
|
||||
* This class provides a logger for the Apple System Log facility.
|
||||
*
|
||||
* As described in the "Getting Started" page,
|
||||
* 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.
|
||||
**/
|
||||
API_DEPRECATED("Use DDOSLogger instead", macosx(10.4,10.12), ios(2.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0))
|
||||
@interface DDASLLogger : DDAbstractLogger <DDLogger>
|
||||
|
||||
/**
|
||||
* Singleton method
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
@property (nonatomic, class, readonly, strong) DDASLLogger *sharedInstance;
|
||||
|
||||
// Inherited from DDAbstractLogger
|
||||
|
||||
// - (id <DDLogFormatter>)logFormatter;
|
||||
// - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
127
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAbstractDatabaseLogger.h
generated
Normal file
127
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAbstractDatabaseLogger.h
generated
Normal file
@@ -0,0 +1,127 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDLog.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
NSInteger _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
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
30
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAssertMacros.h
generated
Normal file
30
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAssertMacros.h
generated
Normal file
@@ -0,0 +1,30 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
/**
|
||||
* NSAssert 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)
|
||||
|
||||
/**
|
||||
* Analog to `DDAssertionFailure` from DDAssert.swift for use in Objective C
|
||||
*/
|
||||
#define DDAssertionFailure(frmt, ...) DDAssert(NO, frmt, ##__VA_ARGS__)
|
||||
@@ -0,0 +1,119 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDContextFilterLogFormatter.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* This class provides a log formatter that filters log statements from a logging context not on the whitelist.
|
||||
* @deprecated Use DDContextAllowlistFilterLogFormatter instead.
|
||||
*
|
||||
* A log formatter can be added to any logger to format and/or filter its output.
|
||||
* You can learn more about log formatters here:
|
||||
* Documentation/CustomFormatters.md
|
||||
*
|
||||
* You can learn more about logging context's here:
|
||||
* Documentation/CustomContext.md
|
||||
*
|
||||
* 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.
|
||||
**/
|
||||
__attribute__((deprecated("Use DDContextAllowlistFilterLogFormatter instead")))
|
||||
typedef DDContextAllowlistFilterLogFormatter DDContextWhitelistFilterLogFormatter;
|
||||
|
||||
@interface DDContextAllowlistFilterLogFormatter (Deprecated)
|
||||
|
||||
/**
|
||||
* Add a context to the whitelist
|
||||
* @deprecated Use -addToAllowlist: instead.
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (void)addToWhitelist:(NSInteger)loggingContext __attribute__((deprecated("Use -addToAllowlist: instead")));
|
||||
|
||||
/**
|
||||
* Remove context from whitelist
|
||||
* @deprecated Use -removeFromAllowlist: instead.
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (void)removeFromWhitelist:(NSInteger)loggingContext __attribute__((deprecated("Use -removeFromAllowlist: instead")));
|
||||
|
||||
/**
|
||||
* Return the whitelist
|
||||
* @deprecated Use allowlist instead.
|
||||
*/
|
||||
@property (nonatomic, readonly, copy) NSArray<NSNumber *> *whitelist __attribute__((deprecated("Use allowlist instead")));
|
||||
|
||||
/**
|
||||
* Check if a context is on the whitelist
|
||||
* @deprecated Use -isOnAllowlist: instead.
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (BOOL)isOnWhitelist:(NSInteger)loggingContext __attribute__((deprecated("Use -isOnAllowlist: instead")));
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
* This class provides a log formatter that filters log statements from a logging context on the blacklist.
|
||||
* @deprecated Use DDContextDenylistFilterLogFormatter instead.
|
||||
**/
|
||||
__attribute__((deprecated("Use DDContextDenylistFilterLogFormatter instead")))
|
||||
typedef DDContextDenylistFilterLogFormatter DDContextBlacklistFilterLogFormatter;
|
||||
|
||||
@interface DDContextDenylistFilterLogFormatter (Deprecated)
|
||||
|
||||
/**
|
||||
* Add a context to the blacklist
|
||||
* @deprecated Use -addToDenylist: instead.
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (void)addToBlacklist:(NSInteger)loggingContext __attribute__((deprecated("Use -addToDenylist: instead")));
|
||||
|
||||
/**
|
||||
* Remove context from blacklist
|
||||
* @deprecated Use -removeFromDenylist: instead.
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (void)removeFromBlacklist:(NSInteger)loggingContext __attribute__((deprecated("Use -removeFromDenylist: instead")));
|
||||
|
||||
/**
|
||||
* Return the blacklist
|
||||
* @deprecated Use denylist instead.
|
||||
*/
|
||||
@property (readonly, copy) NSArray<NSNumber *> *blacklist __attribute__((deprecated("Use denylist instead")));
|
||||
|
||||
/**
|
||||
* Check if a context is on the blacklist
|
||||
* @deprecated Use -isOnDenylist: instead.
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (BOOL)isOnBlacklist:(NSInteger)loggingContext __attribute__((deprecated("Use -isOnDenylist: instead")));
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,117 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <Foundation/Foundation.h>
|
||||
|
||||
// Disable legacy macros
|
||||
#ifndef DD_LEGACY_MACROS
|
||||
#define DD_LEGACY_MACROS 0
|
||||
#endif
|
||||
|
||||
#import <CocoaLumberjack/DDLog.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* This class provides a log formatter that filters log statements from a logging context not on the allowlist.
|
||||
*
|
||||
* A log formatter can be added to any logger to format and/or filter its output.
|
||||
* You can learn more about log formatters here:
|
||||
* Documentation/CustomFormatters.md
|
||||
*
|
||||
* You can learn more about logging context's here:
|
||||
* Documentation/CustomContext.md
|
||||
*
|
||||
* 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 DDContextAllowlistFilterLogFormatter : NSObject <DDLogFormatter>
|
||||
|
||||
/**
|
||||
* Designated default initializer
|
||||
*/
|
||||
- (instancetype)init NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Add a context to the allowlist
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (void)addToAllowlist:(NSInteger)loggingContext;
|
||||
|
||||
/**
|
||||
* Remove context from allowlist
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (void)removeFromAllowlist:(NSInteger)loggingContext;
|
||||
|
||||
/**
|
||||
* Return the allowlist
|
||||
*/
|
||||
@property (nonatomic, readonly, copy) NSArray<NSNumber *> *allowlist;
|
||||
|
||||
/**
|
||||
* Check if a context is on the allowlist
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (BOOL)isOnAllowlist:(NSInteger)loggingContext;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
* This class provides a log formatter that filters log statements from a logging context on the denylist.
|
||||
**/
|
||||
@interface DDContextDenylistFilterLogFormatter : NSObject <DDLogFormatter>
|
||||
|
||||
- (instancetype)init NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Add a context to the denylist
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (void)addToDenylist:(NSInteger)loggingContext;
|
||||
|
||||
/**
|
||||
* Remove context from denylist
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (void)removeFromDenylist:(NSInteger)loggingContext;
|
||||
|
||||
/**
|
||||
* Return the denylist
|
||||
*/
|
||||
@property (readonly, copy) NSArray<NSNumber *> *denylist;
|
||||
|
||||
/**
|
||||
* Check if a context is on the denylist
|
||||
*
|
||||
* @param loggingContext the context
|
||||
*/
|
||||
- (BOOL)isOnDenylist:(NSInteger)loggingContext;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,223 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <Foundation/Foundation.h>
|
||||
|
||||
// Disable legacy macros
|
||||
#ifndef DD_LEGACY_MACROS
|
||||
#define DD_LEGACY_MACROS 0
|
||||
#endif
|
||||
|
||||
#import <CocoaLumberjack/DDLog.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Log formatter mode
|
||||
*/
|
||||
__attribute__((deprecated("DDDispatchQueueLogFormatter is always shareable")))
|
||||
typedef NS_ENUM(NSUInteger, DDDispatchQueueLogFormatterMode){
|
||||
/**
|
||||
* This is the default option, means the formatter can be reused between multiple loggers and therefore is thread-safe.
|
||||
* There is, of course, a performance cost for the thread-safety
|
||||
*/
|
||||
DDDispatchQueueLogFormatterModeShareble = 0,
|
||||
/**
|
||||
* If the formatter will only be used by a single logger, then the thread-safety can be removed
|
||||
* @note: there is an assert checking if the formatter is added to multiple loggers and the mode is non-shareble
|
||||
*/
|
||||
DDDispatchQueueLogFormatterModeNonShareble,
|
||||
};
|
||||
|
||||
/**
|
||||
* Quality of Service names.
|
||||
*
|
||||
* Since macOS 10.10 and iOS 8.0, pthreads, dispatch queues and NSOperations express their
|
||||
* scheduling priority by using an abstract classification called Quality of Service (QOS).
|
||||
*
|
||||
* This formatter will add a representation of this QOS in the log message by using those
|
||||
* string constants.
|
||||
* For example:
|
||||
*
|
||||
* `2011-10-17 20:21:45.435 AppName[19928:5207 (QOS:DF)] Your log message here`
|
||||
*
|
||||
* Where QOS is one of:
|
||||
* `- UI = User Interactive`
|
||||
* `- IN = User Initiated`
|
||||
* `- DF = Default`
|
||||
* `- UT = Utility`
|
||||
* `- BG = Background`
|
||||
* `- UN = Unspecified`
|
||||
*
|
||||
* Note: QOS will be absent in the log messages if running on OS versions that don't support it.
|
||||
**/
|
||||
typedef NSString * DDQualityOfServiceName NS_STRING_ENUM;
|
||||
|
||||
FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceUserInteractive NS_SWIFT_NAME(DDQualityOfServiceName.userInteractive) API_AVAILABLE(macos(10.10), ios(8.0));
|
||||
FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceUserInitiated NS_SWIFT_NAME(DDQualityOfServiceName.userInitiated) API_AVAILABLE(macos(10.10), ios(8.0));
|
||||
FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceDefault NS_SWIFT_NAME(DDQualityOfServiceName.default) API_AVAILABLE(macos(10.10), ios(8.0));
|
||||
FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceUtility NS_SWIFT_NAME(DDQualityOfServiceName.utility) API_AVAILABLE(macos(10.10), ios(8.0));
|
||||
FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceBackground NS_SWIFT_NAME(DDQualityOfServiceName.background) API_AVAILABLE(macos(10.10), ios(8.0));
|
||||
FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceUnspecified NS_SWIFT_NAME(DDQualityOfServiceName.unspecified) API_AVAILABLE(macos(10.10), ios(8.0));
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* Documentation/CustomFormatters.md
|
||||
*
|
||||
* A typical `NSLog` (or `DDTTYLogger`) prints detailed info as `[<process_id>:<thread_id>]`.
|
||||
* 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 DDDispatchQueueLogFormatter : NSObject <DDLogFormatter>
|
||||
|
||||
/**
|
||||
* Standard init method.
|
||||
* Configure using properties as desired.
|
||||
**/
|
||||
- (instancetype)init NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Initializer with ability to set the queue mode
|
||||
*
|
||||
* @param mode choose between DDDispatchQueueLogFormatterModeShareble and DDDispatchQueueLogFormatterModeNonShareble, depending if the formatter is shared between several loggers or not
|
||||
*/
|
||||
- (instancetype)initWithMode:(DDDispatchQueueLogFormatterMode)mode __attribute__((deprecated("DDDispatchQueueLogFormatter is always shareable")));
|
||||
|
||||
/**
|
||||
* 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, atomic) 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, atomic) 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.
|
||||
**/
|
||||
- (nullable NSString *)replacementStringForQueueLabel:(NSString *)longLabel;
|
||||
|
||||
/**
|
||||
* See the `replacementStringForQueueLabel:` description
|
||||
*/
|
||||
- (void)setReplacementString:(nullable NSString *)shortLabel forQueueLabel:(NSString *)longLabel;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* Category on `DDDispatchQueueLogFormatter` to make method declarations easier to extend/modify
|
||||
**/
|
||||
@interface DDDispatchQueueLogFormatter (OverridableMethods)
|
||||
|
||||
/**
|
||||
* Date formatter default configuration
|
||||
*/
|
||||
- (void)configureDateFormatter:(NSDateFormatter *)dateFormatter;
|
||||
|
||||
/**
|
||||
* Formatter method to transfrom from date to string
|
||||
*/
|
||||
- (NSString *)stringFromDate:(NSDate *)date;
|
||||
|
||||
/**
|
||||
* Method to compute the queue thread label
|
||||
*/
|
||||
- (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - DDAtomicCountable
|
||||
|
||||
__attribute__((deprecated("DDAtomicCountable is useless since DDDispatchQueueLogFormatter is always shareable now")))
|
||||
@protocol DDAtomicCountable <NSObject>
|
||||
|
||||
- (instancetype)initWithDefaultValue:(int32_t)defaultValue;
|
||||
- (int32_t)increment;
|
||||
- (int32_t)decrement;
|
||||
- (int32_t)value;
|
||||
|
||||
@end
|
||||
|
||||
__attribute__((deprecated("DDAtomicCountable is deprecated")))
|
||||
@interface DDAtomicCounter: NSObject<DDAtomicCountable>
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,27 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDFileLogger.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DDFileLogger (Buffering)
|
||||
|
||||
- (instancetype)wrapWithBuffer;
|
||||
- (instancetype)unwrapFromBuffer;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
530
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDFileLogger.h
generated
Normal file
530
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDFileLogger.h
generated
Normal file
@@ -0,0 +1,530 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDLog.h>
|
||||
|
||||
@class DDLogFileInfo;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* This class provides a logger to write log statements to a file.
|
||||
**/
|
||||
|
||||
|
||||
// Default configuration and safety/sanity values.
|
||||
//
|
||||
// maximumFileSize -> kDDDefaultLogMaxFileSize
|
||||
// rollingFrequency -> kDDDefaultLogRollingFrequency
|
||||
// maximumNumberOfLogFiles -> kDDDefaultLogMaxNumLogFiles
|
||||
// logFilesDiskQuota -> kDDDefaultLogFilesDiskQuota
|
||||
//
|
||||
// You should carefully consider the proper configuration values for your application.
|
||||
|
||||
extern unsigned long long const kDDDefaultLogMaxFileSize;
|
||||
extern NSTimeInterval const kDDDefaultLogRollingFrequency;
|
||||
extern NSUInteger const kDDDefaultLogMaxNumLogFiles;
|
||||
extern unsigned long long const kDDDefaultLogFilesDiskQuota;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#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.
|
||||
*/
|
||||
@protocol DDLogFileManager <NSObject>
|
||||
@required
|
||||
|
||||
// Public properties
|
||||
|
||||
/**
|
||||
* The maximum number of archived log files to keep on disk.
|
||||
* 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 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 log files 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
|
||||
|
||||
/**
|
||||
* 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<NSString *> *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<NSString *> *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<DDLogFileInfo *> *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<NSString *> *sortedLogFilePaths;
|
||||
|
||||
/**
|
||||
* 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<NSString *> *sortedLogFileNames;
|
||||
|
||||
/**
|
||||
* 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<DDLogFileInfo *> *sortedLogFileInfos;
|
||||
|
||||
// Private methods (only to be used by DDFileLogger)
|
||||
|
||||
/**
|
||||
* Generates a new unique log file path, and creates the corresponding log file.
|
||||
* This method is executed directly on the file logger's internal queue.
|
||||
* The file has to exist by the time the method returns.
|
||||
**/
|
||||
- (nullable NSString *)createNewLogFileWithError:(NSError **)error;
|
||||
|
||||
@optional
|
||||
|
||||
// Private methods (only to be used by DDFileLogger)
|
||||
/**
|
||||
* Creates a new log file ignoring any errors. Deprecated in favor of `-createNewLogFileWithError:`.
|
||||
* Will only be called if `-createNewLogFileWithError:` is not implemented.
|
||||
**/
|
||||
- (nullable NSString *)createNewLogFile __attribute__((deprecated("Use -createNewLogFileWithError:"))) NS_SWIFT_UNAVAILABLE("Use -createNewLogFileWithError:");
|
||||
|
||||
// Notifications from DDFileLogger
|
||||
|
||||
/// Called when a log file was archived. Executed on global queue with default priority.
|
||||
/// @param logFilePath The path to the log file that was archived.
|
||||
/// @param wasRolled Whether or not the archiving happend after rolling the log file.
|
||||
- (void)didArchiveLogFile:(NSString *)logFilePath wasRolled:(BOOL)wasRolled NS_SWIFT_NAME(didArchiveLogFile(atPath:wasRolled:));
|
||||
|
||||
// Deprecated APIs
|
||||
/**
|
||||
* Called when a log file was archived. Executed on global queue with default priority.
|
||||
*/
|
||||
- (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:")));
|
||||
|
||||
/**
|
||||
* Called when the roll action was executed and the log was archived.
|
||||
* Executed on global queue with default priority.
|
||||
*/
|
||||
- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:")));
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Default log file manager.
|
||||
*
|
||||
* All log files are placed inside the logsDirectory.
|
||||
* If a specific logsDirectory isn't specified, the default directory is used.
|
||||
* On Mac, this is in `~/Library/Logs/<Application Name>`.
|
||||
* On iPhone, this is in `~/Library/Caches/Logs`.
|
||||
*
|
||||
* Log files are named `"<bundle identifier> <date> <time>.log"`
|
||||
* Example: `com.organization.myapp 2013-12-03 17-14.log`
|
||||
*
|
||||
* Archived log files are automatically deleted according to the `maximumNumberOfLogFiles` property.
|
||||
**/
|
||||
@interface DDLogFileManagerDefault : NSObject <DDLogFileManager>
|
||||
|
||||
/**
|
||||
* Default initializer
|
||||
*/
|
||||
- (instancetype)init;
|
||||
|
||||
/**
|
||||
* If logDirectory is not specified, then a folder called "Logs" is created in the app's cache directory.
|
||||
* While running on the simulator, the "Logs" folder is located in the library temporary directory.
|
||||
*/
|
||||
- (instancetype)initWithLogsDirectory:(nullable NSString *)logsDirectory NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
/*
|
||||
* Calling this constructor you can override the default "automagically" chosen NSFileProtection level.
|
||||
* Useful if you are writing a command line utility / CydiaSubstrate addon for iOS that has no NSBundle
|
||||
* or like SpringBoard no BackgroundModes key in the NSBundle:
|
||||
* iPhone:~ root# cycript -p SpringBoard
|
||||
* cy# [NSBundle mainBundle]
|
||||
* #"NSBundle </System/Library/CoreServices/SpringBoard.app> (loaded)"
|
||||
* cy# [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
|
||||
* null
|
||||
* cy#
|
||||
**/
|
||||
- (instancetype)initWithLogsDirectory:(nullable NSString *)logsDirectory
|
||||
defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Methods to override.
|
||||
*
|
||||
* Log files are named `"<bundle identifier> <date> <time>.log"`
|
||||
* Example: `com.organization.myapp 2013-12-03 17-14.log`
|
||||
*
|
||||
* If you wish to change default filename, you can override following two methods.
|
||||
* - `newLogFileName` method would be called on new logfile creation.
|
||||
* - `isLogFile:` method would be called to filter log files from all other files in logsDirectory.
|
||||
* You have to parse given filename and return YES if it is logFile.
|
||||
*
|
||||
* **NOTE**
|
||||
* `newLogFileName` returns filename. If appropriate file already exists, number would be added
|
||||
* to filename before extension. You have to handle this case in isLogFile: method.
|
||||
*
|
||||
* Example:
|
||||
* - newLogFileName returns `"com.organization.myapp 2013-12-03.log"`,
|
||||
* file `"com.organization.myapp 2013-12-03.log"` would be created.
|
||||
* - after some time `"com.organization.myapp 2013-12-03.log"` is archived
|
||||
* - newLogFileName again returns `"com.organization.myapp 2013-12-03.log"`,
|
||||
* file `"com.organization.myapp 2013-12-03 2.log"` would be created.
|
||||
* - after some time `"com.organization.myapp 2013-12-03 1.log"` is archived
|
||||
* - newLogFileName again returns `"com.organization.myapp 2013-12-03.log"`,
|
||||
* file `"com.organization.myapp 2013-12-03 3.log"` would be created.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Generates log file name with default format `"<bundle identifier> <date> <time>.log"`
|
||||
* Example: `MobileSafari 2013-12-03 17-14.log`
|
||||
*
|
||||
* You can change it by overriding `newLogFileName` and `isLogFile:` methods.
|
||||
**/
|
||||
@property (readonly, copy) NSString *newLogFileName;
|
||||
|
||||
/**
|
||||
* Default log file name is `"<bundle identifier> <date> <time>.log"`.
|
||||
* Example: `MobileSafari 2013-12-03 17-14.log`
|
||||
*
|
||||
* You can change it by overriding `newLogFileName` and `isLogFile:` methods.
|
||||
**/
|
||||
- (BOOL)isLogFile:(NSString *)fileName NS_SWIFT_NAME(isLogFile(withName:));
|
||||
|
||||
/**
|
||||
* New log files are created empty by default in `createNewLogFile:` method
|
||||
*
|
||||
* If you wish to specify a common file header to use in your log files,
|
||||
* you can set the initial log file contents by overriding `logFileHeader`
|
||||
**/
|
||||
@property (readonly, copy, nullable) NSString *logFileHeader;
|
||||
|
||||
/* Inherited from DDLogFileManager protocol:
|
||||
|
||||
@property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
|
||||
@property (readwrite, assign, atomic) NSUInteger logFilesDiskQuota;
|
||||
|
||||
- (NSString *)logsDirectory;
|
||||
|
||||
- (NSArray *)unsortedLogFilePaths;
|
||||
- (NSArray *)unsortedLogFileNames;
|
||||
- (NSArray *)unsortedLogFileInfos;
|
||||
|
||||
- (NSArray *)sortedLogFilePaths;
|
||||
- (NSArray *)sortedLogFileNames;
|
||||
- (NSArray *)sortedLogFileInfos;
|
||||
*/
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Most users will want file log messages to be prepended with the date and time.
|
||||
* Rather than forcing the majority of users to write their own formatter,
|
||||
* we will supply a logical default formatter.
|
||||
* Users can easily replace this formatter with their own by invoking the `setLogFormatter:` method.
|
||||
* It can also be removed by calling `setLogFormatter:`, and passing a nil parameter.
|
||||
*
|
||||
* In addition to the convenience of having a logical default formatter,
|
||||
* it will also provide a template that makes it easy for developers to copy and change.
|
||||
**/
|
||||
@interface DDLogFileFormatterDefault : NSObject <DDLogFormatter>
|
||||
|
||||
/**
|
||||
* Default initializer
|
||||
*/
|
||||
- (instancetype)init;
|
||||
|
||||
/**
|
||||
* Designated initializer, requires a date formatter
|
||||
*/
|
||||
- (instancetype)initWithDateFormatter:(nullable NSDateFormatter *)dateFormatter NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The standard implementation for a file logger
|
||||
*/
|
||||
@interface DDFileLogger : DDAbstractLogger <DDLogger>
|
||||
|
||||
/**
|
||||
* Default initializer.
|
||||
*/
|
||||
- (instancetype)init;
|
||||
|
||||
/**
|
||||
* Designated initializer, requires a `DDLogFileManager` instance.
|
||||
* A global queue w/ default priority is used to run callbacks.
|
||||
* If needed, specify queue using `initWithLogFileManager:completionQueue:`.
|
||||
*/
|
||||
- (instancetype)initWithLogFileManager:(id <DDLogFileManager>)logFileManager;
|
||||
|
||||
/**
|
||||
* Designated initializer, requires a `DDLogFileManager` instance.
|
||||
* The completionQueue is used to execute `didArchiveLogFile:wasRolled:`,
|
||||
* and the callback in `rollLogFileWithCompletionBlock:`.
|
||||
* If nil, a global queue w/ default priority is used.
|
||||
*/
|
||||
- (instancetype)initWithLogFileManager:(id <DDLogFileManager>)logFileManager
|
||||
completionQueue:(nullable dispatch_queue_t)dispatchQueue NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Deprecated. Use `willLogMessage:`
|
||||
*/
|
||||
- (void)willLogMessage __attribute__((deprecated("Use -willLogMessage:"))) NS_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* Deprecated. Use `didLogMessage:`
|
||||
*/
|
||||
- (void)didLogMessage __attribute__((deprecated("Use -didLogMessage:"))) NS_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* Called when the logger is about to write message. Call super before your implementation.
|
||||
*/
|
||||
- (void)willLogMessage:(DDLogFileInfo *)logFileInfo NS_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* Called when the logger wrote message. Call super after your implementation.
|
||||
*/
|
||||
- (void)didLogMessage:(DDLogFileInfo *)logFileInfo NS_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* Writes all in-memory log data to the permanent storage. Call super before your implementation.
|
||||
* Don't call this method directly, instead use the `[DDLog flushLog]` to ensure all log messages are included in flush.
|
||||
*/
|
||||
- (void)flush NS_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* Called when the logger checks archive or not current log file.
|
||||
* Override this method to extend standard behavior. By default returns NO.
|
||||
* This is executed directly on the logger's internal queue, so keep processing light!
|
||||
*/
|
||||
- (BOOL)shouldArchiveRecentLogFileInfo:(DDLogFileInfo *)recentLogFileInfo;
|
||||
|
||||
/**
|
||||
* Log File Rolling:
|
||||
*
|
||||
* `maximumFileSize`:
|
||||
* The approximate maximum size (in bytes) to allow log files to grow.
|
||||
* If a log file is larger than this value after a log statement is appended,
|
||||
* then the log file is rolled.
|
||||
*
|
||||
* `rollingFrequency`
|
||||
* How often to roll the log file.
|
||||
* The frequency is given as an `NSTimeInterval`, which is a double that specifies the interval in seconds.
|
||||
* Once the log file gets to be this old, it is rolled.
|
||||
*
|
||||
* `doNotReuseLogFiles`
|
||||
* When set, will always create a new log file at application launch.
|
||||
*
|
||||
* Both the `maximumFileSize` and the `rollingFrequency` are used to manage rolling.
|
||||
* Whichever occurs first will cause the log file to be rolled.
|
||||
*
|
||||
* For example:
|
||||
* The `rollingFrequency` is 24 hours,
|
||||
* but the log file surpasses the `maximumFileSize` after only 20 hours.
|
||||
* The log file will be rolled at that 20 hour mark.
|
||||
* A new log file will be created, and the 24 hour timer will be restarted.
|
||||
*
|
||||
* You may optionally disable rolling due to filesize by setting `maximumFileSize` to zero.
|
||||
* If you do so, rolling is based solely on `rollingFrequency`.
|
||||
*
|
||||
* You may optionally disable rolling due to time by setting `rollingFrequency` to zero (or any non-positive number).
|
||||
* If you do so, rolling is based solely on `maximumFileSize`.
|
||||
*
|
||||
* If you disable both `maximumFileSize` and `rollingFrequency`, then the log file won't ever be rolled.
|
||||
* This is strongly discouraged.
|
||||
**/
|
||||
@property (readwrite, assign) unsigned long long maximumFileSize;
|
||||
|
||||
/**
|
||||
* See description for `maximumFileSize`
|
||||
*/
|
||||
@property (readwrite, assign) NSTimeInterval rollingFrequency;
|
||||
|
||||
/**
|
||||
* See description for `maximumFileSize`
|
||||
*/
|
||||
@property (readwrite, assign, atomic) BOOL doNotReuseLogFiles;
|
||||
|
||||
/**
|
||||
* The DDLogFileManager instance can be used to retrieve the list of log files,
|
||||
* and configure the maximum number of archived log files to keep.
|
||||
*
|
||||
* @see DDLogFileManager.maximumNumberOfLogFiles
|
||||
**/
|
||||
@property (strong, nonatomic, readonly) id <DDLogFileManager> logFileManager;
|
||||
|
||||
/**
|
||||
* When using a custom formatter you can set the `logMessage` method not to append
|
||||
* `\n` character after each output. This allows for some greater flexibility with
|
||||
* custom formatters. Default value is YES.
|
||||
**/
|
||||
@property (nonatomic, readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
|
||||
|
||||
/**
|
||||
* You can optionally force the current log file to be rolled with this method.
|
||||
* CompletionBlock will be called on main queue.
|
||||
*/
|
||||
- (void)rollLogFileWithCompletionBlock:(nullable void (^)(void))completionBlock
|
||||
NS_SWIFT_NAME(rollLogFile(withCompletion:));
|
||||
|
||||
/**
|
||||
* Method is deprecated.
|
||||
* @deprecated Use `rollLogFileWithCompletionBlock:` method instead.
|
||||
*/
|
||||
- (void)rollLogFile __attribute__((deprecated("Use -rollLogFileWithCompletionBlock:")));
|
||||
|
||||
// Inherited from DDAbstractLogger
|
||||
|
||||
// - (id <DDLogFormatter>)logFormatter;
|
||||
// - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
/**
|
||||
* Returns the log file that should be used.
|
||||
* If there is an existing log file that is suitable,
|
||||
* within the constraints of `maximumFileSize` and `rollingFrequency`, then it is returned.
|
||||
*
|
||||
* Otherwise a new file is created and returned. If this failes, `NULL` is returned.
|
||||
**/
|
||||
@property (nonatomic, nullable, readonly, strong) DDLogFileInfo *currentLogFileInfo;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* `DDLogFileInfo` is a simple class that provides access to various file attributes.
|
||||
* It provides good performance as it only fetches the information if requested,
|
||||
* and it caches the information to prevent duplicate fetches.
|
||||
*
|
||||
* It was designed to provide quick snapshots of the current state of log files,
|
||||
* and to help sort log files in an array.
|
||||
*
|
||||
* This class does not monitor the files, or update it's cached attribute values if the file changes on disk.
|
||||
* This is not what the class was designed for.
|
||||
*
|
||||
* If you absolutely must get updated values,
|
||||
* you can invoke the reset method which will clear the cache.
|
||||
**/
|
||||
@interface DDLogFileInfo : NSObject
|
||||
|
||||
@property (strong, nonatomic, readonly) NSString *filePath;
|
||||
@property (strong, nonatomic, readonly) NSString *fileName;
|
||||
|
||||
@property (strong, nonatomic, readonly) NSDictionary<NSFileAttributeKey, id> *fileAttributes;
|
||||
|
||||
@property (strong, nonatomic, nullable, readonly) NSDate *creationDate;
|
||||
@property (strong, nonatomic, nullable, readonly) NSDate *modificationDate;
|
||||
|
||||
@property (nonatomic, readonly) unsigned long long fileSize;
|
||||
|
||||
@property (nonatomic, readonly) NSTimeInterval age;
|
||||
|
||||
@property (nonatomic, readwrite) BOOL isArchived;
|
||||
|
||||
+ (nullable instancetype)logFileWithPath:(nullable NSString *)filePath NS_SWIFT_UNAVAILABLE("Use init(filePath:)");
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (instancetype)initWithFilePath:(NSString *)filePath NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (void)reset;
|
||||
- (void)renameFile:(NSString *)newFileName NS_SWIFT_NAME(renameFile(to:));
|
||||
|
||||
- (BOOL)hasExtendedAttributeWithName:(NSString *)attrName;
|
||||
|
||||
- (void)addExtendedAttributeWithName:(NSString *)attrName;
|
||||
- (void)removeExtendedAttributeWithName:(NSString *)attrName;
|
||||
|
||||
- (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another;
|
||||
- (NSComparisonResult)reverseCompareByModificationDate:(DDLogFileInfo *)another;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
82
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDLog+LOGV.h
generated
Normal file
82
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDLog+LOGV.h
generated
Normal file
@@ -0,0 +1,82 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDLog.h>
|
||||
|
||||
/**
|
||||
* The constant/variable/method responsible for controlling the current log level.
|
||||
**/
|
||||
#ifndef LOG_LEVEL_DEF
|
||||
#define LOG_LEVEL_DEF ddLogLevel
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Whether async should be used by log messages, excluding error messages that are always sent sync.
|
||||
**/
|
||||
#ifndef LOG_ASYNC_ENABLED
|
||||
#define LOG_ASYNC_ENABLED YES
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This is the single macro that all other macros below compile into.
|
||||
* This big multiline macro makes all the other macros easier to read.
|
||||
**/
|
||||
#define LOGV_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, avalist) \
|
||||
[DDLog log : isAsynchronous \
|
||||
level : lvl \
|
||||
flag : flg \
|
||||
context : ctx \
|
||||
file : __FILE__ \
|
||||
function : fnct \
|
||||
line : __LINE__ \
|
||||
tag : atag \
|
||||
format : frmt \
|
||||
args : avalist]
|
||||
|
||||
/**
|
||||
* Define version of the macro that only execute if the log level is above the threshold.
|
||||
* The compiled versions essentially look like this:
|
||||
*
|
||||
* if (logFlagForThisLogMsg & ddLogLevel) { execute log message }
|
||||
*
|
||||
* When LOG_LEVEL_DEF is defined as ddLogLevel.
|
||||
*
|
||||
* As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels.
|
||||
* This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques.
|
||||
*
|
||||
* Note that when compiler optimizations are enabled (as they are for your release builds),
|
||||
* the log messages above your logging threshold will automatically be compiled out.
|
||||
*
|
||||
* (If the compiler sees LOG_LEVEL_DEF/ddLogLevel declared as a constant, the compiler simply checks to see
|
||||
* if the 'if' statement would execute, and if not it strips it from the binary.)
|
||||
*
|
||||
* We also define shorthand versions for asynchronous and synchronous logging.
|
||||
**/
|
||||
#define LOGV_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, avalist) \
|
||||
do { if(lvl & flg) LOGV_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, avalist); } while(0)
|
||||
|
||||
/**
|
||||
* Ready to use log macros with no context or tag.
|
||||
**/
|
||||
#define DDLogVError(frmt, avalist) LOGV_MAYBE(NO, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
|
||||
#define DDLogVWarn(frmt, avalist) LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
|
||||
#define DDLogVInfo(frmt, avalist) LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
|
||||
#define DDLogVDebug(frmt, avalist) LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
|
||||
#define DDLogVVerbose(frmt, avalist) LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
|
||||
927
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDLog.h
generated
Normal file
927
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDLog.h
generated
Normal file
@@ -0,0 +1,927 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <Foundation/Foundation.h>
|
||||
|
||||
// The Swift Package integration has no support for the legacy macros.
|
||||
#if __has_include(<CocoaLumberjack/DDLegacyMacros.h>)
|
||||
// Enable 1.9.x legacy macros if imported directly and it's not a swift package build.
|
||||
#ifndef DD_LEGACY_MACROS
|
||||
#define DD_LEGACY_MACROS 1
|
||||
#endif
|
||||
// DD_LEGACY_MACROS is checked in the file itself
|
||||
#import <CocoaLumberjack/DDLegacyMacros.h>
|
||||
#endif
|
||||
|
||||
#ifndef DD_LEGACY_MESSAGE_TAG
|
||||
#define DD_LEGACY_MESSAGE_TAG 1
|
||||
#endif
|
||||
|
||||
// Names of loggers.
|
||||
#import <CocoaLumberjack/DDLoggerNames.h>
|
||||
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
#define DISPATCH_QUEUE_REFERENCE_TYPE strong
|
||||
#else
|
||||
#define DISPATCH_QUEUE_REFERENCE_TYPE assign
|
||||
#endif
|
||||
|
||||
@class DDLogMessage;
|
||||
@class DDLoggerInformation;
|
||||
@protocol DDLogger;
|
||||
@protocol DDLogFormatter;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Define the standard options.
|
||||
*
|
||||
* We default to only 4 levels because it makes it easier for beginners
|
||||
* to make the transition to a logging framework.
|
||||
*
|
||||
* More advanced users may choose to completely customize the levels (and level names) to suite their needs.
|
||||
* For more information on this see the "Custom Log Levels" page:
|
||||
* Documentation/CustomLogLevels.md
|
||||
*
|
||||
* Advanced users may also notice that we're using a bitmask.
|
||||
* This is to allow for custom fine grained logging:
|
||||
* Documentation/FineGrainedLogging.md
|
||||
*
|
||||
* -- Flags --
|
||||
*
|
||||
* Typically you will use the LOG_LEVELS (see below), but the flags may be used directly in certain situations.
|
||||
* For example, say you have a lot of warning log messages, and you wanted to disable them.
|
||||
* However, you still needed to see your error and info log messages.
|
||||
* You could accomplish that with the following:
|
||||
*
|
||||
* static const DDLogLevel ddLogLevel = DDLogFlagError | DDLogFlagInfo;
|
||||
*
|
||||
* When LOG_LEVEL_DEF is defined as ddLogLevel.
|
||||
*
|
||||
* Flags may also be consulted when writing custom log formatters,
|
||||
* as the DDLogMessage class captures the individual flag that caused the log message to fire.
|
||||
*
|
||||
* -- Levels --
|
||||
*
|
||||
* Log levels are simply the proper bitmask of the flags.
|
||||
*
|
||||
* -- Booleans --
|
||||
*
|
||||
* The booleans may be used when your logging code involves more than one line.
|
||||
* For example:
|
||||
*
|
||||
* if (LOG_VERBOSE) {
|
||||
* for (id sprocket in sprockets)
|
||||
* DDLogVerbose(@"sprocket: %@", [sprocket description])
|
||||
* }
|
||||
*
|
||||
* -- Async --
|
||||
*
|
||||
* Defines the default asynchronous options.
|
||||
* The default philosophy for asynchronous logging is very simple:
|
||||
*
|
||||
* Log messages with errors should be executed synchronously.
|
||||
* After all, an error just occurred. The application could be unstable.
|
||||
*
|
||||
* All other log messages, such as debug output, are executed asynchronously.
|
||||
* After all, if it wasn't an error, then it was just informational output,
|
||||
* or something the application was easily able to recover from.
|
||||
*
|
||||
* -- Changes --
|
||||
*
|
||||
* You are strongly discouraged from modifying this file.
|
||||
* If you do, you make it more difficult on yourself to merge future bug fixes and improvements from the project.
|
||||
* Instead, create your own MyLogging.h or ApplicationNameLogging.h or CompanyLogging.h
|
||||
*
|
||||
* For an example of customizing your logging experience, see the "Custom Log Levels" page:
|
||||
* Documentation/CustomLogLevels.md
|
||||
**/
|
||||
|
||||
/**
|
||||
* Flags accompany each log. They are used together with levels to filter out logs.
|
||||
*/
|
||||
typedef NS_OPTIONS(NSUInteger, DDLogFlag){
|
||||
/**
|
||||
* 0...00001 DDLogFlagError
|
||||
*/
|
||||
DDLogFlagError = (1 << 0),
|
||||
|
||||
/**
|
||||
* 0...00010 DDLogFlagWarning
|
||||
*/
|
||||
DDLogFlagWarning = (1 << 1),
|
||||
|
||||
/**
|
||||
* 0...00100 DDLogFlagInfo
|
||||
*/
|
||||
DDLogFlagInfo = (1 << 2),
|
||||
|
||||
/**
|
||||
* 0...01000 DDLogFlagDebug
|
||||
*/
|
||||
DDLogFlagDebug = (1 << 3),
|
||||
|
||||
/**
|
||||
* 0...10000 DDLogFlagVerbose
|
||||
*/
|
||||
DDLogFlagVerbose = (1 << 4)
|
||||
};
|
||||
|
||||
/**
|
||||
* Log levels are used to filter out logs. Used together with flags.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, DDLogLevel){
|
||||
/**
|
||||
* No logs
|
||||
*/
|
||||
DDLogLevelOff = 0,
|
||||
|
||||
/**
|
||||
* Error logs only
|
||||
*/
|
||||
DDLogLevelError = (DDLogFlagError),
|
||||
|
||||
/**
|
||||
* Error and warning logs
|
||||
*/
|
||||
DDLogLevelWarning = (DDLogLevelError | DDLogFlagWarning),
|
||||
|
||||
/**
|
||||
* Error, warning and info logs
|
||||
*/
|
||||
DDLogLevelInfo = (DDLogLevelWarning | DDLogFlagInfo),
|
||||
|
||||
/**
|
||||
* Error, warning, info and debug logs
|
||||
*/
|
||||
DDLogLevelDebug = (DDLogLevelInfo | DDLogFlagDebug),
|
||||
|
||||
/**
|
||||
* Error, warning, info, debug and verbose logs
|
||||
*/
|
||||
DDLogLevelVerbose = (DDLogLevelDebug | DDLogFlagVerbose),
|
||||
|
||||
/**
|
||||
* All logs (1...11111)
|
||||
*/
|
||||
DDLogLevelAll = NSUIntegerMax
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts just the file name, no path or extension
|
||||
*
|
||||
* @param filePath input file path
|
||||
* @param copy YES if we want the result to be copied
|
||||
*
|
||||
* @return the file name
|
||||
*/
|
||||
FOUNDATION_EXTERN NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
|
||||
|
||||
/**
|
||||
* The THIS_FILE macro gives you an NSString of the file name.
|
||||
* For simplicity and clarity, the file name does not include the full path or file extension.
|
||||
*
|
||||
* For example: DDLogWarn(@"%@: Unable to find thingy", THIS_FILE) -> @"MyViewController: Unable to find thingy"
|
||||
**/
|
||||
#define THIS_FILE (DDExtractFileNameWithoutExtension(__FILE__, NO))
|
||||
|
||||
/**
|
||||
* The THIS_METHOD macro gives you the name of the current objective-c method.
|
||||
*
|
||||
* For example: DDLogWarn(@"%@ - Requires non-nil strings", THIS_METHOD) -> @"setMake:model: requires non-nil strings"
|
||||
*
|
||||
* Note: This does NOT work in straight C functions (non objective-c).
|
||||
* Instead you should use the predefined __FUNCTION__ macro.
|
||||
**/
|
||||
#define THIS_METHOD NSStringFromSelector(_cmd)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The main class, exposes all logging mechanisms, loggers, ...
|
||||
* For most of the users, this class is hidden behind the logging functions like `DDLogInfo`
|
||||
*/
|
||||
@interface DDLog : NSObject
|
||||
|
||||
/**
|
||||
* Returns the singleton `DDLog`.
|
||||
* The instance is used by `DDLog` class methods.
|
||||
*/
|
||||
@property (class, nonatomic, strong, readonly) DDLog *sharedInstance;
|
||||
|
||||
/**
|
||||
* Provides access to the underlying logging queue.
|
||||
* This may be helpful to Logger classes for things like thread synchronization.
|
||||
**/
|
||||
@property (class, nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE, readonly) dispatch_queue_t loggingQueue;
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method is used by the macros or logging functions.
|
||||
* It is suggested you stick with the macros as they're easier to use.
|
||||
*
|
||||
* @param asynchronous YES if the logging is done async, NO if you want to force sync
|
||||
* @param level the log level
|
||||
* @param flag the log flag
|
||||
* @param context the context (if any is defined)
|
||||
* @param file the current file
|
||||
* @param function the current function
|
||||
* @param line the current code line
|
||||
* @param tag potential tag
|
||||
* @param format the log format
|
||||
*/
|
||||
+ (void)log:(BOOL)asynchronous
|
||||
level:(DDLogLevel)level
|
||||
flag:(DDLogFlag)flag
|
||||
context:(NSInteger)context
|
||||
file:(const char *)file
|
||||
function:(nullable const char *)function
|
||||
line:(NSUInteger)line
|
||||
tag:(nullable id)tag
|
||||
format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method is used by the macros or logging functions.
|
||||
* It is suggested you stick with the macros as they're easier to use.
|
||||
*
|
||||
* @param asynchronous YES if the logging is done async, NO if you want to force sync
|
||||
* @param level the log level
|
||||
* @param flag the log flag
|
||||
* @param context the context (if any is defined)
|
||||
* @param file the current file
|
||||
* @param function the current function
|
||||
* @param line the current code line
|
||||
* @param tag potential tag
|
||||
* @param format the log format
|
||||
*/
|
||||
- (void)log:(BOOL)asynchronous
|
||||
level:(DDLogLevel)level
|
||||
flag:(DDLogFlag)flag
|
||||
context:(NSInteger)context
|
||||
file:(const char *)file
|
||||
function:(nullable const char *)function
|
||||
line:(NSUInteger)line
|
||||
tag:(nullable id)tag
|
||||
format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method can be used if you have a prepared va_list.
|
||||
* Similar to `log:level:flag:context:file:function:line:tag:format:...`
|
||||
*
|
||||
* @param asynchronous YES if the logging is done async, NO if you want to force sync
|
||||
* @param level the log level
|
||||
* @param flag the log flag
|
||||
* @param context the context (if any is defined)
|
||||
* @param file the current file
|
||||
* @param function the current function
|
||||
* @param line the current code line
|
||||
* @param tag potential tag
|
||||
* @param format the log format
|
||||
* @param argList the arguments list as a va_list
|
||||
*/
|
||||
+ (void)log:(BOOL)asynchronous
|
||||
level:(DDLogLevel)level
|
||||
flag:(DDLogFlag)flag
|
||||
context:(NSInteger)context
|
||||
file:(const char *)file
|
||||
function:(nullable const char *)function
|
||||
line:(NSUInteger)line
|
||||
tag:(nullable id)tag
|
||||
format:(NSString *)format
|
||||
args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method can be used if you have a prepared va_list.
|
||||
* Similar to `log:level:flag:context:file:function:line:tag:format:...`
|
||||
*
|
||||
* @param asynchronous YES if the logging is done async, NO if you want to force sync
|
||||
* @param level the log level
|
||||
* @param flag the log flag
|
||||
* @param context the context (if any is defined)
|
||||
* @param file the current file
|
||||
* @param function the current function
|
||||
* @param line the current code line
|
||||
* @param tag potential tag
|
||||
* @param format the log format
|
||||
* @param argList the arguments list as a va_list
|
||||
*/
|
||||
- (void)log:(BOOL)asynchronous
|
||||
level:(DDLogLevel)level
|
||||
flag:(DDLogFlag)flag
|
||||
context:(NSInteger)context
|
||||
file:(const char *)file
|
||||
function:(nullable const char *)function
|
||||
line:(NSUInteger)line
|
||||
tag:(nullable id)tag
|
||||
format:(NSString *)format
|
||||
args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method can be used if you manually prepared DDLogMessage.
|
||||
*
|
||||
* @param asynchronous YES if the logging is done async, NO if you want to force sync
|
||||
* @param logMessage the log message stored in a `DDLogMessage` model object
|
||||
*/
|
||||
+ (void)log:(BOOL)asynchronous
|
||||
message:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(asynchronous:message:));
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method can be used if you manually prepared DDLogMessage.
|
||||
*
|
||||
* @param asynchronous YES if the logging is done async, NO if you want to force sync
|
||||
* @param logMessage the log message stored in a `DDLogMessage` model object
|
||||
*/
|
||||
- (void)log:(BOOL)asynchronous
|
||||
message:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(asynchronous:message:));
|
||||
|
||||
/**
|
||||
* Since logging can be asynchronous, there may be times when you want to flush the logs.
|
||||
* The framework invokes this automatically when the application quits.
|
||||
**/
|
||||
+ (void)flushLog;
|
||||
|
||||
/**
|
||||
* Since logging can be asynchronous, there may be times when you want to flush the logs.
|
||||
* The framework invokes this automatically when the application quits.
|
||||
**/
|
||||
- (void)flushLog;
|
||||
|
||||
/**
|
||||
* Loggers
|
||||
*
|
||||
* In order for your log statements to go somewhere, you should create and add a logger.
|
||||
*
|
||||
* You can add multiple loggers in order to direct your log statements to multiple places.
|
||||
* And each logger can be configured separately.
|
||||
* So you could have, for example, verbose logging to the console, but a concise log file with only warnings & errors.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Adds the logger to the system.
|
||||
*
|
||||
* This is equivalent to invoking `[DDLog addLogger:logger withLogLevel:DDLogLevelAll]`.
|
||||
**/
|
||||
+ (void)addLogger:(id <DDLogger>)logger;
|
||||
|
||||
/**
|
||||
* Adds the logger to the system.
|
||||
*
|
||||
* This is equivalent to invoking `[DDLog addLogger:logger withLogLevel:DDLogLevelAll]`.
|
||||
**/
|
||||
- (void)addLogger:(id <DDLogger>)logger;
|
||||
|
||||
/**
|
||||
* Adds the logger to the system.
|
||||
*
|
||||
* The level that you provide here is a preemptive filter (for performance).
|
||||
* That is, the level specified here will be used to filter out logMessages so that
|
||||
* the logger is never even invoked for the messages.
|
||||
*
|
||||
* More information:
|
||||
* When you issue a log statement, the logging framework iterates over each logger,
|
||||
* and checks to see if it should forward the logMessage to the logger.
|
||||
* This check is done using the level parameter passed to this method.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* `[DDLog addLogger:consoleLogger withLogLevel:DDLogLevelVerbose];`
|
||||
* `[DDLog addLogger:fileLogger withLogLevel:DDLogLevelWarning];`
|
||||
*
|
||||
* `DDLogError(@"oh no");` => gets forwarded to consoleLogger & fileLogger
|
||||
* `DDLogInfo(@"hi");` => gets forwarded to consoleLogger only
|
||||
*
|
||||
* It is important to remember that Lumberjack uses a BITMASK.
|
||||
* Many developers & third party frameworks may define extra log levels & flags.
|
||||
* For example:
|
||||
*
|
||||
* `#define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000`
|
||||
*
|
||||
* So if you specify `DDLogLevelVerbose` to this method, you won't see the framework's trace messages.
|
||||
*
|
||||
* `(SOME_FRAMEWORK_LOG_FLAG_TRACE & DDLogLevelVerbose) => (01000000 & 00011111) => NO`
|
||||
*
|
||||
* Consider passing `DDLogLevelAll` to this method, which has all bits set.
|
||||
* You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
|
||||
* except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
|
||||
*
|
||||
* `((DDLogLevelAll ^ DDLogLevelVerbose) | DDLogLevelInfo)`
|
||||
**/
|
||||
+ (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level;
|
||||
|
||||
/**
|
||||
* Adds the logger to the system.
|
||||
*
|
||||
* The level that you provide here is a preemptive filter (for performance).
|
||||
* That is, the level specified here will be used to filter out logMessages so that
|
||||
* the logger is never even invoked for the messages.
|
||||
*
|
||||
* More information:
|
||||
* When you issue a log statement, the logging framework iterates over each logger,
|
||||
* and checks to see if it should forward the logMessage to the logger.
|
||||
* This check is done using the level parameter passed to this method.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* `[DDLog addLogger:consoleLogger withLogLevel:DDLogLevelVerbose];`
|
||||
* `[DDLog addLogger:fileLogger withLogLevel:DDLogLevelWarning];`
|
||||
*
|
||||
* `DDLogError(@"oh no");` => gets forwarded to consoleLogger & fileLogger
|
||||
* `DDLogInfo(@"hi");` => gets forwarded to consoleLogger only
|
||||
*
|
||||
* It is important to remember that Lumberjack uses a BITMASK.
|
||||
* Many developers & third party frameworks may define extra log levels & flags.
|
||||
* For example:
|
||||
*
|
||||
* `#define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000`
|
||||
*
|
||||
* So if you specify `DDLogLevelVerbose` to this method, you won't see the framework's trace messages.
|
||||
*
|
||||
* `(SOME_FRAMEWORK_LOG_FLAG_TRACE & DDLogLevelVerbose) => (01000000 & 00011111) => NO`
|
||||
*
|
||||
* Consider passing `DDLogLevelAll` to this method, which has all bits set.
|
||||
* You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
|
||||
* except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
|
||||
*
|
||||
* `((DDLogLevelAll ^ DDLogLevelVerbose) | DDLogLevelInfo)`
|
||||
**/
|
||||
- (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level;
|
||||
|
||||
/**
|
||||
* Remove the logger from the system
|
||||
*/
|
||||
+ (void)removeLogger:(id <DDLogger>)logger;
|
||||
|
||||
/**
|
||||
* Remove the logger from the system
|
||||
*/
|
||||
- (void)removeLogger:(id <DDLogger>)logger;
|
||||
|
||||
/**
|
||||
* Remove all the current loggers
|
||||
*/
|
||||
+ (void)removeAllLoggers;
|
||||
|
||||
/**
|
||||
* Remove all the current loggers
|
||||
*/
|
||||
- (void)removeAllLoggers;
|
||||
|
||||
/**
|
||||
* Return all the current loggers
|
||||
*/
|
||||
@property (class, nonatomic, copy, readonly) NSArray<id<DDLogger>> *allLoggers;
|
||||
|
||||
/**
|
||||
* Return all the current loggers
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSArray<id<DDLogger>> *allLoggers;
|
||||
|
||||
/**
|
||||
* Return all the current loggers with their level (aka DDLoggerInformation).
|
||||
*/
|
||||
@property (class, nonatomic, copy, readonly) NSArray<DDLoggerInformation *> *allLoggersWithLevel;
|
||||
|
||||
/**
|
||||
* Return all the current loggers with their level (aka DDLoggerInformation).
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSArray<DDLoggerInformation *> *allLoggersWithLevel;
|
||||
|
||||
/**
|
||||
* Registered Dynamic Logging
|
||||
*
|
||||
* These methods allow you to obtain a list of classes that are using registered dynamic logging,
|
||||
* and also provides methods to get and set their log level during run time.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Returns an array with the classes that are using registered dynamic logging
|
||||
*/
|
||||
@property (class, nonatomic, copy, readonly) NSArray<Class> *registeredClasses;
|
||||
|
||||
/**
|
||||
* Returns an array with the classes names that are using registered dynamic logging
|
||||
*/
|
||||
@property (class, nonatomic, copy, readonly) NSArray<NSString*> *registeredClassNames;
|
||||
|
||||
/**
|
||||
* Returns the current log level for a certain class
|
||||
*
|
||||
* @param aClass `Class` param
|
||||
*/
|
||||
+ (DDLogLevel)levelForClass:(Class)aClass;
|
||||
|
||||
/**
|
||||
* Returns the current log level for a certain class
|
||||
*
|
||||
* @param aClassName string param
|
||||
*/
|
||||
+ (DDLogLevel)levelForClassWithName:(NSString *)aClassName;
|
||||
|
||||
/**
|
||||
* Set the log level for a certain class
|
||||
*
|
||||
* @param level the new level
|
||||
* @param aClass `Class` param
|
||||
*/
|
||||
+ (void)setLevel:(DDLogLevel)level forClass:(Class)aClass;
|
||||
|
||||
/**
|
||||
* Set the log level for a certain class
|
||||
*
|
||||
* @param level the new level
|
||||
* @param aClassName string param
|
||||
*/
|
||||
+ (void)setLevel:(DDLogLevel)level forClassWithName:(NSString *)aClassName;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* This protocol describes a basic logger behavior.
|
||||
* Basically, it can log messages, store a logFormatter plus a bunch of optional behaviors.
|
||||
* (i.e. flush, get its loggerQueue, get its name, ...
|
||||
*/
|
||||
@protocol DDLogger <NSObject>
|
||||
|
||||
/**
|
||||
* The log message method
|
||||
*
|
||||
* @param logMessage the message (model)
|
||||
*/
|
||||
- (void)logMessage:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(message:));
|
||||
|
||||
/**
|
||||
* Formatters may optionally be added to any logger.
|
||||
*
|
||||
* If no formatter is set, the logger simply logs the message as it is given in logMessage,
|
||||
* or it may use its own built in formatting style.
|
||||
**/
|
||||
@property (nonatomic, strong, nullable) id <DDLogFormatter> logFormatter;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Since logging is asynchronous, adding and removing loggers is also asynchronous.
|
||||
* In other words, the loggers are added and removed at appropriate times with regards to log messages.
|
||||
*
|
||||
* - Loggers will not receive log messages that were executed prior to when they were added.
|
||||
* - Loggers will not receive log messages that were executed after they were removed.
|
||||
*
|
||||
* These methods are executed in the logging thread/queue.
|
||||
* This is the same thread/queue that will execute every logMessage: invocation.
|
||||
* Loggers may use these methods for thread synchronization or other setup/teardown tasks.
|
||||
**/
|
||||
- (void)didAddLogger;
|
||||
|
||||
/**
|
||||
* Since logging is asynchronous, adding and removing loggers is also asynchronous.
|
||||
* In other words, the loggers are added and removed at appropriate times with regards to log messages.
|
||||
*
|
||||
* - Loggers will not receive log messages that were executed prior to when they were added.
|
||||
* - Loggers will not receive log messages that were executed after they were removed.
|
||||
*
|
||||
* These methods are executed in the logging thread/queue given in parameter.
|
||||
* This is the same thread/queue that will execute every logMessage: invocation.
|
||||
* Loggers may use the queue parameter to set specific values on the queue with dispatch_set_specific() function.
|
||||
**/
|
||||
- (void)didAddLoggerInQueue:(dispatch_queue_t)queue;
|
||||
|
||||
/**
|
||||
* See the above description for `didAddLogger`
|
||||
*/
|
||||
- (void)willRemoveLogger;
|
||||
|
||||
/**
|
||||
* Some loggers may buffer IO for optimization purposes.
|
||||
* For example, a database logger may only save occasionally as the disk IO is slow.
|
||||
* In such loggers, this method should be implemented to flush any pending IO.
|
||||
*
|
||||
* This allows invocations of DDLog's flushLog method to be propagated to loggers that need it.
|
||||
*
|
||||
* Note that DDLog's flushLog method is invoked automatically when the application quits,
|
||||
* and it may be also invoked manually by the developer prior to application crashes, or other such reasons.
|
||||
**/
|
||||
- (void)flush;
|
||||
|
||||
/**
|
||||
* Each logger is executed concurrently with respect to the other loggers.
|
||||
* Thus, a dedicated dispatch queue is used for each logger.
|
||||
* Logger implementations may optionally choose to provide their own dispatch queue.
|
||||
**/
|
||||
@property (nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE, readonly) dispatch_queue_t loggerQueue;
|
||||
|
||||
/**
|
||||
* If the logger implementation does not choose to provide its own queue,
|
||||
* one will automatically be created for it.
|
||||
* The created queue will receive its name from this method.
|
||||
* This may be helpful for debugging or profiling reasons.
|
||||
**/
|
||||
@property (copy, nonatomic, readonly) DDLoggerName loggerName;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* This protocol describes the behavior of a log formatter
|
||||
*/
|
||||
@protocol DDLogFormatter <NSObject>
|
||||
@required
|
||||
|
||||
/**
|
||||
* Formatters may optionally be added to any logger.
|
||||
* This allows for increased flexibility in the logging environment.
|
||||
* For example, log messages for log files may be formatted differently than log messages for the console.
|
||||
*
|
||||
* For more information about formatters, see the "Custom Formatters" page:
|
||||
* Documentation/CustomFormatters.md
|
||||
*
|
||||
* The formatter may also optionally filter the log message by returning nil,
|
||||
* in which case the logger will not log the message.
|
||||
**/
|
||||
- (nullable NSString *)formatLogMessage:(DDLogMessage *)logMessage NS_SWIFT_NAME(format(message:));
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* A single formatter instance can be added to multiple loggers.
|
||||
* These methods provides hooks to notify the formatter of when it's added/removed.
|
||||
*
|
||||
* This is primarily for thread-safety.
|
||||
* If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
|
||||
* Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter with 10.0 behavior),
|
||||
* it could possibly use these hooks to switch to thread-safe versions of the code.
|
||||
**/
|
||||
- (void)didAddToLogger:(id <DDLogger>)logger;
|
||||
|
||||
/**
|
||||
* A single formatter instance can be added to multiple loggers.
|
||||
* These methods provides hooks to notify the formatter of when it's added/removed.
|
||||
*
|
||||
* This is primarily for thread-safety.
|
||||
* If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
|
||||
* Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter with 10.0 behavior),
|
||||
* it could possibly use these hooks to switch to thread-safe versions of the code or use dispatch_set_specific()
|
||||
.* to add its own specific values.
|
||||
**/
|
||||
- (void)didAddToLogger:(id <DDLogger>)logger inQueue:(dispatch_queue_t)queue;
|
||||
|
||||
/**
|
||||
* See the above description for `didAddToLogger:`
|
||||
*/
|
||||
- (void)willRemoveFromLogger:(id <DDLogger>)logger;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* This protocol describes a dynamic logging component
|
||||
*/
|
||||
@protocol DDRegisteredDynamicLogging
|
||||
|
||||
/**
|
||||
* Implement these methods to allow a file's log level to be managed from a central location.
|
||||
*
|
||||
* This is useful if you'd like to be able to change log levels for various parts
|
||||
* of your code from within the running application.
|
||||
*
|
||||
* Imagine pulling up the settings for your application,
|
||||
* and being able to configure the logging level on a per file basis.
|
||||
*
|
||||
* The implementation can be very straight-forward:
|
||||
*
|
||||
* ```
|
||||
* + (int)ddLogLevel
|
||||
* {
|
||||
* return ddLogLevel;
|
||||
* }
|
||||
*
|
||||
* + (void)ddSetLogLevel:(DDLogLevel)level
|
||||
* {
|
||||
* ddLogLevel = level;
|
||||
* }
|
||||
* ```
|
||||
**/
|
||||
@property (class, nonatomic, readwrite, setter=ddSetLogLevel:) DDLogLevel ddLogLevel;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef NS_DESIGNATED_INITIALIZER
|
||||
#define NS_DESIGNATED_INITIALIZER
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Log message options, allow copying certain log elements
|
||||
*/
|
||||
typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
|
||||
/**
|
||||
* Use this to use a copy of the file path
|
||||
*/
|
||||
DDLogMessageCopyFile = 1 << 0,
|
||||
/**
|
||||
* Use this to use a copy of the function name
|
||||
*/
|
||||
DDLogMessageCopyFunction = 1 << 1,
|
||||
/**
|
||||
* Use this to use avoid a copy of the message
|
||||
*/
|
||||
DDLogMessageDontCopyMessage = 1 << 2
|
||||
};
|
||||
|
||||
/**
|
||||
* The `DDLogMessage` class encapsulates information about the log message.
|
||||
* If you write custom loggers or formatters, you will be dealing with objects of this class.
|
||||
**/
|
||||
@interface DDLogMessage : NSObject <NSCopying>
|
||||
{
|
||||
// Direct accessors to be used only for performance
|
||||
@public
|
||||
NSString *_message;
|
||||
DDLogLevel _level;
|
||||
DDLogFlag _flag;
|
||||
NSInteger _context;
|
||||
NSString *_file;
|
||||
NSString *_fileName;
|
||||
NSString *_function;
|
||||
NSUInteger _line;
|
||||
#if DD_LEGACY_MESSAGE_TAG
|
||||
id _tag __attribute__((deprecated("Use _representedObject instead", "_representedObject")));;
|
||||
#endif
|
||||
id _representedObject;
|
||||
DDLogMessageOptions _options;
|
||||
NSDate * _timestamp;
|
||||
NSString *_threadID;
|
||||
NSString *_threadName;
|
||||
NSString *_queueLabel;
|
||||
NSUInteger _qos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default `init` for empty messages.
|
||||
*/
|
||||
- (instancetype)init NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Standard init method for a log message object.
|
||||
* Used by the logging primitives. (And the macros use the logging primitives.)
|
||||
*
|
||||
* If you find need to manually create logMessage objects, there is one thing you should be aware of:
|
||||
*
|
||||
* If no flags are passed, the method expects the file and function parameters to be string literals.
|
||||
* That is, it expects the given strings to exist for the duration of the object's lifetime,
|
||||
* and it expects the given strings to be immutable.
|
||||
* In other words, it does not copy these strings, it simply points to them.
|
||||
* This is due to the fact that __FILE__ and __FUNCTION__ are usually used to specify these parameters,
|
||||
* so it makes sense to optimize and skip the unnecessary allocations.
|
||||
* However, if you need them to be copied you may use the options parameter to specify this.
|
||||
*
|
||||
* @param message the message
|
||||
* @param level the log level
|
||||
* @param flag the log flag
|
||||
* @param context the context (if any is defined)
|
||||
* @param file the current file
|
||||
* @param function the current function
|
||||
* @param line the current code line
|
||||
* @param tag potential tag
|
||||
* @param options a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction.
|
||||
* @param timestamp the log timestamp
|
||||
*
|
||||
* @return a new instance of a log message model object
|
||||
*/
|
||||
- (instancetype)initWithMessage:(NSString *)message
|
||||
level:(DDLogLevel)level
|
||||
flag:(DDLogFlag)flag
|
||||
context:(NSInteger)context
|
||||
file:(NSString *)file
|
||||
function:(nullable NSString *)function
|
||||
line:(NSUInteger)line
|
||||
tag:(nullable id)tag
|
||||
options:(DDLogMessageOptions)options
|
||||
timestamp:(nullable NSDate *)timestamp NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Read-only properties
|
||||
**/
|
||||
|
||||
/**
|
||||
* The log message
|
||||
*/
|
||||
@property (readonly, nonatomic) NSString *message;
|
||||
@property (readonly, nonatomic) DDLogLevel level;
|
||||
@property (readonly, nonatomic) DDLogFlag flag;
|
||||
@property (readonly, nonatomic) NSInteger context;
|
||||
@property (readonly, nonatomic) NSString *file;
|
||||
@property (readonly, nonatomic) NSString *fileName;
|
||||
@property (readonly, nonatomic, nullable) NSString * function;
|
||||
@property (readonly, nonatomic) NSUInteger line;
|
||||
#if DD_LEGACY_MESSAGE_TAG
|
||||
@property (readonly, nonatomic, nullable) id tag __attribute__((deprecated("Use representedObject instead", "representedObject")));
|
||||
#endif
|
||||
@property (readonly, nonatomic, nullable) id representedObject;
|
||||
@property (readonly, nonatomic) DDLogMessageOptions options;
|
||||
@property (readonly, nonatomic) NSDate *timestamp;
|
||||
@property (readonly, nonatomic) NSString *threadID; // ID as it appears in NSLog calculated from the machThreadID
|
||||
@property (readonly, nonatomic, nullable) NSString *threadName;
|
||||
@property (readonly, nonatomic) NSString *queueLabel;
|
||||
@property (readonly, nonatomic) NSUInteger qos API_AVAILABLE(macos(10.10), ios(8.0));
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The `DDLogger` protocol specifies that an optional formatter can be added to a logger.
|
||||
* Most (but not all) loggers will want to support formatters.
|
||||
*
|
||||
* However, writing getters and setters in a thread safe manner,
|
||||
* while still maintaining maximum speed for the logging process, is a difficult task.
|
||||
*
|
||||
* To do it right, the implementation of the getter/setter has strict requirements:
|
||||
* - Must NOT require the `logMessage:` method to acquire a lock.
|
||||
* - Must NOT require the `logMessage:` method to access an atomic property (also a lock of sorts).
|
||||
*
|
||||
* To simplify things, an abstract logger is provided that implements the getter and setter.
|
||||
*
|
||||
* Logger implementations may simply extend this class,
|
||||
* and they can ACCESS THE FORMATTER VARIABLE DIRECTLY from within their `logMessage:` method!
|
||||
**/
|
||||
@interface DDAbstractLogger : NSObject <DDLogger>
|
||||
{
|
||||
// Direct accessors to be used only for performance
|
||||
@public
|
||||
id <DDLogFormatter> _logFormatter;
|
||||
dispatch_queue_t _loggerQueue;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong, nullable) id <DDLogFormatter> logFormatter;
|
||||
@property (nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE) dispatch_queue_t loggerQueue;
|
||||
|
||||
// For thread-safety assertions
|
||||
|
||||
/**
|
||||
* Return YES if the current logger uses a global queue for logging
|
||||
*/
|
||||
@property (nonatomic, readonly, getter=isOnGlobalLoggingQueue) BOOL onGlobalLoggingQueue;
|
||||
|
||||
/**
|
||||
* Return YES if the current logger uses the internal designated queue for logging
|
||||
*/
|
||||
@property (nonatomic, readonly, getter=isOnInternalLoggerQueue) BOOL onInternalLoggerQueue;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDLoggerInformation : NSObject
|
||||
|
||||
@property (nonatomic, readonly) id <DDLogger> logger;
|
||||
@property (nonatomic, readonly) DDLogLevel level;
|
||||
|
||||
+ (instancetype)informationWithLogger:(id <DDLogger>)logger
|
||||
andLevel:(DDLogLevel)level;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
101
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDLogMacros.h
generated
Normal file
101
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDLogMacros.h
generated
Normal file
@@ -0,0 +1,101 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDLog.h>
|
||||
|
||||
/**
|
||||
* The constant/variable/method responsible for controlling the current log level.
|
||||
**/
|
||||
#ifndef LOG_LEVEL_DEF
|
||||
#define LOG_LEVEL_DEF ddLogLevel
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Whether async should be used by log messages, excluding error messages that are always sent sync.
|
||||
**/
|
||||
#ifndef LOG_ASYNC_ENABLED
|
||||
#define LOG_ASYNC_ENABLED YES
|
||||
#endif
|
||||
|
||||
/**
|
||||
* These are the two macros that all other macros below compile into.
|
||||
* These big multiline macros makes all the other macros easier to read.
|
||||
**/
|
||||
#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
|
||||
[DDLog log : isAsynchronous \
|
||||
level : lvl \
|
||||
flag : flg \
|
||||
context : ctx \
|
||||
file : __FILE__ \
|
||||
function : fnct \
|
||||
line : __LINE__ \
|
||||
tag : atag \
|
||||
format : (frmt), ## __VA_ARGS__]
|
||||
|
||||
#define LOG_MACRO_TO_DDLOG(ddlog, isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
|
||||
[ddlog log : isAsynchronous \
|
||||
level : lvl \
|
||||
flag : flg \
|
||||
context : ctx \
|
||||
file : __FILE__ \
|
||||
function : fnct \
|
||||
line : __LINE__ \
|
||||
tag : atag \
|
||||
format : (frmt), ## __VA_ARGS__]
|
||||
|
||||
/**
|
||||
* Define version of the macro that only execute if the log level is above the threshold.
|
||||
* The compiled versions essentially look like this:
|
||||
*
|
||||
* if (logFlagForThisLogMsg & ddLogLevel) { execute log message }
|
||||
*
|
||||
* When LOG_LEVEL_DEF is defined as ddLogLevel.
|
||||
*
|
||||
* As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels.
|
||||
* This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques.
|
||||
*
|
||||
* Note that when compiler optimizations are enabled (as they are for your release builds),
|
||||
* the log messages above your logging threshold will automatically be compiled out.
|
||||
*
|
||||
* (If the compiler sees LOG_LEVEL_DEF/ddLogLevel declared as a constant, the compiler simply checks to see
|
||||
* if the 'if' statement would execute, and if not it strips it from the binary.)
|
||||
*
|
||||
* We also define shorthand versions for asynchronous and synchronous logging.
|
||||
**/
|
||||
#define LOG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
|
||||
do { if((lvl & flg) != 0) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
|
||||
|
||||
#define LOG_MAYBE_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ...) \
|
||||
do { if((lvl & flg) != 0) LOG_MACRO_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
|
||||
|
||||
/**
|
||||
* Ready to use log macros with no context or tag.
|
||||
**/
|
||||
#define DDLogError(frmt, ...) LOG_MAYBE(NO, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
#define DDLogWarn(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
#define DDLogInfo(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
#define DDLogDebug(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
#define DDLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define DDLogErrorToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, NO, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
#define DDLogWarnToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
#define DDLogInfoToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
#define DDLogDebugToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
#define DDLogVerboseToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
30
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDLoggerNames.h
generated
Normal file
30
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDLoggerNames.h
generated
Normal file
@@ -0,0 +1,30 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NSString *DDLoggerName NS_EXTENSIBLE_STRING_ENUM;
|
||||
|
||||
FOUNDATION_EXPORT DDLoggerName const DDLoggerNameOS NS_SWIFT_NAME(DDLoggerName.os); // DDOSLogger
|
||||
FOUNDATION_EXPORT DDLoggerName const DDLoggerNameFile NS_SWIFT_NAME(DDLoggerName.file); // DDFileLogger
|
||||
|
||||
FOUNDATION_EXPORT DDLoggerName const DDLoggerNameTTY NS_SWIFT_NAME(DDLoggerName.tty); // DDTTYLogger
|
||||
|
||||
API_DEPRECATED("Use DDOSLogger instead", macosx(10.4, 10.12), ios(2.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0))
|
||||
FOUNDATION_EXPORT DDLoggerName const DDLoggerNameASL NS_SWIFT_NAME(DDLoggerName.asl); // DDASLLogger
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
60
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDMultiFormatter.h
generated
Normal file
60
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDMultiFormatter.h
generated
Normal file
@@ -0,0 +1,60 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <Foundation/Foundation.h>
|
||||
|
||||
// Disable legacy macros
|
||||
#ifndef DD_LEGACY_MACROS
|
||||
#define DD_LEGACY_MACROS 0
|
||||
#endif
|
||||
|
||||
#import <CocoaLumberjack/DDLog.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* This formatter can be used to chain different formatters together.
|
||||
* The log message will processed in the order of the formatters added.
|
||||
**/
|
||||
@interface DDMultiFormatter : NSObject <DDLogFormatter>
|
||||
|
||||
/**
|
||||
* Array of chained formatters
|
||||
*/
|
||||
@property (nonatomic, readonly) NSArray<id<DDLogFormatter>> *formatters;
|
||||
|
||||
/**
|
||||
* Add a new formatter
|
||||
*/
|
||||
- (void)addFormatter:(id<DDLogFormatter>)formatter NS_SWIFT_NAME(add(_:));
|
||||
|
||||
/**
|
||||
* Remove a formatter
|
||||
*/
|
||||
- (void)removeFormatter:(id<DDLogFormatter>)formatter NS_SWIFT_NAME(remove(_:));
|
||||
|
||||
/**
|
||||
* Remove all existing formatters
|
||||
*/
|
||||
- (void)removeAllFormatters NS_SWIFT_NAME(removeAll());
|
||||
|
||||
/**
|
||||
* Check if a certain formatter is used
|
||||
*/
|
||||
- (BOOL)isFormattingWithFormatter:(id<DDLogFormatter>)formatter;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
55
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDOSLogger.h
generated
Normal file
55
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDOSLogger.h
generated
Normal file
@@ -0,0 +1,55 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <Foundation/Foundation.h>
|
||||
|
||||
// Disable legacy macros
|
||||
#ifndef DD_LEGACY_MACROS
|
||||
#define DD_LEGACY_MACROS 0
|
||||
#endif
|
||||
|
||||
#import <CocoaLumberjack/DDLog.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* This class provides a logger for the Apple os_log facility.
|
||||
**/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
|
||||
@interface DDOSLogger : DDAbstractLogger <DDLogger>
|
||||
|
||||
/**
|
||||
* Singleton method
|
||||
*
|
||||
* @return the shared instance with OS_LOG_DEFAULT.
|
||||
*/
|
||||
@property (nonatomic, class, readonly, strong) DDOSLogger *sharedInstance;
|
||||
|
||||
/**
|
||||
Designated initializer
|
||||
|
||||
@param subsystem Desired subsystem in log. E.g. "org.example"
|
||||
@param category Desired category in log. E.g. "Point of interests."
|
||||
@return New instance of DDOSLogger.
|
||||
|
||||
@discussion This method requires either both or no parameter to be set. Much like `(String, String)?` in Swift.
|
||||
If both parameters are nil, this method will return a logger configured with `OS_LOG_DEFAULT`.
|
||||
If both parameters are non-nil, it will return a logger configured with `os_log_create(subsystem, category)`
|
||||
*/
|
||||
- (instancetype)initWithSubsystem:(nullable NSString *)subsystem category:(nullable NSString *)category NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
186
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDTTYLogger.h
generated
Normal file
186
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDTTYLogger.h
generated
Normal file
@@ -0,0 +1,186 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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 <CocoaLumberjack/DDLog.h>
|
||||
|
||||
#define LOG_CONTEXT_ALL INT_MAX
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-function"
|
||||
#if !(TARGET_OS_OSX)
|
||||
// iOS or tvOS or watchOS
|
||||
#import <UIKit/UIColor.h>
|
||||
typedef UIColor DDColor;
|
||||
static inline DDColor* _Nonnull DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
|
||||
#elif defined(DD_CLI) || !__has_include(<AppKit/NSColor.h>)
|
||||
// OS X CLI
|
||||
#import <CocoaLumberjack/CLIColor.h>
|
||||
typedef CLIColor DDColor;
|
||||
static inline DDColor* _Nonnull DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
|
||||
#else
|
||||
// OS X with AppKit
|
||||
#import <AppKit/NSColor.h>
|
||||
typedef NSColor DDColor;
|
||||
static inline DDColor * _Nonnull DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
|
||||
#endif
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* This class provides a logger for Terminal output or Xcode console output,
|
||||
* depending on where you are running your code.
|
||||
*
|
||||
* As described in the "Getting Started" page,
|
||||
* the traditional NSLog() function directs it's output to two places:
|
||||
*
|
||||
* - Apple System Log (so it shows up in Console.app)
|
||||
* - 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 an asl logger.
|
||||
* However, if you instead choose to use file logging (for faster performance),
|
||||
* you may choose to use only a file logger and a tty logger.
|
||||
**/
|
||||
@interface DDTTYLogger : DDAbstractLogger <DDLogger>
|
||||
|
||||
/**
|
||||
* Singleton instance. Returns `nil` if the initialization of the DDTTYLogger fails.
|
||||
*/
|
||||
@property (nonatomic, class, readonly, strong, nullable) DDTTYLogger *sharedInstance;
|
||||
|
||||
/* Inherited from the DDLogger protocol:
|
||||
*
|
||||
* Formatters may optionally be added to any logger.
|
||||
*
|
||||
* If no formatter is set, the logger simply logs the message as it is given in logMessage,
|
||||
* or it may use its own built in formatting style.
|
||||
*
|
||||
* More information about formatters can be found here:
|
||||
* Documentation/CustomFormatters.md
|
||||
*
|
||||
* The actual implementation of these methods is inherited from DDAbstractLogger.
|
||||
|
||||
- (id <DDLogFormatter>)logFormatter;
|
||||
- (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Want to use different colors for different log levels?
|
||||
* Enable this property.
|
||||
*
|
||||
* If you run the application via the Terminal (not Xcode),
|
||||
* the logger will map colors to xterm-256color or xterm-color (if available).
|
||||
*
|
||||
* Xcode does NOT natively support colors in the Xcode debugging console.
|
||||
* You'll need to install the XcodeColors plugin to see colors in the Xcode console.
|
||||
* https://github.com/robbiehanson/XcodeColors
|
||||
*
|
||||
* The default value is NO.
|
||||
**/
|
||||
@property (readwrite, assign) BOOL colorsEnabled;
|
||||
|
||||
/**
|
||||
* When using a custom formatter you can set the `logMessage` method not to append
|
||||
* `\n` character after each output. This allows for some greater flexibility with
|
||||
* custom formatters. Default value is YES.
|
||||
**/
|
||||
@property (nonatomic, readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
|
||||
|
||||
/**
|
||||
Using this initializer is not supported. Please use `DDTTYLogger.sharedInstance`.
|
||||
**/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
* The default color set (foregroundColor, backgroundColor) is:
|
||||
*
|
||||
* - DDLogFlagError = (red, nil)
|
||||
* - DDLogFlagWarning = (orange, nil)
|
||||
*
|
||||
* You can customize the colors however you see fit.
|
||||
* Please note that you are passing a flag, NOT a level.
|
||||
*
|
||||
* GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:DDLogFlagInfo]; // <- Good :)
|
||||
* BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:DDLogLevelInfo]; // <- BAD! :(
|
||||
*
|
||||
* DDLogFlagInfo = 0...00100
|
||||
* DDLogLevelInfo = 0...00111 <- Would match DDLogFlagInfo and DDLogFlagWarning and DDLogFlagError
|
||||
*
|
||||
* If you run the application within Xcode, then the XcodeColors plugin is required.
|
||||
*
|
||||
* If you run the application from a shell, then DDTTYLogger will automatically map the given color to
|
||||
* the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.)
|
||||
*
|
||||
* This method invokes setForegroundColor:backgroundColor:forFlag:context: and applies it to `LOG_CONTEXT_ALL`.
|
||||
**/
|
||||
- (void)setForegroundColor:(nullable DDColor *)txtColor backgroundColor:(nullable DDColor *)bgColor forFlag:(DDLogFlag)mask;
|
||||
|
||||
/**
|
||||
* Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
|
||||
*
|
||||
* A logging context is often used to identify log messages coming from a 3rd party framework,
|
||||
* although logging context's can be used for many different functions.
|
||||
*
|
||||
* Use LOG_CONTEXT_ALL to set the default color for all contexts that have no specific color set defined.
|
||||
*
|
||||
* Logging context's are explained in further detail here:
|
||||
* Documentation/CustomContext.md
|
||||
**/
|
||||
- (void)setForegroundColor:(nullable DDColor *)txtColor backgroundColor:(nullable DDColor *)bgColor forFlag:(DDLogFlag)mask context:(NSInteger)ctxt;
|
||||
|
||||
/**
|
||||
* Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile.
|
||||
* For example, you could do something like this:
|
||||
*
|
||||
* static NSString *const PurpleTag = @"PurpleTag";
|
||||
*
|
||||
* #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
|
||||
*
|
||||
* And then where you configure CocoaLumberjack:
|
||||
*
|
||||
* purple = DDMakeColor((64/255.0), (0/255.0), (128/255.0));
|
||||
*
|
||||
* or any UIColor/NSColor constructor.
|
||||
*
|
||||
* Note: For CLI OS X projects that don't link with AppKit use CLIColor objects instead
|
||||
*
|
||||
* [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
|
||||
* [DDLog addLogger:[DDTTYLogger sharedInstance]];
|
||||
*
|
||||
* This would essentially give you a straight NSLog replacement that prints in purple:
|
||||
*
|
||||
* DDLogPurple(@"I'm a purple log message!");
|
||||
**/
|
||||
- (void)setForegroundColor:(nullable DDColor *)txtColor backgroundColor:(nullable DDColor *)bgColor forTag:(id <NSCopying>)tag;
|
||||
|
||||
/**
|
||||
* Clearing color profiles.
|
||||
**/
|
||||
- (void)clearColorsForFlag:(DDLogFlag)mask;
|
||||
- (void)clearColorsForFlag:(DDLogFlag)mask context:(NSInteger)context;
|
||||
- (void)clearColorsForTag:(id <NSCopying>)tag;
|
||||
- (void)clearColorsForAllFlags;
|
||||
- (void)clearColorsForAllTags;
|
||||
- (void)clearAllColors;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
193
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjackSwift/CocoaLumberjack.swift
generated
Normal file
193
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjackSwift/CocoaLumberjack.swift
generated
Normal file
@@ -0,0 +1,193 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
@_exported import CocoaLumberjack
|
||||
#if SWIFT_PACKAGE
|
||||
import CocoaLumberjackSwiftSupport
|
||||
#endif
|
||||
|
||||
extension DDLogFlag {
|
||||
public static func from(_ logLevel: DDLogLevel) -> DDLogFlag {
|
||||
return DDLogFlag(rawValue: logLevel.rawValue)
|
||||
}
|
||||
|
||||
public init(_ logLevel: DDLogLevel) {
|
||||
self = DDLogFlag(rawValue: logLevel.rawValue)
|
||||
}
|
||||
|
||||
/// Returns the log level, or the lowest equivalent.
|
||||
public func toLogLevel() -> DDLogLevel {
|
||||
if let ourValid = DDLogLevel(rawValue: rawValue) {
|
||||
return ourValid
|
||||
} else {
|
||||
if contains(.verbose) {
|
||||
return .verbose
|
||||
} else if contains(.debug) {
|
||||
return .debug
|
||||
} else if contains(.info) {
|
||||
return .info
|
||||
} else if contains(.warning) {
|
||||
return .warning
|
||||
} else if contains(.error) {
|
||||
return .error
|
||||
} else {
|
||||
return .off
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The log level that can dynamically limit log messages (vs. the static DDDefaultLogLevel). This log level will only be checked, if the message passes the `DDDefaultLogLevel`.
|
||||
public var dynamicLogLevel = DDLogLevel.all
|
||||
|
||||
/// Resets the `dynamicLogLevel` to `.all`.
|
||||
/// - SeeAlso: `dynamicLogLevel`
|
||||
@inlinable
|
||||
public func resetDynamicLogLevel() {
|
||||
dynamicLogLevel = .all
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Please use dynamicLogLevel", renamed: "dynamicLogLevel")
|
||||
public var defaultDebugLevel: DDLogLevel {
|
||||
get {
|
||||
return dynamicLogLevel
|
||||
}
|
||||
set {
|
||||
dynamicLogLevel = newValue
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Please use resetDynamicLogLevel", renamed: "resetDynamicLogLevel")
|
||||
public func resetDefaultDebugLevel() {
|
||||
resetDynamicLogLevel()
|
||||
}
|
||||
|
||||
/// If `true`, all logs (except errors) are logged asynchronously by default.
|
||||
public var asyncLoggingEnabled = true
|
||||
|
||||
@inlinable
|
||||
public func _DDLogMessage(_ message: @autoclosure () -> Any,
|
||||
level: DDLogLevel,
|
||||
flag: DDLogFlag,
|
||||
context: Int,
|
||||
file: StaticString,
|
||||
function: StaticString,
|
||||
line: UInt,
|
||||
tag: Any?,
|
||||
asynchronous: Bool,
|
||||
ddlog: DDLog) {
|
||||
// The `dynamicLogLevel` will always be checked here (instead of being passed in).
|
||||
// We cannot "mix" it with the `DDDefaultLogLevel`, because otherwise the compiler won't strip strings that are not logged.
|
||||
if level.rawValue & flag.rawValue != 0 && dynamicLogLevel.rawValue & flag.rawValue != 0 {
|
||||
// Tell the DDLogMessage constructor to copy the C strings that get passed to it.
|
||||
let logMessage = DDLogMessage(message: String(describing: message()),
|
||||
level: level,
|
||||
flag: flag,
|
||||
context: context,
|
||||
file: String(describing: file),
|
||||
function: String(describing: function),
|
||||
line: line,
|
||||
tag: tag,
|
||||
options: [.copyFile, .copyFunction],
|
||||
timestamp: nil)
|
||||
ddlog.log(asynchronous: asynchronous, message: logMessage)
|
||||
}
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func DDLogDebug(_ message: @autoclosure () -> Any,
|
||||
level: DDLogLevel = DDDefaultLogLevel,
|
||||
context: Int = 0,
|
||||
file: StaticString = #file,
|
||||
function: StaticString = #function,
|
||||
line: UInt = #line,
|
||||
tag: Any? = nil,
|
||||
asynchronous async: Bool = asyncLoggingEnabled,
|
||||
ddlog: DDLog = .sharedInstance) {
|
||||
_DDLogMessage(message(), level: level, flag: .debug, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func DDLogInfo(_ message: @autoclosure () -> Any,
|
||||
level: DDLogLevel = DDDefaultLogLevel,
|
||||
context: Int = 0,
|
||||
file: StaticString = #file,
|
||||
function: StaticString = #function,
|
||||
line: UInt = #line,
|
||||
tag: Any? = nil,
|
||||
asynchronous async: Bool = asyncLoggingEnabled,
|
||||
ddlog: DDLog = .sharedInstance) {
|
||||
_DDLogMessage(message(), level: level, flag: .info, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func DDLogWarn(_ message: @autoclosure () -> Any,
|
||||
level: DDLogLevel = DDDefaultLogLevel,
|
||||
context: Int = 0,
|
||||
file: StaticString = #file,
|
||||
function: StaticString = #function,
|
||||
line: UInt = #line,
|
||||
tag: Any? = nil,
|
||||
asynchronous async: Bool = asyncLoggingEnabled,
|
||||
ddlog: DDLog = .sharedInstance) {
|
||||
_DDLogMessage(message(), level: level, flag: .warning, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func DDLogVerbose(_ message: @autoclosure () -> Any,
|
||||
level: DDLogLevel = DDDefaultLogLevel,
|
||||
context: Int = 0,
|
||||
file: StaticString = #file,
|
||||
function: StaticString = #function,
|
||||
line: UInt = #line,
|
||||
tag: Any? = nil,
|
||||
asynchronous async: Bool = asyncLoggingEnabled,
|
||||
ddlog: DDLog = .sharedInstance) {
|
||||
_DDLogMessage(message(), level: level, flag: .verbose, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func DDLogError(_ message: @autoclosure () -> Any,
|
||||
level: DDLogLevel = DDDefaultLogLevel,
|
||||
context: Int = 0,
|
||||
file: StaticString = #file,
|
||||
function: StaticString = #function,
|
||||
line: UInt = #line,
|
||||
tag: Any? = nil,
|
||||
asynchronous async: Bool = false,
|
||||
ddlog: DDLog = .sharedInstance) {
|
||||
_DDLogMessage(message(), level: level, flag: .error, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
|
||||
}
|
||||
|
||||
/// Returns a String of the current filename, without full path or extension.
|
||||
///
|
||||
/// Analogous to the C preprocessor macro `THIS_FILE`.
|
||||
public func currentFileName(_ fileName: StaticString = #file) -> String {
|
||||
var str = String(describing: fileName)
|
||||
if let idx = str.range(of: "/", options: .backwards)?.upperBound {
|
||||
str = String(str[idx...])
|
||||
}
|
||||
if let idx = str.range(of: ".", options: .backwards)?.lowerBound {
|
||||
str = String(str[..<idx])
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
// swiftlint:disable identifier_name
|
||||
// swiftlint doesn't like func names that begin with a capital letter - deprecated
|
||||
@available(*, deprecated, message: "Please use currentFileName", renamed: "currentFileName")
|
||||
public func CurrentFileName(_ fileName: StaticString = #file) -> String {
|
||||
return currentFileName(fileName)
|
||||
}
|
||||
50
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjackSwift/DDAssert.swift
generated
Normal file
50
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjackSwift/DDAssert.swift
generated
Normal file
@@ -0,0 +1,50 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
#if SWIFT_PACKAGE
|
||||
import CocoaLumberjack
|
||||
import CocoaLumberjackSwiftSupport
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Replacement for Swift's `assert` function that will output a log message even when assertions
|
||||
* are disabled.
|
||||
*
|
||||
* - Parameters:
|
||||
* - condition: The condition to test. Unlike `Swift.assert`, `condition` is always evaluated,
|
||||
* even when assertions are disabled.
|
||||
* - message: A string to log (using `DDLogError`) if `condition` evaluates to `false`.
|
||||
* The default is an empty string.
|
||||
*/
|
||||
@inlinable
|
||||
public func DDAssert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = "", level: DDLogLevel = DDDefaultLogLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = false, ddlog: DDLog = DDLog.sharedInstance) {
|
||||
if !condition() {
|
||||
DDLogError(message(), level: level, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
|
||||
Swift.assertionFailure(message(), file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replacement for Swift's `assertionFailure` function that will output a log message even
|
||||
* when assertions are disabled.
|
||||
*
|
||||
* - Parameters:
|
||||
* - message: A string to log (using `DDLogError`). The default is an empty string.
|
||||
*/
|
||||
@inlinable
|
||||
public func DDAssertionFailure(_ message: @autoclosure () -> String = "", level: DDLogLevel = DDDefaultLogLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = false, ddlog: DDLog = DDLog.sharedInstance) {
|
||||
DDLogError(message(), level: level, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
|
||||
Swift.assertionFailure(message(), file: file, line: line)
|
||||
}
|
||||
112
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjackSwift/DDLog+Combine.swift
generated
Normal file
112
Example/Pods/CocoaLumberjack/Sources/CocoaLumberjackSwift/DDLog+Combine.swift
generated
Normal file
@@ -0,0 +1,112 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
#if arch(arm64) || arch(x86_64)
|
||||
#if canImport(Combine)
|
||||
import Combine
|
||||
|
||||
#if SWIFT_PACKAGE
|
||||
import CocoaLumberjack
|
||||
import CocoaLumberjackSwiftSupport
|
||||
#endif
|
||||
|
||||
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
extension DDLog {
|
||||
/**
|
||||
* Creates a message publisher.
|
||||
*
|
||||
* The publisher will add and remove loggers as subscriptions are added and removed.
|
||||
*
|
||||
* The level that you provide here is a preemptive filter (for performance).
|
||||
* That is, the level specified here will be used to filter out logMessages so that
|
||||
* the logger is never even invoked for the messages.
|
||||
*
|
||||
* More information:
|
||||
* See -[DDLog addLogger:with:]
|
||||
*
|
||||
* - Parameter logLevel: preemptive filter of the message returned by the publisher. All levels are sent by default
|
||||
* - Returns: A MessagePublisher that emits LogMessages filtered by the specified logLevel
|
||||
**/
|
||||
public func messagePublisher(with logLevel: DDLogLevel = .all) -> MessagePublisher {
|
||||
return MessagePublisher(log: self, with: logLevel)
|
||||
}
|
||||
|
||||
// MARK: - MessagePublisher
|
||||
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
public struct MessagePublisher: Combine.Publisher {
|
||||
public typealias Output = DDLogMessage
|
||||
public typealias Failure = Never
|
||||
|
||||
private let log: DDLog
|
||||
private let logLevel: DDLogLevel
|
||||
|
||||
public init(log: DDLog, with logLevel: DDLogLevel) {
|
||||
self.log = log
|
||||
self.logLevel = logLevel
|
||||
}
|
||||
|
||||
public func receive<S>(subscriber: S) where S: Subscriber, S.Failure == Failure, S.Input == Output {
|
||||
let subscription = Subscription(log: log, with: logLevel, subscriber: subscriber)
|
||||
subscriber.receive(subscription: subscription)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Subscription
|
||||
private final class Subscription<S: Subscriber>: NSObject, DDLogger, Combine.Subscription where S.Input == DDLogMessage {
|
||||
private var subscriber: S?
|
||||
private weak var log: DDLog?
|
||||
|
||||
//Not used but DDLogger requires it. The preferred way to achieve this is to use the `map()` Combine operator of the publisher.
|
||||
//ie:
|
||||
// DDLog.sharedInstance.messagePublisher()
|
||||
// .map { [format log message] }
|
||||
// .sink(receiveValue: { [process log message] })
|
||||
//
|
||||
var logFormatter: DDLogFormatter?
|
||||
|
||||
init(log: DDLog, with logLevel: DDLogLevel, subscriber: S) {
|
||||
self.subscriber = subscriber
|
||||
self.log = log
|
||||
|
||||
super.init()
|
||||
|
||||
log.add(self, with: logLevel)
|
||||
}
|
||||
|
||||
func request(_ demand: Subscribers.Demand) {
|
||||
//The log messages are endless until canceled, so we won't do any demand management.
|
||||
//Combine operators can be used to deal with it as needed.
|
||||
}
|
||||
|
||||
func cancel() {
|
||||
log?.remove(self)
|
||||
subscriber = nil
|
||||
}
|
||||
|
||||
func log(message logMessage: DDLogMessage) {
|
||||
_ = subscriber?.receive(logMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
extension Publisher where Output == DDLogMessage {
|
||||
public func formatted(with formatter: DDLogFormatter) -> Publishers.CompactMap<Self, String> {
|
||||
return compactMap { formatter.format(message: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
// Software License Agreement (BSD License)
|
||||
//
|
||||
// Copyright (c) 2010-2021, 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.
|
||||
|
||||
#ifndef SwiftLogLevel_h
|
||||
#define SwiftLogLevel_h
|
||||
|
||||
#import <CocoaLumberjack/DDLog.h>
|
||||
|
||||
#ifndef DD_LOG_LEVEL
|
||||
// #warning 'DD_LOG_LEVEL' is not defined. Using 'DDLogLevelAll' as default. Consider defining it yourself.
|
||||
#define DD_LOG_LEVEL DDLogLevelAll
|
||||
#endif
|
||||
|
||||
static const DDLogLevel DDDefaultLogLevel = DD_LOG_LEVEL;
|
||||
|
||||
#endif /* SwiftLogLevel_h */
|
||||
Reference in New Issue
Block a user