Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
825 changes: 232 additions & 593 deletions docs/sdk-reference/observability/logging.md

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions examples/java/sdk-reference/observability/basic-usage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.DurableHandler;

public class BasicUsage extends DurableHandler<Object, String> {
@Override
public String handleRequest(Object event, DurableContext context) {
context.getLogger().info("Starting workflow");

String result = context.step("process", String.class, stepCtx -> "done");

context.getLogger().info("Workflow complete: {}", result);
return result;
}
}
21 changes: 21 additions & 0 deletions examples/java/sdk-reference/observability/custom-logger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import software.amazon.lambda.durable.DurableConfig;
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.DurableHandler;
import software.amazon.lambda.durable.logging.LoggerConfig;

public class CustomLogger extends DurableHandler<Object, Void> {

@Override
protected DurableConfig createConfiguration() {
// Allow logs during replay by overriding the default LoggerConfig.
return DurableConfig.builder()
.withLoggerConfig(LoggerConfig.withReplayLogging())
.build();
}

@Override
public Void handleRequest(Object event, DurableContext context) {
context.getLogger().info("Logs appear on every replay");
return null;
}
}
17 changes: 17 additions & 0 deletions examples/java/sdk-reference/observability/logger-interface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import org.slf4j.Logger;
import software.amazon.lambda.durable.logging.DurableLogger;

// DurableLogger wraps an SLF4J Logger and adds MDC entries:
// durableExecutionArn, requestId, operationId, operationName, attempt
//
// Obtain it from any context:
// DurableLogger logger = context.getLogger();
// DurableLogger logger = stepContext.getLogger();
//
// Available methods:
// logger.trace(String format, Object... args)
// logger.debug(String format, Object... args)
// logger.info(String format, Object... args)
// logger.warn(String format, Object... args)
// logger.error(String format, Object... args)
// logger.error(String message, Throwable t)
16 changes: 16 additions & 0 deletions examples/java/sdk-reference/observability/powertools-logger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.lambda.powertools.logging.Logging;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class MyHandler implements RequestHandler<Object, String> {

private static final Logger logger = LoggerFactory.getLogger(MyHandler.class);

@Logging
public String handleRequest(Object event, Context context) {
logger.info("Running handler");
return "ok";
}
}
16 changes: 16 additions & 0 deletions examples/java/sdk-reference/observability/replay-suppression.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.DurableHandler;

public class ReplaySuppression extends DurableHandler<Object, String> {
@Override
public String handleRequest(Object event, DurableContext context) {
// context.getLogger() suppresses duplicate logs during replay by default.
// Logs from completed operations do not repeat when the SDK replays.
context.getLogger().info("Step 1 starting");

String result = context.step("step-1", String.class, stepCtx -> "result");

context.getLogger().info("Step 1 complete: {}", result);
return result;
}
}
14 changes: 14 additions & 0 deletions examples/java/sdk-reference/observability/step-context-logger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.DurableHandler;
import software.amazon.lambda.durable.StepContext;

public class StepContextLogger extends DurableHandler<Object, String> {
@Override
public String handleRequest(Object event, DurableContext context) {
return context.step("process", String.class, (StepContext stepCtx) -> {
// stepCtx.getLogger() includes operationId, operationName, and attempt in MDC.
stepCtx.getLogger().info("Running step");
return "done";
});
}
}
11 changes: 11 additions & 0 deletions examples/python/sdk-reference/observability/basic-usage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from aws_durable_execution_sdk_python import DurableContext, durable_execution


@durable_execution
def handler(event: dict, context: DurableContext):
context.logger.info("Starting workflow")

result = context.step(lambda ctx: "done")

context.logger.info("Workflow complete", extra={"result": result})
return result
11 changes: 11 additions & 0 deletions examples/python/sdk-reference/observability/custom-logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from aws_lambda_powertools import Logger

from aws_durable_execution_sdk_python import DurableContext, durable_execution

powertools_logger = Logger(service="my-service")


@durable_execution
def handler(event: dict, context: DurableContext):
context.set_logger(powertools_logger)
context.logger.info("Using Powertools logger")
24 changes: 24 additions & 0 deletions examples/python/sdk-reference/observability/logger-interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from collections.abc import Mapping
from typing import Protocol


