Add logging when reloading fails

This commit is contained in:
Gus Cairo 2025-05-07 11:30:50 +01:00
parent eb78ed3992
commit 8fbba2dd52
2 changed files with 31 additions and 8 deletions

View File

@ -266,6 +266,7 @@ var targets: [PackageDescription.Target] = [
.product(name: "SwiftASN1", package: "swift-asn1"),
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
.product(name: "Logging", package: "swift-log"),
],
swiftSettings: strictConcurrencySettings
),
@ -307,6 +308,7 @@ let package = Package(
.package(url: "https://github.com/apple/swift-asn1.git", from: "1.3.1"),
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.8.0"),
.package(url: "https://github.com/apple/swift-async-algorithms.git", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.3"),
],
targets: targets

View File

@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
import AsyncAlgorithms
import Logging
import NIOConcurrencyHelpers
import NIOSSL
import ServiceLifecycle
@ -205,6 +206,7 @@ public struct TimedCertificateReloader: CertificateReloader {
private let certificateDescription: CertificateDescription
private let privateKeyDescription: PrivateKeyDescription
private let state: NIOLockedValueBox<CertificateKeyPair?>
private let logger: Logger?
/// A `NIOSSLContextConfigurationOverride` that will be used as part of the NIO application's TLS configuration.
/// Its certificate and private key will be kept up-to-date via the reload mechanism the ``TimedCertificateReloader``
@ -229,12 +231,14 @@ public struct TimedCertificateReloader: CertificateReloader {
public init(
refreshInterval: TimeAmount,
certificateDescription: CertificateDescription,
privateKeyDescription: PrivateKeyDescription
privateKeyDescription: PrivateKeyDescription,
logger: Logger? = nil
) {
self.init(
refreshInterval: Duration(refreshInterval),
certificateDescription: certificateDescription,
privateKeyDescription: privateKeyDescription
privateKeyDescription: privateKeyDescription,
logger: logger
)
}
@ -248,12 +252,14 @@ public struct TimedCertificateReloader: CertificateReloader {
public init(
refreshInterval: TimeAmount,
validatingCertificateDescription: CertificateDescription,
validatingPrivateKeyDescription: PrivateKeyDescription
validatingPrivateKeyDescription: PrivateKeyDescription,
logger: Logger? = nil
) throws {
try self.init(
refreshInterval: Duration(refreshInterval),
validatingCertificateDescription: validatingCertificateDescription,
validatingPrivateKeyDescription: validatingPrivateKeyDescription
validatingPrivateKeyDescription: validatingPrivateKeyDescription,
logger: nil
)
}
@ -265,12 +271,14 @@ public struct TimedCertificateReloader: CertificateReloader {
public init(
refreshInterval: Duration,
certificateDescription: CertificateDescription,
privateKeyDescription: PrivateKeyDescription
privateKeyDescription: PrivateKeyDescription,
logger: Logger? = nil
) {
self.refreshInterval = refreshInterval
self.certificateDescription = certificateDescription
self.privateKeyDescription = privateKeyDescription
self.state = NIOLockedValueBox(nil)
self.logger = logger
// Immediately try to load the configured cert and key to avoid having to wait for the first
// reload loop to run.
@ -289,12 +297,14 @@ public struct TimedCertificateReloader: CertificateReloader {
public init(
refreshInterval: Duration,
validatingCertificateDescription: CertificateDescription,
validatingPrivateKeyDescription: PrivateKeyDescription
validatingPrivateKeyDescription: PrivateKeyDescription,
logger: Logger? = nil
) throws {
self.refreshInterval = refreshInterval
self.certificateDescription = validatingCertificateDescription
self.privateKeyDescription = validatingPrivateKeyDescription
self.state = NIOLockedValueBox(nil)
self.logger = logger
// Immediately try to load the configured cert and key to avoid having to wait for the first
// reload loop to run.
@ -306,8 +316,19 @@ public struct TimedCertificateReloader: CertificateReloader {
/// - Important: You *must* call this method to get certificate and key updates.
public func run() async throws {
for try await _ in AsyncTimerSequence.repeating(every: self.refreshInterval).cancelOnGracefulShutdown() {
// We don't want to throw out of this method so simply ignore errors thrown from `reloadPair`.
try? self.reloadPair()
do {
try self.reloadPair()
} catch {
self.logger?.error(
"""
An unexpected error was encountered while trying to reload the certificate and \
private key pair.
""",
metadata: [
"error": error
]
)
}
}
}