From 7a7e90f9c352ad5cfecf93810c5c5a9b0c4dd9b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Mon, 30 Jun 2025 10:25:31 +0200 Subject: [PATCH 1/5] Give user the possibility to pass their logger to the lambda runtime --- .../FoundationSupport/Lambda+JSON.swift | 10 ++++++++-- Sources/AWSLambdaRuntime/LambdaHandlers.swift | 9 +++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift b/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift index 9bd4d30f..100be759 100644 --- a/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift +++ b/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift @@ -23,6 +23,8 @@ import class Foundation.JSONDecoder import class Foundation.JSONEncoder #endif +import Logging + public struct LambdaJSONEventDecoder: LambdaEventDecoder { @usableFromInline let jsonDecoder: JSONDecoder @@ -85,10 +87,12 @@ extension LambdaCodableAdapter { extension LambdaRuntime { /// Initialize an instance with a `LambdaHandler` defined in the form of a closure **with a non-`Void` return type**. /// - Parameters: + /// - logger: The logger to use for the runtime. Defaults to a logger with label "LambdaRuntime". /// - decoder: The decoder object that will be used to decode the incoming `ByteBuffer` event into the generic `Event` type. `JSONDecoder()` used as default. /// - encoder: The encoder object that will be used to encode the generic `Output` into a `ByteBuffer`. `JSONEncoder()` used as default. /// - body: The handler in the form of a closure. public convenience init( + logger: Logger = Logger(label: "LambdaRuntime"), decoder: JSONDecoder = JSONDecoder(), encoder: JSONEncoder = JSONEncoder(), body: sending @escaping (Event, LambdaContext) async throws -> Output @@ -108,13 +112,15 @@ extension LambdaRuntime { handler: LambdaHandlerAdapter(handler: ClosureHandler(body: body)) ) - self.init(handler: handler) + self.init(handler: handler, logger: logger) } /// Initialize an instance with a `LambdaHandler` defined in the form of a closure **with a `Void` return type**. + /// - Parameter logger: The logger to use for the runtime. Defaults to a logger with label "LambdaRuntime". /// - Parameter body: The handler in the form of a closure. /// - Parameter decoder: The decoder object that will be used to decode the incoming `ByteBuffer` event into the generic `Event` type. `JSONDecoder()` used as default. public convenience init( + logger: Logger = Logger(label: "LambdaRuntime"), decoder: JSONDecoder = JSONDecoder(), body: sending @escaping (Event, LambdaContext) async throws -> Void ) @@ -132,7 +138,7 @@ extension LambdaRuntime { handler: LambdaHandlerAdapter(handler: ClosureHandler(body: body)) ) - self.init(handler: handler) + self.init(handler: handler, logger: logger) } } #endif // trait: FoundationJSONSupport diff --git a/Sources/AWSLambdaRuntime/LambdaHandlers.swift b/Sources/AWSLambdaRuntime/LambdaHandlers.swift index 4b5975cb..c65d8919 100644 --- a/Sources/AWSLambdaRuntime/LambdaHandlers.swift +++ b/Sources/AWSLambdaRuntime/LambdaHandlers.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// import NIOCore +import Logging /// The base handler protocol that receives a `ByteBuffer` representing the incoming event and returns the response as a `ByteBuffer` too. /// This handler protocol supports response streaming. Bytes can be streamed outwards through the ``LambdaResponseStreamWriter`` @@ -175,11 +176,15 @@ public struct ClosureHandler: LambdaHandler { extension LambdaRuntime { /// Initialize an instance with a ``StreamingLambdaHandler`` in the form of a closure. - /// - Parameter body: The handler in the form of a closure. + /// - Parameter + /// - logger: The logger to use for the runtime. Defaults to a logger with label "LambdaRuntime". + /// - body: The handler in the form of a closure. public convenience init( + logger: Logger = Logger(label: "LambdaRuntime"), body: @Sendable @escaping (ByteBuffer, LambdaResponseStreamWriter, LambdaContext) async throws -> Void + ) where Handler == StreamingClosureHandler { - self.init(handler: StreamingClosureHandler(body: body)) + self.init(handler: StreamingClosureHandler(body: body), logger: logger) } /// Initialize an instance with a ``LambdaHandler`` defined in the form of a closure **with a non-`Void` return type**, an encoder, and a decoder. From 23929596dad1c9323eaa9a5effe21c0b855f1131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Mon, 30 Jun 2025 10:30:21 +0200 Subject: [PATCH 2/5] swift format --- Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift | 2 +- Sources/AWSLambdaRuntime/LambdaHandlers.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift b/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift index 100be759..0f6b3647 100644 --- a/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift +++ b/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift @@ -23,7 +23,7 @@ import class Foundation.JSONDecoder import class Foundation.JSONEncoder #endif -import Logging +import Logging public struct LambdaJSONEventDecoder: LambdaEventDecoder { @usableFromInline let jsonDecoder: JSONDecoder diff --git a/Sources/AWSLambdaRuntime/LambdaHandlers.swift b/Sources/AWSLambdaRuntime/LambdaHandlers.swift index c65d8919..3dc492eb 100644 --- a/Sources/AWSLambdaRuntime/LambdaHandlers.swift +++ b/Sources/AWSLambdaRuntime/LambdaHandlers.swift @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -import NIOCore import Logging +import NIOCore /// The base handler protocol that receives a `ByteBuffer` representing the incoming event and returns the response as a `ByteBuffer` too. /// This handler protocol supports response streaming. Bytes can be streamed outwards through the ``LambdaResponseStreamWriter`` From b15497de16e393bc5036cc587904cda8af7411e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Tue, 1 Jul 2025 15:03:27 +0200 Subject: [PATCH 3/5] use the provider Logger's log level by default --- Sources/AWSLambdaRuntime/LambdaRuntime.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sources/AWSLambdaRuntime/LambdaRuntime.swift b/Sources/AWSLambdaRuntime/LambdaRuntime.swift index 7aba2812..d1d1674c 100644 --- a/Sources/AWSLambdaRuntime/LambdaRuntime.swift +++ b/Sources/AWSLambdaRuntime/LambdaRuntime.swift @@ -46,7 +46,11 @@ public final class LambdaRuntime: @unchecked Sendable where Handler: St // developers have to wait for AWS Lambda to dispose and recreate a runtime environment to pickup a change // this approach is less flexible but more performant than reading the value of the environment variable at each invocation var log = logger - log.logLevel = Lambda.env("LOG_LEVEL").flatMap(Logger.Level.init) ?? .info + + // use the LOG_LEVEL environment variable to set the log level. + // if the environment variable is not set, use the default log level from the logger provided + log.logLevel = Lambda.env("LOG_LEVEL").flatMap(Logger.Level.init) ?? logger.logLevel + self.logger = log self.logger.debug("LambdaRuntime initialized") } From a742c8f2199238ad59f1f02a9708ae3fbe57789d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Tue, 1 Jul 2025 15:05:12 +0200 Subject: [PATCH 4/5] move logger to last arg --- .../AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift b/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift index 0f6b3647..9b47bd7d 100644 --- a/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift +++ b/Sources/AWSLambdaRuntime/FoundationSupport/Lambda+JSON.swift @@ -87,14 +87,14 @@ extension LambdaCodableAdapter { extension LambdaRuntime { /// Initialize an instance with a `LambdaHandler` defined in the form of a closure **with a non-`Void` return type**. /// - Parameters: - /// - logger: The logger to use for the runtime. Defaults to a logger with label "LambdaRuntime". /// - decoder: The decoder object that will be used to decode the incoming `ByteBuffer` event into the generic `Event` type. `JSONDecoder()` used as default. /// - encoder: The encoder object that will be used to encode the generic `Output` into a `ByteBuffer`. `JSONEncoder()` used as default. + /// - logger: The logger to use for the runtime. Defaults to a logger with label "LambdaRuntime". /// - body: The handler in the form of a closure. public convenience init( - logger: Logger = Logger(label: "LambdaRuntime"), decoder: JSONDecoder = JSONDecoder(), encoder: JSONEncoder = JSONEncoder(), + logger: Logger = Logger(label: "LambdaRuntime"), body: sending @escaping (Event, LambdaContext) async throws -> Output ) where @@ -116,12 +116,12 @@ extension LambdaRuntime { } /// Initialize an instance with a `LambdaHandler` defined in the form of a closure **with a `Void` return type**. - /// - Parameter logger: The logger to use for the runtime. Defaults to a logger with label "LambdaRuntime". /// - Parameter body: The handler in the form of a closure. /// - Parameter decoder: The decoder object that will be used to decode the incoming `ByteBuffer` event into the generic `Event` type. `JSONDecoder()` used as default. + /// - Parameter logger: The logger to use for the runtime. Defaults to a logger with label "LambdaRuntime". public convenience init( - logger: Logger = Logger(label: "LambdaRuntime"), decoder: JSONDecoder = JSONDecoder(), + logger: Logger = Logger(label: "LambdaRuntime"), body: sending @escaping (Event, LambdaContext) async throws -> Void ) where From 1b4e150221066471e5c73eaaf3d2787444707501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Tue, 1 Jul 2025 15:05:25 +0200 Subject: [PATCH 5/5] add logger to more convenience initializers --- Sources/AWSLambdaRuntime/LambdaHandlers.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/AWSLambdaRuntime/LambdaHandlers.swift b/Sources/AWSLambdaRuntime/LambdaHandlers.swift index 3dc492eb..cc23fa4a 100644 --- a/Sources/AWSLambdaRuntime/LambdaHandlers.swift +++ b/Sources/AWSLambdaRuntime/LambdaHandlers.swift @@ -191,6 +191,7 @@ extension LambdaRuntime { /// - Parameters: /// - encoder: The encoder object that will be used to encode the generic `Output` into a `ByteBuffer`. /// - decoder: The decoder object that will be used to decode the incoming `ByteBuffer` event into the generic `Event` type. + /// - logger: The logger to use for the runtime. Defaults to a logger with label "LambdaRuntime". /// - body: The handler in the form of a closure. public convenience init< Event: Decodable, @@ -200,6 +201,7 @@ extension LambdaRuntime { >( encoder: sending Encoder, decoder: sending Decoder, + logger: Logger = Logger(label: "LambdaRuntime"), body: sending @escaping (Event, LambdaContext) async throws -> Output ) where @@ -219,15 +221,17 @@ extension LambdaRuntime { handler: streamingAdapter ) - self.init(handler: codableWrapper) + self.init(handler: codableWrapper, logger: logger) } /// Initialize an instance with a ``LambdaHandler`` defined in the form of a closure **with a `Void` return type**, an encoder, and a decoder. /// - Parameters: /// - decoder: The decoder object that will be used to decode the incoming `ByteBuffer` event into the generic `Event` type. + /// - logger: The logger to use for the runtime. Defaults to a logger with label "LambdaRuntime". /// - body: The handler in the form of a closure. public convenience init( decoder: sending Decoder, + logger: Logger = Logger(label: "LambdaRuntime"), body: sending @escaping (Event, LambdaContext) async throws -> Void ) where @@ -244,6 +248,6 @@ extension LambdaRuntime { handler: LambdaHandlerAdapter(handler: ClosureHandler(body: body)) ) - self.init(handler: handler) + self.init(handler: handler, logger: logger) } }