Skip to content

Commit 7efd570

Browse files
committed
Reformat metadata, add category to handler.
1 parent 874c89a commit 7efd570

19 files changed

Lines changed: 181 additions & 29 deletions

File tree

Sources/ContainerCommands/Image/ImageInspect.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,13 @@ extension Application {
6363
}
6464

6565
if !allErrors.isEmpty {
66-
let logger = Logger(label: "ImageInspect", factory: { _ in StderrLogHandler() })
6766
for (name, error) in allErrors {
68-
logger.error("\(name): \(error.localizedDescription)")
67+
log.error(
68+
"image inspect failed",
69+
metadata: [
70+
"name": "\(name)",
71+
"error": "\(error.localizedDescription)",
72+
])
6973
}
7074

7175
throw InspectError(succeeded: succeededImages, failed: allErrors)

Sources/ContainerCommands/Network/NetworkDelete.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ extension Application {
8989
}
9090

9191
var failed = [String]()
92-
let logger = log
92+
let _log = log
9393
try await withThrowingTaskGroup(of: NetworkState?.self) { group in
9494
for network in networks {
9595
group.addTask {
@@ -100,7 +100,12 @@ extension Application {
100100
print(network.id)
101101
return nil
102102
} catch {
103-
logger.error("failed to delete network \(network.id): \(error)")
103+
_log.error(
104+
"failed to delete network",
105+
metadata: [
106+
"id": "\(network.id)",
107+
"error": "\(error)",
108+
])
104109
return network
105110
}
106111
}

Sources/ContainerCommands/Network/NetworkPrune.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,12 @@ extension Application.NetworkCommand {
5555
// Note: This failure may occur due to a race condition between the network/
5656
// container collection above and a container run command that attaches to a
5757
// network listed in the networksToPrune collection.
58-
log.error("failed to prune network", metadata: ["id": "\(network.id)", "error": "\(error)"])
58+
log.error(
59+
"failed to prune network",
60+
metadata: [
61+
"id": "\(network.id)",
62+
"error": "\(error)",
63+
])
5964
}
6065
}
6166

Sources/ContainerCommands/Volume/VolumeDelete.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ extension Application.VolumeCommand {
6868
}
6969

7070
var failed = [String]()
71-
let logger = log
71+
let _log = log
7272
try await withThrowingTaskGroup(of: Volume?.self) { group in
7373
for volume in volumes {
7474
group.addTask {
@@ -77,7 +77,12 @@ extension Application.VolumeCommand {
7777
print(volume.id)
7878
return nil
7979
} catch {
80-
logger.error("failed to delete volume \(volume.id): \(error)")
80+
_log.error(
81+
"failed to delete volume",
82+
metadata: [
83+
"id": "\(volume.id)",
84+
"error": "\(error)",
85+
])
8186
return volume
8287
}
8388
}

Sources/ContainerLog/FileLogHandler.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public struct FileLogHandler: LogHandler {
2525
public var metadata: Logger.Metadata = [:]
2626

2727
private let label: String
28+
private let category: String
2829
private let fileHandle: FileHandle
2930

3031
public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? {
@@ -36,8 +37,17 @@ public struct FileLogHandler: LogHandler {
3637
}
3738
}
3839

39-
public init(label: String, path: FilePath) throws {
40+
/// Create a log handler that appends to the specified file.
41+
///
42+
/// - Parameters:
43+
/// - label: A unique identifier for the application.
44+
/// - category: An identifier for the application subsystem.
45+
/// - path: The log file location. The log handler creates the
46+
/// file and parent directory if needed.
47+
/// - Returns: The log handler.
48+
public init(label: String, category: String, path: FilePath) throws {
4049
self.label = label
50+
self.category = category
4151
let parentPath = path.removingLastComponent()
4252
try FileManager.default.createDirectory(atPath: parentPath.string, withIntermediateDirectories: true)
4353
if !FileManager.default.fileExists(atPath: path.string) {
@@ -74,16 +84,18 @@ public struct FileLogHandler: LogHandler {
7484

7585
let text: String
7686
if !effectiveMetadata.isEmpty {
77-
text = "\(timestamp) [\(level)] \(label) \(effectiveMetadata.description): \(message)\n"
87+
text = "\(timestamp) [\(level)] \(label) \(category) \(effectiveMetadata.description): \(message)\n"
7888
} else {
79-
text = "\(timestamp) [\(level)] \(label): \(message)\n"
89+
text = "\(timestamp) [\(level)] \(label): \(category) \(message)\n"
8090
}
8191
if let data = text.data(using: .utf8) {
8292
fileHandle.write(data)
8393
}
8494
}
8595

96+
/// Failures relating to the log handler.
8697
public enum FileLogFailure: Error {
98+
/// The log handler could not open the log file.
8799
case openFailed
88100
}
89101
}

Sources/ContainerLog/ServiceLogger.swift

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,56 @@ import SystemPackage
1919

2020
/// Common logging setup for application services.
2121
public struct ServiceLogger {
22-
/// Create a logger
22+
/// Set up the logging system and create a root logger.
23+
///
24+
/// - Parameters:
25+
/// - label: A unique identifier for the application.
26+
/// - category: An identifier for the application subsystem.
27+
/// - metadata: Metadata to include for all messsages. A message
28+
/// specific value for a duplicate key overrides these values.
29+
/// - debug: Enable debug logging.
30+
/// - logPath: If supplied, create log files under the named
31+
/// directory. Otherwise, log to the OS log facility.
32+
/// - Returns: The root logger.
2333
public static func bootstrap(
24-
category: String,
2534
label: String = "com.apple.container",
35+
category: String,
2636
metadata: [String: String] = [:],
2737
debug: Bool,
2838
logPath: FilePath?
2939
) -> Logger {
40+
// Select the log handler and bootstrap logging.
3041
LoggingSystem.bootstrap { label in
3142
if let logPath {
32-
if let handler = try? FileLogHandler(label: label, path: logPath) {
43+
if let handler = try? FileLogHandler(
44+
label: label,
45+
category: category,
46+
path: logPath
47+
) {
3348
return handler
3449
}
3550
}
3651
return OSLogHandler(label: label, category: category)
3752
}
53+
54+
// Configure log level and metadata.
3855
var log = Logger(label: label)
3956
if debug {
4057
log.logLevel = .debug
4158
}
4259
for (key, value) in metadata {
4360
log[metadataKey: key] = "\(value)"
4461
}
62+
63+
// Log an error if for some reason FileLogHandler init failed.
64+
if let logPath, log.handler as? OSLogHandler != nil {
65+
log.error(
66+
"unable to initialize FileLogHandler, using OSLogHandler",
67+
metadata: [
68+
"logPath": "\(logPath)"
69+
])
70+
}
71+
4572
return log
4673
}
4774
}

Sources/ContainerXPC/XPCServer.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,24 @@ public struct XPCServer: Sendable {
199199
let response = try await handler(message)
200200
xpc_connection_send_message(connection, response.underlying)
201201
} catch let error as ContainerizationError {
202-
log.error("route handler threw an error", metadata: ["route": "\(route)", "error": "\(error)"])
202+
log.error(
203+
"route handler threw an error",
204+
metadata: [
205+
"route": "\(route)",
206+
"error": "\(error)",
207+
])
203208
Self.replyWithError(
204209
connection: connection,
205210
object: object,
206211
err: error
207212
)
208213
} catch {
209-
log.error("route handler threw an error", metadata: ["route": "\(route)", "error": "\(error)"])
214+
log.error(
215+
"route handler threw an error",
216+
metadata: [
217+
"route": "\(route)",
218+
"error": "\(error)",
219+
])
210220
let message = XPCMessage(object: object)
211221
let reply = message.reply()
212222

Sources/Helpers/APIServer/APIServer+Start.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,12 @@ extension APIServer {
142142
*/
143143
}
144144
} catch {
145-
log.error("helper failed", metadata: ["name": "\(commandName)", "error": "\(error)"])
145+
log.error(
146+
"helper failed",
147+
metadata: [
148+
"name": "\(commandName)",
149+
"error": "\(error)",
150+
])
146151
APIServer.exit(withError: error)
147152
}
148153
}
@@ -224,6 +229,7 @@ extension APIServer {
224229
let svc = HealthCheckHarness(
225230
appRoot: appRoot,
226231
installRoot: installRoot,
232+
logRoot: logRoot,
227233
log: log
228234
)
229235
routes[XPCRoute.ping] = svc.ping

Sources/Helpers/APIServer/DirectoryWatcher.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ public class DirectoryWatcher {
6666
let files = try FileManager.default.contentsOfDirectory(atPath: directoryURL.path)
6767
try handler(files.map { directoryURL.appending(path: $0) })
6868
} catch {
69-
self.log.error("failed to run DirectoryWatcher handler", metadata: ["error": "\(error)", "path": "\(directoryURL.path)"])
69+
self.log.error(
70+
"failed to run DirectoryWatcher handler",
71+
metadata: [
72+
"error": "\(error)",
73+
"path": "\(directoryURL.path)",
74+
])
7075
}
7176
}
7277

Sources/Helpers/Images/ImagesHelper.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,12 @@ extension ImagesHelper {
8080
log.info("starting XPC server")
8181
try await xpc.listen()
8282
} catch {
83-
log.error("helper failed", metadata: ["name": "\(commandName)", "error": "\(error)"])
83+
log.error(
84+
"helper failed",
85+
metadata: [
86+
"name": "\(commandName)",
87+
"error": "\(error)",
88+
])
8489
ImagesHelper.exit(withError: error)
8590
}
8691
}

0 commit comments

Comments
 (0)