-
Notifications
You must be signed in to change notification settings - Fork 25
refactor: logging using string interpolation - WPB-14876 #2480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/create-new-logger-WPB-14297
Are you sure you want to change the base?
refactor: logging using string interpolation - WPB-14876 #2480
Conversation
…o chore/move-WireLogger-into-WireFoundation-WPB-10941
…o chore/abstract-logging
…o chore/move-WireLogger-into-WireFoundation-WPB-10941
…o chore/abstract-logging
# Conflicts: # WireDomain/Sources/WireDomain/Repositories/UserClients/Models/UserClientInfo.swift # WireFoundation/Tests/WireLoggingTests/PlaceholderTests.swift # wire-ios-system/Source/Logging/WireLogger.swift # wire-ios/Wire-iOS Tests/WireAnalytics_DatadogTests.swift # wire-ios/Wire-iOS.xcodeproj/project.pbxproj # wire-ios/WireCommonComponents/Analytics/WireAnalytics.swift # wire-ios/WireCommonComponents/Logging/CocoaLumberjackLogger.swift
…ging-using-string-interpolation-WPB-14297
…ging-using-string-interpolation-WPB-14297 # Conflicts: # WireAnalytics/Package.swift # WireNetwork/Package.swift # WireUI/Sources/WireSettingsUI/Account/BackupImportExport/BackupImportExportBuilder.swift # wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+Account.swift
…ging-using-string-interpolation-WPB-14297 # Conflicts: # WireLogging/Sources/WireLogging/LogMessage/WireLogAttribute.swift
…ging-using-string-interpolation-WPB-14297
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR continues the migration from the legacy logging system to the new WireLogger interface with string interpolation support, specifically refactoring the WireBackup module and related components. The changes introduce safer logging practices through explicit safePublic labels and custom error interpolation to prevent accidental exposure of sensitive data.
Key Changes
- Migrated WireBackup module (CreateBackupUseCase, ImportBackupUseCase, BackupLocalStore) to use new WireTaggedLogger with string interpolation
- Introduced BackupProgress struct to encapsulate progress values, improving type safety
- Added custom WireLogInterpolation extensions for BackupProgress, Error types, and basic types requiring explicit safePublic labeling
- Removed WireLegacyLogging dependency from WireBackup, WireAnalytics, and WireDatadog packages
Reviewed changes
Copilot reviewed 40 out of 40 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| WireLogging/Sources/WireLogging/TaggedLogger/WireLogger+Singletons.swift | Added WireLogger singleton instances and setup mechanism with lazy initialization |
| WireLogging/Sources/WireLogging/TaggedLogger/WireTaggedLogger.swift | Enhanced WireTaggedLogger with additionalAttributes support |
| WireLogging/Sources/WireLogging/LogMessage/WireLogInterpolation+*.swift | Added interpolation extensions for errors, basic types, and obfuscation control |
| WireBackup/Sources/WireBackup/UseCases/*.swift | Migrated backup use cases to use WireTaggedLogger with new logging patterns |
| WireBackup/Sources/WireBackup/Extensions/WireLogging/*.swift | Added WireLogger extensions for createBackup and importBackup tags |
| WireFoundation/Sources/WireFoundation/Protocols/BackupRestore/*.swift | Introduced BackupProgress struct and updated progress enums to use it |
| wire-ios/WireCommonComponents/Analytics/*.swift | Setup new multiplex log handler combining OSLog, CocoaLumberjack, and Datadog |
| wire-ios/WireCommonComponents/Logging/CocoaLumberjackLogger.swift | Added NewCocoaLumberjackLogger adapter for new logging interface |
| wire-ios/Wire-iOS/Sources/UserInterface/Settings/*.swift | Updated to use new logger singleton names (createBackup, importBackup) |
| WireUI/Sources/WireSettingsUI/Account/BackupImportExport/*.swift | Migrated UI components to WireTaggedLoggerProtocol |
| WireAnalytics/Sources/WireDatadog/*.swift | Renamed WireLogLevel to WireLogType for consistency |
| WireNetwork/Sources/WireNetwork/Extensions/*.swift | Added WireLogAttribute extensions for push channel versions |
| WireUI/Package.swift | Added WireLogging and WireLoggingSupport dependencies |
| WireBackup/Package.swift | Removed WireLegacyLogging dependency |
| WireAnalytics/Package.swift | Removed WireLegacyLogging dependency |
Comments suppressed due to low confidence (2)
WireLogging/Sources/WireLogging/TaggedLogger/WireTaggedLogger.swift:50
- The
additionalAttributesproperty is documented (lines 24-25) as having the least priority and being merged with attributes passed tolog(). However, thelog()method (lines 39-50) only passes the method parameter'sadditionalAttributesto the handler, ignoring the instance propertyself.additionalAttributes. The instance property should be merged with the method parameter before passing to the handler, with the method parameter taking precedence for duplicate keys as documented.
private func log(
_ type: WireLogType,
_ message: WireLogMessage,
_ additionalAttributes: [WireLogAttribute]
) {
handler.log(
tag: tag,
type: type,
message: message,
additionalAttributes: additionalAttributes
)
}
WireBackup/Sources/WireBackup/Extensions/WireLogging/WireLogger+instances.swift:25
- These static logger properties directly access
logHandlerduring initialization. If these properties are accessed beforeWireLogger.setup()is called,logHandlerwill benil, causing a runtime crash. Consider adding a precondition check in the privateWireTaggedLogger()helper function in WireLogger+Singletons.swift or making these properties lazy to ensure they're only created after setup.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| static func progress(_ current: Int, _ total: Int) -> Self { | ||
| .progress(current: current, total: total) | ||
| } | ||
|
|
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The two progress convenience methods are duplicates with different parameter labels. Line 32-33 uses unlabeled parameters (_:_:), while line 36-37 uses named parameters (current:total:), but both create the same BackupProgress instance. This creates ambiguity for callers and is redundant. Consider keeping only one variant, preferably the one with named parameters for better code clarity.
| static func progress(_ current: Int, _ total: Int) -> Self { | |
| .progress(current: current, total: total) | |
| } |
| finalAttributes["version"] = buildVersion | ||
|
|
||
| let level = level.mapToDatadogLogLevel() | ||
| let level = logType.mapToDatadogLogLevel() |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The log method receives a type parameter (line 110) but on line 119 it uses the instance property logType instead. This means all log messages will always use the same level (.debug) regardless of what was passed as the type parameter. This should be let level = type.mapToDatadogLogLevel().
| let level = logType.mapToDatadogLogLevel() | |
| let level = type.mapToDatadogLogLevel() |
|
|
||
| struct NewWireDatadogLogger: WireLogHandlerProtocol { | ||
|
|
||
| let additionalAttributes = LogAttributes() |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The additionalAttributes property is declared but never used in the NewWireDatadogLogger struct. It should either be removed or integrated into the logging logic if it was intended to provide default attributes for all log messages.
|
|
||
| static var pushChannelV1: WireLogAttribute { .init("push_channel", "v1") } | ||
|
|
||
| /// PushChannelV2 (consumable notifications sync) |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent spacing in documentation comments. Line 31 has "PushChannelV2" without spacing, while lines 23 and 27 use proper spacing ("Legacy pushChannel" and "PushChannel V1"). For consistency, line 31 should be "PushChannel V2" (with space before V2).
| /// PushChannelV2 (consumable notifications sync) | |
| /// PushChannel V2 (consumable notifications sync) |
| func log( | ||
| tag: WireLogTag, | ||
| type: WireLogType, | ||
| message: WireLogMessage, | ||
| additionalAttributes: [WireLogAttribute] | ||
| ) { | ||
| switch type { | ||
| case .debug: | ||
| logger.debug(message.content, attributes: [.tag: tag.rawValue]) | ||
| case .info: | ||
| logger.info(message.content, attributes: [.tag: tag.rawValue]) | ||
| case .notice: | ||
| logger.notice(message.content, attributes: [.tag: tag.rawValue]) | ||
| case .warn: | ||
| logger.warn(message.content, attributes: [.tag: tag.rawValue]) | ||
| case .error: | ||
| logger.error(message.content, attributes: [.tag: tag.rawValue]) | ||
| case .critical: | ||
| logger.critical(message.content, attributes: [.tag: tag.rawValue]) | ||
| } | ||
| } |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The additionalAttributes parameter is not used in the log method. The method only passes the tag to the underlying logger but ignores any additional attributes that might be provided. If additional attributes should be logged, they need to be merged with the tag attribute and passed to the logger. Otherwise, this parameter should be documented as currently unused.
| static func progress(_ current: Int, _ total: Int) -> Self { | ||
| .progress(current: current, total: total) | ||
| } |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The two progress convenience methods are duplicates with different parameter labels. Line 30-31 uses named parameters (current:total:), while line 34-35 uses unlabeled parameters (_:_:), but both call the same underlying method. This creates ambiguity for callers and is redundant. Consider keeping only one variant, preferably the one with named parameters for better code clarity.
| static func progress(_ current: Int, _ total: Int) -> Self { | |
| .progress(current: current, total: total) | |
| } |
| var sensibleInformation: String | ||
| init(stringLiteral value: StringLiteralType) { | ||
| sensibleInformation = value |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property name sensibleInformation appears to be a typo. It should likely be sensitiveInformation (meaning private/secret data) rather than sensibleInformation (meaning reasonable/practical).
| var sensibleInformation: String | |
| init(stringLiteral value: StringLiteralType) { | |
| sensibleInformation = value | |
| var sensitiveInformation: String | |
| init(stringLiteral value: StringLiteralType) { | |
| sensitiveInformation = value |
netbe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left some questions
| if let key = LogAttributesKey(rawValue: additionalAttribute.key) { | ||
| attributes[key] = additionalAttribute.value | ||
| } else { | ||
| assertionFailure(additionalAttribute.key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion:
| assertionFailure(additionalAttribute.key) | |
| assertionFailure("unsupported attribute: \(additionalAttribute.key)") |
| import WireLogging | ||
| import WireSystem | ||
|
|
||
| // TODO: the new implementation currently just wraps the old one, rewrite! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: @caldrian do you plan to do it in this PR?
| static let createBackup = WireTaggedLogger(tag: "create-backup", handler: logHandler) | ||
|
|
||
| static let importBackup = WireTaggedLogger(tag: "import-backup", handler: logHandler) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: so each framework we'll get different instances?
|
|
||
| @testable import WireLogging | ||
|
|
||
| struct WireLogInterpolationAnyErrorTests { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
praise: nice to have this tested
|
This PR is stale because it has been open 30 days with no activity. Please update it or close it in case is not relevant anymore. |
…ging-using-string-interpolation-WPB-14297 # Conflicts: # WireAnalytics/Sources/WireDatadog/WireDatadog.swift # WireAnalytics/Sources/WireDatadog/WireFakeDatadog.swift # WireLogging/Sources/WireLogging/TaggedLogger/WireLogger+Singletons.swift # WireUI/Sources/WireSettingsUI/Account/BackupImportExport/Import/ImportBackupViewModel.swift
Issue
This is the third PR in a series,
This PR adjusts WireBackup to use the new logging module.
Checklist
[WPB-XXX].UI accessibility checklist
If your PR includes UI changes, please utilize this checklist: