From af19a1b07245b7d0be4fd492bd3731964937c7c6 Mon Sep 17 00:00:00 2001 From: Gil Date: Wed, 23 May 2018 07:00:05 -0700 Subject: Reimplement C++ logging (#1313) * Add direct support for formatting Objective-C objects * Rewrite log.h * Convert FSTWarn to LOG_WARN * Convert FSTLog to LOG_DEBUG * Remove FSTLogger --- .../Example/Tests/SpecTests/FSTMockDatastore.mm | 6 +- Firestore/Example/Tests/SpecTests/FSTSpecTests.mm | 4 +- .../Tests/SpecTests/FSTSyncEngineTestDriver.mm | 10 +-- Firestore/Source/API/FIRFirestore.mm | 52 +++++++-------- Firestore/Source/Core/FSTFirestoreClient.mm | 4 +- Firestore/Source/Core/FSTSyncEngine.mm | 6 +- Firestore/Source/Local/FSTLevelDB.mm | 1 - Firestore/Source/Local/FSTLocalStore.mm | 12 ++-- Firestore/Source/Remote/FSTDatastore.mm | 12 ++-- Firestore/Source/Remote/FSTExponentialBackoff.mm | 9 ++- Firestore/Source/Remote/FSTOnlineStateTracker.mm | 12 ++-- Firestore/Source/Remote/FSTRemoteEvent.mm | 5 +- Firestore/Source/Remote/FSTRemoteStore.mm | 15 ++--- Firestore/Source/Remote/FSTStream.mm | 36 +++++----- Firestore/Source/Util/FSTLogger.h | 26 -------- Firestore/Source/Util/FSTLogger.mm | 41 ------------ .../firestore/local/leveldb_transaction.cc | 4 +- Firestore/core/src/firebase/firestore/util/log.h | 71 +++++++++++++------- .../core/src/firebase/firestore/util/log_apple.mm | 77 ++++------------------ .../core/src/firebase/firestore/util/log_stdio.cc | 63 ++++-------------- .../src/firebase/firestore/util/string_format.h | 7 ++ .../core/test/firebase/firestore/util/log_test.cc | 20 ++---- 22 files changed, 179 insertions(+), 314 deletions(-) delete mode 100644 Firestore/Source/Util/FSTLogger.h delete mode 100644 Firestore/Source/Util/FSTLogger.mm (limited to 'Firestore') diff --git a/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm b/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm index dd34556..c846ec5 100644 --- a/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm +++ b/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm @@ -21,7 +21,6 @@ #import "Firestore/Source/Remote/FSTSerializerBeta.h" #import "Firestore/Source/Remote/FSTStream.h" #import "Firestore/Source/Util/FSTAssert.h" -#import "Firestore/Source/Util/FSTLogger.h" #import "Firestore/Example/Tests/Remote/FSTWatchChange+Testing.h" @@ -29,6 +28,7 @@ #include "Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.h" #include "Firestore/core/src/firebase/firestore/core/database_info.h" #include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" #include "Firestore/core/src/firebase/firestore/util/string_apple.h" using firebase::firestore::auth::CredentialsProvider; @@ -117,7 +117,7 @@ NS_ASSUME_NONNULL_BEGIN } - (void)watchQuery:(FSTQueryData *)query { - FSTLog(@"watchQuery: %d: %@", query.targetID, query.query); + LOG_DEBUG("watchQuery: %s: %s", query.targetID, query.query); self.datastore.watchStreamRequestCount += 1; // Snapshot version is ignored on the wire FSTQueryData *sentQueryData = [query queryDataByReplacingSnapshotVersion:SnapshotVersion::None() @@ -127,7 +127,7 @@ NS_ASSUME_NONNULL_BEGIN } - (void)unwatchTargetID:(FSTTargetID)targetID { - FSTLog(@"unwatchTargetID: %d", targetID); + LOG_DEBUG("unwatchTargetID: %s", targetID); [self.activeTargets removeObjectForKey:@(targetID)]; } diff --git a/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm b/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm index 5a7cb72..7b10bd4 100644 --- a/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm +++ b/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm @@ -37,7 +37,6 @@ #import "Firestore/Source/Util/FSTAssert.h" #import "Firestore/Source/Util/FSTClasses.h" #import "Firestore/Source/Util/FSTDispatchQueue.h" -#import "Firestore/Source/Util/FSTLogger.h" #import "Firestore/Example/Tests/Remote/FSTWatchChange+Testing.h" #import "Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.h" @@ -46,6 +45,7 @@ #include "Firestore/core/src/firebase/firestore/auth/user.h" #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" #include "Firestore/core/src/firebase/firestore/util/string_apple.h" #include "Firestore/core/test/firebase/firestore/testutil/testutil.h" @@ -620,7 +620,7 @@ static NSString *const kNoIOSTag = @"no-ios"; @try { [self setUpForSpecWithConfig:config]; for (NSDictionary *step in steps) { - FSTLog(@"Doing step %@", step); + LOG_DEBUG("Doing step %s", step); [self doStep:step]; [self validateStepExpectations:step[@"expect"]]; [self validateStateExpectations:step[@"stateExpect"]]; diff --git a/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm b/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm index 2aa0e30..40ebfb9 100644 --- a/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm +++ b/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm @@ -31,7 +31,6 @@ #import "Firestore/Source/Remote/FSTDatastore.h" #import "Firestore/Source/Remote/FSTWatchChange.h" #import "Firestore/Source/Util/FSTAssert.h" -#import "Firestore/Source/Util/FSTLogger.h" #import "Firestore/Example/Tests/Core/FSTSyncEngine+Testing.h" #import "Firestore/Example/Tests/SpecTests/FSTMockDatastore.h" @@ -41,6 +40,7 @@ #include "Firestore/core/src/firebase/firestore/core/database_info.h" #include "Firestore/core/src/firebase/firestore/model/database_id.h" #include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" using firebase::firestore::auth::EmptyCredentialsProvider; using firebase::firestore::auth::HashUser; @@ -202,7 +202,7 @@ NS_ASSUME_NONNULL_BEGIN FSTAssert([actualWrite isEqual:expectedWrite], @"Mock datastore received write %@ but first outstanding mutation was %@", actualWrite, expectedWrite); - FSTLog(@"A write was sent: %@", actualWrite); + LOG_DEBUG("A write was sent: %s", actualWrite); } - (int)sentWritesCount { @@ -271,7 +271,7 @@ NS_ASSUME_NONNULL_BEGIN [[self currentOutstandingWrites] removeObjectAtIndex:0]; } - FSTLog(@"Failing a write."); + LOG_DEBUG("Failing a write."); [self.dispatchQueue dispatchSync:^{ [self.datastore failWriteWithError:error]; }]; @@ -321,11 +321,11 @@ NS_ASSUME_NONNULL_BEGIN FSTOutstandingWrite *write = [[FSTOutstandingWrite alloc] init]; write.write = mutation; [[self currentOutstandingWrites] addObject:write]; - FSTLog(@"sending a user write."); + LOG_DEBUG("sending a user write."); [self.dispatchQueue dispatchSync:^{ [self.syncEngine writeMutations:@[ mutation ] completion:^(NSError *_Nullable error) { - FSTLog(@"A callback was called with error: %@", error); + LOG_DEBUG("A callback was called with error: %s", error); write.done = YES; write.error = error; }]; diff --git a/Firestore/Source/API/FIRFirestore.mm b/Firestore/Source/API/FIRFirestore.mm index 5486b75..0ed9082 100644 --- a/Firestore/Source/API/FIRFirestore.mm +++ b/Firestore/Source/API/FIRFirestore.mm @@ -34,7 +34,6 @@ #import "Firestore/Source/Core/FSTFirestoreClient.h" #import "Firestore/Source/Util/FSTAssert.h" #import "Firestore/Source/Util/FSTDispatchQueue.h" -#import "Firestore/Source/Util/FSTLogger.h" #import "Firestore/Source/Util/FSTUsageValidation.h" #include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" @@ -42,6 +41,7 @@ #include "Firestore/core/src/firebase/firestore/core/database_info.h" #include "Firestore/core/src/firebase/firestore/model/database_id.h" #include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" #include "Firestore/core/src/firebase/firestore/util/string_apple.h" #include "absl/memory/memory.h" @@ -246,31 +246,31 @@ extern "C" NSString *const FIRFirestoreErrorDomain = @"FIRFirestoreErrorDomain"; FSTAssert(_settings.dispatchQueue, @"FirestoreSettings.dispatchQueue cannot be nil."); if (!_settings.timestampsInSnapshotsEnabled) { - FSTWarn( - @"The behavior for system Date objects stored in Firestore is going to change " - "AND YOUR APP MAY BREAK.\n" - "To hide this warning and ensure your app does not break, you need to add " - "the following code to your app before calling any other Cloud Firestore methods:\n" - "\n" - "let db = Firestore.firestore()\n" - "let settings = db.settings\n" - "settings.areTimestampsInSnapshotsEnabled = true\n" - "db.settings = settings\n" - "\n" - "With this change, timestamps stored in Cloud Firestore will be read back as " - "Firebase Timestamp objects instead of as system Date objects. So you will " - "also need to update code expecting a Date to instead expect a Timestamp. " - "For example:\n" - "\n" - "// old:\n" - "let date: Date = documentSnapshot.get(\"created_at\") as! Date\n" - "// new:\n" - "let timestamp: Timestamp = documentSnapshot.get(\"created_at\") as! Timestamp\n" - "let date: Date = timestamp.dateValue()\n" - "\n" - "Please audit all existing usages of Date when you enable the new behavior. In a " - "future release, the behavior will be changed to the new behavior, so if you do not " - "follow these steps, YOUR APP MAY BREAK."); + LOG_WARN( + "The behavior for system Date objects stored in Firestore is going to change " + "AND YOUR APP MAY BREAK.\n" + "To hide this warning and ensure your app does not break, you need to add " + "the following code to your app before calling any other Cloud Firestore methods:\n" + "\n" + "let db = Firestore.firestore()\n" + "let settings = db.settings\n" + "settings.areTimestampsInSnapshotsEnabled = true\n" + "db.settings = settings\n" + "\n" + "With this change, timestamps stored in Cloud Firestore will be read back as " + "Firebase Timestamp objects instead of as system Date objects. So you will " + "also need to update code expecting a Date to instead expect a Timestamp. " + "For example:\n" + "\n" + "// old:\n" + "let date: Date = documentSnapshot.get(\"created_at\") as! Date\n" + "// new:\n" + "let timestamp: Timestamp = documentSnapshot.get(\"created_at\") as! Timestamp\n" + "let date: Date = timestamp.dateValue()\n" + "\n" + "Please audit all existing usages of Date when you enable the new behavior. In a " + "future release, the behavior will be changed to the new behavior, so if you do not " + "follow these steps, YOUR APP MAY BREAK."); } const DatabaseInfo database_info(*self.databaseID, util::MakeStringView(_persistenceKey), diff --git a/Firestore/Source/Core/FSTFirestoreClient.mm b/Firestore/Source/Core/FSTFirestoreClient.mm index cede958..da19960 100644 --- a/Firestore/Source/Core/FSTFirestoreClient.mm +++ b/Firestore/Source/Core/FSTFirestoreClient.mm @@ -45,11 +45,11 @@ #import "Firestore/Source/Util/FSTAssert.h" #import "Firestore/Source/Util/FSTClasses.h" #import "Firestore/Source/Util/FSTDispatchQueue.h" -#import "Firestore/Source/Util/FSTLogger.h" #include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" #include "Firestore/core/src/firebase/firestore/core/database_info.h" #include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" #include "Firestore/core/src/firebase/firestore/util/string_apple.h" namespace util = firebase::firestore::util; @@ -226,7 +226,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)userDidChange:(const User &)user { [self.workerDispatchQueue verifyIsCurrentQueue]; - FSTLog(@"User Changed: %s", user.uid().c_str()); + LOG_DEBUG("User Changed: %s", user.uid()); [self.syncEngine userDidChange:user]; } diff --git a/Firestore/Source/Core/FSTSyncEngine.mm b/Firestore/Source/Core/FSTSyncEngine.mm index ed97d6c..9d9e526 100644 --- a/Firestore/Source/Core/FSTSyncEngine.mm +++ b/Firestore/Source/Core/FSTSyncEngine.mm @@ -40,12 +40,12 @@ #import "Firestore/Source/Remote/FSTRemoteEvent.h" #import "Firestore/Source/Util/FSTAssert.h" #import "Firestore/Source/Util/FSTDispatchQueue.h" -#import "Firestore/Source/Util/FSTLogger.h" #include "Firestore/core/src/firebase/firestore/auth/user.h" #include "Firestore/core/src/firebase/firestore/core/target_id_generator.h" #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" using firebase::firestore::auth::HashUser; using firebase::firestore::auth::User; @@ -470,7 +470,7 @@ static const FSTListenSequenceNumber kIrrelevantSequenceNumber = -1; break; case FSTLimboDocumentChangeTypeRemoved: - FSTLog(@"Document no longer in limbo: %s", limboChange.key.ToString().c_str()); + LOG_DEBUG("Document no longer in limbo: %s", limboChange.key.ToString()); [self.limboDocumentRefs removeReferenceToKey:limboChange.key forID:targetID]; break; @@ -485,7 +485,7 @@ static const FSTListenSequenceNumber kIrrelevantSequenceNumber = -1; DocumentKey key{limboChange.key}; if (_limboTargetsByKey.find(key) == _limboTargetsByKey.end()) { - FSTLog(@"New document in limbo: %s", key.ToString().c_str()); + LOG_DEBUG("New document in limbo: %s", key.ToString()); TargetId limboTargetID = _targetIdGenerator.NextId(); FSTQuery *query = [FSTQuery queryWithPath:key.path()]; FSTQueryData *queryData = [[FSTQueryData alloc] initWithQuery:query diff --git a/Firestore/Source/Local/FSTLevelDB.mm b/Firestore/Source/Local/FSTLevelDB.mm index bc2f2eb..6d0f8af 100644 --- a/Firestore/Source/Local/FSTLevelDB.mm +++ b/Firestore/Source/Local/FSTLevelDB.mm @@ -25,7 +25,6 @@ #import "Firestore/Source/Local/FSTLevelDBRemoteDocumentCache.h" #import "Firestore/Source/Remote/FSTSerializerBeta.h" #import "Firestore/Source/Util/FSTAssert.h" -#import "Firestore/Source/Util/FSTLogger.h" #include "Firestore/core/src/firebase/firestore/auth/user.h" #include "Firestore/core/src/firebase/firestore/core/database_info.h" diff --git a/Firestore/Source/Local/FSTLocalStore.mm b/Firestore/Source/Local/FSTLocalStore.mm index 0d6a785..245dd62 100644 --- a/Firestore/Source/Local/FSTLocalStore.mm +++ b/Firestore/Source/Local/FSTLocalStore.mm @@ -37,12 +37,12 @@ #import "Firestore/Source/Model/FSTMutationBatch.h" #import "Firestore/Source/Remote/FSTRemoteEvent.h" #import "Firestore/Source/Util/FSTAssert.h" -#import "Firestore/Source/Util/FSTLogger.h" #include "Firestore/core/src/firebase/firestore/auth/user.h" #include "Firestore/core/src/firebase/firestore/core/target_id_generator.h" #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" using firebase::firestore::auth::User; using firebase::firestore::core::TargetIdGenerator; @@ -324,11 +324,11 @@ NS_ASSUME_NONNULL_BEGIN SnapshotVersion{doc.version} >= SnapshotVersion{existingDoc.version}) { [self.remoteDocumentCache addEntry:doc]; } else { - FSTLog( - @"FSTLocalStore Ignoring outdated watch update for %s. " - "Current version: %s Watch version: %s", - key.ToString().c_str(), existingDoc.version.timestamp().ToString().c_str(), - doc.version.timestamp().ToString().c_str()); + LOG_DEBUG( + "FSTLocalStore Ignoring outdated watch update for %s. " + "Current version: %s Watch version: %s", + key.ToString(), existingDoc.version.timestamp().ToString(), + doc.version.timestamp().ToString()); } // The document might be garbage because it was unreferenced by everything. diff --git a/Firestore/Source/Remote/FSTDatastore.mm b/Firestore/Source/Remote/FSTDatastore.mm index f0852fe..d45af6b 100644 --- a/Firestore/Source/Remote/FSTDatastore.mm +++ b/Firestore/Source/Remote/FSTDatastore.mm @@ -33,7 +33,6 @@ #import "Firestore/Source/Remote/FSTStream.h" #import "Firestore/Source/Util/FSTAssert.h" #import "Firestore/Source/Util/FSTDispatchQueue.h" -#import "Firestore/Source/Util/FSTLogger.h" #import "Firestore/Protos/objc/google/firestore/v1beta1/Firestore.pbrpc.h" @@ -43,6 +42,7 @@ #include "Firestore/core/src/firebase/firestore/model/database_id.h" #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" #include "Firestore/core/src/firebase/firestore/util/string_apple.h" namespace util = firebase::firestore::util; @@ -217,8 +217,8 @@ typedef GRPCProtoCall * (^RPCFactory)(void); /** Logs the (whitelisted) headers returned for an GRPCProtoCall RPC. */ + (void)logHeadersForRPC:(GRPCProtoCall *)rpc RPCName:(NSString *)rpcName { if ([FIRFirestore isLoggingEnabled]) { - FSTLog(@"RPC %@ returned headers (whitelisted): %@", rpcName, - [FSTDatastore extractWhiteListedHeaders:rpc.responseHeaders]); + LOG_DEBUG("RPC %s returned headers (whitelisted): %s", rpcName, + [FSTDatastore extractWhiteListedHeaders:rpc.responseHeaders]); } } @@ -239,7 +239,7 @@ typedef GRPCProtoCall * (^RPCFactory)(void); handler:^(GCFSCommitResponse *response, NSError *_Nullable error) { error = [FSTDatastore firestoreErrorForError:error]; [self.workerDispatchQueue dispatchAsync:^{ - FSTLog(@"RPC CommitRequest completed. Error: %@", error); + LOG_DEBUG("RPC CommitRequest completed. Error: %s", error); [FSTDatastore logHeadersForRPC:rpc RPCName:@"CommitRequest"]; completion(error); }]; @@ -272,7 +272,7 @@ typedef GRPCProtoCall * (^RPCFactory)(void); error = [FSTDatastore firestoreErrorForError:error]; [self.workerDispatchQueue dispatchAsync:^{ if (error) { - FSTLog(@"RPC BatchGetDocuments completed. Error: %@", error); + LOG_DEBUG("RPC BatchGetDocuments completed. Error: %s", error); [FSTDatastore logHeadersForRPC:rpc RPCName:@"BatchGetDocuments"]; completion(nil, error); return; @@ -285,7 +285,7 @@ typedef GRPCProtoCall * (^RPCFactory)(void); closure->results.insert({doc.key, doc}); } else { // Streaming response is done, call completion - FSTLog(@"RPC BatchGetDocuments completed successfully."); + LOG_DEBUG("RPC BatchGetDocuments completed successfully."); [FSTDatastore logHeadersForRPC:rpc RPCName:@"BatchGetDocuments"]; FSTAssert(!response, @"Got response after done."); NSMutableArray *docs = diff --git a/Firestore/Source/Remote/FSTExponentialBackoff.mm b/Firestore/Source/Remote/FSTExponentialBackoff.mm index 20b50a5..2bddbf7 100644 --- a/Firestore/Source/Remote/FSTExponentialBackoff.mm +++ b/Firestore/Source/Remote/FSTExponentialBackoff.mm @@ -18,10 +18,10 @@ #include -#include "Firestore/core/src/firebase/firestore/util/secure_random.h" - #import "Firestore/Source/Util/FSTDispatchQueue.h" -#import "Firestore/Source/Util/FSTLogger.h" + +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/secure_random.h" using firebase::firestore::util::SecureRandom; @@ -71,8 +71,7 @@ using firebase::firestore::util::SecureRandom; // First schedule the block using the current base (which may be 0 and should be honored as such). NSTimeInterval delayWithJitter = _currentBase + [self jitterDelay]; if (_currentBase > 0) { - FSTLog(@"Backing off for %.2f seconds (base delay: %.2f seconds)", delayWithJitter, - _currentBase); + LOG_DEBUG("Backing off for %s seconds (base delay: %s seconds)", delayWithJitter, _currentBase); } self.timerCallback = diff --git a/Firestore/Source/Remote/FSTOnlineStateTracker.mm b/Firestore/Source/Remote/FSTOnlineStateTracker.mm index e782397..e512a3c 100644 --- a/Firestore/Source/Remote/FSTOnlineStateTracker.mm +++ b/Firestore/Source/Remote/FSTOnlineStateTracker.mm @@ -18,7 +18,8 @@ #import "Firestore/Source/Remote/FSTRemoteStore.h" #import "Firestore/Source/Util/FSTAssert.h" #import "Firestore/Source/Util/FSTDispatchQueue.h" -#import "Firestore/Source/Util/FSTLogger.h" + +#include "Firestore/core/src/firebase/firestore/util/log.h" NS_ASSUME_NONNULL_BEGIN @@ -83,10 +84,9 @@ static const NSTimeInterval kOnlineStateTimeout = 10; FSTAssert( self.state == FSTOnlineStateUnknown, @"Timer should be canceled if we transitioned to a different state."); - FSTLog( - @"Watch stream didn't reach Online or Offline within %f seconds. " - @"Considering " - "client offline.", + LOG_DEBUG( + "Watch stream didn't reach Online or Offline within %s seconds. " + "Considering client offline.", kOnlineStateTimeout); [self logClientOfflineWarningIfNecessary]; [self setAndBroadcastState:FSTOnlineStateOffline]; @@ -138,7 +138,7 @@ static const NSTimeInterval kOnlineStateTimeout = 10; - (void)logClientOfflineWarningIfNecessary { if (self.shouldWarnClientIsOffline) { - FSTWarn(@"Could not reach Firestore backend."); + LOG_WARN("Could not reach Firestore backend."); self.shouldWarnClientIsOffline = NO; } } diff --git a/Firestore/Source/Remote/FSTRemoteEvent.mm b/Firestore/Source/Remote/FSTRemoteEvent.mm index 438072e..ebd9b93 100644 --- a/Firestore/Source/Remote/FSTRemoteEvent.mm +++ b/Firestore/Source/Remote/FSTRemoteEvent.mm @@ -24,9 +24,10 @@ #import "Firestore/Source/Remote/FSTWatchChange.h" #import "Firestore/Source/Util/FSTAssert.h" #import "Firestore/Source/Util/FSTClasses.h" -#import "Firestore/Source/Util/FSTLogger.h" + #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" using firebase::firestore::model::DocumentKey; using firebase::firestore::model::SnapshotVersion; @@ -577,7 +578,7 @@ initWithSnapshotVersion:(SnapshotVersion)snapshotVersion } break; default: - FSTWarn(@"Unknown target watch change type: %ld", (long)targetChange.state); + LOG_WARN("Unknown target watch change type: %s", targetChange.state); } } } diff --git a/Firestore/Source/Remote/FSTRemoteStore.mm b/Firestore/Source/Remote/FSTRemoteStore.mm index 0ea4887..e0adb4e 100644 --- a/Firestore/Source/Remote/FSTRemoteStore.mm +++ b/Firestore/Source/Remote/FSTRemoteStore.mm @@ -32,11 +32,11 @@ #import "Firestore/Source/Remote/FSTStream.h" #import "Firestore/Source/Remote/FSTWatchChange.h" #import "Firestore/Source/Util/FSTAssert.h" -#import "Firestore/Source/Util/FSTLogger.h" #include "Firestore/core/src/firebase/firestore/auth/user.h" #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" #include "Firestore/core/src/firebase/firestore/util/string_apple.h" namespace util = firebase::firestore::util; @@ -205,7 +205,7 @@ static const int kMaxPendingWrites = 10; #pragma mark Shutdown - (void)shutdown { - FSTLog(@"FSTRemoteStore %p shutting down", (__bridge void *)self); + LOG_DEBUG("FSTRemoteStore %s shutting down", (__bridge void *)self); [self disableNetworkInternal]; // Set the FSTOnlineState to Unknown (rather than Offline) to avoid potentially triggering // spurious listener events with cached data, etc. @@ -213,7 +213,7 @@ static const int kMaxPendingWrites = 10; } - (void)userDidChange:(const User &)user { - FSTLog(@"FSTRemoteStore %p changing users: %s", (__bridge void *)self, user.uid().c_str()); + LOG_DEBUG("FSTRemoteStore %s changing users: %s", (__bridge void *)self, user.uid()); if ([self isNetworkEnabled]) { // Tear down and re-create our network streams. This will ensure we get a fresh auth token // for the new user and re-fill the write pipeline with new mutations from the LocalStore @@ -408,7 +408,7 @@ static const int kMaxPendingWrites = 10; } if (trackedRemote.size() != static_cast(filter.count)) { - FSTLog(@"Existence filter mismatch, resetting mapping"); + LOG_DEBUG("Existence filter mismatch, resetting mapping"); // Make sure the mismatch is exposed in the remote event [remoteEvent handleExistenceFilterMismatchForTargetID:target]; @@ -490,8 +490,7 @@ static const int kMaxPendingWrites = 10; - (void)cleanUpWriteStreamState { self.lastBatchSeen = kFSTBatchIDUnknown; - FSTLog(@"Stopping write stream with %lu pending writes", - (unsigned long)[self.pendingWrites count]); + LOG_DEBUG("Stopping write stream with %s pending writes", [self.pendingWrites count]); [self.pendingWrites removeAllObjects]; } @@ -618,8 +617,8 @@ static const int kMaxPendingWrites = 10; // stream is no longer valid. if ([FSTDatastore isPermanentWriteError:error] || [FSTDatastore isAbortedError:error]) { NSString *token = [self.writeStream.lastStreamToken base64EncodedStringWithOptions:0]; - FSTLog(@"FSTRemoteStore %p error before completed handshake; resetting stream token %@: %@", - (__bridge void *)self, token, error); + LOG_DEBUG("FSTRemoteStore %s error before completed handshake; resetting stream token %s: %s", + (__bridge void *)self, token, error); self.writeStream.lastStreamToken = nil; [self.localStore setLastStreamToken:nil]; } diff --git a/Firestore/Source/Remote/FSTStream.mm b/Firestore/Source/Remote/FSTStream.mm index f4ec675..0e45418 100644 --- a/Firestore/Source/Remote/FSTStream.mm +++ b/Firestore/Source/Remote/FSTStream.mm @@ -29,7 +29,6 @@ #import "Firestore/Source/Util/FSTAssert.h" #import "Firestore/Source/Util/FSTClasses.h" #import "Firestore/Source/Util/FSTDispatchQueue.h" -#import "Firestore/Source/Util/FSTLogger.h" #import "Firestore/Protos/objc/google/firestore/v1beta1/Firestore.pbrpc.h" @@ -38,6 +37,7 @@ #include "Firestore/core/src/firebase/firestore/model/database_id.h" #include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" #include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" #include "Firestore/core/src/firebase/firestore/util/string_apple.h" namespace util = firebase::firestore::util; @@ -258,7 +258,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; return; } - FSTLog(@"%@ %p start", NSStringFromClass([self class]), (__bridge void *)self); + LOG_DEBUG("%s %s start", NSStringFromClass([self class]), (__bridge void *)self); FSTAssert(self.state == FSTStreamStateInitial, @"Already started"); self.state = FSTStreamStateAuth; @@ -311,7 +311,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; /** Backs off after an error. */ - (void)performBackoffWithDelegate:(id)delegate { - FSTLog(@"%@ %p backoff", NSStringFromClass([self class]), (__bridge void *)self); + LOG_DEBUG("%s %s backoff", NSStringFromClass([self class]), (__bridge void *)self); [self.workerDispatchQueue verifyIsCurrentQueue]; FSTAssert(self.state == FSTStreamStateError, @"Should only perform backoff in an error case"); @@ -381,13 +381,13 @@ static const NSTimeInterval kIdleTimeout = 60.0; // If this is an intentional close ensure we don't delay our next connection attempt. [self.backoff reset]; } else if (error != nil && error.code == FIRFirestoreErrorCodeResourceExhausted) { - FSTLog(@"%@ %p Using maximum backoff delay to prevent overloading the backend.", [self class], - (__bridge void *)self); + LOG_DEBUG("%s %s Using maximum backoff delay to prevent overloading the backend.", [self class], + (__bridge void *)self); [self.backoff resetToMax]; } if (finalState != FSTStreamStateError) { - FSTLog(@"%@ %p Performing stream teardown", [self class], (__bridge void *)self); + LOG_DEBUG("%s %s Performing stream teardown", [self class], (__bridge void *)self); [self tearDown]; } @@ -395,7 +395,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; // Clean up the underlying RPC. If this close: is in response to an error, don't attempt to // call half-close to avoid secondary failures. if (finalState != FSTStreamStateError) { - FSTLog(@"%@ %p Closing stream client-side", [self class], (__bridge void *)self); + LOG_DEBUG("%s %s Closing stream client-side", [self class], (__bridge void *)self); @synchronized(self.requestsWriter) { [self.requestsWriter finishWithError:nil]; } @@ -426,7 +426,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; } - (void)stop { - FSTLog(@"%@ %p stop", NSStringFromClass([self class]), (__bridge void *)self); + LOG_DEBUG("%s %s stop", NSStringFromClass([self class]), (__bridge void *)self); if ([self isStarted]) { [self closeWithFinalState:FSTStreamStateStopped error:nil]; } @@ -550,7 +550,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; * Called by the stream when the underlying RPC has been closed for whatever reason. */ - (void)handleStreamClose:(nullable NSError *)error { - FSTLog(@"%@ %p close: %@", NSStringFromClass([self class]), (__bridge void *)self, error); + LOG_DEBUG("%s %s close: %s", NSStringFromClass([self class]), (__bridge void *)self, error); FSTAssert([self isStarted], @"handleStreamClose: called for non-started stream."); // In theory the stream could close cleanly, however, in our current model we never expect this @@ -577,9 +577,9 @@ static const NSTimeInterval kIdleTimeout = 60.0; if (!self.messageReceived) { self.messageReceived = YES; if ([FIRFirestore isLoggingEnabled]) { - FSTLog(@"%@ %p headers (whitelisted): %@", NSStringFromClass([self class]), - (__bridge void *)self, - [FSTDatastore extractWhiteListedHeaders:self.rpc.responseHeaders]); + LOG_DEBUG("%s %s headers (whitelisted): %s", NSStringFromClass([self class]), + (__bridge void *)self, + [FSTDatastore extractWhiteListedHeaders:self.rpc.responseHeaders]); } } NSError *error; @@ -665,7 +665,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; request.addTarget = [_serializer encodedTarget:query]; request.labels = [_serializer encodedListenRequestLabelsForQueryData:query]; - FSTLog(@"FSTWatchStream %p watch: %@", (__bridge void *)self, request); + LOG_DEBUG("FSTWatchStream %s watch: %s", (__bridge void *)self, request); [self writeRequest:request]; } @@ -677,7 +677,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; request.database = [_serializer encodedDatabaseID]; request.removeTarget = targetID; - FSTLog(@"FSTWatchStream %p unwatch: %@", (__bridge void *)self, request); + LOG_DEBUG("FSTWatchStream %s unwatch: %s", (__bridge void *)self, request); [self writeRequest:request]; } @@ -686,7 +686,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; * watchStreamDidChange:snapshotVersion: callback. */ - (void)handleStreamMessage:(GCFSListenResponse *)proto { - FSTLog(@"FSTWatchStream %p response: %@", (__bridge void *)self, proto); + LOG_DEBUG("FSTWatchStream %s response: %s", (__bridge void *)self, proto); [self.workerDispatchQueue verifyIsCurrentQueue]; // A successful response means the stream is healthy. @@ -765,7 +765,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; // TODO(dimond): Support stream resumption. We intentionally do not set the stream token on the // handshake, ignoring any stream token we might have. - FSTLog(@"FSTWriteStream %p initial request: %@", (__bridge void *)self, request); + LOG_DEBUG("FSTWriteStream %s initial request: %s", (__bridge void *)self, request); [self writeRequest:request]; } @@ -783,7 +783,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; request.writesArray = protos; request.streamToken = self.lastStreamToken; - FSTLog(@"FSTWriteStream %p mutation request: %@", (__bridge void *)self, request); + LOG_DEBUG("FSTWriteStream %s mutation request: %s", (__bridge void *)self, request); [self writeRequest:request]; } @@ -792,7 +792,7 @@ static const NSTimeInterval kIdleTimeout = 60.0; * that on to the mutationResultsHandler. */ - (void)handleStreamMessage:(GCFSWriteResponse *)response { - FSTLog(@"FSTWriteStream %p response: %@", (__bridge void *)self, response); + LOG_DEBUG("FSTWriteStream %s response: %s", (__bridge void *)self, response); [self.workerDispatchQueue verifyIsCurrentQueue]; // Always capture the last stream token. diff --git a/Firestore/Source/Util/FSTLogger.h b/Firestore/Source/Util/FSTLogger.h deleted file mode 100644 index c4e2b85..0000000 --- a/Firestore/Source/Util/FSTLogger.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2017 Google - * - * 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 - -NS_ASSUME_NONNULL_BEGIN - -/** Logs to NSLog if [FIRFirestore isLoggingEnabled] is YES. */ -void FSTLog(NSString *format, ...) NS_FORMAT_FUNCTION(1, 2); - -void FSTWarn(NSString *format, ...) NS_FORMAT_FUNCTION(1, 2); - -NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTLogger.mm b/Firestore/Source/Util/FSTLogger.mm deleted file mode 100644 index f0081e0..0000000 --- a/Firestore/Source/Util/FSTLogger.mm +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2017 Google - * - * 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 "Firestore/Source/Util/FSTLogger.h" - -#import - -#import "Firestore/Source/API/FIRFirestore+Internal.h" - -NS_ASSUME_NONNULL_BEGIN - -void FSTLog(NSString *format, ...) { - if ([FIRFirestore isLoggingEnabled]) { - va_list args; - va_start(args, format); - FIRLogBasic(FIRLoggerLevelDebug, kFIRLoggerFirestore, @"I-FST000001", format, args); - va_end(args); - } -} - -void FSTWarn(NSString *format, ...) { - va_list args; - va_start(args, format); - FIRLogBasic(FIRLoggerLevelWarning, kFIRLoggerFirestore, @"I-FST000001", format, args); - va_end(args); -} - -NS_ASSUME_NONNULL_END diff --git a/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc b/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc index 3581ef5..da9f004 100644 --- a/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc +++ b/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc @@ -212,9 +212,7 @@ void LevelDbTransaction::Commit() { batch.Put(it->first, it->second); } - if (util::LogGetLevel() <= util::kLogLevelDebug) { - util::LogDebug("Committing transaction: %s", ToString().c_str()); - } + LOG_DEBUG("Committing transaction: %s", ToString()); Status status = db_->Write(write_options_, &batch); HARD_ASSERT(status.ok(), "Failed to commit transaction:\n%s\n Failed: %s", diff --git a/Firestore/core/src/firebase/firestore/util/log.h b/Firestore/core/src/firebase/firestore/util/log.h index 1944596..248d434 100644 --- a/Firestore/core/src/firebase/firestore/util/log.h +++ b/Firestore/core/src/firebase/firestore/util/log.h @@ -17,44 +17,65 @@ #ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ #define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ -#include +#include + +#include "Firestore/core/src/firebase/firestore/util/string_format.h" namespace firebase { namespace firestore { namespace util { -/// @brief Levels used when logging messages. +// Levels used when logging messages. enum LogLevel { - /// Verbose Log Level - kLogLevelVerbose = 0, - /// Debug Log Level + // Debug Log Level kLogLevelDebug, - /// Info Log Level - kLogLevelInfo, - /// Warning Log Level + // Warning Log Level kLogLevelWarning, - /// Error Log Level - kLogLevelError, }; -// Common log methods. +// Log a message if kLogLevelDebug is enabled. Arguments are not evaluated if +// logging is disabled. +// +// @param format A format string suitable for use with `util::StringFormat` +// @param ... C++ variadic arguments that match the format string. Not C +// varargs. +#define LOG_DEBUG(...) \ + do { \ + namespace _util = firebase::firestore::util; \ + if (_util::LogIsLoggable(_util::kLogLevelDebug)) { \ + std::string _message = _util::StringFormat(__VA_ARGS__); \ + _util::LogMessage(_util::kLogLevelDebug, _message); \ + } \ + } while (0) + +// Log a message if kLogLevelWarn is enabled (it is by default). Arguments are +// not evaluated if logging is disabled. +// +// @param format A format string suitable for use with `util::StringFormat` +// @param ... C++ variadic arguments that match the format string. Not C +// varargs. +#define LOG_WARN(...) \ + do { \ + namespace _util = firebase::firestore::util; \ + if (_util::LogIsLoggable(_util::kLogLevelWarning)) { \ + std::string _message = _util::StringFormat(__VA_ARGS__); \ + _util::LogMessage(_util::kLogLevelWarning, _message); \ + } \ + } while (0) + +// Tests to see if the given log level is loggable. +bool LogIsLoggable(LogLevel level); + +// Is debug logging enabled? +inline bool LogIsDebugEnabled() { + return LogIsLoggable(kLogLevelDebug); +} // All messages at or above the specified log level value are displayed. void LogSetLevel(LogLevel level); -// Get the currently set log level. -LogLevel LogGetLevel(); -// Log a debug message to the system log. -void LogDebug(const char* format, ...); -// Log an info message to the system log. -void LogInfo(const char* format, ...); -// Log a warning to the system log. -void LogWarning(const char* format, ...); -// Log an error to the system log. -void LogError(const char* format, ...); -// Log a firebase message (implemented by the platform specific logger). -void LogMessageV(LogLevel log_level, const char* format, va_list args); -// Log a firebase message via LogMessageV(). -void LogMessage(LogLevel log_level, const char* format, ...); + +// Log a message at the given level. +void LogMessage(LogLevel log_level, const std::string& message); } // namespace util } // namespace firestore diff --git a/Firestore/core/src/firebase/firestore/util/log_apple.mm b/Firestore/core/src/firebase/firestore/util/log_apple.mm index cb2c58e..45e4f55 100644 --- a/Firestore/core/src/firebase/firestore/util/log_apple.mm +++ b/Firestore/core/src/firebase/firestore/util/log_apple.mm @@ -19,6 +19,7 @@ #import #import +#include #include #include "Firestore/core/src/firebase/firestore/util/string_apple.h" @@ -32,90 +33,40 @@ namespace { // Translates a C++ LogLevel to the equivalent Objective-C FIRLoggerLevel FIRLoggerLevel ToFIRLoggerLevel(LogLevel level) { switch (level) { - case kLogLevelVerbose: // fall through case kLogLevelDebug: return FIRLoggerLevelDebug; - case kLogLevelInfo: - return FIRLoggerLevelInfo; case kLogLevelWarning: return FIRLoggerLevelWarning; - case kLogLevelError: - return FIRLoggerLevelError; default: // Unsupported log level. FIRSetLoggerLevel will deal with it. return static_cast(-1); } } -} // namespace - -void LogSetLevel(LogLevel level) { - FIRSetLoggerLevel(ToFIRLoggerLevel(level)); -} - -LogLevel LogGetLevel() { - // We return the true log level. True log level is what the SDK used to - // determine whether to log instead of what parameter is used in the last call - // of LogSetLevel(). - if (FIRIsLoggableLevel(FIRLoggerLevelInfo, NO)) { - if (FIRIsLoggableLevel(FIRLoggerLevelDebug, NO)) { - // FIRLoggerLevelMax is actually kLogLevelDebug right now. We do not check - // further. - return kLogLevelDebug; - } else { - return kLogLevelInfo; - } - } else { - if (FIRIsLoggableLevel(FIRLoggerLevelWarning, NO)) { - return kLogLevelWarning; - } else { - return kLogLevelError; - } - } -} - -void LogDebug(const char* format, ...) { +// Actually logs a message via FIRLogger. This must be a C varargs function +// so that we can call FIRLogBasic which takes a `va_list`. +void LogMessageV(LogLevel level, NSString* format, ...) { va_list list; va_start(list, format); - FIRLogBasic(FIRLoggerLevelDebug, kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), list); - va_end(list); -} -void LogInfo(const char* format, ...) { - va_list list; - va_start(list, format); - FIRLogBasic(FIRLoggerLevelInfo, kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), list); - va_end(list); -} + FIRLogBasic(ToFIRLoggerLevel(level), kFIRLoggerFirestore, @"I-FST000001", + format, list); -void LogWarning(const char* format, ...) { - va_list list; - va_start(list, format); - FIRLogBasic(FIRLoggerLevelWarning, kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), list); va_end(list); } -void LogError(const char* format, ...) { - va_list list; - va_start(list, format); - FIRLogBasic(FIRLoggerLevelError, kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), list); - va_end(list); +} // namespace + +void LogSetLevel(LogLevel level) { + FIRSetLoggerLevel(ToFIRLoggerLevel(level)); } -void LogMessageV(LogLevel log_level, const char* format, va_list args) { - FIRLogBasic(ToFIRLoggerLevel(log_level), kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), args); +bool LogIsLoggable(LogLevel level) { + return FIRIsLoggableLevel(ToFIRLoggerLevel(level), NO); } -void LogMessage(LogLevel log_level, const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(log_level, format, list); - va_end(list); +void LogMessage(LogLevel level, const std::string& message) { + LogMessageV(level, @"%s", message.c_str()); } } // namespace util diff --git a/Firestore/core/src/firebase/firestore/util/log_stdio.cc b/Firestore/core/src/firebase/firestore/util/log_stdio.cc index b277406..6fff885 100644 --- a/Firestore/core/src/firebase/firestore/util/log_stdio.cc +++ b/Firestore/core/src/firebase/firestore/util/log_stdio.cc @@ -19,77 +19,42 @@ #include #include +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + namespace firebase { namespace firestore { namespace util { -LogLevel g_log_level = kLogLevelInfo; +LogLevel g_log_level = kLogLevelWarning; void LogSetLevel(LogLevel level) { g_log_level = level; } -LogLevel LogGetLevel() { - return g_log_level; -} - -void LogDebug(const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(kLogLevelDebug, format, list); - va_end(list); -} - -void LogInfo(const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(kLogLevelInfo, format, list); - va_end(list); -} - -void LogWarning(const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(kLogLevelWarning, format, list); - va_end(list); +bool LogIsLoggable(LogLevel level) { + return level >= g_log_level; } -void LogError(const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(kLogLevelError, format, list); - va_end(list); -} - -void LogMessageV(LogLevel log_level, const char* format, va_list args) { +void LogMessage(LogLevel log_level, const std::string& message) { if (log_level < g_log_level) { return; } + + const char* level_word; + switch (log_level) { - case kLogLevelVerbose: - printf("VERBOSE: "); - break; case kLogLevelDebug: - printf("DEBUG: "); - break; - case kLogLevelInfo: + level_word = "DEBUG"; break; case kLogLevelWarning: - printf("WARNING: "); + level_word = "WARNING"; break; - case kLogLevelError: - printf("ERROR: "); + default: + UNREACHABLE(); break; } - vprintf(format, args); - printf("\n"); -} -void LogMessage(LogLevel log_level, const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(log_level, format, list); - va_end(list); + printf("%s: %s\n", level_word, message.c_str()); } } // namespace util diff --git a/Firestore/core/src/firebase/firestore/util/string_format.h b/Firestore/core/src/firebase/firestore/util/string_format.h index 3d7a1dc..f8da785 100644 --- a/Firestore/core/src/firebase/firestore/util/string_format.h +++ b/Firestore/core/src/firebase/firestore/util/string_format.h @@ -21,6 +21,7 @@ #include #include +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" #include "absl/base/attributes.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" @@ -66,6 +67,12 @@ class FormatArg : public absl::AlphaNum { : FormatArg{std::forward(value), internal::FormatChoice<0>{}} { } +#if __OBJC__ + FormatArg(NSObject* object) // NOLINT(runtime/explicit) + : AlphaNum{MakeStringView([object description])} { + } +#endif + private: /** * Creates a FormatArg from a boolean value, representing the string diff --git a/Firestore/core/test/firebase/firestore/util/log_test.cc b/Firestore/core/test/firebase/firestore/util/log_test.cc index 973b174..73050ea 100644 --- a/Firestore/core/test/firebase/firestore/util/log_test.cc +++ b/Firestore/core/test/firebase/firestore/util/log_test.cc @@ -33,27 +33,19 @@ namespace util { // defaults write firebase_firestore_util_log_apple_test // /google/firebase/debug_mode NO TEST(Log, SetAndGet) { - LogSetLevel(kLogLevelVerbose); + EXPECT_FALSE(LogIsDebugEnabled()); LogSetLevel(kLogLevelDebug); - EXPECT_EQ(kLogLevelDebug, LogGetLevel()); - - LogSetLevel(kLogLevelInfo); - EXPECT_EQ(kLogLevelInfo, LogGetLevel()); + EXPECT_TRUE(LogIsDebugEnabled()); LogSetLevel(kLogLevelWarning); - EXPECT_EQ(kLogLevelWarning, LogGetLevel()); - - LogSetLevel(kLogLevelError); - EXPECT_EQ(kLogLevelError, LogGetLevel()); + EXPECT_FALSE(LogIsDebugEnabled()); } TEST(Log, LogAllKinds) { - LogDebug("test debug logging %d", 1); - LogInfo("test info logging %d", 2); - LogWarning("test warning logging %d", 3); - LogError("test error logging %d", 4); - LogMessage(kLogLevelError, "test va-args %s %c %d", "abc", ':', 123); + LOG_DEBUG("test debug logging %s", 1); + LOG_WARN("test warning logging %s", 3); + LOG_DEBUG("test va-args %s %s %s", "abc", std::string{"def"}, 123); } } // namespace util -- cgit v1.2.3