class LoggerInterface(Protocol):
def debug(
self, msg: object, *args: object, extra: Mapping[str, object] | None = None
) -> None: ...

def info(
self, msg: object, *args: object, extra: Mapping[str, object] | None = None
) -> None: ...

def warning(
self, msg: object, *args: object, extra: Mapping[str, object] | None = None
) -> None: ...

def error(
self, msg: object, *args: object, extra: Mapping[str, object] | None = None
) -> None: ...

def exception(
self, msg: object, *args: object, extra: Mapping[str, object] | None = None
) -> None: ...
11 changes: 11 additions & 0 deletions examples/python/sdk-reference/observability/powertools-logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from aws_lambda_powertools import Logger

from aws_durable_execution_sdk_python import DurableContext, durable_execution

powertools_logger = Logger(service="my-service")


@durable_execution
def handler(event: dict, context: DurableContext):
context.set_logger(powertools_logger)
context.logger.info("Running handler")
13 changes: 13 additions & 0 deletions examples/python/sdk-reference/observability/replay-suppression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from aws_durable_execution_sdk_python import DurableContext, durable_execution


@durable_execution
def handler(event: dict, context: DurableContext):
# context.logger suppresses duplicate logs during replay by default.
# Logs from completed operations do not repeat when the SDK replays.
context.logger.info("Step 1 starting")

result = context.step(lambda ctx: "result")

context.logger.info("Step 1 complete", extra={"result": result})
return result
11 changes: 11 additions & 0 deletions examples/python/sdk-reference/observability/step-context-logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from aws_durable_execution_sdk_python import DurableContext, StepContext, durable_execution


@durable_execution
def handler(event: dict, context: DurableContext):
def process(step_ctx: StepContext) -> str:
# step_ctx.logger includes executionArn, operationId, and attempt.
step_ctx.logger.info("Running step")
return "done"

return context.step(process, name="process")
12 changes: 12 additions & 0 deletions examples/typescript/sdk-reference/observability/basic-usage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(async (event, context: DurableContext) => {
context.logger.info("Starting workflow");

const result = await context.step("process", async () => {
return "done";
});

context.logger.info("Workflow complete", { result });
return result;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";
import { Logger } from "@aws-lambda-powertools/logger";

const powertoolsLogger = new Logger({ serviceName: "my-service" });

export const handler = withDurableExecution(async (event, context: DurableContext) => {
context.configureLogger({ customLogger: powertoolsLogger });
context.logger.info("Using Powertools logger");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(async (event, context: DurableContext) => {
// Pass modeAware: false to emit logs on every replay.
context.configureLogger({ modeAware: false });

context.logger.info("This logs on every replay");

await context.step("step-1", async () => {
return "result";
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { DurableLogger, DurableLoggingContext } from "@aws/durable-execution-sdk-js";

// DurableLogger interface — implement this to use a custom logger.
interface DurableLogger {
log?(level: "INFO" | "WARN" | "ERROR" | "DEBUG", ...params: unknown[]): void;
error(...params: unknown[]): void;
warn(...params: unknown[]): void;
info(...params: unknown[]): void;
debug(...params: unknown[]): void;
configureDurableLoggingContext?(context: DurableLoggingContext): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Logger } from '@aws-lambda-powertools/logger';
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

const powertoolsLogger = new Logger({ serviceName: 'my-service' });

export const handler = withDurableExecution(async (event, context: DurableContext) => {
context.configureLogger({ customLogger: powertoolsLogger });
context.logger.info('Running handler');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(async (event, context: DurableContext) => {
// context.logger suppresses duplicate logs during replay by default.
// Logs from completed operations do not repeat when the SDK replays.
context.logger.info("Step 1 starting");

await context.step("step-1", async () => {
return "result";
});

context.logger.info("Step 1 complete");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DurableContext, withDurableExecution } from "@aws/durable-execution-sdk-js";

export const handler = withDurableExecution(async (event, context: DurableContext) => {
await context.step("process", async (stepCtx) => {
// stepCtx.logger includes operationId and attempt in every log entry.
stepCtx.logger.info("Running step");
return "done";
});
});
Loading