From f67e75243365d0f74145cecef88c6fd20edb1953 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Fri, 27 Sep 2024 14:25:04 -0400 Subject: [PATCH 01/11] Add privacy support to Logger in Dataconnect --- Sources/DataConnect.swift | 3 + Sources/Internal/CodableTimestamp.swift | 4 +- .../FirebaseLogger/DataConnectLogger.swift | 18 --- .../FirebaseLogger/FirebaseLogger.swift | 54 ------- Sources/Internal/GrpcClient.swift | 145 +++++------------- 5 files changed, 46 insertions(+), 178 deletions(-) delete mode 100644 Sources/Internal/FirebaseLogger/DataConnectLogger.swift delete mode 100644 Sources/Internal/FirebaseLogger/FirebaseLogger.swift diff --git a/Sources/DataConnect.swift b/Sources/DataConnect.swift index 75f3113..036517e 100644 --- a/Sources/DataConnect.swift +++ b/Sources/DataConnect.swift @@ -17,6 +17,7 @@ import Foundation import FirebaseAppCheck import FirebaseAuth import FirebaseCore +import OSLog @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public class DataConnect { @@ -31,6 +32,8 @@ public class DataConnect { private static var instanceStore = InstanceStore() + static let logger = Logger(subsystem: "com.google.firebase", category: "data_connect") + public enum EmulatorDefaults { public static let host = "127.0.0.1" public static let port = 9399 diff --git a/Sources/Internal/CodableTimestamp.swift b/Sources/Internal/CodableTimestamp.swift index 714b578..493af5e 100644 --- a/Sources/Internal/CodableTimestamp.swift +++ b/Sources/Internal/CodableTimestamp.swift @@ -52,9 +52,9 @@ extension CodableTimestamp { .firstMatch(in: timestampString, range: NSRange(location: 0, length: timestampString.count)) != nil else { - FirebaseLogger.dataConnect + DataConnect.logger .error( - "Timestamp string format doesn't support." + "Timestamp string \(timestampString, privacy: .private) format doesn't support." ) throw DataConnectError.invalidTimestampFormat } diff --git a/Sources/Internal/FirebaseLogger/DataConnectLogger.swift b/Sources/Internal/FirebaseLogger/DataConnectLogger.swift deleted file mode 100644 index 199c9a8..0000000 --- a/Sources/Internal/FirebaseLogger/DataConnectLogger.swift +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2024 Google LLC -// -// 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. - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -extension FirebaseLogger { - static let dataConnect = FirebaseLogger(category: "data_connect") -} diff --git a/Sources/Internal/FirebaseLogger/FirebaseLogger.swift b/Sources/Internal/FirebaseLogger/FirebaseLogger.swift deleted file mode 100644 index 838f441..0000000 --- a/Sources/Internal/FirebaseLogger/FirebaseLogger.swift +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2024 Google LLC -// -// 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 -import OSLog - -@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) -public class FirebaseLogger { - let subsystem: String = "com.google.firebase" - - let category: String - - private let logger: Logger - - public init(category: String) { - self.category = category - logger = Logger(subsystem: subsystem, category: category) - } - - public func notice(_ message: String) { - logger.notice("\(message)") - } - - public func info(_ message: String) { - logger.info("\(message)") - } - - public func debug(_ message: String) { - logger.debug("\(message)") - } - - public func warning(_ message: String) { - logger.warning("\(message)") - } - - public func error(_ message: String) { - logger.error("\(message)") - } - - public func fault(_ message: String) { - logger.fault("\(message)") - } -} diff --git a/Sources/Internal/GrpcClient.swift b/Sources/Internal/GrpcClient.swift index 129c2c9..3b523ac 100644 --- a/Sources/Internal/GrpcClient.swift +++ b/Sources/Internal/GrpcClient.swift @@ -50,9 +50,6 @@ actor GrpcClient: CustomStringConvertible { private let callerSDKType: CallerSDKType - // Remove debug flag when logging privacy is properly handled. - private let debugEnable = false - enum RequestHeaders { static let googRequestParamsHeader = "x-goog-request-params" static let authorizationHeader = "x-firebase-auth-token" @@ -65,11 +62,8 @@ actor GrpcClient: CustomStringConvertible { private lazy var client: FirebaseDataConnectAsyncClient? = { do { - if debugEnable == true { - FirebaseLogger.dataConnect.debug("\(self.description) initialization starts.") - } else { - FirebaseLogger.dataConnect.debug("GrpcClient initialization starts.") - } + DataConnect.logger + .debug("GrpcClient \(self.description, privacy: .private) initialization starts.") let group = PlatformSupport.makeEventLoopGroup(loopCount: threadPoolSize) let channel = try GRPCChannelPool.with( target: .host(serverSettings.host, port: serverSettings.port), @@ -78,18 +72,11 @@ actor GrpcClient: CustomStringConvertible { .plaintext, eventLoopGroup: group ) - if debugEnable == true { - FirebaseLogger.dataConnect.debug("\(self.description) has been created.") - } else { - FirebaseLogger.dataConnect.debug("GrpcClient has been created.") - } + DataConnect.logger.debug("GrpcClient\(self.description, privacy: .private) has been created.") return FirebaseDataConnectAsyncClient(channel: channel) } catch { - if debugEnable == true { - FirebaseLogger.dataConnect.error("Error:\(error) when creating \(self.description).") - } else { - FirebaseLogger.dataConnect.debug("Error:\(error) when creating GrpcClient.") - } + DataConnect.logger + .debug("Error:\(error) when creating GrpcClient\(self.description, privacy: .private).") return nil } }() @@ -130,8 +117,7 @@ actor GrpcClient: CustomStringConvertible { googRequestHeaderValue = "location=\(self.connectorConfig.location)&frontend=data" description = """ - GrpcClient: \ - projectId=\(projectId) \ + : projectId=\(projectId) \ connector=\(connectorConfig.connector) \ host=\(serverSettings.host) \ port=\(serverSettings.port) \ @@ -145,7 +131,7 @@ actor GrpcClient: CustomStringConvertible { .Type) async throws -> OperationResult { guard let client else { - FirebaseLogger.dataConnect + DataConnect.logger .error("When calling executeQuery(), grpc client has not been configured.") throw DataConnectError.grpcNotConfigured } @@ -155,49 +141,29 @@ actor GrpcClient: CustomStringConvertible { connectorName: connectorName, request: request ) + let requestString = try ": " + grpcRequest.jsonString() do { - if debugEnable == true { - try FirebaseLogger.dataConnect - .debug("executeQuery() sends grpc request: \(grpcRequest.jsonString()).") - } else { - try FirebaseLogger.dataConnect - .debug("executeQuery() sends grpc request.") - } + DataConnect.logger + .debug("executeQuery() sends grpc request\(requestString, privacy: .private).") let results = try await client.executeQuery(grpcRequest, callOptions: createCallOptions()) - if debugEnable == true { - try FirebaseLogger.dataConnect - .debug("executeQuery() receives response: \(results.jsonString()).") - } else { - try FirebaseLogger.dataConnect - .debug("executeQuery() receives response.") - } + let resultsString = try ": " + results.jsonString() + DataConnect.logger + .debug("executeQuery() receives response\(resultsString, privacy: .private).") // Not doing error decoding here if let decodedResults = try codec.decode(result: results.data, asType: resultType) { return OperationResult(data: decodedResults) } else { // In future, set this as error in OperationResult - if debugEnable == true { - try FirebaseLogger.dataConnect - .error("executeQuery() response: \(results.jsonString()) decode failed.") - } else { - try FirebaseLogger.dataConnect - .error("executeQuery() response decode failed.") - } + DataConnect.logger + .debug("executeQuery() response\(resultsString, privacy: .private) decode failed.") throw DataConnectError.decodeFailed } } catch { - if debugEnable == true { - try FirebaseLogger.dataConnect - .error( - "executeQuery() with request: \(grpcRequest.jsonString()) grpc call FAILED with \(error)." - ) - } else { - try FirebaseLogger.dataConnect - .error( - "executeQuery() grpc call FAILED with \(error)." - ) - } + DataConnect.logger + .error( + "executeQuery()\(requestString, privacy: .private) grpc call FAILED with \(error)." + ) throw error } } @@ -208,7 +174,7 @@ actor GrpcClient: CustomStringConvertible { .Type) async throws -> OperationResult { guard let client else { - FirebaseLogger.dataConnect + DataConnect.logger .error("When calling executeMutation(), grpc client has not been configured.") throw DataConnectError.grpcNotConfigured } @@ -219,46 +185,27 @@ actor GrpcClient: CustomStringConvertible { request: request ) + let requestString = try ": " + grpcRequest.jsonString() + do { - if debugEnable == true { - try FirebaseLogger.dataConnect - .debug("executeMutation() sends grpc request: \(grpcRequest.jsonString()).") - } else { - try FirebaseLogger.dataConnect - .debug("executeMutation() sends grpc request.") - } + DataConnect.logger + .debug("executeMutation() sends grpc request \(requestString, privacy: .private).") let results = try await client.executeMutation(grpcRequest, callOptions: createCallOptions()) - if debugEnable == true { - try FirebaseLogger.dataConnect - .debug("executeMutation() receives response: \(results.jsonString()).") - } else { - try FirebaseLogger.dataConnect - .debug("executeMutation() receives response.") - } + let resultsString = try ": " + results.jsonString() + DataConnect.logger + .debug("executeMutation() receives response\(resultsString, privacy: .private).") if let decodedResults = try codec.decode(result: results.data, asType: resultType) { return OperationResult(data: decodedResults) } else { - if debugEnable == true { - try FirebaseLogger.dataConnect - .error("executeMutation() response: \(results.jsonString()) decode failed.") - } else { - try FirebaseLogger.dataConnect - .error("executeMutation() response decode failed.") - } + DataConnect.logger + .debug("executeMutation() response\(resultsString, privacy: .private) decode failed.") throw DataConnectError.decodeFailed } } catch { - if debugEnable == true { - try FirebaseLogger.dataConnect - .error( - "executeMutation() with request: \(grpcRequest.jsonString()) grpc call FAILED with \(error)." - ) - } else { - try FirebaseLogger.dataConnect - .error( - "executeMutation() grpc call FAILED with \(error)." - ) - } + DataConnect.logger + .error( + "executeMutation()\(requestString, privacy: .private) grpc call FAILED with \(error)." + ) throw error } } @@ -274,18 +221,13 @@ actor GrpcClient: CustomStringConvertible { do { if let token = try await auth.currentUser?.getIDToken() { headers.add(name: RequestHeaders.authorizationHeader, value: "\(token)") - if debugEnable == true { - FirebaseLogger.dataConnect - .debug("Auth token added: \(token)") - } else { - FirebaseLogger.dataConnect - .debug("Auth token added.") - } + DataConnect.logger + .debug("Auth token added \(token, privacy: .private)") } else { - FirebaseLogger.dataConnect.debug("No auth token available. Not adding auth header.") + DataConnect.logger.debug("No auth token available. Not adding auth header.") } } catch { - FirebaseLogger.dataConnect + DataConnect.logger .debug("Cannot get auth token successfully due to: \(error). Not adding auth header.") } @@ -293,19 +235,14 @@ actor GrpcClient: CustomStringConvertible { do { if let token = try await appCheck?.token(forcingRefresh: false) { headers.add(name: RequestHeaders.appCheckHeader, value: token.token) - if debugEnable == true { - FirebaseLogger.dataConnect - .debug("App Check token added: \(token.token)") - } else { - FirebaseLogger.dataConnect - .debug("App Check token added.") - } + DataConnect.logger + .debug("App Check token added \(token.token)") } else { - FirebaseLogger.dataConnect + DataConnect.logger .debug("App Check token unavailable. Not adding App Check header.") } } catch { - FirebaseLogger.dataConnect + DataConnect.logger .debug( "Cannot get App Check token successfully due to: \(error). Not adding App Check header." ) From cc81914e9dee44dbde485e6a913c581e43854598 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Thu, 3 Oct 2024 15:14:34 -0400 Subject: [PATCH 02/11] Format logging string and add public API support --- Sources/DataConnect.swift | 4 +- Sources/Internal/CodableTimestamp.swift | 7 +- Sources/Internal/GrpcClient.swift | 70 ++++++++++--------- .../Internal/Logger/DataConnectLogLevel.swift | 24 +++++++ .../Internal/Logger/DataConnectLogger.swift | 62 ++++++++++++++++ .../Logger/DataConnectMessageCode.swift | 18 +++++ 6 files changed, 145 insertions(+), 40 deletions(-) create mode 100644 Sources/Internal/Logger/DataConnectLogLevel.swift create mode 100644 Sources/Internal/Logger/DataConnectLogger.swift create mode 100644 Sources/Internal/Logger/DataConnectMessageCode.swift diff --git a/Sources/DataConnect.swift b/Sources/DataConnect.swift index 036517e..aaa309e 100644 --- a/Sources/DataConnect.swift +++ b/Sources/DataConnect.swift @@ -32,13 +32,13 @@ public class DataConnect { private static var instanceStore = InstanceStore() - static let logger = Logger(subsystem: "com.google.firebase", category: "data_connect") - public enum EmulatorDefaults { public static let host = "127.0.0.1" public static let port = 9399 } + public static var logLevel = LogLevel.WARN + // MARK: Static Creation /// Returns an instance of DataConnect matching the parameters. diff --git a/Sources/Internal/CodableTimestamp.swift b/Sources/Internal/CodableTimestamp.swift index 493af5e..8230642 100644 --- a/Sources/Internal/CodableTimestamp.swift +++ b/Sources/Internal/CodableTimestamp.swift @@ -52,10 +52,9 @@ extension CodableTimestamp { .firstMatch(in: timestampString, range: NSRange(location: 0, length: timestampString.count)) != nil else { - DataConnect.logger - .error( - "Timestamp string \(timestampString, privacy: .private) format doesn't support." - ) + DataConnectLogger.error( + "Timestamp string \(timestampString, privacy: .private) format doesn't support." + ) throw DataConnectError.invalidTimestampFormat } diff --git a/Sources/Internal/GrpcClient.swift b/Sources/Internal/GrpcClient.swift index 3b523ac..f658710 100644 --- a/Sources/Internal/GrpcClient.swift +++ b/Sources/Internal/GrpcClient.swift @@ -18,10 +18,10 @@ import FirebaseAppCheck import FirebaseAuth import FirebaseCore import GRPC +import Logging import NIOCore import NIOHPACK import NIOPosix -import OSLog import SwiftProtobuf @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) @@ -62,7 +62,7 @@ actor GrpcClient: CustomStringConvertible { private lazy var client: FirebaseDataConnectAsyncClient? = { do { - DataConnect.logger + DataConnectLogger .debug("GrpcClient \(self.description, privacy: .private) initialization starts.") let group = PlatformSupport.makeEventLoopGroup(loopCount: threadPoolSize) let channel = try GRPCChannelPool.with( @@ -72,10 +72,10 @@ actor GrpcClient: CustomStringConvertible { .plaintext, eventLoopGroup: group ) - DataConnect.logger.debug("GrpcClient\(self.description, privacy: .private) has been created.") + DataConnectLogger.debug("GrpcClient\(self.description, privacy: .private) has been created.") return FirebaseDataConnectAsyncClient(channel: channel) } catch { - DataConnect.logger + DataConnectLogger .debug("Error:\(error) when creating GrpcClient\(self.description, privacy: .private).") return nil } @@ -131,8 +131,7 @@ actor GrpcClient: CustomStringConvertible { .Type) async throws -> OperationResult { guard let client else { - DataConnect.logger - .error("When calling executeQuery(), grpc client has not been configured.") + DataConnectLogger.error("When calling executeQuery(), grpc client has not been configured.") throw DataConnectError.grpcNotConfigured } @@ -144,26 +143,25 @@ actor GrpcClient: CustomStringConvertible { let requestString = try ": " + grpcRequest.jsonString() do { - DataConnect.logger + DataConnectLogger .debug("executeQuery() sends grpc request\(requestString, privacy: .private).") let results = try await client.executeQuery(grpcRequest, callOptions: createCallOptions()) let resultsString = try ": " + results.jsonString() - DataConnect.logger + DataConnectLogger .debug("executeQuery() receives response\(resultsString, privacy: .private).") // Not doing error decoding here if let decodedResults = try codec.decode(result: results.data, asType: resultType) { return OperationResult(data: decodedResults) } else { // In future, set this as error in OperationResult - DataConnect.logger + DataConnectLogger .debug("executeQuery() response\(resultsString, privacy: .private) decode failed.") throw DataConnectError.decodeFailed } } catch { - DataConnect.logger - .error( - "executeQuery()\(requestString, privacy: .private) grpc call FAILED with \(error)." - ) + DataConnectLogger.error( + "executeQuery()\(requestString, privacy: .private) grpc call FAILED with \(error)." + ) throw error } } @@ -174,7 +172,7 @@ actor GrpcClient: CustomStringConvertible { .Type) async throws -> OperationResult { guard let client else { - DataConnect.logger + DataConnectLogger .error("When calling executeMutation(), grpc client has not been configured.") throw DataConnectError.grpcNotConfigured } @@ -188,24 +186,23 @@ actor GrpcClient: CustomStringConvertible { let requestString = try ": " + grpcRequest.jsonString() do { - DataConnect.logger + DataConnectLogger .debug("executeMutation() sends grpc request \(requestString, privacy: .private).") let results = try await client.executeMutation(grpcRequest, callOptions: createCallOptions()) let resultsString = try ": " + results.jsonString() - DataConnect.logger + DataConnectLogger .debug("executeMutation() receives response\(resultsString, privacy: .private).") if let decodedResults = try codec.decode(result: results.data, asType: resultType) { return OperationResult(data: decodedResults) } else { - DataConnect.logger + DataConnectLogger .debug("executeMutation() response\(resultsString, privacy: .private) decode failed.") throw DataConnectError.decodeFailed } } catch { - DataConnect.logger - .error( - "executeMutation()\(requestString, privacy: .private) grpc call FAILED with \(error)." - ) + DataConnectLogger.error( + "executeMutation()\(requestString, privacy: .private) grpc call FAILED with \(error)." + ) throw error } } @@ -221,13 +218,12 @@ actor GrpcClient: CustomStringConvertible { do { if let token = try await auth.currentUser?.getIDToken() { headers.add(name: RequestHeaders.authorizationHeader, value: "\(token)") - DataConnect.logger - .debug("Auth token added \(token, privacy: .private)") + DataConnectLogger.debug("Auth token added") } else { - DataConnect.logger.debug("No auth token available. Not adding auth header.") + DataConnectLogger.debug("No auth token available. Not adding auth header.") } } catch { - DataConnect.logger + DataConnectLogger .debug("Cannot get auth token successfully due to: \(error). Not adding auth header.") } @@ -235,20 +231,26 @@ actor GrpcClient: CustomStringConvertible { do { if let token = try await appCheck?.token(forcingRefresh: false) { headers.add(name: RequestHeaders.appCheckHeader, value: token.token) - DataConnect.logger - .debug("App Check token added \(token.token)") + DataConnectLogger.debug("App Check token added") } else { - DataConnect.logger - .debug("App Check token unavailable. Not adding App Check header.") + DataConnectLogger.debug("App Check token unavailable. Not adding App Check header.") } } catch { - DataConnect.logger - .debug( - "Cannot get App Check token successfully due to: \(error). Not adding App Check header." - ) + DataConnectLogger.debug( + "Cannot get App Check token successfully due to: \(error). Not adding App Check header." + ) + } + + var options = CallOptions(customMetadata: headers) + + // Enable GRPC tracing + if DataConnect.logLevel.rawValue <= LogLevel.DEBUG.rawValue { + var logger = Logger(label: "com.google.firebase.dataconnect.grpc") + logger.logLevel = .trace + options.logger = logger + options.requestIDProvider = .autogenerated } - let options = CallOptions(customMetadata: headers) return options } } diff --git a/Sources/Internal/Logger/DataConnectLogLevel.swift b/Sources/Internal/Logger/DataConnectLogLevel.swift new file mode 100644 index 0000000..328037b --- /dev/null +++ b/Sources/Internal/Logger/DataConnectLogLevel.swift @@ -0,0 +1,24 @@ +// Copyright 2024 Google LLC +// +// 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. + +public enum LogLevel: Int { + // Log all messages, including detailed debug logs + case DEBUG = 0 + + // Only log warnings and errors; this is the default log level. + case WARN = 1 + + // Do not log anything. + case NONE = 2 +} diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift new file mode 100644 index 0000000..abb47cb --- /dev/null +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -0,0 +1,62 @@ +// Copyright 2024 Google LLC +// +// 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 OSLog + +class DataConnectLogger { + private static let logger = Logger( + subsystem: "com.google.firebase", + category: "[FirebaseDataConnect]" + ) + + private static let logPrefix = "\(Version.sdkVersion) - [FirebaseDataConnect]" + + static func debug(_ message: String, code: MessageCode = .placeHolder) { + if DataConnect.logLevel.rawValue <= LogLevel.DEBUG.rawValue { + let messageCode = String(format: "I-FDC%06d", code.rawValue) + logger.debug("\(logPrefix)[\(messageCode)] \(message)") + } + } + + static func warning(_ message: String, code: MessageCode = .placeHolder) { + if DataConnect.logLevel.rawValue <= LogLevel.WARN.rawValue { + let messageCode = String(format: "I-FDC%06d", code.rawValue) + logger.warning("\(logPrefix)[\(messageCode)] \(message)") + } + } + + static func error(_ message: String, code: MessageCode = .placeHolder) { + if DataConnect.logLevel.rawValue <= LogLevel.WARN.rawValue { + let messageCode = String(format: "I-FDC%06d", code.rawValue) + logger.error("\(logPrefix)[\(messageCode)] \(message)") + } + } +} + +enum LogPrivacy: Int { + case `public` = 0 + + case `private` = 1 +} + +extension DefaultStringInterpolation { + mutating func appendInterpolation(_ value: String, privacy: LogPrivacy = .public) { + switch privacy { + case .private: + appendLiteral("") + default: + appendLiteral(value) + } + } +} diff --git a/Sources/Internal/Logger/DataConnectMessageCode.swift b/Sources/Internal/Logger/DataConnectMessageCode.swift new file mode 100644 index 0000000..2136e76 --- /dev/null +++ b/Sources/Internal/Logger/DataConnectMessageCode.swift @@ -0,0 +1,18 @@ +// Copyright 2024 Google LLC +// +// 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. + +enum MessageCode: Int { + // DataConnect Logging message code should be align with backend and is TBD + case placeHolder = 0 +} From 6f51ae3478c46122bb978b89f40cfbcac46c444b Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Thu, 3 Oct 2024 15:32:36 -0400 Subject: [PATCH 03/11] remove privacy when debug enabled --- Sources/Internal/Logger/DataConnectLogger.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift index abb47cb..b4d9e59 100644 --- a/Sources/Internal/Logger/DataConnectLogger.swift +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -52,10 +52,9 @@ enum LogPrivacy: Int { extension DefaultStringInterpolation { mutating func appendInterpolation(_ value: String, privacy: LogPrivacy = .public) { - switch privacy { - case .private: + if privacy == .private, DataConnect.logLevel.rawValue > LogLevel.DEBUG.rawValue { appendLiteral("") - default: + } else { appendLiteral(value) } } From 68ec124b3f1252c3ed09054feddc5d52c17f0c3d Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Thu, 3 Oct 2024 15:51:14 -0400 Subject: [PATCH 04/11] Add version restriction --- Sources/Internal/Logger/DataConnectLogger.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift index b4d9e59..51fde59 100644 --- a/Sources/Internal/Logger/DataConnectLogger.swift +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -14,6 +14,7 @@ import OSLog +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) class DataConnectLogger { private static let logger = Logger( subsystem: "com.google.firebase", From 3ec0f6d0a7075a868282596b51c4edf1e01f61b1 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Thu, 3 Oct 2024 16:44:17 -0400 Subject: [PATCH 05/11] Add version restriction 2 --- Sources/Internal/Logger/DataConnectLogger.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift index 51fde59..feabdbf 100644 --- a/Sources/Internal/Logger/DataConnectLogger.swift +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -51,6 +51,7 @@ enum LogPrivacy: Int { case `private` = 1 } +@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) extension DefaultStringInterpolation { mutating func appendInterpolation(_ value: String, privacy: LogPrivacy = .public) { if privacy == .private, DataConnect.logLevel.rawValue > LogLevel.DEBUG.rawValue { From 265f0e5656da89577d246b34af66daaea1e2134a Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Tue, 8 Oct 2024 16:18:42 -0400 Subject: [PATCH 06/11] add FIRPrivateLogDisabled --- Sources/DataConnect.swift | 35 ++++++++++++++++++- Sources/Internal/GrpcClient.swift | 5 +-- .../Internal/Logger/DataConnectLogger.swift | 4 +-- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/Sources/DataConnect.swift b/Sources/DataConnect.swift index aaa309e..16a2230 100644 --- a/Sources/DataConnect.swift +++ b/Sources/DataConnect.swift @@ -19,6 +19,8 @@ import FirebaseAuth import FirebaseCore import OSLog +let kFIRPrivateLogDisabledArgument = "-FIRPrivateLogDisabled" + @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public class DataConnect { private var connectorConfig: ConnectorConfig @@ -37,7 +39,26 @@ public class DataConnect { public static let port = 9399 } - public static var logLevel = LogLevel.WARN + class ArgumentFlag { + static var enablePrivacyLogging = true + } + + private static let logLevelQueue = DispatchQueue( + label: "com.google.firebase.dataconnect.logLevel", + attributes: .concurrent + ) + private static var _logLevel: LogLevel = .WARN + + public static var logLevel: LogLevel { + get { + return logLevelQueue.sync { _logLevel } + } + set { + logLevelQueue.async(flags: .barrier) { + _logLevel = newValue + } + } + } // MARK: Static Creation @@ -109,6 +130,18 @@ public class DataConnect { callerSDKType: self.callerSDKType ) operationsManager = OperationsManager(grpcClient: grpcClient) + + LoadArgument() + } + + private func LoadArgument() { + let arguments = ProcessInfo.processInfo.arguments + if arguments.contains(kFIRPrivateLogDisabledArgument) { + ArgumentFlag.enablePrivacyLogging = false + DataConnectLogger.debug("DataConnect privacy logging disabled.") + } else { + DataConnectLogger.debug("DataConnect privacy logging enabled.") + } } // MARK: Operations diff --git a/Sources/Internal/GrpcClient.swift b/Sources/Internal/GrpcClient.swift index f658710..c334298 100644 --- a/Sources/Internal/GrpcClient.swift +++ b/Sources/Internal/GrpcClient.swift @@ -63,7 +63,7 @@ actor GrpcClient: CustomStringConvertible { private lazy var client: FirebaseDataConnectAsyncClient? = { do { DataConnectLogger - .debug("GrpcClient \(self.description, privacy: .private) initialization starts.") + .debug("GrpcClient\(self.description, privacy: .private) initialization starts.") let group = PlatformSupport.makeEventLoopGroup(loopCount: threadPoolSize) let channel = try GRPCChannelPool.with( target: .host(serverSettings.host, port: serverSettings.port), @@ -244,7 +244,8 @@ actor GrpcClient: CustomStringConvertible { var options = CallOptions(customMetadata: headers) // Enable GRPC tracing - if DataConnect.logLevel.rawValue <= LogLevel.DEBUG.rawValue { + if DataConnect.logLevel.rawValue <= LogLevel.DEBUG.rawValue, + DataConnect.ArgumentFlag.enablePrivacyLogging == false { var logger = Logger(label: "com.google.firebase.dataconnect.grpc") logger.logLevel = .trace options.logger = logger diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift index feabdbf..dc6c6c8 100644 --- a/Sources/Internal/Logger/DataConnectLogger.swift +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -54,8 +54,8 @@ enum LogPrivacy: Int { @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) extension DefaultStringInterpolation { mutating func appendInterpolation(_ value: String, privacy: LogPrivacy = .public) { - if privacy == .private, DataConnect.logLevel.rawValue > LogLevel.DEBUG.rawValue { - appendLiteral("") + if privacy == .private, DataConnect.ArgumentFlag.enablePrivacyLogging { + appendLiteral(" ") } else { appendLiteral(value) } From be24fc222dff6799554f59417949a4a83d81ef7c Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Wed, 9 Oct 2024 00:18:20 -0400 Subject: [PATCH 07/11] add FIRPrivateConfig --- Sources/DataConnect.swift | 17 --------- Sources/Internal/GrpcClient.swift | 2 +- .../Internal/Logger/DataConnectLogger.swift | 37 ++++++++++++++----- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Sources/DataConnect.swift b/Sources/DataConnect.swift index 16a2230..cf84a1c 100644 --- a/Sources/DataConnect.swift +++ b/Sources/DataConnect.swift @@ -43,23 +43,6 @@ public class DataConnect { static var enablePrivacyLogging = true } - private static let logLevelQueue = DispatchQueue( - label: "com.google.firebase.dataconnect.logLevel", - attributes: .concurrent - ) - private static var _logLevel: LogLevel = .WARN - - public static var logLevel: LogLevel { - get { - return logLevelQueue.sync { _logLevel } - } - set { - logLevelQueue.async(flags: .barrier) { - _logLevel = newValue - } - } - } - // MARK: Static Creation /// Returns an instance of DataConnect matching the parameters. diff --git a/Sources/Internal/GrpcClient.swift b/Sources/Internal/GrpcClient.swift index c334298..bd624ce 100644 --- a/Sources/Internal/GrpcClient.swift +++ b/Sources/Internal/GrpcClient.swift @@ -244,7 +244,7 @@ actor GrpcClient: CustomStringConvertible { var options = CallOptions(customMetadata: headers) // Enable GRPC tracing - if DataConnect.logLevel.rawValue <= LogLevel.DEBUG.rawValue, + if DataConnectLogger.logLevel.rawValue <= FirebaseLoggerLevel.info.rawValue, DataConnect.ArgumentFlag.enablePrivacyLogging == false { var logger = Logger(label: "com.google.firebase.dataconnect.grpc") logger.logLevel = .trace diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift index dc6c6c8..c9c8335 100644 --- a/Sources/Internal/Logger/DataConnectLogger.swift +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -13,6 +13,7 @@ // limitations under the License. import OSLog +import FirebaseCore @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) class DataConnectLogger { @@ -22,25 +23,41 @@ class DataConnectLogger { ) private static let logPrefix = "\(Version.sdkVersion) - [FirebaseDataConnect]" - - static func debug(_ message: String, code: MessageCode = .placeHolder) { - if DataConnect.logLevel.rawValue <= LogLevel.DEBUG.rawValue { + + static let logLevel = FirebaseConfiguration.shared.loggerLevel() + + static func error(_ message: String, code: MessageCode = .placeHolder) { + if logLevel.rawValue <= FirebaseLoggerLevel.debug.rawValue { let messageCode = String(format: "I-FDC%06d", code.rawValue) - logger.debug("\(logPrefix)[\(messageCode)] \(message)") + logger.error("\(logPrefix)[\(messageCode)] \(message)") } } - + static func warning(_ message: String, code: MessageCode = .placeHolder) { - if DataConnect.logLevel.rawValue <= LogLevel.WARN.rawValue { + if logLevel.rawValue <= FirebaseLoggerLevel.warning.rawValue { let messageCode = String(format: "I-FDC%06d", code.rawValue) logger.warning("\(logPrefix)[\(messageCode)] \(message)") } } - - static func error(_ message: String, code: MessageCode = .placeHolder) { - if DataConnect.logLevel.rawValue <= LogLevel.WARN.rawValue { + + static func notice(_ message: String, code: MessageCode = .placeHolder) { + if logLevel.rawValue <= FirebaseLoggerLevel.notice.rawValue { let messageCode = String(format: "I-FDC%06d", code.rawValue) - logger.error("\(logPrefix)[\(messageCode)] \(message)") + logger.notice("\(logPrefix)[\(messageCode)] \(message)") + } + } + + static func info(_ message: String, code: MessageCode = .placeHolder) { + if logLevel.rawValue <= FirebaseLoggerLevel.info.rawValue { + let messageCode = String(format: "I-FDC%06d", code.rawValue) + logger.info("\(logPrefix)[\(messageCode)] \(message)") + } + } + + static func debug(_ message: String, code: MessageCode = .placeHolder) { + if logLevel.rawValue <= FirebaseLoggerLevel.debug.rawValue { + let messageCode = String(format: "I-FDC%06d", code.rawValue) + logger.debug("\(logPrefix)[\(messageCode)] \(message)") } } } From cd4602a5e0d23a79b8c57880d9db7907556b5540 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Wed, 9 Oct 2024 15:20:36 -0400 Subject: [PATCH 08/11] bug fix --- Sources/DataConnect.swift | 12 ++++----- Sources/Internal/CodableTimestamp.swift | 2 +- Sources/Internal/GrpcClient.swift | 9 +++---- .../Internal/Logger/DataConnectLogLevel.swift | 24 ----------------- .../Internal/Logger/DataConnectLogger.swift | 26 +++++++++---------- 5 files changed, 24 insertions(+), 49 deletions(-) delete mode 100644 Sources/Internal/Logger/DataConnectLogLevel.swift diff --git a/Sources/DataConnect.swift b/Sources/DataConnect.swift index cf84a1c..22520db 100644 --- a/Sources/DataConnect.swift +++ b/Sources/DataConnect.swift @@ -40,7 +40,7 @@ public class DataConnect { } class ArgumentFlag { - static var enablePrivacyLogging = true + static var privateLoggingEnabled = true } // MARK: Static Creation @@ -114,16 +114,16 @@ public class DataConnect { ) operationsManager = OperationsManager(grpcClient: grpcClient) - LoadArgument() + LoadArguments() } - private func LoadArgument() { + private func LoadArguments() { let arguments = ProcessInfo.processInfo.arguments if arguments.contains(kFIRPrivateLogDisabledArgument) { - ArgumentFlag.enablePrivacyLogging = false - DataConnectLogger.debug("DataConnect privacy logging disabled.") + ArgumentFlag.privateLoggingEnabled = false + DataConnectLogger.debug("DataConnect private logging disabled.") } else { - DataConnectLogger.debug("DataConnect privacy logging enabled.") + DataConnectLogger.debug("DataConnect private logging enabled.") } } diff --git a/Sources/Internal/CodableTimestamp.swift b/Sources/Internal/CodableTimestamp.swift index 8230642..6eccefb 100644 --- a/Sources/Internal/CodableTimestamp.swift +++ b/Sources/Internal/CodableTimestamp.swift @@ -53,7 +53,7 @@ extension CodableTimestamp { length: timestampString.count)) != nil else { DataConnectLogger.error( - "Timestamp string \(timestampString, privacy: .private) format doesn't support." + "Timestamp string \(timestampString) format doesn't support." ) throw DataConnectError.invalidTimestampFormat } diff --git a/Sources/Internal/GrpcClient.swift b/Sources/Internal/GrpcClient.swift index bd624ce..5fe39ef 100644 --- a/Sources/Internal/GrpcClient.swift +++ b/Sources/Internal/GrpcClient.swift @@ -218,7 +218,7 @@ actor GrpcClient: CustomStringConvertible { do { if let token = try await auth.currentUser?.getIDToken() { headers.add(name: RequestHeaders.authorizationHeader, value: "\(token)") - DataConnectLogger.debug("Auth token added") + DataConnectLogger.debug("Auth token added.") } else { DataConnectLogger.debug("No auth token available. Not adding auth header.") } @@ -231,7 +231,7 @@ actor GrpcClient: CustomStringConvertible { do { if let token = try await appCheck?.token(forcingRefresh: false) { headers.add(name: RequestHeaders.appCheckHeader, value: token.token) - DataConnectLogger.debug("App Check token added") + DataConnectLogger.debug("App Check token added.") } else { DataConnectLogger.debug("App Check token unavailable. Not adding App Check header.") } @@ -244,12 +244,11 @@ actor GrpcClient: CustomStringConvertible { var options = CallOptions(customMetadata: headers) // Enable GRPC tracing - if DataConnectLogger.logLevel.rawValue <= FirebaseLoggerLevel.info.rawValue, - DataConnect.ArgumentFlag.enablePrivacyLogging == false { + if DataConnectLogger.logLevel.rawValue >= FirebaseLoggerLevel.debug.rawValue, + DataConnect.ArgumentFlag.privateLoggingEnabled == false { var logger = Logger(label: "com.google.firebase.dataconnect.grpc") logger.logLevel = .trace options.logger = logger - options.requestIDProvider = .autogenerated } return options diff --git a/Sources/Internal/Logger/DataConnectLogLevel.swift b/Sources/Internal/Logger/DataConnectLogLevel.swift deleted file mode 100644 index 328037b..0000000 --- a/Sources/Internal/Logger/DataConnectLogLevel.swift +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2024 Google LLC -// -// 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. - -public enum LogLevel: Int { - // Log all messages, including detailed debug logs - case DEBUG = 0 - - // Only log warnings and errors; this is the default log level. - case WARN = 1 - - // Do not log anything. - case NONE = 2 -} diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift index c9c8335..096220b 100644 --- a/Sources/Internal/Logger/DataConnectLogger.swift +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import OSLog import FirebaseCore +import OSLog @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) class DataConnectLogger { @@ -23,39 +23,39 @@ class DataConnectLogger { ) private static let logPrefix = "\(Version.sdkVersion) - [FirebaseDataConnect]" - + static let logLevel = FirebaseConfiguration.shared.loggerLevel() - + static func error(_ message: String, code: MessageCode = .placeHolder) { - if logLevel.rawValue <= FirebaseLoggerLevel.debug.rawValue { + if logLevel.rawValue >= FirebaseLoggerLevel.error.rawValue { let messageCode = String(format: "I-FDC%06d", code.rawValue) logger.error("\(logPrefix)[\(messageCode)] \(message)") } } - + static func warning(_ message: String, code: MessageCode = .placeHolder) { - if logLevel.rawValue <= FirebaseLoggerLevel.warning.rawValue { + if logLevel.rawValue >= FirebaseLoggerLevel.warning.rawValue { let messageCode = String(format: "I-FDC%06d", code.rawValue) logger.warning("\(logPrefix)[\(messageCode)] \(message)") } } - + static func notice(_ message: String, code: MessageCode = .placeHolder) { - if logLevel.rawValue <= FirebaseLoggerLevel.notice.rawValue { + if logLevel.rawValue >= FirebaseLoggerLevel.notice.rawValue { let messageCode = String(format: "I-FDC%06d", code.rawValue) logger.notice("\(logPrefix)[\(messageCode)] \(message)") } } - + static func info(_ message: String, code: MessageCode = .placeHolder) { - if logLevel.rawValue <= FirebaseLoggerLevel.info.rawValue { + if logLevel.rawValue >= FirebaseLoggerLevel.info.rawValue { let messageCode = String(format: "I-FDC%06d", code.rawValue) logger.info("\(logPrefix)[\(messageCode)] \(message)") } } - + static func debug(_ message: String, code: MessageCode = .placeHolder) { - if logLevel.rawValue <= FirebaseLoggerLevel.debug.rawValue { + if logLevel.rawValue >= FirebaseLoggerLevel.debug.rawValue { let messageCode = String(format: "I-FDC%06d", code.rawValue) logger.debug("\(logPrefix)[\(messageCode)] \(message)") } @@ -71,7 +71,7 @@ enum LogPrivacy: Int { @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) extension DefaultStringInterpolation { mutating func appendInterpolation(_ value: String, privacy: LogPrivacy = .public) { - if privacy == .private, DataConnect.ArgumentFlag.enablePrivacyLogging { + if privacy == .private, DataConnect.ArgumentFlag.privateLoggingEnabled { appendLiteral(" ") } else { appendLiteral(value) From eb487b0873023a1ba8d6b82b1e98f8d4ebcfd901 Mon Sep 17 00:00:00 2001 From: cherylEnkidu <96084918+cherylEnkidu@users.noreply.github.com> Date: Thu, 10 Oct 2024 13:32:05 -0400 Subject: [PATCH 09/11] Update Sources/Internal/Logger/DataConnectLogger.swift Co-authored-by: Nick Cooke <36927374+ncooke3@users.noreply.github.com> --- Sources/Internal/Logger/DataConnectLogger.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift index 096220b..2c9042b 100644 --- a/Sources/Internal/Logger/DataConnectLogger.swift +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -24,7 +24,9 @@ class DataConnectLogger { private static let logPrefix = "\(Version.sdkVersion) - [FirebaseDataConnect]" - static let logLevel = FirebaseConfiguration.shared.loggerLevel() + static var logLevel: FirebaseLoggerLevel { + return FirebaseConfiguration.shared.loggerLevel() + } static func error(_ message: String, code: MessageCode = .placeHolder) { if logLevel.rawValue >= FirebaseLoggerLevel.error.rawValue { From 888dd142065904819883ceba5d3875c2af3f21ae Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Tue, 15 Oct 2024 11:23:19 -0400 Subject: [PATCH 10/11] Address feedbacks --- Sources/DataConnect.swift | 18 -------------- Sources/Internal/GrpcClient.swift | 2 +- .../Internal/Logger/DataConnectLogger.swift | 24 ++++++++++++++----- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/Sources/DataConnect.swift b/Sources/DataConnect.swift index 22520db..269bfd1 100644 --- a/Sources/DataConnect.swift +++ b/Sources/DataConnect.swift @@ -19,8 +19,6 @@ import FirebaseAuth import FirebaseCore import OSLog -let kFIRPrivateLogDisabledArgument = "-FIRPrivateLogDisabled" - @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public class DataConnect { private var connectorConfig: ConnectorConfig @@ -39,10 +37,6 @@ public class DataConnect { public static let port = 9399 } - class ArgumentFlag { - static var privateLoggingEnabled = true - } - // MARK: Static Creation /// Returns an instance of DataConnect matching the parameters. @@ -113,18 +107,6 @@ public class DataConnect { callerSDKType: self.callerSDKType ) operationsManager = OperationsManager(grpcClient: grpcClient) - - LoadArguments() - } - - private func LoadArguments() { - let arguments = ProcessInfo.processInfo.arguments - if arguments.contains(kFIRPrivateLogDisabledArgument) { - ArgumentFlag.privateLoggingEnabled = false - DataConnectLogger.debug("DataConnect private logging disabled.") - } else { - DataConnectLogger.debug("DataConnect private logging enabled.") - } } // MARK: Operations diff --git a/Sources/Internal/GrpcClient.swift b/Sources/Internal/GrpcClient.swift index 5fe39ef..ea1ef3d 100644 --- a/Sources/Internal/GrpcClient.swift +++ b/Sources/Internal/GrpcClient.swift @@ -245,7 +245,7 @@ actor GrpcClient: CustomStringConvertible { // Enable GRPC tracing if DataConnectLogger.logLevel.rawValue >= FirebaseLoggerLevel.debug.rawValue, - DataConnect.ArgumentFlag.privateLoggingEnabled == false { + DataConnectLogger.privateLoggingEnabled == false { var logger = Logger(label: "com.google.firebase.dataconnect.grpc") logger.logLevel = .trace options.logger = logger diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift index 2c9042b..081aecb 100644 --- a/Sources/Internal/Logger/DataConnectLogger.swift +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -15,13 +15,26 @@ import FirebaseCore import OSLog +let privateLogDisabledArgument = "-FIRPrivateLogDisabled" + @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) class DataConnectLogger { - private static let logger = Logger( + static let logger = Logger( subsystem: "com.google.firebase", category: "[FirebaseDataConnect]" ) + static let privateLoggingEnabled: Bool = { + let arguments = ProcessInfo.processInfo.arguments + if arguments.contains(privateLogDisabledArgument) { + DataConnectLogger.debug("DataConnect private logging disabled.") + return false + } else { + DataConnectLogger.debug("DataConnect private logging enabled.") + return true + } + }() + private static let logPrefix = "\(Version.sdkVersion) - [FirebaseDataConnect]" static var logLevel: FirebaseLoggerLevel { @@ -64,16 +77,15 @@ class DataConnectLogger { } } -enum LogPrivacy: Int { - case `public` = 0 - - case `private` = 1 +enum LogPrivacy { + case `public` + case `private` } @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) extension DefaultStringInterpolation { mutating func appendInterpolation(_ value: String, privacy: LogPrivacy = .public) { - if privacy == .private, DataConnect.ArgumentFlag.privateLoggingEnabled { + if privacy == .private, DataConnectLogger.privateLoggingEnabled { appendLiteral(" ") } else { appendLiteral(value) From 675f8cd0d05109e4967f456f0d51201e6b2c997a Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Wed, 30 Oct 2024 15:37:35 -0400 Subject: [PATCH 11/11] address feedbacks --- Package.resolved | 16 ++++----- Sources/DataConnect.swift | 1 - Sources/Internal/CodableTimestamp.swift | 2 +- Sources/Internal/GrpcClient.swift | 33 ++++++++++--------- .../Internal/Logger/DataConnectLogger.swift | 4 +-- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Package.resolved b/Package.resolved index 909d54b..2dc7036 100644 --- a/Package.resolved +++ b/Package.resolved @@ -23,8 +23,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk", "state" : { - "revision" : "9118aca998dbe2ceac45d64b21a91c6376928df7", - "version" : "11.1.0" + "revision" : "f909f901bfba9e27e4e9da83242a4915d6dd64bb", + "version" : "11.3.0" } }, { @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleAppMeasurement.git", "state" : { - "revision" : "07a2f57d147d2bf368a0d2dcb5579ff082d9e44f", - "version" : "11.1.0" + "revision" : "93406fd21b85e66e2d6dbf50b472161fd75c3f1f", + "version" : "11.3.0" } }, { @@ -68,8 +68,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/grpc/grpc-swift.git", "state" : { - "revision" : "6a90b7e77e29f9bda6c2b3a4165a40d6c02cfda1", - "version" : "1.23.0" + "revision" : "07123ed731671e800ab8d641006613612e954746", + "version" : "1.23.1" } }, { @@ -203,8 +203,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-protobuf.git", "state" : { - "revision" : "e17d61f26df0f0e06f58f6977ba05a097a720106", - "version" : "1.27.1" + "revision" : "ebc7251dd5b37f627c93698e4374084d98409633", + "version" : "1.28.2" } }, { diff --git a/Sources/DataConnect.swift b/Sources/DataConnect.swift index 269bfd1..75f3113 100644 --- a/Sources/DataConnect.swift +++ b/Sources/DataConnect.swift @@ -17,7 +17,6 @@ import Foundation import FirebaseAppCheck import FirebaseAuth import FirebaseCore -import OSLog @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) public class DataConnect { diff --git a/Sources/Internal/CodableTimestamp.swift b/Sources/Internal/CodableTimestamp.swift index 6eccefb..5864bd8 100644 --- a/Sources/Internal/CodableTimestamp.swift +++ b/Sources/Internal/CodableTimestamp.swift @@ -53,7 +53,7 @@ extension CodableTimestamp { length: timestampString.count)) != nil else { DataConnectLogger.error( - "Timestamp string \(timestampString) format doesn't support." + "Timestamp string format \(timestampString) is not supported." ) throw DataConnectError.invalidTimestampFormat } diff --git a/Sources/Internal/GrpcClient.swift b/Sources/Internal/GrpcClient.swift index ea1ef3d..8fae092 100644 --- a/Sources/Internal/GrpcClient.swift +++ b/Sources/Internal/GrpcClient.swift @@ -63,7 +63,7 @@ actor GrpcClient: CustomStringConvertible { private lazy var client: FirebaseDataConnectAsyncClient? = { do { DataConnectLogger - .debug("GrpcClient\(self.description, privacy: .private) initialization starts.") + .debug("GrpcClient: \(self.description, privacy: .private) initialization starts.") let group = PlatformSupport.makeEventLoopGroup(loopCount: threadPoolSize) let channel = try GRPCChannelPool.with( target: .host(serverSettings.host, port: serverSettings.port), @@ -72,11 +72,12 @@ actor GrpcClient: CustomStringConvertible { .plaintext, eventLoopGroup: group ) - DataConnectLogger.debug("GrpcClient\(self.description, privacy: .private) has been created.") + DataConnectLogger + .debug("GrpcClient: \(self.description, privacy: .private) has been created.") return FirebaseDataConnectAsyncClient(channel: channel) } catch { DataConnectLogger - .debug("Error:\(error) when creating GrpcClient\(self.description, privacy: .private).") + .debug("Error:\(error) when creating GrpcClient: \(self.description, privacy: .private).") return nil } }() @@ -117,7 +118,7 @@ actor GrpcClient: CustomStringConvertible { googRequestHeaderValue = "location=\(self.connectorConfig.location)&frontend=data" description = """ - : projectId=\(projectId) \ + projectId=\(projectId) \ connector=\(connectorConfig.connector) \ host=\(serverSettings.host) \ port=\(serverSettings.port) \ @@ -140,27 +141,27 @@ actor GrpcClient: CustomStringConvertible { connectorName: connectorName, request: request ) - let requestString = try ": " + grpcRequest.jsonString() + let requestString = try grpcRequest.jsonString() do { DataConnectLogger - .debug("executeQuery() sends grpc request\(requestString, privacy: .private).") + .debug("executeQuery() sends grpc request: \(requestString, privacy: .private).") let results = try await client.executeQuery(grpcRequest, callOptions: createCallOptions()) - let resultsString = try ": " + results.jsonString() + let resultsString = try results.jsonString() DataConnectLogger - .debug("executeQuery() receives response\(resultsString, privacy: .private).") + .debug("executeQuery() receives response: \(resultsString, privacy: .private).") // Not doing error decoding here if let decodedResults = try codec.decode(result: results.data, asType: resultType) { return OperationResult(data: decodedResults) } else { // In future, set this as error in OperationResult DataConnectLogger - .debug("executeQuery() response\(resultsString, privacy: .private) decode failed.") + .debug("executeQuery() response: \(resultsString, privacy: .private) decode failed.") throw DataConnectError.decodeFailed } } catch { DataConnectLogger.error( - "executeQuery()\(requestString, privacy: .private) grpc call FAILED with \(error)." + "executeQuery(): \(requestString, privacy: .private) grpc call FAILED with \(error)." ) throw error } @@ -183,25 +184,25 @@ actor GrpcClient: CustomStringConvertible { request: request ) - let requestString = try ": " + grpcRequest.jsonString() + let requestString = try grpcRequest.jsonString() do { DataConnectLogger - .debug("executeMutation() sends grpc request \(requestString, privacy: .private).") + .debug("executeMutation() sends grpc request: \(requestString, privacy: .private).") let results = try await client.executeMutation(grpcRequest, callOptions: createCallOptions()) - let resultsString = try ": " + results.jsonString() + let resultsString = try results.jsonString() DataConnectLogger - .debug("executeMutation() receives response\(resultsString, privacy: .private).") + .debug("executeMutation() receives response: \(resultsString, privacy: .private).") if let decodedResults = try codec.decode(result: results.data, asType: resultType) { return OperationResult(data: decodedResults) } else { DataConnectLogger - .debug("executeMutation() response\(resultsString, privacy: .private) decode failed.") + .debug("executeMutation() response: \(resultsString, privacy: .private) decode failed.") throw DataConnectError.decodeFailed } } catch { DataConnectLogger.error( - "executeMutation()\(requestString, privacy: .private) grpc call FAILED with \(error)." + "executeMutation(): \(requestString, privacy: .private) grpc call FAILED with \(error)." ) throw error } diff --git a/Sources/Internal/Logger/DataConnectLogger.swift b/Sources/Internal/Logger/DataConnectLogger.swift index 081aecb..f4dc679 100644 --- a/Sources/Internal/Logger/DataConnectLogger.swift +++ b/Sources/Internal/Logger/DataConnectLogger.swift @@ -13,7 +13,7 @@ // limitations under the License. import FirebaseCore -import OSLog +import os let privateLogDisabledArgument = "-FIRPrivateLogDisabled" @@ -86,7 +86,7 @@ enum LogPrivacy { extension DefaultStringInterpolation { mutating func appendInterpolation(_ value: String, privacy: LogPrivacy = .public) { if privacy == .private, DataConnectLogger.privateLoggingEnabled { - appendLiteral(" ") + appendLiteral("") } else { appendLiteral(value) }