betalabs/laravel-cloudwatch-logs
A Laravel package that sends your application logs to AWS CloudWatch Logs, offering a custom log driver with configurable log groups and streams. Lightweight setup and sensible defaults for centralizing Laravel logs in AWS.
Architecture fit. The package is a narrow, single-purpose adapter: a Laravel logging channel driver that forwards Monolog records to AWS CloudWatch Logs. It slots into the existing config/logging.php channel paradigm rather than introducing a new abstraction, so it fits the framework's extension model cleanly (a service provider registering a driver via LogManager::extend, resolved through the standard stack/single/daily channel configuration). For a TPM, the important framing is that this is infrastructure plumbing, not product capability — adopting it changes where logs land, not what the application does.
Integration feasibility. Low complexity in principle. Requirements are predictable: aws/aws-sdk-php, an IAM principal with logs:CreateLogStream / logs:PutLogEvents / logs:DescribeLogStreams, a pre-created log group, and a region. Credential resolution will follow the SDK's default chain, which means it works with instance profiles, ECS task roles, and IRSA on EKS — but also means misconfiguration fails silently at the logging layer rather than at boot. The main unknowns to verify in a spike: how it derives log stream names (per-day vs. per-host — this materially affects cost and traceability), whether it batches or issues one PutLogEvents per record, and how it handles CloudWatch's per-call limits (10,000 events / 1 MB per request) and the sequence-token requirement.
Technical risk. The dominant risk is supply chain, not code. One star, zero dependents, and a description scoped to a single company's internal ("as needed at pagevamp") requirement are strong signals this is an extracted internal utility rather than a supported open-source project. A single-maintainer package with no downstream consumers has an unquantified bus factor and no community pressure to fix edge cases. Secondary risks: retry/throttling behavior under load (CloudWatch returns 400 ThrottlingException readily; an unretried logging path can either drop records or, worse, block request handling); synchronous network I/O added to the logging path if no queue/async path exists; and unbounded payload behavior that could amplify error-storm traffic into API cost.
Key questions.
Stack fit. Good fit for a conventional Laravel deployment already on AWS with IAM-based credentials — EC2 with instance profiles, ECS with task roles, or EKS with IRSA. It is a poor fit where the platform already ships logs centrally (see alternatives). It assumes the application has direct egress to the CloudWatch Logs endpoint; in a locked-down VPC that means a VPC interface endpoint for logs, which is a real (if modest) cost and network-policy item.
Migration path. Treated correctly, this is a zero-downtime, additive change: add a new cloudwatch channel, add it to the existing stack alongside the current file/stderr channel, verify record parity in the AWS console, then drop the legacy channel from the stack. Keeping both for a defined soak period is the right default — dual-writing is cheap and gives an instant rollback lever. Because Laravel resolves channels lazily, a broken driver degrades to a logged exception in the stack handler rather than taking down the app; that's a safety property worth confirming rather than assuming.
Compatibility. Two axes to pin: Laravel major version (the LogManager::extend contract and Monolog 2→3 migration are both breaking-ish surfaces) and PHP version. The published last-release date of 2026-10-22 is anomalous relative to typical package histories and should be verified against the actual tag list — a date that doesn't reconcile with the repo's commit history is a yellow flag on release hygiene. Pin an exact version and do not allow ^-range drift on an unmaintained package.
Sequencing.
maxbanton/cwh (established Monolog CloudWatch handler), a hand-rolled ~100-line Monolog handler over the AWS SDK, or — the option most TPMs should put on the table first — removing it from the application entirely by using the CloudWatch Agent or FireLens/fluent-bit to ship container stdout. That last option eliminates the dependency, the in-process network call, the IAM surface on the app role, and the supply-chain question in one move.PutLogEvents error metrics and on log-group ingest volume dropping unexpectedly.Maintenance. The honest baseline: plan to own this. With one star and no dependents, upstream is unlikely to absorb fixes; the realistic posture is a shallow internal fork pinned to a specific commit with a named owner. The surface is small enough (a Monolog handler plus a service provider) that forking is genuinely low-cost — which is also the argument that the package's value is modest and its dependency risk is avoidable by writing it oneself.
Support. No vendor, no SLA, no security-advisory channel. That matters most for transitive dependencies: the package pulls aws/aws-sdk-php, which is large and frequently updated with its own security fixes, so we'd own keeping that current regardless. Add it to the SBOM and the dependency-review gate.
Scaling. Two scaling dimensions to model. Volume: cost is per-GB ingested and, if retained beyond the free tier, per-GB stored — error storms that were previously free local disk writes become a variable bill, so CloudWatch Logs spend should be forecast from current log volume times a multiplier, and retention must be set explicitly (never "never expire"). Concurrency: CloudWatch log streams are ordered sequences; with N workers writing to a shared stream name, sequence-token conflicts cause rejections and silently dropped records. This is the most likely production surprise and the single most important behavior to test under load.
Failure modes. Ranked by expected impact:
Ramp-up. Low for an engineer familiar with Laravel logging config; the conceptual load is IAM plus CloudWatch's batching semantics, not the library. Budget roughly half a day for the spike and two to three days for full integration, dual-write verification, IaC, and alerting. The larger organizational task is the decision itself — this package's score of ~20 with 1 star and 0 dependents should be read as "viable reference implementation, unproven dependency." My recommendation as TPM: use it as a design input, not a dependency. Either the platform's existing log-shipping mechanism covers this need, or the ~100 lines it takes to write in-house are cheaper over a two-year horizon than owning an unsupported upstream.
How can I help you explore Laravel packages today?