Here are 4 simple Watchtower demo examples that you can easily copy and use:

Key Points:

  • Basic usage – Just add the handler to any logger
  • Web frameworks – Flask, FastAPI, Django integration
  • Custom configuration – Log groups, streams, formatters
  • Error handling – Exception logging with stack traces

Simple Watchtower Demo Examples

1. Basic Usage

import watchtower, logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.addHandler(watchtower.CloudWatchLogsHandler())
logger.info("Hi")
logger.info(dict(foo="bar", details={}))

2. Flask App with Watchtower

import watchtower, flask, logging
logging.basicConfig(level=logging.INFO)
app = flask.Flask("loggable")
handler = watchtower.CloudWatchLogsHandler()
app.logger.addHandler(handler)
logging.getLogger("werkzeug").addHandler(handler)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

3. Custom Log Group and Stream

import watchtower, logging
logger = logging.getLogger('my_app')
handler = watchtower.CloudWatchLogsHandler(
    log_group='my-app-logs',
    stream_name='production'
)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logger.info("App started")

4. With Formatter

import watchtower, logging
logger = logging.getLogger('formatted')
handler = watchtower.CloudWatchLogsHandler()
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logger.info("Formatted message")

Also, below are the alternatives of Watchtower in 2025:

1. Standard Python logging:

How It Works

By default, Lambda automatically captures logs for all function invocations and sends them to CloudWatch Logs, provided your function’s execution role has the necessary permissions. These logs are, by default, stored in a log group named /aws/lambda/

import logging

# Configure the logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info("This message will appear in CloudWatch Logs")
    logger.error("This error will also appear in CloudWatch Logs")
    
    # Even print statements work
    print("This print statement also goes to CloudWatch")
    
    return {
        'statusCode': 200,
        'body': 'Hello World'
    }

2. AWS Lambda Powertools (Recommended):

Logger provides an opinionated logger with output structured as JSON and efficiently handles logs for AWS Lambda, ensuring logs are formatted correctly and recorded in CloudWatch seamlessly.

from aws_lambda_powertools import Logger
logger = Logger()

@logger.inject_lambda_context
def lambda_handler(event, context):
    logger.info("Processing event", extra={"event": event})
    return {"statusCode": 200}

3. Direct Boto3 CloudWatch Logs Client

You can use Amazon CloudWatch Logs API directly through boto3 to programmatically access and analyze your AWS CloudWatch logs

import boto3
import json
from datetime import datetime

def send_log_to_cloudwatch(message, log_group, log_stream):
    client = boto3.client('logs')
    timestamp = int(datetime.now().timestamp() * 1000)
    client.put_log_events(
        logGroupName=log_group,
        logStreamName=log_stream,
        logEvents=[
            {
                'timestamp': timestamp,
                'message': json.dumps(message) if isinstance(message, dict) else str(message)
            }
        ]
    )

Need Help With Cloud Development?

Work with our skilled Cloud developers to accelerate your project and boost its performance.

Hire Cloud Developers

Support On Demand!

Related Q&A