DDOSLogger.m 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Software License Agreement (BSD License)
  2. //
  3. // Copyright (c) 2010-2024, Deusty, LLC
  4. // All rights reserved.
  5. //
  6. // Redistribution and use of this software in source and binary forms,
  7. // with or without modification, are permitted provided that the following conditions are met:
  8. //
  9. // * Redistributions of source code must retain the above copyright notice,
  10. // this list of conditions and the following disclaimer.
  11. //
  12. // * Neither the name of Deusty nor the names of its contributors may be used
  13. // to endorse or promote products derived from this software without specific
  14. // prior written permission of Deusty, LLC.
  15. #import <TargetConditionals.h>
  16. #import <os/log.h>
  17. #import <CocoaLumberjack/DDOSLogger.h>
  18. @implementation DDOSLogLevelMapperDefault
  19. - (instancetype)init {
  20. self = [super init];
  21. return self;
  22. }
  23. - (os_log_type_t)osLogTypeForLogFlag:(DDLogFlag)logFlag {
  24. switch (logFlag) {
  25. case DDLogFlagError:
  26. case DDLogFlagWarning:
  27. return OS_LOG_TYPE_ERROR;
  28. case DDLogFlagInfo:
  29. return OS_LOG_TYPE_INFO;
  30. case DDLogFlagDebug:
  31. case DDLogFlagVerbose:
  32. return OS_LOG_TYPE_DEBUG;
  33. default:
  34. return OS_LOG_TYPE_DEFAULT;
  35. }
  36. }
  37. @end
  38. #if TARGET_OS_SIMULATOR
  39. @implementation DDOSLogLevelMapperSimulatorConsoleAppWorkaround
  40. - (os_log_type_t)osLogTypeForLogFlag:(DDLogFlag)logFlag {
  41. __auto_type defaultMapping = [super osLogTypeForLogFlag:logFlag];
  42. return (defaultMapping == OS_LOG_TYPE_DEBUG) ? OS_LOG_TYPE_DEFAULT : defaultMapping;
  43. }
  44. @end
  45. #endif
  46. @interface DDOSLogger ()
  47. @property (nonatomic, copy, readonly, nullable) NSString *subsystem;
  48. @property (nonatomic, copy, readonly, nullable) NSString *category;
  49. @property (nonatomic, strong, readonly, nonnull) os_log_t logger;
  50. @end
  51. @implementation DDOSLogger
  52. @synthesize subsystem = _subsystem;
  53. @synthesize category = _category;
  54. @synthesize logLevelMapper = _logLevelMapper;
  55. @synthesize logger = _logger;
  56. #pragma mark - Shared Instance
  57. API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
  58. static DDOSLogger *sharedInstance;
  59. + (instancetype)sharedInstance {
  60. static dispatch_once_t DDOSLoggerOnceToken;
  61. dispatch_once(&DDOSLoggerOnceToken, ^{
  62. sharedInstance = [[[self class] alloc] init];
  63. });
  64. return sharedInstance;
  65. }
  66. #pragma mark - Initialization
  67. - (instancetype)initWithSubsystem:(NSString *)subsystem category:(NSString *)category {
  68. NSAssert((subsystem == nil) == (category == nil),
  69. @"Either both subsystem and category or neither should be nil.");
  70. if (self = [super init]) {
  71. _subsystem = [subsystem copy];
  72. _category = [category copy];
  73. _logLevelMapper = [[DDOSLogLevelMapperDefault alloc] init];
  74. }
  75. return self;
  76. }
  77. - (instancetype)init {
  78. return [self initWithSubsystem:nil category:nil];
  79. }
  80. - (instancetype)initWithSubsystem:(NSString *)subsystem
  81. category:(NSString *)category
  82. logLevelMapper:(id<DDOSLogLevelMapper>)logLevelMapper {
  83. if (self = [self initWithSubsystem:subsystem category:category]) {
  84. NSParameterAssert(logLevelMapper);
  85. _logLevelMapper = logLevelMapper;
  86. }
  87. return self;
  88. }
  89. - (instancetype)initWithLogLevelMapper:(id<DDOSLogLevelMapper>)logLevelMapper {
  90. return [self initWithSubsystem:nil category:nil logLevelMapper:logLevelMapper];
  91. }
  92. #pragma mark - Mapper
  93. - (id<DDOSLogLevelMapper>)logLevelMapper {
  94. if (_logLevelMapper == nil) {
  95. _logLevelMapper = [[DDOSLogLevelMapperDefault alloc] init];
  96. }
  97. return _logLevelMapper;
  98. }
  99. #pragma mark - os_log
  100. - (os_log_t)logger {
  101. if (_logger == nil) {
  102. if (self.subsystem == nil || self.category == nil) {
  103. _logger = OS_LOG_DEFAULT;
  104. } else {
  105. _logger = os_log_create(self.subsystem.UTF8String, self.category.UTF8String);
  106. }
  107. }
  108. return _logger;
  109. }
  110. #pragma mark - DDLogger
  111. - (DDLoggerName)loggerName {
  112. return DDLoggerNameOS;
  113. }
  114. - (void)logMessage:(DDLogMessage *)logMessage {
  115. #if !TARGET_OS_WATCH // See DDASLLogCapture.m -> Was never supported on watchOS.
  116. // Skip captured log messages.
  117. if ([logMessage->_fileName isEqualToString:@"DDASLLogCapture"]) {
  118. return;
  119. }
  120. #endif
  121. if (@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) {
  122. __auto_type message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
  123. if (message != nil) {
  124. __auto_type logType = [self.logLevelMapper osLogTypeForLogFlag:logMessage->_flag];
  125. os_log_with_type(self.logger, logType, "%{public}s", message.UTF8String);
  126. }
  127. }
  128. }
  129. @end