Skip to content

Commit b44db4e

Browse files
Add privacy support to Logger in Dataconnect (#29)
Co-authored-by: Nick Cooke <[email protected]>
1 parent 13f249b commit b44db4e

File tree

5 files changed

+150
-171
lines changed

5 files changed

+150
-171
lines changed

Sources/Internal/CodableTimestamp.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ extension CodableTimestamp {
5252
.firstMatch(in: timestampString, range: NSRange(location: 0,
5353
length: timestampString.count)) !=
5454
nil else {
55-
FirebaseLogger.dataConnect
56-
.error(
57-
"Timestamp string format doesn't support."
58-
)
55+
DataConnectLogger.error(
56+
"Timestamp string format \(timestampString) is not supported."
57+
)
5958
throw DataConnectError.invalidTimestampFormat
6059
}
6160

Sources/Internal/FirebaseLogger/FirebaseLogger.swift

Lines changed: 0 additions & 54 deletions
This file was deleted.

Sources/Internal/GrpcClient.swift

Lines changed: 50 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ import Foundation
1818
@preconcurrency import FirebaseAuth
1919
import FirebaseCore
2020
import GRPC
21+
import Logging
2122
import NIOCore
2223
import NIOHPACK
2324
import NIOPosix
24-
import OSLog
2525
import SwiftProtobuf
2626

2727
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@@ -50,9 +50,6 @@ actor GrpcClient: CustomStringConvertible {
5050

5151
private let callerSDKType: CallerSDKType
5252

53-
// Remove debug flag when logging privacy is properly handled.
54-
private let debugEnable = false
55-
5653
enum RequestHeaders {
5754
static let googRequestParamsHeader = "x-goog-request-params"
5855
static let authorizationHeader = "x-firebase-auth-token"
@@ -65,11 +62,8 @@ actor GrpcClient: CustomStringConvertible {
6562

6663
private lazy var client: FirebaseDataConnectAsyncClient? = {
6764
do {
68-
if debugEnable == true {
69-
FirebaseLogger.dataConnect.debug("\(self.description) initialization starts.")
70-
} else {
71-
FirebaseLogger.dataConnect.debug("GrpcClient initialization starts.")
72-
}
65+
DataConnectLogger
66+
.debug("GrpcClient: \(self.description, privacy: .private) initialization starts.")
7367
let group = PlatformSupport.makeEventLoopGroup(loopCount: threadPoolSize)
7468
let channel = try GRPCChannelPool.with(
7569
target: .host(serverSettings.host, port: serverSettings.port),
@@ -78,18 +72,12 @@ actor GrpcClient: CustomStringConvertible {
7872
.plaintext,
7973
eventLoopGroup: group
8074
)
81-
if debugEnable == true {
82-
FirebaseLogger.dataConnect.debug("\(self.description) has been created.")
83-
} else {
84-
FirebaseLogger.dataConnect.debug("GrpcClient has been created.")
85-
}
75+
DataConnectLogger
76+
.debug("GrpcClient: \(self.description, privacy: .private) has been created.")
8677
return FirebaseDataConnectAsyncClient(channel: channel)
8778
} catch {
88-
if debugEnable == true {
89-
FirebaseLogger.dataConnect.error("Error:\(error) when creating \(self.description).")
90-
} else {
91-
FirebaseLogger.dataConnect.debug("Error:\(error) when creating GrpcClient.")
92-
}
79+
DataConnectLogger
80+
.debug("Error:\(error) when creating GrpcClient: \(self.description, privacy: .private).")
9381
return nil
9482
}
9583
}()
@@ -128,7 +116,6 @@ actor GrpcClient: CustomStringConvertible {
128116
googRequestHeaderValue = "location=\(self.connectorConfig.location)&frontend=data"
129117

130118
description = """
131-
GrpcClient: \
132119
projectId=\(projectId) \
133120
connector=\(connectorConfig.connector) \
134121
host=\(serverSettings.host) \
@@ -143,8 +130,7 @@ actor GrpcClient: CustomStringConvertible {
143130
.Type)
144131
async throws -> OperationResult<ResultType> {
145132
guard let client else {
146-
FirebaseLogger.dataConnect
147-
.error("When calling executeQuery(), grpc client has not been configured.")
133+
DataConnectLogger.error("When calling executeQuery(), grpc client has not been configured.")
148134
throw DataConnectError.grpcNotConfigured
149135
}
150136

@@ -153,49 +139,28 @@ actor GrpcClient: CustomStringConvertible {
153139
connectorName: connectorName,
154140
request: request
155141
)
142+
let requestString = try grpcRequest.jsonString()
156143

157144
do {
158-
if debugEnable == true {
159-
try FirebaseLogger.dataConnect
160-
.debug("executeQuery() sends grpc request: \(grpcRequest.jsonString()).")
161-
} else {
162-
try FirebaseLogger.dataConnect
163-
.debug("executeQuery() sends grpc request.")
164-
}
145+
DataConnectLogger
146+
.debug("executeQuery() sends grpc request: \(requestString, privacy: .private).")
165147
let results = try await client.executeQuery(grpcRequest, callOptions: createCallOptions())
166-
if debugEnable == true {
167-
try FirebaseLogger.dataConnect
168-
.debug("executeQuery() receives response: \(results.jsonString()).")
169-
} else {
170-
try FirebaseLogger.dataConnect
171-
.debug("executeQuery() receives response.")
172-
}
148+
let resultsString = try results.jsonString()
149+
DataConnectLogger
150+
.debug("executeQuery() receives response: \(resultsString, privacy: .private).")
173151
// Not doing error decoding here
174152
if let decodedResults = try codec.decode(result: results.data, asType: resultType) {
175153
return OperationResult(data: decodedResults)
176154
} else {
177155
// In future, set this as error in OperationResult
178-
if debugEnable == true {
179-
try FirebaseLogger.dataConnect
180-
.error("executeQuery() response: \(results.jsonString()) decode failed.")
181-
} else {
182-
try FirebaseLogger.dataConnect
183-
.error("executeQuery() response decode failed.")
184-
}
156+
DataConnectLogger
157+
.debug("executeQuery() response: \(resultsString, privacy: .private) decode failed.")
185158
throw DataConnectError.decodeFailed
186159
}
187160
} catch {
188-
if debugEnable == true {
189-
try FirebaseLogger.dataConnect
190-
.error(
191-
"executeQuery() with request: \(grpcRequest.jsonString()) grpc call FAILED with \(error)."
192-
)
193-
} else {
194-
try FirebaseLogger.dataConnect
195-
.error(
196-
"executeQuery() grpc call FAILED with \(error)."
197-
)
198-
}
161+
DataConnectLogger.error(
162+
"executeQuery(): \(requestString, privacy: .private) grpc call FAILED with \(error)."
163+
)
199164
throw error
200165
}
201166
}
@@ -206,7 +171,7 @@ actor GrpcClient: CustomStringConvertible {
206171
.Type)
207172
async throws -> OperationResult<ResultType> {
208173
guard let client else {
209-
FirebaseLogger.dataConnect
174+
DataConnectLogger
210175
.error("When calling executeMutation(), grpc client has not been configured.")
211176
throw DataConnectError.grpcNotConfigured
212177
}
@@ -217,46 +182,26 @@ actor GrpcClient: CustomStringConvertible {
217182
request: request
218183
)
219184

185+
let requestString = try grpcRequest.jsonString()
186+
220187
do {
221-
if debugEnable == true {
222-
try FirebaseLogger.dataConnect
223-
.debug("executeMutation() sends grpc request: \(grpcRequest.jsonString()).")
224-
} else {
225-
try FirebaseLogger.dataConnect
226-
.debug("executeMutation() sends grpc request.")
227-
}
188+
DataConnectLogger
189+
.debug("executeMutation() sends grpc request: \(requestString, privacy: .private).")
228190
let results = try await client.executeMutation(grpcRequest, callOptions: createCallOptions())
229-
if debugEnable == true {
230-
try FirebaseLogger.dataConnect
231-
.debug("executeMutation() receives response: \(results.jsonString()).")
232-
} else {
233-
try FirebaseLogger.dataConnect
234-
.debug("executeMutation() receives response.")
235-
}
191+
let resultsString = try results.jsonString()
192+
DataConnectLogger
193+
.debug("executeMutation() receives response: \(resultsString, privacy: .private).")
236194
if let decodedResults = try codec.decode(result: results.data, asType: resultType) {
237195
return OperationResult(data: decodedResults)
238196
} else {
239-
if debugEnable == true {
240-
try FirebaseLogger.dataConnect
241-
.error("executeMutation() response: \(results.jsonString()) decode failed.")
242-
} else {
243-
try FirebaseLogger.dataConnect
244-
.error("executeMutation() response decode failed.")
245-
}
197+
DataConnectLogger
198+
.debug("executeMutation() response: \(resultsString, privacy: .private) decode failed.")
246199
throw DataConnectError.decodeFailed
247200
}
248201
} catch {
249-
if debugEnable == true {
250-
try FirebaseLogger.dataConnect
251-
.error(
252-
"executeMutation() with request: \(grpcRequest.jsonString()) grpc call FAILED with \(error)."
253-
)
254-
} else {
255-
try FirebaseLogger.dataConnect
256-
.error(
257-
"executeMutation() grpc call FAILED with \(error)."
258-
)
259-
}
202+
DataConnectLogger.error(
203+
"executeMutation(): \(requestString, privacy: .private) grpc call FAILED with \(error)."
204+
)
260205
throw error
261206
}
262207
}
@@ -274,44 +219,39 @@ actor GrpcClient: CustomStringConvertible {
274219
do {
275220
if let token = try await auth.currentUser?.getIDToken() {
276221
headers.add(name: RequestHeaders.authorizationHeader, value: "\(token)")
277-
if debugEnable == true {
278-
FirebaseLogger.dataConnect
279-
.debug("Auth token added: \(token)")
280-
} else {
281-
FirebaseLogger.dataConnect
282-
.debug("Auth token added.")
283-
}
222+
DataConnectLogger.debug("Auth token added.")
284223
} else {
285-
FirebaseLogger.dataConnect.debug("No auth token available. Not adding auth header.")
224+
DataConnectLogger.debug("No auth token available. Not adding auth header.")
286225
}
287226
} catch {
288-
FirebaseLogger.dataConnect
227+
DataConnectLogger
289228
.debug("Cannot get auth token successfully due to: \(error). Not adding auth header.")
290229
}
291230

292231
// Add AppCheck token if available
293232
do {
294233
if let token = try await appCheck?.token(forcingRefresh: false) {
295234
headers.add(name: RequestHeaders.appCheckHeader, value: token.token)
296-
if debugEnable == true {
297-
FirebaseLogger.dataConnect
298-
.debug("App Check token added: \(token.token)")
299-
} else {
300-
FirebaseLogger.dataConnect
301-
.debug("App Check token added.")
302-
}
235+
DataConnectLogger.debug("App Check token added.")
303236
} else {
304-
FirebaseLogger.dataConnect
305-
.debug("App Check token unavailable. Not adding App Check header.")
237+
DataConnectLogger.debug("App Check token unavailable. Not adding App Check header.")
306238
}
307239
} catch {
308-
FirebaseLogger.dataConnect
309-
.debug(
310-
"Cannot get App Check token successfully due to: \(error). Not adding App Check header."
311-
)
240+
DataConnectLogger.debug(
241+
"Cannot get App Check token successfully due to: \(error). Not adding App Check header."
242+
)
243+
}
244+
245+
var options = CallOptions(customMetadata: headers)
246+
247+
// Enable GRPC tracing
248+
if DataConnectLogger.logLevel.rawValue >= FirebaseLoggerLevel.debug.rawValue,
249+
DataConnectLogger.privateLoggingEnabled == false {
250+
var logger = Logger(label: "com.google.firebase.dataconnect.grpc")
251+
logger.logLevel = .trace
252+
options.logger = logger
312253
}
313254

314-
let options = CallOptions(customMetadata: headers)
315255
return options
316256
}
317257
}

0 commit comments

Comments
 (0)