Pass data to the correct CocoaLumberjack fields

This commit is contained in:
Max Radermacher 2023-11-17 12:30:04 -06:00 committed by GitHub
parent ea99e9002f
commit af692d0a1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 188 additions and 243 deletions

View File

@ -28,7 +28,7 @@ Pod::Spec.new do |s|
s.prefix_header_file = 'SignalCoreKit/SCKPrefix.h'
s.xcconfig = { 'OTHER_CFLAGS' => '$(inherited) -DSQLITE_HAS_CODEC' }
s.dependency 'CocoaLumberjack'
s.dependency 'CocoaLumberjack', '~> 3.7.4'
s.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'SignalCoreKitTests/src/**/*.{h,m,swift}'

View File

@ -10,10 +10,12 @@ public struct OWSAssertionError: Error {
#endif
public let description: String
public init(_ description: String,
file: String = #file,
function: String = #function,
line: Int = #line) {
public init(
_ description: String,
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
#if TESTABLE_BUILD
if Self.test_skipAssertions {
Logger.warn("assertionError: \(description)")

View File

@ -2,75 +2,90 @@
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import CocoaLumberjack
import Foundation
@inlinable
public func owsFormatLogMessage(_ logString: String,
file: String = #file,
function: String = #function,
line: Int = #line) -> String {
let filename = (file as NSString).lastPathComponent
// We format the filename & line number in a format compatible
// with XCode's "Open Quickly..." feature.
return "[\(filename):\(line) \(function)]: \(logString)"
}
/**
* A minimal DDLog wrapper for swift.
*/
open class Logger: NSObject {
open class func verbose(_ logString: @autoclosure () -> String,
file: String = #file,
function: String = #function,
line: Int = #line) {
guard ShouldLogVerbose() else {
public enum Logger {
/// Logs `logString()` if the level represented by `flag` is enabled.
public static func log(
_ logString: @autoclosure () -> String,
flag: DDLogFlag,
file: String,
function: String,
line: Int
) {
guard ShouldLogFlag(flag) else {
return
}
OWSLogger.verbose(owsFormatLogMessage(logString(), file: file, function: function, line: line))
DDLog.log(asynchronous: true, message: DDLogMessage(
message: logString(),
level: ddLogLevel,
flag: flag,
context: 0,
file: file,
function: function,
line: UInt(line),
tag: nil,
timestamp: nil
))
}
open class func debug(_ logString: @autoclosure () -> String,
file: String = #file,
function: String = #function,
line: Int = #line) {
guard ShouldLogDebug() else {
return
}
OWSLogger.debug(owsFormatLogMessage(logString(), file: file, function: function, line: line))
private static func log(
_ logString: @autoclosure () -> String,
flag: DDLogFlag,
fileID: String,
function: String,
line: Int
) {
log(logString(), flag: flag, file: (fileID as NSString).lastPathComponent, function: function, line: line)
}
open class func info(_ logString: @autoclosure () -> String,
file: String = #file,
function: String = #function,
line: Int = #line) {
guard ShouldLogInfo() else {
return
}
OWSLogger.info(owsFormatLogMessage(logString(), file: file, function: function, line: line))
public static func verbose(
_ logString: @autoclosure () -> String,
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
log(logString(), flag: .verbose, fileID: file, function: function, line: line)
}
open class func warn(_ logString: @autoclosure () -> String,
file: String = #file,
function: String = #function,
line: Int = #line) {
guard ShouldLogWarning() else {
return
}
OWSLogger.warn(owsFormatLogMessage(logString(), file: file, function: function, line: line))
public static func debug(
_ logString: @autoclosure () -> String,
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
log(logString(), flag: .debug, fileID: file, function: function, line: line)
}
open class func error(_ logString: @autoclosure () -> String,
file: String = #file,
function: String = #function,
line: Int = #line) {
guard ShouldLogError() else {
return
}
OWSLogger.error(owsFormatLogMessage(logString(), file: file, function: function, line: line))
public static func info(
_ logString: @autoclosure () -> String,
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
log(logString(), flag: .info, fileID: file, function: function, line: line)
}
open class func flush() {
OWSLogger.flush()
public static func warn(
_ logString: @autoclosure () -> String,
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
log(logString(), flag: .warning, fileID: file, function: function, line: line)
}
public static func error(
_ logString: @autoclosure () -> String,
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
log(logString(), flag: .error, fileID: file, function: function, line: line)
}
public static func flush() {
DDLog.flushLog()
}
}

View File

@ -110,14 +110,12 @@ NS_ASSUME_NONNULL_BEGIN
#define OWSFailDebug(_messageFormat, ...) \
do { \
OWSLogError(_messageFormat, ##__VA_ARGS__); \
OWSLogFlush(); \
OWSFailWithoutLogging(_messageFormat, ##__VA_ARGS__); \
} while (0)
#define OWSCFailDebug(_messageFormat, ...) \
do { \
OWSLogError(_messageFormat, ##__VA_ARGS__); \
OWSLogFlush(); \
OWSCFailWithoutLogging(_messageFormat, ##__VA_ARGS__); \
} while (NO)
@ -139,66 +137,19 @@ void SwiftExit(NSString *message, const char *file, const char *function, int li
SwiftExit(_message, __FILE__, __PRETTY_FUNCTION__, __LINE__); \
} while (NO)
// Avoids Clang analyzer warning:
// Value stored to 'x' during it's initialization is never read
#define SUPPRESS_DEADSTORE_WARNING(x) \
do { \
(void)x; \
} while (0)
__attribute__((annotate("returns_localized_nsstring"))) static inline NSString *LocalizationNotNeeded(NSString *s)
{
return s;
}
#define OWSGuardWithException(X, ExceptionName) \
do { \
if (!(X)) { \
OWSRaiseException(ExceptionName, @"Guard failed: %s", CONVERT_EXPR_TO_STRING(X)); \
} \
} while (NO)
#define OWSRaiseException(name, formatParam, ...) \
do { \
OWSLogWarn(@"Exception: %@ %@", name, [NSString stringWithFormat:formatParam, ##__VA_ARGS__]); \
OWSLogFlush(); \
@throw [NSException exceptionWithName:name \
reason:[NSString stringWithFormat:formatParam, ##__VA_ARGS__] \
userInfo:nil]; \
} while (NO)
#define OWSRaiseExceptionWithUserInfo(name, userInfoParam, formatParam, ...) \
do { \
OWSLogWarn( \
@"Exception: %@ %@ %@", name, userInfoParam, [NSString stringWithFormat:formatParam, ##__VA_ARGS__]); \
OWSLogFlush(); \
@throw [NSException exceptionWithName:name \
reason:[NSString stringWithFormat:formatParam, ##__VA_ARGS__] \
userInfo:userInfoParam]; \
} while (NO)
// UI JANK
//
// In pursuit of smooth UI, we want to continue moving blocking operations off the main thread.
// Add `OWSJanksUI` in code paths that shouldn't be called on the main thread.
// Because we have pervasively broken this tenant, enabling it by default would be too disruptive
// but it's helpful while unjanking and maybe someday we can have it enabled by default.
//#define DEBUG_UI_JANK 1
#ifdef DEBUG
#ifdef DEBUG_UI_JANK
#define OWSJanksUI() \
do { \
OWSAssertDebug(![NSThread isMainThread]) \
} while (NO)
#endif
#endif
#ifndef OWSJanksUI
#define OWSJanksUI()
#endif
#pragma mark - Overflow Math
#define ows_add_overflow(a, b, resultRef) \

View File

@ -11,7 +11,7 @@ void SwiftExit(NSString *message, const char *file, const char *function, int li
{
NSString *_file = [NSString stringWithFormat:@"%s", file];
NSString *_function = [NSString stringWithFormat:@"%s", function];
[OWSSwiftUtils owsFail:message file:_file function:_function line:line];
[OWSSwiftUtils owsFailObjC:message file:_file function:_function line:line];
}
NS_ASSUME_NONNULL_END

View File

@ -7,11 +7,16 @@
NS_ASSUME_NONNULL_BEGIN
#ifdef DEBUG
static const NSUInteger ddLogLevel = DDLogLevelAll;
static const DDLogLevel ddLogLevel = DDLogLevelAll;
#else
static const NSUInteger ddLogLevel = DDLogLevelInfo;
static const DDLogLevel ddLogLevel = DDLogLevelInfo;
#endif
static inline BOOL ShouldLogFlag(DDLogFlag flag)
{
return (ddLogLevel & flag) != 0;
}
static inline BOOL ShouldLogVerbose(void)
{
return ddLogLevel >= DDLogLevelVerbose;
@ -37,67 +42,28 @@ static inline BOOL ShouldLogError(void)
return ddLogLevel >= DDLogLevelError;
}
/**
* A minimal DDLog wrapper for swift.
*/
@interface OWSLogger : NSObject
/// When toggled, all subsequent logs at info or higher will be immediately flushed
@property (class, atomic, assign) BOOL aggressiveFlushing;
+ (void)verbose:(NSString *)logString;
+ (void)debug:(NSString *)logString;
+ (void)info:(NSString *)logString;
+ (void)warn:(NSString *)logString;
+ (void)error:(NSString *)logString;
+ (void)flush;
+ (void)verbose:(NSString *)logString __attribute__((deprecated));
+ (void)debug:(NSString *)logString __attribute__((deprecated));
+ (void)info:(NSString *)logString __attribute__((deprecated));
+ (void)warn:(NSString *)logString __attribute__((deprecated));
+ (void)error:(NSString *)logString __attribute__((deprecated));
@end
#define OWSLogPrefix() \
([NSString stringWithFormat:@"[%@:%d %s]: ", \
[[NSString stringWithUTF8String:__FILE__] lastPathComponent], \
__LINE__, \
__PRETTY_FUNCTION__])
/// A helper method for `OWSLogIfEnabled`, which checks if a level should be logged.
void OWSLogUnconditionally(DDLogFlag flag, const char *file, BOOL shouldTrimFilePath, NSUInteger line, const char *function, NSString *format, ...) NS_FORMAT_FUNCTION(6,7);
#define OWSLogVerbose(_messageFormat, ...) \
do { \
DDLogVerbose(@"💙 %@%@", OWSLogPrefix(), [NSString stringWithFormat:_messageFormat, ##__VA_ARGS__]); \
} while (0)
#define OWSLogIfEnabled(flg, fmt, ...) \
do { if (ShouldLogFlag(flg)) OWSLogUnconditionally(flg, __FILE__, YES, __LINE__, __PRETTY_FUNCTION__, (fmt), ## __VA_ARGS__); } while (0)
#define OWSLogDebug(_messageFormat, ...) \
do { \
DDLogDebug(@"💚 %@%@", OWSLogPrefix(), [NSString stringWithFormat:_messageFormat, ##__VA_ARGS__]); \
} while (0)
#define OWSLogVerbose(fmt, ...) OWSLogIfEnabled(DDLogFlagVerbose, fmt, ##__VA_ARGS__)
#define OWSLogDebug(fmt, ...) OWSLogIfEnabled(DDLogFlagDebug, fmt, ##__VA_ARGS__)
#define OWSLogInfo(fmt, ...) OWSLogIfEnabled(DDLogFlagInfo, fmt, ##__VA_ARGS__)
#define OWSLogWarn(fmt, ...) OWSLogIfEnabled(DDLogFlagWarning, fmt, ##__VA_ARGS__)
#define OWSLogError(fmt, ...) OWSLogIfEnabled(DDLogFlagError, fmt, ##__VA_ARGS__)
#define OWSLogInfo(_messageFormat, ...) \
do { \
DDLogInfo(@"💛 %@%@", OWSLogPrefix(), [NSString stringWithFormat:_messageFormat, ##__VA_ARGS__]); \
if (OWSLogger.aggressiveFlushing) { \
OWSLogFlush(); \
} \
} while (0)
#define OWSLogWarn(_messageFormat, ...) \
do { \
DDLogWarn(@"🧡 %@%@", OWSLogPrefix(), [NSString stringWithFormat:_messageFormat, ##__VA_ARGS__]); \
if (OWSLogger.aggressiveFlushing) { \
OWSLogFlush(); \
} \
} while (0)
#define OWSLogError(_messageFormat, ...) \
do { \
DDLogError(@"❤️ %@%@", OWSLogPrefix(), [NSString stringWithFormat:_messageFormat, ##__VA_ARGS__]); \
if (OWSLogger.aggressiveFlushing) { \
OWSLogFlush(); \
} \
} while (0)
#define OWSLogFlush() \
do { \
[DDLog flushLog]; \
} while (0)
#define OWSLogFlush() do { [DDLog flushLog]; } while (0)
NS_ASSUME_NONNULL_END

View File

@ -9,57 +9,63 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSLogger
static void logUnconditionally(DDLogFlag flag, const char *file, BOOL shouldTrimFilePath, NSUInteger line, const char *function, NSString *message)
{
OWSCAssert(ShouldLogFlag(flag));
NSString *fileObj = [NSString stringWithFormat:@"%s", file];
fileObj = shouldTrimFilePath ? fileObj.lastPathComponent : fileObj;
DDLogMessage *logMessage = [[DDLogMessage alloc] initWithMessage:message
level:ddLogLevel
flag:flag
context:0
file:fileObj
function:[NSString stringWithFormat:@"%s", function]
line:line
tag:nil
options:0
timestamp:nil];
[DDLog log:YES message:logMessage];
}
void OWSLogUnconditionally(DDLogFlag flag, const char *file, BOOL shouldTrimFilePath, NSUInteger line, const char *function, NSString *format, ...)
{
va_list args;
va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
logUnconditionally(flag, file, shouldTrimFilePath, line, function, message);
}
static void _logShim(DDLogFlag flag, NSString *logString) {
if (!ShouldLogFlag(flag)) {
return;
}
logUnconditionally(flag, "", NO, 0, "", logString);
}
+ (void)verbose:(NSString *)logString
{
DDLogVerbose(@"💙 %@", logString);
_logShim(DDLogFlagVerbose, logString);
}
+ (void)debug:(NSString *)logString
{
DDLogDebug(@"💚 %@", logString);
_logShim(DDLogFlagDebug, logString);
}
+ (void)info:(NSString *)logString
{
DDLogInfo(@"💛 %@", logString);
if (self.aggressiveFlushing) {
[self flush];
}
_logShim(DDLogFlagInfo, logString);
}
+ (void)warn:(NSString *)logString
{
DDLogWarn(@"🧡 %@", logString);
if (self.aggressiveFlushing) {
[self flush];
}
_logShim(DDLogFlagWarning, logString);
}
+ (void)error:(NSString *)logString
{
DDLogError(@"❤️ %@", logString);
if (self.aggressiveFlushing) {
[self flush];
}
}
+ (void)flush
{
OWSLogFlush();
}
static _Atomic BOOL _aggressiveLogFlushingEnabled = ATOMIC_VAR_INIT(NO);
+ (BOOL)aggressiveFlushing
{
return atomic_load(&_aggressiveLogFlushingEnabled);
}
+ (void)setAggressiveFlushing:(BOOL)isEnabled
{
if (atomic_exchange(&_aggressiveLogFlushingEnabled, isEnabled) != isEnabled) {
[self warn:[NSString stringWithFormat:@"%@ aggressive log flushing", isEnabled ? @"Enabled" : @"Disabled"]];
}
_logShim(DDLogFlagError, logString);
}
@end

View File

@ -12,72 +12,80 @@ public func assertOnQueue(_ queue: DispatchQueue) {
}
@inlinable
public func AssertIsOnMainThread(file: String = #file,
function: String = #function,
line: Int = #line) {
public func AssertIsOnMainThread(
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
if !Thread.isMainThread {
owsFailDebug("Must be on main thread.", file: file, function: function, line: line)
}
}
@inlinable
public func AssertNotOnMainThread(file: String = #file,
function: String = #function,
line: Int = #line) {
public func AssertNotOnMainThread(
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
if Thread.isMainThread {
owsFailDebug("Must be off main thread.", file: file, function: function, line: line)
}
}
@inlinable
public func owsFailDebug(_ logMessage: String,
file: String = #file,
function: String = #function,
line: Int = #line) {
public func owsFailDebug(
_ logMessage: String,
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
Logger.error(logMessage, file: file, function: function, line: line)
Logger.flush()
let formattedMessage = owsFormatLogMessage(logMessage, file: file, function: function, line: line)
if IsDebuggerAttached() {
TrapDebugger()
} else {
assertionFailure(formattedMessage)
assertionFailure(logMessage)
}
}
@inlinable
public func owsFail(_ logMessage: String,
file: String = #file,
function: String = #function,
line: Int = #line) -> Never {
public func owsFail(
_ logMessage: String,
file: String = #fileID,
function: String = #function,
line: Int = #line
) -> Never {
logStackTrace()
owsFailDebug(logMessage, file: file, function: function, line: line)
let formattedMessage = owsFormatLogMessage(logMessage, file: file, function: function, line: line)
fatalError(formattedMessage)
Logger.flush()
fatalError(logMessage)
}
@inlinable
public func owsAssertDebug(_ condition: Bool,
_ message: @autoclosure () -> String = String(),
file: String = #file,
function: String = #function,
line: Int = #line) {
public func owsAssertDebug(
_ condition: Bool,
_ message: @autoclosure () -> String = String(),
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
if !condition {
let message: String = message()
owsFailDebug(message.isEmpty ? "Assertion failed." : message,
file: file, function: function, line: line)
owsFailDebug(message.isEmpty ? "Assertion failed." : message, file: file, function: function, line: line)
}
}
@inlinable
public func owsAssert(_ condition: Bool,
_ message: @autoclosure () -> String = String(),
file: String = #file,
function: String = #function,
line: Int = #line) {
public func owsAssert(
_ condition: Bool,
_ message: @autoclosure () -> String = String(),
file: String = #fileID,
function: String = #function,
line: Int = #line
) {
if !condition {
let message: String = message()
owsFail(message.isEmpty ? "Assertion failed." : message,
file: file, function: function, line: line)
owsFail(message.isEmpty ? "Assertion failed." : message, file: file, function: function, line: line)
}
}
@ -85,17 +93,14 @@ public func owsAssert(_ condition: Bool,
public class OWSSwiftUtils: NSObject {
// This method can be invoked from Obj-C to exit the app.
@objc
public class func owsFail(_ logMessage: String,
file: String = #file,
function: String = #function,
line: Int = #line) -> Never {
logStackTrace()
owsFailDebug(logMessage, file: file, function: function, line: line)
let formattedMessage = owsFormatLogMessage(logMessage, file: file, function: function, line: line)
fatalError(formattedMessage)
public class func owsFailObjC(
_ logMessage: String,
file: String = #fileID,
function: String = #function,
line: Int = #line
) -> Never {
owsFail(logMessage, file: file, function: function, line: line)
}
}
public func logStackTrace() {