Registry / aws / watchtower

watchtower

JSON →
library3.4.0pypypi✓ verified 25d ago

Watchtower is a log handler for Amazon Web Services (AWS) CloudWatch Logs. It acts as a lightweight adapter between the Python `logging` system and CloudWatch Logs, using the `boto3` AWS SDK to aggregate logs into batches and send them to AWS. It is currently at version 3.4.0 and sees regular, although not strictly scheduled, releases with bug fixes and new features.

pip install watchtower
INSTALL
IMPORT
SIG · WATCHTOWER
W
watchtower
awspythonv3.4.0
Install
3.8s avg
Import
738ms
Disk
50MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v3.4.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.786s · 51.5MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 3.8s · import 0.690s · 52MB
50MB installed
● package 50MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

CloudWatchLogHandler
from watchtower import CloudWatchLogHandler
logging
import logging

This quickstart demonstrates how to integrate Watchtower with the Python `logging` module to send logs to AWS CloudWatch. It sets up a basic logger and a `CloudWatchLogHandler`, then sends a few example log messages. Ensure your AWS credentials and default region are configured either via environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`) or through the AWS CLI (`aws configure`) for `boto3` to automatically pick them up.

import logging import os from watchtower import CloudWatchLogHandler # Configure basic logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Set AWS credentials via environment variables for boto3 (e.g., AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION) # Or configure AWS CLI (aws configure) for boto3 to pick up credentials automatically # Create a CloudWatchLogHandler instance # Recommended: specify log_group_name and region_name explicitly # boto3 will automatically pick up credentials from env vars or IAM roles. handler = CloudWatchLogHandler( log_group_name=os.environ.get('AWS_LOG_GROUP', 'my-python-app'), region_name=os.environ.get('AWS_REGION', 'us-east-1') ) # Add the handler to the logger logger.addHandler(handler) # Log some messages logger.info('Hello from Watchtower!') logger.warning('This is a warning message.') logger.error(dict(error_code=500, message='Something went wrong')) # For applications that might exit quickly, ensure logs are flushed # In typical web applications or long-running services, this is handled on shutdown. handler.flush()
Debug
Known issues
breakingStarting with v3.0.0, non-JSON-serializable objects (e.g., `datetime` objects, custom classes) in log messages are now represented by their `repr()` string instead of being converted to `isoformat()` or `null`. This change might increase log data volume or alter parsing expectations.
fix
Review existing code that logs complex objects and adjust downstream log parsing or processing logic to account for `repr()` string representations. If the old behavior is desired, custom JSON serialization should be implemented before passing data to the logger.
affects: >=3.0.0
deprecatedThe `datetime.utcnow()` method, previously used internally by Watchtower, has been replaced due to deprecation. While this primarily affects internal implementation, users with custom logging formats or direct manipulation of `datetime` objects might encounter related issues or are encouraged to update their own code to use timezone-aware `datetime.now(timezone.utc)` for consistency.
fix
Ensure your Python environment uses a version of `watchtower` that includes the fix. For your own code, replace `datetime.utcnow()` with `datetime.now(timezone.utc)`.
affects: >=3.1.0
gotchaAs of v3.0.1, Watchtower truncates log messages based on byte length (256 KB CloudWatch Logs limit) rather than Unicode character count. This can lead to unexpected truncation of messages containing multi-byte Unicode characters, potentially cutting off messages mid-character.
fix
Be aware of the byte-length limit for log messages. If logs frequently contain long Unicode strings, consider pre-truncating or encoding them to ensure meaningful parts are preserved within the byte limit before they reach Watchtower.
affects: >=3.0.1
gotchaCloudWatch log stream naming conventions changed in v3.4.0, specifically removing ':' from `program_name` to prevent issues. Also, `strftime` format strings are explicitly noted as being required for certain configurations. Incorrect stream naming can lead to logs not appearing where expected or creating many unintended log streams.
fix
If customizing log stream names, ensure they comply with CloudWatch naming rules and the expected `strftime` format. For high-volume applications or those using process pools, ensure the log stream name is unique per source using template variables like `{machine_name}/{program_name}/{logger_name}/{process_id}`.
affects: >=3.4.0
gotchaWatchtower uses `boto3`, which in turn relies on `botocore` and `urllib3`. These dependencies can produce a significant amount of `DEBUG` level log messages, which can overwhelm application logs if not properly filtered.
fix
To reduce noise, set the logging level for `boto3`, `botocore`, and `urllib3` to `WARNING` or higher. For example: `logging.getLogger('boto3').setLevel(logging.WARNING)`, `logging.getLogger('botocore').setLevel(logging.WARNING)`, `logging.getLogger('urllib3').setLevel(logging.WARNING)`.
affects: *
gotchaThe process running Watchtower requires appropriate AWS Identity and Access Management (IAM) permissions to call the CloudWatch Logs API (e.g., `logs:CreateLogGroup`, `logs:CreateLogStream`, `logs:PutLogEvents`). Lack of these permissions is a common reason for logs not appearing in CloudWatch.
fix
Attach an AWS managed IAM policy (e.g., `CloudWatchLogsFullAccess` for testing, or a more restrictive custom policy with `logs:CreateLogGroup`, `logs:CreateLogStream`, `logs:PutLogEvents`) to the IAM role or user credentials used by your application. Refer to `boto3` credentials documentation for how credentials are loaded.
affects: *
breakingThe `CloudWatchLogHandler` constructor received an unexpected keyword argument 'region_name'. This argument was introduced in `watchtower` v3.0.0. Using it with older versions (prior to v3.0.0) will result in a `TypeError`.
fix
Upgrade `watchtower` to version 3.0.0 or higher to use the `region_name` argument directly. If upgrading is not an option, configure the AWS region via a `boto3.session.Session` object and pass it using the `session` argument to `CloudWatchLogHandler` (e.g., `CloudWatchLogHandler(session=boto3.Session(region_name='your-region'))`), or ensure the AWS region is configured through environment variables or AWS config files which `boto3` will pick up automatically.
affects: <3.0.0
breakingStarting with Watchtower v3.0.0, the `CloudWatchLogHandler` no longer accepts `region_name` as a direct keyword argument in its constructor. The AWS region must now be configured through environment variables (e.g., `AWS_REGION`), `boto3` configuration, or by providing an initialized `boto3.Session` object via the `boto3_session` argument.
fix
Remove `region_name` from the `CloudWatchLogHandler` constructor. Ensure the AWS region is set via `AWS_REGION` environment variable or provide a `boto3.Session` configured with the desired region using the `boto3_session` argument. For example, `handler = CloudWatchLogHandler(log_group_name='my-group', boto3_session=boto3.Session(region_name='us-east-1'))` or simply rely on `AWS_REGION` environment variable if it's set.
affects: >=3.0.0
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'watchtower'
The 'watchtower' package is not installed in the current Python environment.
fix
pip install watchtower
ImportError: cannot import name 'CloudWatchLogHandler' from 'watchtower'
The class name for the CloudWatch log handler was changed from `CloudWatchLogHandler` to `WatchtowerLogHandler` in library version 0.7.0; this error occurs when using an outdated import statement.
fix
from watchtower import WatchtowerLogHandler
botocore.exceptions.NoCredentialsError: Unable to locate credentials
Boto3, used by Watchtower, cannot find AWS access keys or assume an IAM role, which are necessary to interact with AWS services.
fix
Configure AWS credentials using environment variables (e.g., AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), the shared credentials file (~/.aws/credentials), or an attached IAM role for EC2/ECS/EKS/Lambda.
botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the PutLogEvents operation: User is not authorized to perform: logs:PutLogEvents on resource
The AWS IAM user or role assumed by Watchtower lacks the necessary permissions to write log events to the specified CloudWatch Logs group and stream.
fix
Grant the IAM entity (user/role) permissions for `logs:CreateLogGroup`, `logs:CreateLogStream`, and `logs:PutLogEvents` on the relevant CloudWatch Logs resources.
Upgrade
Version history
3.4.0latest on PyPI · released Feb 25, 2025
Audit
Dependencies
boto3requiredRequired for interacting with AWS CloudWatch Logs API.
Agent activity
46 hits · last 30 days
node
38
Amazon
1
OpenAI (training)
1
Resources
watchtower — pip install watchtower · libregistry