Skip to content

Commit

Permalink
RCOCOA-2273: Add support for Logger categories/ Improve current logge…
Browse files Browse the repository at this point in the history
…r. (#8608)

Add support for Logger categories
  • Loading branch information
dianaafanador3 authored Jun 29, 2024
1 parent 0e34f1c commit 9f850cb
Show file tree
Hide file tree
Showing 12 changed files with 840 additions and 137 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
x.y.z Release notes (yyyy-MM-dd)
=============================================================
### Enhancements
* None.
* Added support for filtering logs by category. Users wil have more fine grained control over
the log level for each category as well.
```swift
Logger.setLogLevel(.info, category: Category.Storage.transactions)
```

### Fixed
* <How to hit and notice issue? what was the impact?> ([#????](https://github.com/realm/realm-swift/issues/????), since v?.?.?)
* None.

<!-- ### Breaking Changes - ONLY INCLUDE FOR NEW MAJOR version -->
### Deprecations
* `RLMLogger.level`/`Logger.level` has been deprecated in favor of using `RLMLogger.setLevel:forCategory:`/`Logger.setLevel(:category:)` and `RLMLogger.getLevelForCategory:`/`Logger.getLevel(for:)`.
* It is not recommended to initialize a `RLMLogger/Logger` with a level anymore.

### Compatibility
* Realm Studio: 15.0.0 or later.
Expand Down
4 changes: 4 additions & 0 deletions Realm.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@
AC81360F287F21350029F15E /* AsymmetricObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC81360E287F21350029F15E /* AsymmetricObject.swift */; };
AC813612287F21700029F15E /* RLMAsymmetricObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AC813610287F21700029F15E /* RLMAsymmetricObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
AC813613287F21700029F15E /* RLMAsymmetricObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC813611287F21700029F15E /* RLMAsymmetricObject.mm */; };
AC848BEC2BFFA4AF0026A2A6 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC848BEB2BFFA4AF0026A2A6 /* Logger.swift */; };
AC8846762686573B00DF4A65 /* SwiftUISyncTestHostApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC8846752686573B00DF4A65 /* SwiftUISyncTestHostApp.swift */; };
AC8846782686573B00DF4A65 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC8846772686573B00DF4A65 /* ContentView.swift */; };
AC8846B72687BC4100DF4A65 /* SwiftUIServerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC8846B62687BC4100DF4A65 /* SwiftUIServerTests.swift */; };
Expand Down Expand Up @@ -912,6 +913,7 @@
AC81360E287F21350029F15E /* AsymmetricObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsymmetricObject.swift; sourceTree = "<group>"; };
AC813610287F21700029F15E /* RLMAsymmetricObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RLMAsymmetricObject.h; sourceTree = "<group>"; };
AC813611287F21700029F15E /* RLMAsymmetricObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RLMAsymmetricObject.mm; sourceTree = "<group>"; };
AC848BEB2BFFA4AF0026A2A6 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
AC8846732686573B00DF4A65 /* SwiftUISyncTestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUISyncTestHost.app; sourceTree = BUILT_PRODUCTS_DIR; };
AC8846752686573B00DF4A65 /* SwiftUISyncTestHostApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUISyncTestHostApp.swift; sourceTree = "<group>"; };
AC8846772686573B00DF4A65 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1362,6 +1364,7 @@
AC7825B82ACD90BE007ABA4B /* Geospatial.swift */,
5D1534B71CCFF545008976D7 /* LinkingObjects.swift */,
5D660FE41BE98D670021E04F /* List.swift */,
AC848BEB2BFFA4AF0026A2A6 /* Logger.swift */,
0C3BD4D225C1C5AB007CFDD3 /* Map.swift */,
5D660FE51BE98D670021E04F /* Migration.swift */,
CF76F80124816B3800890DD2 /* MongoClient.swift */,
Expand Down Expand Up @@ -2558,6 +2561,7 @@
3F857A482769291800F9B9B1 /* KeyPathStrings.swift in Sources */,
5D1534B81CCFF545008976D7 /* LinkingObjects.swift in Sources */,
5D660FF21BE98D670021E04F /* List.swift in Sources */,
AC848BEC2BFFA4AF0026A2A6 /* Logger.swift in Sources */,
0C3BD4D325C1C5AB007CFDD3 /* Map.swift in Sources */,
5D660FF31BE98D670021E04F /* Migration.swift in Sources */,
CF76F80224816B3800890DD2 /* MongoClient.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion Realm/ObjectServerTests/RLMSyncTestCase.mm
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ - (RLMApp *)appWithId:(NSString *)appId {
RLMApp *app = [RLMApp appWithConfiguration:config];
RLMSyncManager *syncManager = app.syncManager;
syncManager.userAgent = self.name;
RLMLogger.defaultLogger.level = RLMLogLevelWarn;
[RLMLogger setLevel:RLMLogLevelWarn forCategory:RLMLogCategorySync];
return app;
}

Expand Down
114 changes: 106 additions & 8 deletions Realm/RLMLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,33 +48,95 @@ typedef RLM_CLOSED_ENUM(NSUInteger, RLMLogLevel) {
RLMLogLevelAll
} NS_SWIFT_NAME(LogLevel);

/**
An enum representing different categories of sync-related logging that can be configured.
Setting the log level for a parent category automatically sets the same level for all child categories.
Category hierarchy:
```
Realm
├─► Storage
│ ├─► Transaction
│ ├─► Query
│ ├─► Object
│ └─► Notification
├─► Sync
│ ├─► Client
│ │ ├─► Session
│ │ ├─► Changeset
│ │ ├─► Network
│ │ └─► Reset
│ └─► Server
├─► App
└─► Sdk
```
*/
typedef NS_ENUM(NSUInteger, RLMLogCategory) {
/// Top level log category for Realm, updating this category level would set all other subcategories too.
RLMLogCategoryRealm,
/// Log category for all sdk related logs.
RLMLogCategorySDK,
/// Log category for all app related logs.
RLMLogCategoryApp,
/// Log category for all database related logs.
RLMLogCategoryStorage,
/// Log category for all database transaction related logs.
RLMLogCategoryStorageTransaction,
/// Log category for all database queries related logs.
RLMLogCategoryStorageQuery,
/// Log category for all database object related logs.
RLMLogCategoryStorageObject,
/// Log category for all database notification related logs.
RLMLogCategoryStorageNotification,
/// Log category for all sync related logs.
RLMLogCategorySync,
/// Log category for all sync client related logs.
RLMLogCategorySyncClient,
/// Log category for all sync client session related logs.
RLMLogCategorySyncClientSession,
/// Log category for all sync client changeset related logs.
RLMLogCategorySyncClientChangeset,
/// Log category for all sync client network related logs.
RLMLogCategorySyncClientNetwork,
/// Log category for all sync client reset related logs.
RLMLogCategorySyncClientReset,
/// Log category for all sync server related logs.
RLMLogCategorySyncServer
};

