{"id":26233610,"url":"https://github.com/phpnexus/cwh","last_synced_at":"2025-04-22T12:10:46.894Z","repository":{"id":164485124,"uuid":"639942687","full_name":"phpnexus/cwh","owner":"phpnexus","description":"Amazon Web Services CloudWatch Logs Handler for Monolog library","archived":false,"fork":false,"pushed_at":"2024-08-02T10:17:06.000Z","size":168,"stargazers_count":29,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T15:01:37.610Z","etag":null,"topics":["aws","cloudwatch","monolog","php","php8"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"maxbanton/cwh","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phpnexus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-12T15:24:12.000Z","updated_at":"2025-03-17T14:30:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"b1cd2e27-1a3a-497f-ae79-9abd8a7c67e8","html_url":"https://github.com/phpnexus/cwh","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpnexus%2Fcwh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpnexus%2Fcwh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpnexus%2Fcwh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpnexus%2Fcwh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phpnexus","download_url":"https://codeload.github.com/phpnexus/cwh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250237832,"owners_count":21397401,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","cloudwatch","monolog","php","php8"],"created_at":"2025-03-13T01:16:42.188Z","updated_at":"2025-04-22T12:10:46.864Z","avatar_url":"https://github.com/phpnexus.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AWS CloudWatch Logs Handler for Monolog\n\n[![Actions Status](https://github.com/phpnexus/cwh/workflows/Pipeline/badge.svg)](https://github.com/phpnexus/cwh/actions)\n[![Coverage Status](https://img.shields.io/coveralls/phpnexus/cwh/master.svg)](https://coveralls.io/github/phpnexus/cwh?branch=master)\n[![License](https://img.shields.io/packagist/l/phpnexus/cwh.svg)](https://github.com/phpnexus/cwh/blob/master/LICENSE)\n[![Version](https://img.shields.io/packagist/v/phpnexus/cwh.svg)](https://packagist.org/packages/phpnexus/cwh)\n[![Downloads](https://img.shields.io/packagist/dt/phpnexus/cwh.svg)](https://packagist.org/packages/phpnexus/cwh/stats)\n\n***This is a fork and continuation of the original [maxbanton/cwh](https://github.com/maxbanton/cwh) repository.***\n\nHandler for PHP logging library [Monolog](https://github.com/Seldaek/monolog) for sending log entries to\n[AWS CloudWatch Logs](http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html) service.\n\nBefore using this library, it's recommended to get acquainted with the [pricing](https://aws.amazon.com/en/cloudwatch/pricing/) for AWS CloudWatch services.\n\nPlease press **\u0026#9733; Star** button if you find this library useful.\n\n## Disclaimer\nThis library uses AWS API through AWS PHP SDK, which has limits on concurrent requests. It means that on high concurrent or high load applications it may not work on it's best way. Please consider using another solution such as logging to the stdout and redirecting logs with fluentd.\n\n## Requirements\n* PHP \u003e=8.1\n* AWS account with proper permissions (see list of permissions below)\n\n## Features\n* Up to 10000 batch logs sending in order to avoid _Rate exceeded_ errors\n* Log Groups creating with tags\n* AWS CloudWatch Logs staff lazy loading\n* Suitable for web applications and for long-living CLI daemons and workers\n* **New!** Configurable rate limit, useful with small batch sizes on long-living CLI daemons and workers\n\n## Installation\nInstall the latest version with [Composer](https://getcomposer.org/) by running\n\n```bash\n$ composer require phpnexus/cwh:^3.0\n```\n\n## Basic Usage\n```php\n\u003c?php\n\nuse Aws\\CloudWatchLogs\\CloudWatchLogsClient;\nuse Monolog\\Logger;\nuse Monolog\\Level;\nuse Monolog\\Formatter\\JsonFormatter;\nuse PhpNexus\\Cwh\\Handler\\CloudWatch;\n\n$sdkParams = [\n    'region' =\u003e 'eu-west-1',\n    'version' =\u003e 'latest',\n    'credentials' =\u003e [\n        'key' =\u003e 'your AWS key',\n        'secret' =\u003e 'your AWS secret',\n        'token' =\u003e 'your AWS session token', // token is optional\n    ]\n];\n\n// Instantiate AWS SDK CloudWatch Logs Client\n$client = new CloudWatchLogsClient($sdkParams);\n\n// Log group name, will be created if none\n$groupName = 'php-logtest';\n\n// Log stream name, will be created if none\n$streamName = 'ec2-instance-1';\n\n// Days to keep logs, 14 by default. Set to `null` to allow indefinite retention.\n$retentionDays = 30;\n\n// Instantiate handler (tags are optional)\n$handler = new CloudWatch($client, $groupName, $streamName, $retentionDays, 10000, ['my-awesome-tag' =\u003e 'tag-value'], Level::Info);\n\n// Optionally set the JsonFormatter to be able to access your log messages in a structured way\n$handler-\u003esetFormatter(new JsonFormatter());\n\n// Create a log channel\n$log = new Logger('name');\n\n// Set handler\n$log-\u003epushHandler($handler);\n\n// Add records to the log\n$log-\u003edebug('Foo');\n$log-\u003ewarning('Bar');\n$log-\u003eerror('Baz');\n```\n\n## Advanced Usage\n### Prevent automatic creation of log groups and streams\nThe default behavior is to check if the destination log group and log stream exists and create the log group and log stream if necessary.\n\nThis activity always sends a `DescribeLogGroups` and `DescribeLogStreams` API call to AWS, and will send a `CreateLogGroup` API call or `CreateLogStream` API call to AWS if the log group or log stream doesn't exist.\n\nAWS have a default quota of [10 requests per second](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html) for `DescribeLogGroups` and [25 requests per second](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html) `DescribeLogStreams` per region per account, which will become a bottleneck even in medium traffic environments.\n\nBy setting `$createGroup` and `$createStream` to `false`, this library will not automatically create the destination log group or log stream, and hence will not send any `DescribeLogGroups` or `DescribeLogStreams` API calls to AWS.\n\n```php\n\u003c?php\n\nuse Aws\\CloudWatchLogs\\CloudWatchLogsClient;\nuse Monolog\\Logger;\nuse Monolog\\Level;\nuse Monolog\\Formatter\\JsonFormatter;\nuse PhpNexus\\Cwh\\Handler\\CloudWatch;\n\n$sdkParams = [\n    'region' =\u003e 'ap-northeast-1',\n    'version' =\u003e 'latest',\n    'credentials' =\u003e [\n        'key' =\u003e 'your AWS key',\n        'secret' =\u003e 'your AWS secret',\n        'token' =\u003e 'your AWS session token', // token is optional\n    ]\n];\n\n// Instantiate AWS SDK CloudWatch Logs Client\n$client = new CloudWatchLogsClient($sdkParams);\n\n// Log group name (must exist already)\n$groupName = 'php-logtest';\n\n// Log stream name (must exist already)\n$streamName = 'ec2-instance-1';\n\n// Instantiate handler\n$handler = new CloudWatch($client, $groupName, $streamName, level: Level::Info, createGroup: false, createStream: false);\n\n// Optionally set the JsonFormatter to be able to access your log messages in a structured way\n$handler-\u003esetFormatter(new JsonFormatter());\n\n// Create a log channel\n$log = new Logger('name');\n\n// Set handler\n$log-\u003epushHandler($handler);\n\n// Add records to the log\n$log-\u003edebug('Foo');\n$log-\u003ewarning('Bar');\n$log-\u003eerror('Baz');\n```\n\n### **New!** Rate limiting\nThe default behavior is to send logs in batches of 10000, or when the script terminates. This is appropriate for short-lived requests, but not for long-lived CLI daemons and workers.\n\nFor these cases, a smaller `$batchSize` of 1 would be more appropriate. However, with a smaller batch size the number of `putLogEvents` requests to AWS will increase and may reach the [per account per region limit](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html).\n\nTo help avoid this rate limit, use the `$rpsLimit` option to limit the number of requests per second that your CLI daemon or worker can send.\n\n*Note: This limit is only applicable for one instance of a CLI daemon or worker. With multiple instances, adjust the `$rpsLimit` accordingly.*\n\n```php\n\u003c?php\n\nuse Aws\\CloudWatchLogs\\CloudWatchLogsClient;\nuse Monolog\\Logger;\nuse Monolog\\Level;\nuse Monolog\\Formatter\\JsonFormatter;\nuse PhpNexus\\Cwh\\Handler\\CloudWatch;\n\n$sdkParams = [\n    'region' =\u003e 'ap-northeast-1',\n    'version' =\u003e 'latest',\n    'credentials' =\u003e [\n        'key' =\u003e 'your AWS key',\n        'secret' =\u003e 'your AWS secret',\n        'token' =\u003e 'your AWS session token', // token is optional\n    ]\n];\n\n// Instantiate AWS SDK CloudWatch Logs Client\n$client = new CloudWatchLogsClient($sdkParams);\n\n// Log group name, will be created if none\n$groupName = 'php-logtest';\n\n// Log stream name, will be created if none\n$streamName = 'cli-worker';\n\n// Instantiate handler\n$handler = new CloudWatch($client, $groupName, $streamName, batchSize: 1, level: Level::Info, rpsLimit: 100);\n\n// Optionally set the JsonFormatter to be able to access your log messages in a structured way\n$handler-\u003esetFormatter(new JsonFormatter());\n\n// Create a log channel\n$log = new Logger('name');\n\n// Set handler\n$log-\u003epushHandler($handler);\n\n// Add lots of records to the log very quickly\n$i = 0;\ndo {\n    $log-\u003einfo('Foo');\n} while ($i++ \u003c 500);\n```\n\n## Frameworks integration\n - [Silex](http://silex.sensiolabs.org/doc/master/providers/monolog.html#customization)\n - [Symfony](http://symfony.com/doc/current/logging.html) ([Example](https://github.com/maxbanton/cwh/issues/10#issuecomment-296173601))\n - [Lumen](https://lumen.laravel.com/docs/5.2/errors)\n - [Laravel](https://laravel.com/docs/5.4/errors) ([Example](https://stackoverflow.com/a/51790656/1856778))\n\n [And many others](https://github.com/Seldaek/monolog#framework-integrations)\n\n## AWS IAM needed permissions\nIf you prefer to use a separate programmatic IAM user (recommended) or want to define a policy, you will need the following permissions depending on your configuration.\n\nAlways required:\n1. `PutLogEvents` [aws docs](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html)\n\nIf `$createGroup` is `true` (default):\n1. `DescribeLogGroups` [aws docs](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogGroups.html)\n1. `CreateLogGroup` [aws docs](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html)\n1. `PutRetentionPolicy` [aws docs](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutRetentionPolicy.html)\n\nIf `$createStream` is `true` (default):\n1. `CreateLogStream` [aws docs](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogStream.html)\n1. `DescribeLogStreams` [aws docs](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogStreams.html)\n\n*Note: The below samples include permissions to create log groups and streams. Remove the \"AllowCreateLogGroup\" statement when setting the `$createGroup` argument to `false`. Remove the \"AllowCreateLogStream\" statement when setting the `$createStream` argument to `false`.*\n\n### Sample 1: Write to any log stream in any log group\nThis policy example allows writing to any log stream in a log group (named `my-app`). The log streams will be created automatically.\n\n```json\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"AllowCreateLogGroup\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"logs:CreateLogGroup\",\n                \"logs:DescribeLogGroups\",\n                \"logs:PutRetentionPolicy\"\n            ],\n            \"Resource\": \"arn:aws:logs:*:*:log-group:*\"\n        },\n        {\n            \"Sid\": \"AllowCreateLogStream\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"logs:CreateLogStream\",\n                \"logs:DescribeLogStreams\"\n            ],\n            \"Resource\": \"arn:aws:logs:*:*:log-group:*:*\"\n        },\n        {\n            \"Sid\": \"AllowPutLogEvents\",\n            \"Effect\": \"Allow\",\n            \"Action\": \"logs:PutLogEvents\",\n            \"Resource\": \"arn:aws:logs:*:*:log-group:*:*\"\n        }\n    ]\n}\n```\n\n### Sample 2: Write to any log stream in a log group\nThis policy example allows writing to any log stream in a log group (named `my-app`). The log streams will be created automatically.\n\n```json\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"AllowCreateLogGroup\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"logs:CreateLogGroup\",\n                \"logs:DescribeLogGroups\",\n                \"logs:PutRetentionPolicy\"\n            ],\n            \"Resource\": \"arn:aws:logs:*:*:log-group:*\"\n        },\n        {\n            \"Sid\": \"AllowCreateLogStream\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"logs:CreateLogStream\",\n                \"logs:DescribeLogStreams\"\n            ],\n            \"Resource\": \"arn:aws:logs:*:*:log-group:my-app:*\"\n        },\n        {\n            \"Sid\": \"AllowPutLogEvents\",\n            \"Effect\": \"Allow\",\n            \"Action\": \"logs:PutLogEvents\",\n            \"Resource\": \"arn:aws:logs:*:*:log-group:my-app:*\"\n        }\n    ]\n}\n```\n\n### Sample 3: Write to specific log streams in a log group\nThis policy example allows writing to specific log streams (named `my-stream-1` and `my-stream-2`) in a log group (named `my-app`).\n\n```json\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"AllowCreateLogGroup\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"logs:CreateLogGroup\",\n                \"logs:DescribeLogGroups\",\n                \"logs:PutRetentionPolicy\"\n            ],\n            \"Resource\": \"arn:aws:logs:*:*:log-group:*\"\n        },\n        {\n            \"Sid\": \"AllowCreateLogStream\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"logs:CreateLogStream\",\n                \"logs:DescribeLogStreams\"\n            ],\n            \"Resource\": \"arn:aws:logs:*:*:log-group:my-app:*\"\n        },\n        {\n            \"Sid\": \"AllowPutLogEvents\",\n            \"Effect\": \"Allow\",\n            \"Action\": \"logs:PutLogEvents\",\n            \"Resource\": [\n                \"arn:aws:logs:*:*:log-group:my-app:log-stream:my-stream-1\",\n                \"arn:aws:logs:*:*:log-group:my-app:log-stream:my-stream-2\",\n            ]\n        }\n    ]\n}\n```\n\nReference: [Actions, resources, and condition keys for Amazon CloudWatch Logs](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazoncloudwatchlogs.html)\n\n## Issues\nFeel free to [report any issues](https://github.com/phpnexus/cwh/issues/new)\n\n## Contributing\nPlease check [this document](https://github.com/phpnexus/cwh/blob/master/CONTRIBUTING.md)\n\n___\n\nMade in Ukraine 🇺🇦\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpnexus%2Fcwh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphpnexus%2Fcwh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpnexus%2Fcwh/lists"}