@@ -11,44 +11,63 @@ import (
1111 "os"
1212)
1313
14- // Field represents an optional field to include in log records.
14+ // Field represents a Lambda context field to include in log records.
1515type Field struct {
1616 key string
1717 value func (* LambdaContext ) string
1818}
1919
20- // FunctionArn includes the invoked function ARN in log records.
21- var FunctionArn = Field {"functionArn" , func (lc * LambdaContext ) string { return lc .InvokedFunctionArn }} //nolint: staticcheck
20+ // FieldFunctionARN returns a Field that includes the invoked function ARN in log records.
21+ func FieldFunctionARN () Field {
22+ return Field {"functionArn" , func (lc * LambdaContext ) string { return lc .InvokedFunctionArn }}
23+ }
24+
25+ // FieldTenantID returns a Field that includes the tenant ID in log records (for multi-tenant functions).
26+ func FieldTenantID () Field {
27+ return Field {"tenantId" , func (lc * LambdaContext ) string { return lc .TenantID }}
28+ }
29+
30+ // logOptions holds configuration for the Lambda log handler.
31+ type logOptions struct {
32+ fields []Field
33+ }
34+
35+ // LogOption is a functional option for configuring the Lambda log handler.
36+ type LogOption func (* logOptions )
2237
23- // TenantId includes the tenant ID in log records (for multi-tenant functions).
24- var TenantId = Field {"tenantId" , func (lc * LambdaContext ) string { return lc .TenantID }} //nolint: staticcheck
38+ // WithFields includes the specified fields in log records.
39+ func WithFields (fields ... Field ) LogOption {
40+ return func (o * logOptions ) {
41+ o .fields = append (o .fields , fields ... )
42+ }
43+ }
2544
26- // Handler returns a [slog.Handler] for AWS Lambda structured logging.
45+ // LogHandler returns a [slog.Handler] for AWS Lambda structured logging.
2746// It reads AWS_LAMBDA_LOG_FORMAT and AWS_LAMBDA_LOG_LEVEL from environment,
2847// and injects requestId from Lambda context into each log record.
2948//
30- // By default, only requestId is injected. Pass optional fields to include more:
31- //
32- // // Default: only requestId
33- // slog.SetDefault(slog.New(lambdacontext.Handler()))
34- //
35- // // With functionArn and tenantId
36- // slog.SetDefault(slog.New(lambdacontext.Handler(lambdacontext.FunctionArn, lambdacontext.TenantId)))
37- func Handler ( fields ... Field ) slog. Handler {
49+ // By default, only requestId is injected. Use WithFields to include more.
50+ // See the package examples for usage.
51+ func LogHandler ( opts ... LogOption ) slog. Handler {
52+ options := & logOptions {}
53+ for _ , opt := range opts {
54+ opt ( options )
55+ }
56+
3857 level := parseLogLevel ()
39- opts := & slog.HandlerOptions {
58+ handlerOpts := & slog.HandlerOptions {
4059 Level : level ,
4160 ReplaceAttr : ReplaceAttr ,
4261 }
4362
4463 var h slog.Handler
45- if LogFormatName == "JSON" {
46- h = slog .NewJSONHandler (os .Stdout , opts )
64+ if LogFormat == "JSON" {
65+ h = slog .NewJSONHandler (os .Stdout , handlerOpts )
4766 } else {
48- h = slog .NewTextHandler (os .Stdout , opts )
67+ h = slog .NewTextHandler (os .Stdout , handlerOpts )
4968 }
5069
51- return & lambdaHandler {handler : h , fields : fields }
70+ return & lambdaHandler {handler : h , fields : options . fields }
5271}
5372
5473// ReplaceAttr maps slog's default keys to AWS Lambda's log format (time->timestamp, msg->message).
@@ -67,7 +86,7 @@ func ReplaceAttr(groups []string, attr slog.Attr) slog.Attr {
6786}
6887
6988// Attrs returns Lambda context fields as slog-compatible key-value pairs.
70- // For most use cases, using [Handler ] with slog.InfoContext is preferred.
89+ // For most use cases, using [LogHandler ] with slog.InfoContext is preferred.
7190func (lc * LambdaContext ) Attrs () []any {
7291 return []any {"requestId" , lc .AwsRequestID }
7392}
@@ -88,9 +107,9 @@ func (h *lambdaHandler) Handle(ctx context.Context, r slog.Record) error {
88107 if lc , ok := FromContext (ctx ); ok {
89108 r .AddAttrs (slog .String ("requestId" , lc .AwsRequestID ))
90109
91- for _ , f := range h .fields {
92- if v := f .value (lc ); v != "" {
93- r .AddAttrs (slog .String (f .key , v ))
110+ for _ , field := range h .fields {
111+ if v := field .value (lc ); v != "" {
112+ r .AddAttrs (slog .String (field .key , v ))
94113 }
95114 }
96115 }
@@ -114,7 +133,7 @@ func (h *lambdaHandler) WithGroup(name string) slog.Handler {
114133}
115134
116135func parseLogLevel () slog.Level {
117- switch LogLevelName {
136+ switch LogLevel {
118137 case "DEBUG" :
119138 return slog .LevelDebug
120139 case "INFO" :
0 commit comments