/// A log callback function which can be set on RLMLogger.
///
/// The log function may be called from multiple threads simultaneously, and is
/// responsible for performing its own synchronization if any is required.
RLM_SWIFT_SENDABLE // invoked on a background thread
typedef void (^RLMLogFunction)(RLMLogLevel level, NSString *message);

/// A log callback function which can be set on RLMLogger.
///
/// The log function may be called from multiple threads simultaneously, and is
/// responsible for performing its own synchronization if any is required.
RLM_SWIFT_SENDABLE // invoked on a background thread
typedef void (^RLMLogCategoryFunction)(RLMLogLevel level, RLMLogCategory category, NSString *message) NS_REFINED_FOR_SWIFT;
/**
`RLMLogger` is used for creating your own custom logging logic.
Global logger class used by all Realm components.
You can define your own logger creating an instance of `RLMLogger` and define the log function which will be
invoked whenever there is a log message.
Set this custom logger as you default logger using `setDefaultLogger`.
RLMLogger.defaultLogger = [[RLMLogger alloc] initWithLevel:RLMLogLevelDebug
logFunction:^(RLMLogLevel level, NSString * message) {
NSLog(@"Realm Log - %lu, %@", (unsigned long)level, message);
RLMLogger.defaultLogger = [[RLMLogger alloc] initWithLogFunction:^(RLMLogLevel level, NSString *category, NSString *message) {
NSLog(@"Realm Log - %lu, %@, %@", (unsigned long)level, category, message);
}];
@note By default default log threshold level is `RLMLogLevelInfo`, and logging strings are output to Apple System Logger.
@note The default log threshold level is `RLMLogLevelInfo` for the log category `RLMLogCategoryRealm`,
and logging strings are output to Apple System Logger.
*/
@interface RLMLogger : NSObject

/**
Gets the logging threshold level used by the logger.
*/
@property (nonatomic) RLMLogLevel level;
@property (nonatomic) RLMLogLevel level
__attribute__((deprecated("Use `setLevel(level:category)` or `setLevel:category` instead.")));

/// :nodoc:
- (instancetype)init NS_UNAVAILABLE;
Expand All @@ -84,16 +146,52 @@ typedef void (^RLMLogFunction)(RLMLogLevel level, NSString *message);
@param level The log level to be set for the logger.
@param logFunction The log function which will be invoked whenever there is a log message.
@note This will set the log level for the log category `RLMLogCategoryRealm`.
*/
- (instancetype)initWithLevel:(RLMLogLevel)level logFunction:(RLMLogFunction)logFunction
__attribute__((deprecated("Use `initWithLogFunction:` instead.")));

/**
Creates a logger with a callback, which will be invoked whenever there is a log message.
@param logFunction The log function which will be invoked whenever there is a log message.
*/
- (instancetype)initWithLevel:(RLMLogLevel)level logFunction:(RLMLogFunction)logFunction;
- (instancetype)initWithLogFunction:(RLMLogCategoryFunction)logFunction;

#pragma mark RLMLogger Default Logger API

/**
The current default logger. When setting a logger as default, this logger will be used whenever information must be logged.
The current default logger. When setting a logger as default, this logger will replace the current default logger and will
be used whenever information must be logged.
*/
@property (class) RLMLogger *defaultLogger NS_SWIFT_NAME(shared);

/**
Log a message to the supplied level.
@param logLevel The log level for the message.
@param category The log category for the message.
@param message The message to log.
*/
- (void)logWithLevel:(RLMLogLevel)logLevel category:(RLMLogCategory)category message:(NSString *)message;

/**
Sets the gobal log level for a given category.
@param level The log level to be set for the logger.
@param category The log function which will be invoked whenever there is a log message.
*/
+ (void)setLevel:(RLMLogLevel)level forCategory:(RLMLogCategory)category NS_REFINED_FOR_SWIFT;

/**
Gets the global log level for the specified category.
@param category The log category which we need the level.
@returns The log level for the specified category
*/
+ (RLMLogLevel)levelForCategory:(RLMLogCategory)category NS_REFINED_FOR_SWIFT;

@end

RLM_HEADER_AUDIT_END(nullability)
Loading

0 comments on commit 9f850cb

Please sign in to comment.