GithubHelp home page GithubHelp logo

osperlabs / logbeam Goto Github PK

View Code? Open in Web Editor NEW
11.0 4.0 9.0 12 KB

A python logging handler for CloudWatch Logs

License: MIT License

Makefile 4.73% Python 95.27%
python python3 logging logging-library cloudwatch-logs aws cloudwatchlogs-agent

logbeam's Introduction

logbeam - A python logging handler for CloudWatch Logs

A standard Python logging handler using the event batching framework supplied by the awscli-cwlogs package.

Logs are submitted in batches to the CloudWatch API, with configurable limits on the maximum age of messages before a partial batch is transmitted, and maximum batch sizes. These all match the same configuration options you'll find for configuring the cwlogs agent

Installation

pip install logbeam

Usage

Here's an example for setting up your root logging handler for use with logbeam's CloudWatchLogsHandler

import logging
from logbeam import CloudWatchLogsHandler

cw_handler = CloudWatchLogsHandler(
    log_group_name='my_log_group',
    log_stream_name='my_log_stream',
    buffer_duration=10000,
    batch_count=10,
    batch_size=1048576
)

# If you use the root logger instead of __name__ you will need to turn off
# propagation for loggers 'cwlogs' and 'botocore' or a cycle of logs about
# log message delivery will be created, causing the log handler never to
# exit and your program to hang.
logger = logging.getLogger(__name__)

logger.setLevel(logging.INFO)
logger.addHandler(cw_handler)

logger.info("Hello world!")

Warning: As mentioned in the snippet above, if you attach the handler to the root logger (logging.getLogger()) you need to disable propagation for the cwlogs and botocore loggers to prevent an infinite loop of logs. The following example sends logs from these loggers to stderr instead:

local_handler = logging.StreamHandler()

for logger_name in ('cwlogs', 'botocore'):
    lg = logging.getLogger(logger_name)

    # Don't propagate to the root handler if it has a CloudWatchLogsHandler
    lg.propagate = False

    # Write logs to stderr instead
    lg.addHandler(local_handler)

Handler arguments

The CloudWatchLogsHandler can be initialised with the following args

  • log_group_name - the destination CloudWatch log group name
  • log_stream_name - the destination CloudWatch log stream name
  • buffer_duration - (default 10000) maximum age in ms of the oldest log item in a batch before the batch must be transmitted to CloudWatch.
  • batch_count- (default 10000) maximum number of log items in a batch before the batch must be transmitted to CloudWatch.
  • batch_size - (default 1024*1024) maximum size in bytes a batch of logs can reach before being transmitted to CloudWatch.
  • logs_client - (optional) an initialised boto3 CloudWatchLogs.Client. if this isn't supplied the handler will initialise its own.

IAM Permissions

Here is the minimum IAM policy required for logbeam

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:DescribeLogStreams"
            ],
            "Resource": [
                "arn:aws:logs:<region>:<account_id>:log-group:<log_group>:log-stream:"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:<region>:<account_id>:log-group:<log_group>:log-stream:<log_stream>"
            ]
        }
    ]
}

A word on batch settings

Log records are buffered in memory for a short while before being sent to CloudWatch, meaning there is a small chance of losing log records in the event of some kind of apocalypse (e.g. unexpected process termination).

Under normal conditions the shutdown of the Python logging system when the process exits will instruct the CloudWatch threads created by the handler to flush their buffers and wait for them to exit.

If the process is forcefully terminated (e.g. SIGKILL) any logs that are in the buffer and haven't been transmitted to CloudWatch yet will be lost. For this reason it is sensible to configure the buffer_duration to be relatively short.

The buffer size (in bytes) and length (number of items) should not be set too low, because of the CloudWatch Logs API limit of a maximum 5 PutLogEvents calls per second for a log stream. If these values are too low and you are emitting lots of log items each batch will queue up behind the last one for 0.2 seconds.

logbeam's People

Contributors

hamstah avatar nickrw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

logbeam's Issues

Upgrade to latest awscli

logbeam currently uses awscli-1.9.8. I removed awscli and installed the latest version (1.14.30). logbeam worked fine but perhaps there are issues that I am not aware of.

Resource Not Found Exception got

I have following code :

import logging from logbeam import CloudWatchLogsHandler cw_handler = CloudWatchLogsHandler( log_group_name='my_log_group', log_stream_name='my_log_stream', buffer_duration=10000, batch_count=10, batch_size=1048576 )

Caught exception: An error occurred (ResourceNotFoundException) when calling the PutLogEvents operation: The specified log group does not exist.

Too small batch_count may lead to excessive memory usage

The default configuration of logbeam that is passed to cwlogs is the following:

buffer_duration = 10000
batch_count = 10
batch_size = 1024 * 1024

Default AWS's configuration is:
buffer_duration = 5000
batch_count = 1000
batch_size = 32768

logbeam sets maximum batch_size but sets batch_count too low which may lead (and does in our case) to slow log queue processing and excessive memory usage. It may be beneficial to set default batch_count to at least 1000.

ImportError: cannot import name 'CloudWatchLogsHandler'

I have installed the latest logbeam 1.0.1.

pip3.6 install logbeam --user

I tried to run the sample code mentioned on the pypi repo, However, I am getting import error.

I am running the sample code as python3.6 testlogbeam.py

When unable to connect to AWS Cloudwatch, AttributeError: 'CloudWatchLogsHandler' object has no attribute 'sink' when shutting down logbeam handler

If you create a logbeam logging handler on a machine that has no Internet access, an error like the following occurs while the application closes:

Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.6.4_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"main", mod_spec)
File "/usr/local/Cellar/python3/3.6.4_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/terris/science37/edc-export-service/edcexport/main.py", line 16, in
EDCExportService().start()
File "/Users/terris/science37/edc-export-service/edcexport/edcexport.py", line 75, in start
loop.run_forever()
File "/usr/local/Cellar/python3/3.6.4_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 421, in run_forever
self._run_once()
File "/usr/local/Cellar/python3/3.6.4_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 1395, in _run_once
event_list = self._selector.select(timeout)
File "/usr/local/Cellar/python3/3.6.4_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/selectors.py", line 577, in select
kev_list = self._kqueue.control(None, max_ev, timeout)
KeyboardInterrupt
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.6.4_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/logging/init.py", line 1944, in shutdown
h.close()
File "/Users/terris/venv/edc/lib/python3.6/site-packages/logbeam/init.py", line 160, in close
self.sink.shutdown()
AttributeError: 'CloudWatchLogsHandler' object has no attribute 'sink'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.