Various logging fixes (#164)

Various logging fixes:
* imported the ObjCWrapper and updated the MXLogger. Also added back support for app containers
* updated MXLog.swift from El and fixed/improved its logging format
* updated most app log strings
* Remove unnecessary swiftlint rule
* Various tweaks following code review
* Added back type annoation on MXLogger logFiles method
* Fix generated Swift-ObjC header name
This commit is contained in:
Stefan Ceriu
2022-08-30 18:05:21 +03:00
committed by GitHub
parent c92e6c2092
commit 39be67cec6
24 changed files with 288 additions and 102 deletions
+49
View File
@@ -0,0 +1,49 @@
//
// Copyright 2021 The Matrix.org Foundation C.I.C
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "MXLogObjcWrapper.h"
#define MXLogVerbose(message, ...) { \
[MXLogObjcWrapper logVerbose:[NSString stringWithFormat: message, ##__VA_ARGS__] file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__]; \
}
#define MXLogDebug(message, ...) { \
[MXLogObjcWrapper logDebug:[NSString stringWithFormat: message, ##__VA_ARGS__] file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__]; \
}
#define MXLogInfo(message, ...) { \
[MXLogObjcWrapper logInfo:[NSString stringWithFormat: message, ##__VA_ARGS__] file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__]; \
}
#define MXLogWarning(message, ...) { \
[MXLogObjcWrapper logWarning:[NSString stringWithFormat: message, ##__VA_ARGS__] file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__]; \
}
#define MXLogError(message) { \
[MXLogObjcWrapper logError:message file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__ context:nil]; \
}
#define MXLogErrorDetails(message, details) { \
[MXLogObjcWrapper logError:message file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__ context:details]; \
}
#define MXLogFailure(message) { \
[MXLogObjcWrapper logFailure:message file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__ context:nil]; \
}
#define MXLogFailureDetails(message, details) { \
[MXLogObjcWrapper logFailure:message file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__ context:details]; \
}
+55 -29
View File
@@ -67,8 +67,8 @@ private var logger: SwiftyBeaver.Type = {
}
public static func verbose(_ message: @autoclosure () -> Any,
_ file: String = #file,
_ function: String = #function,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.verbose(message(), file, function, line: line, context: context)
@@ -80,8 +80,8 @@ private var logger: SwiftyBeaver.Type = {
}
public static func debug(_ message: @autoclosure () -> Any,
_ file: String = #file,
_ function: String = #function,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.debug(message(), file, function, line: line, context: context)
@@ -93,8 +93,8 @@ private var logger: SwiftyBeaver.Type = {
}
public static func info(_ message: @autoclosure () -> Any,
_ file: String = #file,
_ function: String = #function,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.info(message(), file, function, line: line, context: context)
@@ -106,8 +106,8 @@ private var logger: SwiftyBeaver.Type = {
}
public static func warning(_ message: @autoclosure () -> Any,
_ file: String = #file,
_ function: String = #function,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.warning(message(), file, function, line: line, context: context)
@@ -118,32 +118,57 @@ private var logger: SwiftyBeaver.Type = {
logger.warning(message, file, function, line: line)
}
public static func error(_ message: @autoclosure () -> Any,
_ file: String = #file,
_ function: String = #function,
/// Log error with additional details
///
/// - Parameters:
/// - message: Description of the error without any variables (this is to improve error aggregations by type)
/// - context: Additional context-dependent details about the issue
public static func error(_ message: String,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.error(message(), file, function, line: line, context: context)
logger.error(message, file, function, line: line, context: context)
}
@available(swift, obsoleted: 5.4)
@objc public static func logError(_ message: String, file: String, function: String, line: Int) {
logger.error(message, file, function, line: line)
@objc public static func logError(_ message: String,
file: String,
function: String,
line: Int,
context: Any? = nil) {
logger.error(message, file, function, line: line, context: context)
}
public static func failure(_ message: @autoclosure () -> Any,
_ file: String = #file,
_ function: String = #function,
/// Log failure with additional details
///
/// A failure is any type of programming error which should never occur in production. In `DEBUG` configuration
/// any failure will raise `assertionFailure`
///
/// - Parameters:
/// - message: Description of the error without any variables (this is to improve error aggregations by type)
/// - context: Additional context-dependent details about the issue
public static func failure(_ message: String,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.error(message(), file, function, line: line, context: context)
assertionFailure("\(message())")
logger.error(message, file, function, line: line, context: context)
#if DEBUG
assertionFailure("\(message)")
#endif
}
@available(swift, obsoleted: 5.4)
@objc public static func logFailure(_ message: String, file: String, function: String, line: Int) {
logger.error(message, file, function, line: line)
assertionFailure(message)
@objc public static func logFailure(_ message: String,
file: String,
function: String,
line: Int,
context: Any? = nil) {
logger.error(message, file, function, line: line, context: context)
#if DEBUG
assertionFailure("\(message)")
#endif
}
// MARK: - Private
@@ -152,24 +177,27 @@ private var logger: SwiftyBeaver.Type = {
if let subLogName = configuration.subLogName {
MXLogger.setSubLogName(subLogName)
}
MXLogger.redirectNSLog(toFiles: configuration.redirectLogsToFiles,
numberOfFiles: configuration.maxLogFilesCount,
sizeLimit: configuration.logFilesSizeLimit)
guard configuration.logLevel != .none else {
logger.removeAllDestinations()
return
}
logger.removeAllDestinations()
let consoleDestination = ConsoleDestination()
consoleDestination.useNSLog = true
consoleDestination.asynchronously = false
consoleDestination.format = "$M"
consoleDestination.format = "$C$N.$F:$l $M $X$c" // See https://docs.swiftybeaver.com/article/20-custom-format
consoleDestination.levelColor.verbose = ""
consoleDestination.levelColor.debug = ""
consoleDestination.levelColor.info = ""
consoleDestination.levelColor.warning = "⚠️"
consoleDestination.levelColor.error = "🚨"
consoleDestination.levelColor.warning = "⚠️ "
consoleDestination.levelColor.error = "🚨 "
switch configuration.logLevel {
case .verbose:
@@ -185,8 +213,6 @@ private var logger: SwiftyBeaver.Type = {
case .none:
break
}
logger.removeAllDestinations()
logger.addDestination(consoleDestination)
}
}
@@ -0,0 +1,40 @@
//
// Copyright 2021 The Matrix.org Foundation C.I.C
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
An `MXLog` Objective-C wrapper used to allow calling Swift methods from the variadic macros defined in `MXLog.h`
*/
@interface MXLogObjcWrapper : NSObject
+ (void)logVerbose:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line;
+ (void)logDebug:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line;
+ (void)logInfo:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line;
+ (void)logWarning:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line;
+ (void)logError:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line context:(nullable id)context;
+ (void)logFailure:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line context:(nullable id)context;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,52 @@
//
// Copyright 2021 The Matrix.org Foundation C.I.C
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "MXLogObjcWrapper.h"
#import "GeneratedInterface-Swift.h"
@implementation MXLogObjcWrapper
+ (void)logVerbose:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line
{
[MXLog logVerbose:message file:file function:function line:line];
}
+ (void)logDebug:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line
{
[MXLog logDebug:message file:file function:function line:line];
}
+ (void)logInfo:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line
{
[MXLog logInfo:message file:file function:function line:line];
}
+ (void)logWarning:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line
{
[MXLog logWarning:message file:file function:function line:line];
}
+ (void)logError:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line context:(id)context
{
[MXLog logError:message file:file function:function line:line context:context];
}
+ (void)logFailure:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line context:(id)context
{
[MXLog logFailure:message file:file function:function line:line context:context];
}
@end
+29 -29
View File
@@ -16,7 +16,8 @@
*/
#import "MXLogger.h"
#import <UIKit/UIKit.h>
#import "MXLog.h"
#import "GeneratedInterface-Swift.h"
// stderr so it can be restored
int stderrSave = 0;
@@ -80,24 +81,24 @@ static NSString *subLogName;
if ([fileManager fileExistsAtPath:nsLogPathOlder])
{
// Temp log
[log appendFormat:@"[MXLogger] redirectNSLogToFiles: removeItemAtPath: %@\n", nsLogPathOlder];
[log appendFormat:@"removeItemAtPath: %@\n", nsLogPathOlder];
NSError *error;
[fileManager removeItemAtPath:nsLogPathOlder error:&error];
if (error)
{
[log appendFormat:@"[MXLogger] ERROR: removeItemAtPath: %@. Error: %@\n", nsLogPathOlder, error];
[log appendFormat:@"removeItemAtPath: %@. Error: %@\n", nsLogPathOlder, error];
}
}
// Temp log
[log appendFormat:@"[MXLogger] redirectNSLogToFiles: moveItemAtPath: %@ toPath: %@\n", nsLogPathCurrent, nsLogPathOlder];
[log appendFormat:@"moveItemAtPath: %@ toPath: %@\n", nsLogPathCurrent, nsLogPathOlder];
NSError *error;
[fileManager moveItemAtPath:nsLogPathCurrent toPath:nsLogPathOlder error:&error];
if (error)
{
[log appendFormat:@"[MXLogger] ERROR: moveItemAtPath: %@ toPath: %@. Error: %@\n", nsLogPathCurrent, nsLogPathOlder, error];
[log appendFormat:@"moveItemAtPath: %@ toPath: %@. Error: %@\n", nsLogPathCurrent, nsLogPathOlder, error];
}
}
}
@@ -108,11 +109,11 @@ static NSString *subLogName;
NSString *nsLogPath = [logsFolderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"console%@.log", subLogName]];
freopen([nsLogPath fileSystemRepresentation], "w+", stderr);
// MXLogDebug(@"[MXLogger] redirectNSLogToFiles: YES");
MXLogDebug(@"redirectNSLogToFiles: YES");
if (log.length)
{
// We can now log into files
// MXLogDebug(@"%@", log);
MXLogDebug(@"%@", log);
}
[self removeExtraFilesFromCount:numberOfFiles];
@@ -162,7 +163,7 @@ static NSString *subLogName;
}
}
// MXLogDebug(@"[MXLogger] logFiles: %@", logFiles);
MXLogDebug(@"logFiles: %@", logFiles);
return logFiles;
}
@@ -200,13 +201,12 @@ static void handleUncaughtException(NSException *exception)
NSString *version = [[NSProcessInfo processInfo] operatingSystemVersionString];
#endif
NSArray *backtrace = [exception callStackSymbols];
NSString *description = [NSString stringWithFormat:@"%.0f - %@\n%@\nApplication: %@ (%@)\nApplication version: %@\nMatrix SDK version: %@\nBuild: %@\n%@ %@\n\nMain thread: %@\n%@\n",
NSString *description = [NSString stringWithFormat:@"%.0f - %@\n%@\nApplication: %@ (%@)\nApplication version: %@\nBuild: %@\n%@ %@\n\nMain thread: %@\n%@\n",
[[NSDate date] timeIntervalSince1970],
[NSDate date],
exception.description,
app, appId,
appVersion,
@"",
buildVersion,
model, version,
[NSThread isMainThread] ? @"YES" : @"NO",
@@ -220,8 +220,9 @@ static void handleUncaughtException(NSException *exception)
encoding:NSStringEncodingConversionAllowLossy
error:nil];
NSLog(@"[MXLogger] handleUncaughtException:\n%@", description);
// MXLogError(@"[MXLogger] handleUncaughtException:\n%@", description);
MXLogErrorDetails(@"handleUncaughtException", @{
@"description": description ?: @"unknown"
});
}
// Signals emitted by the app are handled here
@@ -302,16 +303,16 @@ static NSString* crashLogPath(void)
{
NSString *logsFolderPath = nil;
// NSURL *sharedContainerURL = [[NSFileManager defaultManager] applicationGroupContainerURL];
// if (sharedContainerURL)
// {
// logsFolderPath = [sharedContainerURL path];
// }
// else
// {
NSURL *sharedContainerURL = [[NSFileManager defaultManager] appGroupContainerURL];
if (sharedContainerURL)
{
logsFolderPath = [sharedContainerURL path];
}
else
{
NSArray<NSURL *> *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
logsFolderPath = paths[0].path;
// }
}
return logsFolderPath;
}
@@ -332,7 +333,7 @@ static NSString* crashLogPath(void)
if ([fileManager fileExistsAtPath:logFile])
{
[fileManager removeItemAtPath:logFile error:nil];
// MXLogDebug(@"[MXLogger] removeExtraFilesFromCount: %@. removeItemAtPath: %@\n", @(count), logFile);
MXLogDebug(@"removeExtraFilesFromCount: %@. removeItemAtPath: %@\n", @(count), logFile);
}
else
{
@@ -374,19 +375,18 @@ static NSString* crashLogPath(void)
if (removeFiles)
{
// MXLogDebug(@"[MXLogger] removeFilesAfterSizeLimit: Remove files from index %@ because logs are too large (%@ for a limit of %@)\n",
// @(index),
// [NSByteCountFormatter stringFromByteCount:logSize countStyle:NSByteCountFormatterCountStyleBinary],
// [NSByteCountFormatter stringFromByteCount:sizeLimit countStyle:NSByteCountFormatterCountStyleBinary]);
MXLogDebug(@"removeFilesAfterSizeLimit: Remove files from index %@ because logs are too large (%@ for a limit of %@)\n",
@(index),
[NSByteCountFormatter stringFromByteCount:logSize countStyle:NSByteCountFormatterCountStyleBinary],
[NSByteCountFormatter stringFromByteCount:sizeLimit countStyle:NSByteCountFormatterCountStyleBinary]);
[self removeExtraFilesFromCount:index];
}
else
{
// MXLogDebug(@"[MXLogger] removeFilesAfterSizeLimit: No need: %@ for a limit of %@\n",
// [NSByteCountFormatter stringFromByteCount:logSize countStyle:NSByteCountFormatterCountStyleBinary],
// [NSByteCountFormatter stringFromByteCount:sizeLimit countStyle:NSByteCountFormatterCountStyleBinary]);
MXLogDebug(@"removeFilesAfterSizeLimit: No need: %@ for a limit of %@\n",
[NSByteCountFormatter stringFromByteCount:logSize countStyle:NSByteCountFormatterCountStyleBinary],
[NSByteCountFormatter stringFromByteCount:sizeLimit countStyle:NSByteCountFormatterCountStyleBinary]);
}
}
@end