Skip to content

Commit

Permalink
Use structured logging when we log things
Browse files Browse the repository at this point in the history
  • Loading branch information
gwynne committed May 29, 2024
1 parent c284c2e commit ba5bcab
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 20 deletions.
6 changes: 3 additions & 3 deletions Sources/FluentKit/Migration/Migrator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private final class DatabaseMigrator: Sendable {
self.database.logger.critical("The migration at \(migration.name) is in a private context. Either explicitly give it a name by adding the `var name: String` property or make the migration `internal` or `public` instead of `private`.")
fatalError("Private migrations not allowed")
}
self.database.logger.error("The migration at \(migration.name) has an unexpected default name. Consider giving it an explicit name by adding a `var name: String` property before applying these migrations.")
self.database.logger.error("The migration has an unexpected default name. Consider giving it an explicit name by adding a `var name: String` property before applying these migrations.", metadata: ["migration": .string(migration.name)])
}
}

Expand Down Expand Up @@ -197,7 +197,7 @@ private final class DatabaseMigrator: Sendable {

return MigrationLog(name: migration.name, batch: batch).save(on: self.database)
}.flatMapErrorThrowing {
self.database.logger.error("[Migrator] Failed prepare: \(String(reflecting: $0))", metadata: ["migration": .string(migration.name)])
self.database.logger.error("[Migrator] Failed prepare", metadata: ["migration": .string(migration.name), "error": .string(String(reflecting: $0))])

throw $0
}
Expand All @@ -211,7 +211,7 @@ private final class DatabaseMigrator: Sendable {

return MigrationLog.query(on: self.database).filter(\.$name == migration.name).delete()
}.flatMapErrorThrowing {
self.database.logger.error("[Migrator] Failed revert: \(String(reflecting: $0))", metadata: ["migration": .string(migration.name)])
self.database.logger.error("[Migrator] Failed revert", metadata: ["migration": .string(migration.name), "error": .string(String(reflecting: $0))])

throw $0
}
Expand Down
4 changes: 3 additions & 1 deletion Sources/FluentKit/Query/Builder/QueryBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,9 @@ public final class QueryBuilder<Model>
break
}

self.database.logger.debug("\(self.query)")
// N.B.: We use `self.query` here instead of `query` so that the logging reflects the query the user requested,
// without having to deal with the noise of us having added default fields, or doing deletedAt checks, etc.
self.database.logger.debug("Running query", metadata: self.query.describedByLoggingMetadata)
self.database.history?.add(self.query)

let loop = self.database.eventLoop
Expand Down
11 changes: 1 addition & 10 deletions Sources/FluentKit/Query/Database/DatabaseQuery+Filter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,10 @@ extension DatabaseQuery.Filter: CustomStringConvertible {
switch self {
case .value(let field, let method, let value):
return "\(field) \(method) \(value)"

case .field(let fieldA, let method, let fieldB):
return "\(fieldA) \(method) \(fieldB)"

case .group(let filters, let relation):
return filters.map{ "(\($0.description))" }.joined(separator: " \(relation) ")

return filters.map { "(\($0))" }.joined(separator: " \(relation) ")
case .custom(let any):
return "custom(\(any))"
}
Expand All @@ -83,20 +80,16 @@ extension DatabaseQuery.Filter.Method: CustomStringConvertible {
switch self {
case .equality(let inverse):
return inverse ? "!=" : "="

case .order(let inverse, let equality):
if equality {
return inverse ? "<=" : ">="
} else {
return inverse ? "<" : ">"
}

case .subset(let inverse):
return inverse ? "!~~" : "~~"

case .contains(let inverse, let contains):
return inverse ? "!\(contains)" : "\(contains)"

case .custom(let any):
return "custom(\(any))"
}
Expand All @@ -108,10 +101,8 @@ extension DatabaseQuery.Filter.Method.Contains: CustomStringConvertible {
switch self {
case .prefix:
return "startswith"

case .suffix:
return "endswith"

case .anywhere:
return "contains"
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/FluentKit/Query/Database/DatabaseQuery+Value.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ extension DatabaseQuery.Value: CustomStringConvertible {
switch self {
case .bind(let encodable):
if let convertible = encodable as? any CustomDebugStringConvertible {
return convertible.debugDescription
return String(reflecting: convertible)
} else {
return "\(encodable)"
return String(describing: encodable)
}
case .dictionary(let dictionary):
return dictionary.description
return String(describing: dictionary)
case .array(let array):
return array.description
return String(describing: array)
case .enumCase(let string):
return string
case .null:
Expand Down
26 changes: 24 additions & 2 deletions Sources/FluentKit/Query/Database/DatabaseQuery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ extension DatabaseQuery: CustomStringConvertible {
"\(self.action)",
]
if let space = self.space {
parts.append(space)
parts.append("\(space).\(self.schema)")
} else {
parts.append(self.schema)
}
parts.append(self.schema)
if self.isUnique {
parts.append("unique")
}
Expand All @@ -57,4 +58,25 @@ extension DatabaseQuery: CustomStringConvertible {
}
return parts.joined(separator: " ")
}

var describedByLoggingMetadata: Logger.Metadata {
func valueMetadata(_ input: DatabaseQuery.Value) -> Logger.MetadataValue {
switch input {
case .dictionary(let d): return .dictionary(.init(uniqueKeysWithValues: d.map { ($0.description, valueMetadata($1)) }))
case .array(let a): return .array(a.map { valueMetadata($0) })
default: return .stringConvertible(input)
}
}

return [
"action": "\(self.action)",
"schema": "\(self.space.map { "\($0)." } ?? "")\(self.schema)",
"unique": "\(self.isUnique)",
"fields": .array(self.fields.map { .stringConvertible($0) }),
"filters": .array(self.filters.map { .stringConvertible($0) }),
"input": self.input.count == 1 ? valueMetadata(self.input.first!) : .array(self.input.map { valueMetadata($0) }),
"limits": .array(self.limits.map { .stringConvertible($0) }),
"offsets": .array(self.offsets.map { .stringConvertible($0) }),
]
}
}

0 comments on commit ba5bcab

Please sign in to comment.