example/handler.go

// Worked example of using lambdalog in an AWS Lambda handler.
//
// Deploy with any standard Lambda Go packaging; see mercemay.top/src/lambdalog/
// for the rest of the source tree.
package main

import (
	"context"
	"errors"
	"os"
	"time"

	"github.com/aws/aws-lambda-go/lambda"

	"mercemay.top/src/lambdalog"
)

// logger is a package-level base logger. Child loggers are derived per-invocation
// so that request-scoped attributes don't leak across cold-start-warmed containers.
var logger = lambdalog.New(os.Stdout).With("service", "order-events")

// Event is the payload this handler accepts.
type Event struct {
	OrderID string   `json:"order_id"`
	Items   []string `json:"items"`
}

// Result is the response body.
type Result struct {
	Accepted bool   `json:"accepted"`
	Reason   string `json:"reason,omitempty"`
}

func handle(ctx context.Context, evt Event) (Result, error) {
	log := logger.FromContext(ctx).With("order_id", evt.OrderID)

	start := time.Now()
	log.Info("received order", "items", len(evt.Items))

	if len(evt.Items) == 0 {
		log.Warn("rejected empty order")
		return Result{Accepted: false, Reason: "empty"}, nil
	}

	if err := process(ctx, evt); err != nil {
		log.Error("processing failed", "err", err, "dur_ms", time.Since(start).Milliseconds())
		return Result{}, err
	}

	log.Info("accepted", "dur_ms", time.Since(start).Milliseconds())
	return Result{Accepted: true}, nil
}

func process(ctx context.Context, evt Event) error {
	if evt.OrderID == "" {
		return errors.New("missing order id")
	}
	_ = ctx
	return nil
}

func main() {
	lambda.Start(handle)
}