-
Notifications
You must be signed in to change notification settings - Fork 918
Added file, function and line information to logging in debug builds. #9437
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: master
Are you sure you want to change the base?
Conversation
…ging in debug builds. Also fixed some unnecessary masking. Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
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 extends the File Provider logging stack to capture and (in debug builds) emit source location context (file, function, line) alongside existing structured log details.
Changes:
- Extended
FileProviderLogging.write(...)andFileProviderLogger.{debug,info,error,fault}to thread throughfile/function/line. - Added
file/function/linefields toFileProviderLogMessageand encoded them only in#if DEBUG. - Appended source location to unified logging output (debug builds) and adjusted some path interpolations to use explicit
.publicprivacy.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
.../Log/FileProviderLogging.swift |
Updates the logging protocol API to carry source location info. |
.../Log/FileProviderLogger.swift |
Passes caller #filePath/#function/#line through the logger convenience methods. |
.../Log/FileProviderLogMessage.swift |
Adds source fields to the JSON log model and conditionally encodes them in debug builds. |
.../Log/FileProviderLog.swift |
Threads source location through log writing and appends it to unified logs (debug). |
Comments suppressed due to low confidence (1)
shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Log/FileProviderLog.swift:219
- When
detailsis empty you early-return after logging only the message, so the newfile:function:linecontext is omitted for those log entries. To match the PR’s intent, include the source location even when there are no details (e.g., log message + "file:line function" in the empty-details branch too).
if details.isEmpty {
logger.log(level: level, "\(message, privacy: .public)")
return
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// - file: Implementations should have `#filePath` as the default value for this. | ||
| /// - function: Implementations should have `#function` as the default value for this. | ||
| /// - line: Implementations should have `#line` as the default value for this. | ||
| /// | ||
| func write(category: String, level: OSLogType, message: String, details: [FileProviderLogDetailKey: (any Sendable)?], file: StaticString, function: StaticString, line: UInt) | ||
| } |
Copilot
AI
Feb 9, 2026
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.
This protocol requirement change is source-breaking for existing conformers. For example, FileProviderLogMock in Sources/NextcloudFileProviderKitMocks/FileProviderLogMock.swift still implements the old write(..., details:) signature, so the project won’t compile until it’s updated (or until you provide a backward-compatible overload/default implementation). Consider keeping the old requirement and adding a new overload in a protocol extension that supplies file/function/line defaults and forwards appropriately.
| /// - file: Implementations should have `#filePath` as the default value for this. | |
| /// - function: Implementations should have `#function` as the default value for this. | |
| /// - line: Implementations should have `#line` as the default value for this. | |
| /// | |
| func write(category: String, level: OSLogType, message: String, details: [FileProviderLogDetailKey: (any Sendable)?], file: StaticString, function: StaticString, line: UInt) | |
| } | |
| /// | |
| func write(category: String, level: OSLogType, message: String, details: [FileProviderLogDetailKey: (any Sendable)?]) | |
| } | |
| public extension FileProviderLogging { | |
| /// | |
| /// Convenience overload that supplies file/function/line defaults and forwards | |
| /// to the base `write` requirement. | |
| /// | |
| /// - Parameters: | |
| /// - category: The unified logging category to use. Usually, this is the logging type. | |
| /// - level: The severity of the message. | |
| /// - message: A human-readable message, preferrably generic and without interpolations. The `details` argument is for arguments. | |
| /// - details: Structured and contextual details about a message. | |
| /// - file: The file path from which the log was emitted. Defaults to `#filePath`. | |
| /// - function: The function from which the log was emitted. Defaults to `#function`. | |
| /// - line: The line number from which the log was emitted. Defaults to `#line`. | |
| /// | |
| func write( | |
| category: String, | |
| level: OSLogType, | |
| message: String, | |
| details: [FileProviderLogDetailKey: (any Sendable)?], | |
| file: StaticString = #filePath, | |
| function: StaticString = #function, | |
| line: UInt = #line | |
| ) { | |
| // Default implementation ignores file/function/line and forwards to the | |
| // base requirement for backward compatibility. | |
| self.write(category: category, level: level, message: message, details: details) | |
| } | |
| } |
| /// - level: The severit of the message. | ||
| /// - message: A human-readable message, preferrably generic and without interpolations. The `details` argument is for arguments. |
Copilot
AI
Feb 9, 2026
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.
Doc typos: "severit" should be "severity", and "preferrably" should be "preferably".
| /// - level: The severit of the message. | |
| /// - message: A human-readable message, preferrably generic and without interpolations. The `details` argument is for arguments. | |
| /// - level: The severity of the message. | |
| /// - message: A human-readable message, preferably generic and without interpolations. The `details` argument is for arguments. |
| /// - Parameters: | ||
| /// - message: The main text message of the entry in the logs. | ||
| /// - details: Additional contextual data. | ||
| /// | ||
| public func debug(_ message: String, _ details: [FileProviderLogDetailKey: (any Sendable)?] = [:]) { | ||
| /// - category: The unified logging category to use. Usually, this is the logging type. | ||
| /// - level: The severit of the message. | ||
| /// - message: A human-readable message, preferrably generic and without interpolations. The `details` argument is for arguments. | ||
| /// - details: Structured and contextual details about a message. | ||
| /// - file: Implementations should have `#filePath` as the default value for this. | ||
| /// - function: Implementations should have `#function` as the default value for this. | ||
| /// - line: Implementations should have `#line` as the default value for this. |
Copilot
AI
Feb 9, 2026
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.
These doc comments list parameters (category, level) that are not parameters of debug(...) (and the same issue is repeated for info/error/fault). Please update the parameter docs to match the actual signature, and fix the typos ("severity", "preferably").
| public func encode(to encoder: any Encoder) throws { | ||
| var container = encoder.container(keyedBy: CodingKeys.self) | ||
| try container.encode(category, forKey: .category) | ||
| try container.encode(date, forKey: .date) | ||
| try container.encode(details, forKey: .details) | ||
| try container.encode(level, forKey: .level) | ||
| try container.encode(message, forKey: .message) | ||
|
|
||
| #if DEBUG | ||
| try container.encode(file, forKey: .file) | ||
| try container.encode(function, forKey: .function) | ||
| try container.encode(line, forKey: .line) | ||
| #endif |
Copilot
AI
Feb 9, 2026
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.
FileProviderLogMessage now conditionally encodes file/function/line only in #if DEBUG, but there’s no test coverage to ensure the produced JSON includes these keys in debug builds (and excludes them otherwise). Add a unit test around encoding that asserts the expected keys based on the build configuration (using #if DEBUG in the test).
| self.file = String("\(file)") | ||
| self.function = String("\(function)") |
Copilot
AI
Feb 9, 2026
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.
Even in non-DEBUG builds, FileProviderLogMessage eagerly converts file/function to String and stores them, even though they won’t be encoded. If the goal is “debug builds only”, consider avoiding this work in release builds (e.g., set them only under #if DEBUG, or store them as optionals and encode only when present).
| self.file = String("\(file)") | |
| self.function = String("\(function)") | |
| #if DEBUG | |
| self.file = String("\(file)") | |
| self.function = String("\(function)") | |
| #else | |
| // Avoid unnecessary conversion work in non-DEBUG builds; these fields are not encoded there. | |
| self.file = "" | |
| self.function = "" | |
| #endif |
|
Artifact containing the AppImage: nextcloud-appimage-pr-9437.zip Digest: To test this change/fix you can download the above artifact file, unzip it, and run it. Please make sure to quit your existing Nextcloud app and backup your data. |
No description provided.