PHPackages                             adminintelligence/laravel-log-shipper - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. adminintelligence/laravel-log-shipper

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

adminintelligence/laravel-log-shipper
=====================================

Ships your Laravel logs to a central server. Because local problems deserve global visibility.

v1.3.0(2mo ago)0130↓100%MITPHPPHP ^8.1CI passing

Since Dec 9Pushed 2mo agoCompare

[ Source](https://github.com/ADMIN-INTELLIGENCE-GmbH/laravel-log-shipper)[ Packagist](https://packagist.org/packages/adminintelligence/laravel-log-shipper)[ Docs](https://github.com/ADMIN-INTELLIGENCE-GmbH/laravel-log-shipper)[ RSS](/packages/adminintelligence-laravel-log-shipper/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (8)Versions (8)Used By (0)

Laravel Log Shipper
===================

[](#laravel-log-shipper)

[![Tests](https://github.com/ADMIN-INTELLIGENCE-GmbH/laravel-log-shipper/actions/workflows/tests.yml/badge.svg)](https://github.com/ADMIN-INTELLIGENCE-GmbH/laravel-log-shipper/actions/workflows/tests.yml)[![Latest Version on Packagist](https://camo.githubusercontent.com/e26e7fc036e6692602eae3a894da8049ecb689a097cf9263b0486665b7ad0490/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f61646d696e696e74656c6c6967656e63652f6c61726176656c2d6c6f672d736869707065722e737667)](https://packagist.org/packages/adminintelligence/laravel-log-shipper)[![License](https://camo.githubusercontent.com/b7428a4386df8442c738aa22bfc9677367b52061fd2cfb703542e05fe7e67e65/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f61646d696e696e74656c6c6967656e63652f6c61726176656c2d6c6f672d736869707065722e737667)](https://packagist.org/packages/adminintelligence/laravel-log-shipper)

A Laravel package that ships your application logs to a central server.

Companion Service: Logger
-------------------------

[](#companion-service-logger)

This package is designed to work with [**Logger**](https://github.com/ADMIN-INTELLIGENCE-GmbH/logger) — a centralized log aggregation service built with Laravel.

**Logger provides:**

- **Web Dashboard** — Search, filter, and browse logs with pagination
- **Multi-Project Support** — Manage logs from multiple applications with isolated project keys
- **Failing Controllers Report** — Identify error hotspots by controller
- **Retention Policies** — Configurable per-project log retention (7, 14, 30, 90 days, or infinite)
- **Webhook Notifications** — Slack/Discord/Mattermost-compatible alerts for errors and critical events
- **Dark Mode** — Full dark theme support

> **Note:** You can also use this package with any HTTP endpoint that accepts JSON log payloads.

Requirements
------------

[](#requirements)

- PHP 8.1 or higher
- Laravel 10, 11, or 12
- A queue driver (recommended: Redis, database, or SQS)

Installation
------------

[](#installation)

```
composer require adminintelligence/laravel-log-shipper
```

Configuration
-------------

[](#configuration)

Publish the configuration file:

```
php artisan vendor:publish --tag=log-shipper-config
```

Add the following to your `.env` file:

```
LOG_SHIPPER_ENABLED=true
LOG_SHIPPER_ENDPOINT=https://your-log-server.com/api/ingest
LOG_SHIPPER_KEY=your-project-api-key
LOG_SHIPPER_QUEUE=redis
LOG_SHIPPER_QUEUE_NAME=logs

```

### Upgrading Configuration

[](#upgrading-configuration)

If you're upgrading from a previous version and want to use the new features (IP obfuscation, enhanced status metrics, etc.), republish the configuration file:

```
php artisan vendor:publish --tag=log-shipper-config --force
```

> **⚠️ Warning:** This will overwrite your existing `config/log-shipper.php` file. Make sure to back up any custom configurations first, or manually merge the new options from the [published config](https://github.com/ADMIN-INTELLIGENCE-GmbH/laravel-log-shipper/blob/main/config/log-shipper.php).

**New configuration options in recent versions:**

- `ip_obfuscation` - Privacy-compliant IP address obfuscation
- `max_payload_size` - Payload size limiting for security
- `status.metrics.foldersize` - Folder size monitoring
- `status.metrics.node_npm` - Node.js and npm version detection
- `status.metrics.dependency_checks` - Outdated package detection
- `status.metrics.security_audits` - Security vulnerability scanning
- `status.monitored_folders` - Folders to monitor for size metrics

Usage
-----

[](#usage)

Add the log shipper channel to your `config/logging.php`:

```
'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['daily', 'log_shipper'],
        'ignore_exceptions' => false,
    ],

    'log_shipper' => [
        'driver' => 'custom',
        'via' => \AdminIntelligence\LogShipper\Logging\CreateCustomLogger::class,
        'level' => 'error', // Only ship errors and above
    ],

    // ... other channels
],
```

Now any log at the configured level or above will be shipped to your central server:

```
Log::error('Something went wrong', ['order_id' => 123]);
```

Configuration Options
---------------------

[](#configuration-options)

OptionDescriptionDefault`enabled`Enable/disable log shipping`true``api_endpoint`The URL of your log server-`api_key`Your project's API key-`queue_connection`Queue connection to use`default``queue_name`Queue name for log jobs`default``retries`Number of attempts before failing`3``backoff`Wait time between retries (seconds)`[2, 5, 10]``circuit_breaker`Circuit breaker configuration`enabled``fallback_channel`Local channel to use if shipping fails`null``ip_obfuscation`IP address obfuscation settings`disabled``max_payload_size`Max payload size in bytes`1048576``sanitize_fields`Fields to redact from logsSee config`send_context`Context data to includeSee configLog Payload
-----------

[](#log-payload)

When a log event is shipped, the following data is sent:

### Core Log Data (Always Sent)

[](#core-log-data-always-sent)

FieldTypeDescription`level`stringLog level (error, warning, info, debug, etc.)`message`stringThe log message`context`arrayAny context array passed to the log call`datetime`stringTimestamp in `Y-m-d H:i:s.u` format`channel`stringThe logging channel name`extra`arrayAdditional Monolog processor data### Optional Context Data

[](#optional-context-data)

These fields can be toggled via the `send_context` configuration:

FieldTypeDefaultDescription`user_id`int|nullenabledAuthenticated user's ID`ip_address`string|nullenabledClient IP address`user_agent`string|nullenabledBrowser/client user agent string`request_method`string|nullenabledHTTP method (GET, POST, PUT, DELETE, etc.)`request_url`string|nullenabledFull request URL including query string`route_name`string|nullenabledLaravel route name`controller_action`string|nullenabledController and action handling the request`app_env`string|nullenabledApplication environment (local, staging, production)`app_debug`bool|nullenabledWhether debug mode is enabled`referrer`string|nullenabledHTTP Referer headerTo disable specific context fields, update your `config/log-shipper.php`:

```
'send_context' => [
    'user_id' => true,
    'ip_address' => true,
    'user_agent' => false, // disabled
    // ...
],
```

### Example Log Payload

[](#example-log-payload)

Here is an example of the JSON payload sent for a log event:

```
{
    "level": "error",
    "message": "Order processing failed",
    "context": {
        "order_id": 12345,
        "reason": "Payment declined"
    },
    "datetime": "2025-12-11 14:30:45.123456",
    "channel": "local",
    "extra": {},
    "user_id": "1",
    "ip_address": "127.0.0.1",
    "user_agent": "Mozilla/5.0...",
    "request_method": "POST",
    "request_url": "https://api.example.com/orders",
    "route_name": "orders.store",
    "controller_action": "App\\Http\\Controllers\\OrderController@store",
    "app_env": "production",
    "app_debug": false
}
```

Status Monitoring
-----------------

[](#status-monitoring)

The package can automatically push system health metrics to your log server on a configurable interval. This helps you monitor the health of your application instances.

### Enable Status Push

[](#enable-status-push)

Add the following to your `.env` file:

```
LOG_SHIPPER_STATUS_ENABLED=true
LOG_SHIPPER_STATUS_ENDPOINT=https://your-log-server.com/api/stats
LOG_SHIPPER_STATUS_INTERVAL=5 # minutes (default: 5)
```

You can also configure the disk path to monitor:

```
LOG_SHIPPER_DISK_PATH=/
```

#### Interval Configuration

[](#interval-configuration)

The `LOG_SHIPPER_STATUS_INTERVAL` setting supports flexible scheduling:

IntervalBehaviorExample1-59Every N minutes`5` = Every 5 minutes60-1439Every N hours`120` = Every 2 hours, `180` = Every 3 hours1440+Daily`1440` = Daily at midnightThe scheduler automatically selects the appropriate cron expression based on your interval value.

### Collected Metrics

[](#collected-metrics)

> **Note:** Status pushing relies on Laravel's scheduler. Ensure you have the scheduler running: `* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1`

### Example Status Payload

[](#example-status-payload)

Here is an example of the JSON payload sent for a status update:

```
{
    "timestamp": "2025-12-18T16:53:12+00:00",
    "app_name": "ticket",
    "app_env": "local",
    "app_debug": true,
    "instance_id": "Boxxy",
    "log_shipper_version": "1.3.0",
    "system": {
        "memory_usage": 33554432,
        "memory_peak": 33554432,
        "server_memory": {
            "total": 26841100288,
            "free": 23864168448,
            "used": 2976931840,
            "percent_used": 11.09
        },
        "cpu_usage": 0.18,
        "php_version": "8.4.15",
        "laravel_version": "12.42.0",
        "uptime": 25162,
        "disk_space": {
            "total": 269490393088,
            "free": 239698132992,
            "used": 29792260096,
            "percent_used": 11.06,
            "disks": [
                {
                    "path": "/",
                    "total": 269490393088,
                    "free": 239698132992,
                    "used": 29792260096,
                    "percent_used": 11.06
                },
                {
                    "path": "/boot/efi",
                    "total": 536870912,
                    "free": 499122176,
                    "used": 37748736,
                    "percent_used": 7.03
                }
            ]
        },
        "node_version": "v24.11.1",
        "npm_version": "11.6.2",
        "composer_outdated": 6,
        "npm_outdated": 9,
        "composer_audit": 0,
        "npm_audit": 0
    },
    "queue": {
        "error": "Could not fetch queue metrics"
    },
    "database": {
        "status": "connected",
        "latency_ms": 8.51
    },
    "cache": [],
    "filesize": [],
    "foldersize": {
        "upload": -1,
        "cache": 523732,
        "email-assets": -1
    }
}
```

### System Metrics Details

[](#system-metrics-details)

The status payload includes the following system metrics:

#### Core Status Data

[](#core-status-data)

FieldTypeDescription`timestamp`stringISO-8601 timestamp of the report`app_name`stringApplication name from `config('app.name')``app_env`stringApplication environment (local, production, etc.)`app_debug`boolWhether debug mode is enabled`instance_id`stringHostname of the server`log_shipper_version`stringVersion of the log shipper package#### System Object

[](#system-object)

FieldTypeDescription`memory_usage`intCurrent memory usage of the PHP process (bytes)`memory_peak`intPeak memory usage of the PHP process (bytes)`server_memory`objectServer-level RAM metrics (see below)`cpu_usage`float|nullCPU usage percentage or load average`php_version`stringPHP version`laravel_version`stringLaravel framework version`uptime`int|nullSystem uptime in seconds (null if unavailable)`disk_space`objectPrimary disk metrics + `disks` array of all mounted filesystems`node_version`string|nullNode.js version (if enabled)`npm_version`string|nullnpm version (if enabled)`composer_outdated`intCount of outdated Composer packages (if enabled)`npm_outdated`intCount of outdated npm packages (if enabled)`composer_audit`intCount of Composer security advisories (if enabled)`npm_audit`intCount of npm security vulnerabilities (if enabled)#### Server Memory Object

[](#server-memory-object)

FieldTypeDescription`total`int|nullTotal system RAM (bytes)`free`int|nullAvailable system RAM (bytes)`used`int|nullUsed system RAM (bytes)`percent_used`float|nullPercentage of RAM in use> **Note on macOS:** The `percent_used` includes filesystem cache. This is normal macOS behavior and does not indicate memory pressure.

#### Disk Space Object

[](#disk-space-object)

FieldTypeDescription`total`int|nullTotal size of the primary disk (bytes)`free`int|nullFree space on the primary disk (bytes)`used`int|nullUsed space on the primary disk (bytes)`percent_used`float|nullPercentage of primary disk in use`disks`arrayOne entry per mounted filesystem (see below)Each entry in `disks` contains:

FieldTypeDescription`path`stringMount point (e.g. `/`, `/boot/efi`, `C:`)`total`floatTotal size of the filesystem (bytes)`free`floatFree space on the filesystem (bytes)`used`floatUsed space on the filesystem (bytes)`percent_used`floatPercentage of the filesystem in use#### Queue Object

[](#queue-object)

- **Size**: Queue jobs count (excluding the status job itself)
- **Connection**: Active queue connection

#### Database Object

[](#database-object)

- **Status**: Connection status (`connected` or `disconnected`)
- **Latency**: Query latency in milliseconds

#### Cache Object

[](#cache-object)

- **Driver**: Active cache driver

#### Filesize Object

[](#filesize-object)

- **Files**: Sizes of specific monitored files (configurable)

#### Foldersize Object

[](#foldersize-object)

- **Folders**: Total sizes of specific monitored folders, including all nested files (configurable)

To configure which metrics are sent or to monitor specific files/folders, publish the config and update the `status` section:

```
'status' => [
    'metrics' => [
        'system' => true,
        'queue' => true,
        'database' => true,
        'cache' => false,
        'filesize' => true,
        'foldersize' => true,

        // Optional expensive metrics (disabled by default)
        'node_npm' => false,              // Node.js and npm versions
        'dependency_checks' => false,     // Outdated package counts
        'security_audits' => false,       // Security vulnerability counts
    ],

    'monitored_files' => [
        storage_path('logs/laravel.log'),
        storage_path('logs/worker.log'),
    ],

    'monitored_folders' => [
        storage_path('logs'),
        storage_path('app/cache'),
    ],
],
```

> **Performance Note:** The optional metrics (`node_npm`, `dependency_checks`, `security_audits`) can be slow as they execute shell commands. Enable these only if you need them and have increased the job timeout accordingly (default: 120 seconds).

> **Note:** Status pushing relies on Laravel's scheduler. Ensure you have the scheduler running: `* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1`

Data Sanitization
-----------------

[](#data-sanitization)

The package automatically redacts sensitive fields from your logs. The following field patterns are redacted by default:

Field PatternExamples`password`password, user\_password, password\_hash`password_confirmation`password\_confirmation`credit_card`credit\_card, credit\_card\_number`card_number`card\_number`cvv`cvv, card\_cvv`api_key`api\_key, stripe\_api\_key`secret`secret, client\_secret`token`token, access\_token, refresh\_token`authorization`authorizationAdd additional fields to sanitize in the config file:

```
'sanitize_fields' => [
    'password',
    'credit_card',
    'ssn', // add your own
    // ...
],
```

IP Address Obfuscation
----------------------

[](#ip-address-obfuscation)

For privacy compliance (GDPR, CCPA), you can enable IP address obfuscation to anonymize client IP addresses before they are logged.

### Enable IP Obfuscation

[](#enable-ip-obfuscation)

Add the following to your `.env` file:

```
LOG_SHIPPER_IP_OBFUSCATION_ENABLED=true
LOG_SHIPPER_IP_OBFUSCATION_METHOD=mask # or 'hash'
```

### Obfuscation Methods

[](#obfuscation-methods)

#### Mask (Default)

[](#mask-default)

Zeroes out the last octet of IPv4 addresses and the last 64 bits of IPv6 addresses:

- **IPv4:** `192.168.1.100` → `192.168.1.0`
- **IPv6:** `2001:db8:85a3::8a2e:370:7334` → `2001:db8:85a3::`

This method preserves geographic information while protecting individual privacy.

#### Hash

[](#hash)

Generates a one-way hash of the IP address:

- **IPv4:** `192.168.1.100` → `ip_a3f5c8e91d2b4f67`
- **IPv6:** `2001:db8:85a3::8a2e:370:7334` → `ip_b9e4d1c72a8f3e56`

This method provides maximum privacy while maintaining consistency (the same IP always produces the same hash).

### Configuration

[](#configuration-1)

```
// config/log-shipper.php
'ip_obfuscation' => [
    'enabled' => env('LOG_SHIPPER_IP_OBFUSCATION_ENABLED', false),
    'method' => env('LOG_SHIPPER_IP_OBFUSCATION_METHOD', 'mask'), // 'mask' or 'hash'
],
```

Security Features
-----------------

[](#security-features)

### HTTPS Enforcement

[](#https-enforcement)

In production environments, the package **automatically enforces HTTPS** for the API endpoint. HTTP endpoints will be rejected to prevent credential leaks.

```
# Accepted in production
LOG_SHIPPER_ENDPOINT=https://secure.example.com/api/ingest

# Rejected in production (only allowed in local/staging/testing)
LOG_SHIPPER_ENDPOINT=http://insecure.example.com/api/ingest
```

### Payload Size Limits

[](#payload-size-limits)

To prevent denial-of-service attacks via oversized log payloads, the package limits the maximum payload size:

```
// config/log-shipper.php
'max_payload_size' => env('LOG_SHIPPER_MAX_PAYLOAD_SIZE', 1048576), // 1MB default
```

If a payload exceeds this limit, the context will be truncated and marked with `_truncated: true`.

Sync Mode
---------

[](#sync-mode)

By default, logs are shipped via queued jobs for better performance. If you prefer synchronous shipping (useful for debugging or simple setups), set:

```
LOG_SHIPPER_QUEUE=sync
```

> **Note:** Sync mode will block your application until the HTTP request completes. Use queued mode in production for better performance.

Batch Shipping
--------------

[](#batch-shipping)

For high-traffic applications, dispatching a job for every log event can create significant queue pressure. You can enable batch shipping to buffer logs in Redis and ship them in chunks.

### Enable Batch Shipping

[](#enable-batch-shipping)

Add the following to your `.env` file:

```
LOG_SHIPPER_BATCH_ENABLED=true
LOG_SHIPPER_BATCH_SIZE=100
LOG_SHIPPER_BATCH_INTERVAL=1 # Run every minute
```

### Requirements

[](#requirements-1)

- Redis connection (configured in `config/database.php`)
- Laravel Scheduler running

### How it Works

[](#how-it-works)

1. Logs are pushed to a Redis list (`log_shipper_buffer`) instead of dispatching a job immediately.
2. A scheduled command (`log-shipper:ship-batch`) runs every minute.
3. The command pops logs in batches (default: 100) and dispatches a single job per batch.
4. The job ships the batch to the log server in a single HTTP request.

Reliability &amp; Fault Tolerance
---------------------------------

[](#reliability--fault-tolerance)

This package includes built-in mechanisms to ensure your application remains stable even if the log server is down.

### Retries &amp; Backoff

[](#retries--backoff)

If the log server returns a 4xx/5xx error or is unreachable, the job will automatically retry based on your configuration.

```
// config/log-shipper.php
'retries' => 3,
'backoff' => [2, 5, 10], // Wait 2s, then 5s, then 10s
```

### Circuit Breaker

[](#circuit-breaker)

To prevent your queue from being flooded with failing jobs during an outage, the Circuit Breaker will temporarily stop dispatching new log jobs.

```
// config/log-shipper.php
'circuit_breaker' => [
    'enabled' => true,
    'failure_threshold' => 5, // Open circuit after 5 consecutive failures
    'duration' => 300, // Keep circuit open for 5 minutes
],
```

When the circuit is open, logs are skipped entirely to protect your application's performance.

Fallback Channel
----------------

[](#fallback-channel)

If the log shipper fails to send logs (after all retries are exhausted), you can configure a fallback channel to ensure logs are not lost.

Add the following to your `.env` file:

```
LOG_SHIPPER_FALLBACK=daily
```

When a failure occurs, the original log payload will be written to the specified channel, along with failure details in the context.

> **Important:** Do not set the fallback channel to `log_shipper` itself, as this will create an infinite loop. The package automatically prevents this scenario.

Changelog
---------

[](#changelog)

Please see [CHANGELOG.md](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover a security vulnerability, please see [SECURITY.md](SECURITY.md) for reporting instructions.

License
-------

[](#license)

The MIT License (MIT). Please see [LICENSE](LICENSE) for more information.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance85

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~18 days

Total

5

Last Release

78d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6f542b25a7db724f5005a70f05fc6a2c288cf76dfc4c786f9a9b34f2eafa26a1?d=identicon)[j-bill](/maintainers/j-bill)

---

Top Contributors

[![AIjbillinger](https://avatars.githubusercontent.com/u/77721531?v=4)](https://github.com/AIjbillinger "AIjbillinger (33 commits)")

---

Tags

laravelloggingmonologcentralized-logginglog-shipper

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/adminintelligence-laravel-log-shipper/health.svg)

```
[![Health](https://phpackages.com/badges/adminintelligence-laravel-log-shipper/health.svg)](https://phpackages.com/packages/adminintelligence-laravel-log-shipper)
```

###  Alternatives

[shaffe/laravel-mail-log-channel

A package to support logging via email in Laravel

1286.2k](/packages/shaffe-laravel-mail-log-channel)[naoray/laravel-github-monolog

Log driver to store logs as github issues

10619.4k](/packages/naoray-laravel-github-monolog)[yzen.dev/mono-processor

This Processor will display in the logs bread crumbs by which you can more quickly and accurately identify the cause of the error.

116.1k](/packages/yzendev-mono-processor)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
