PHPackages                             polarity-labs/observer-agent - 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. polarity-labs/observer-agent

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

polarity-labs/observer-agent
============================

Lightweight server and Laravel application monitoring agent

v0.0.9(2w ago)026↓100%MITPHPPHP ^8.2

Since Feb 7Pushed 2w agoCompare

[ Source](https://github.com/Polarity-Labs/observer-laravel-agent)[ Packagist](https://packagist.org/packages/polarity-labs/observer-agent)[ RSS](/packages/polarity-labs-observer-agent/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (2)Versions (8)Used By (0)

Observer
========

[](#observer)

Lightweight server and Laravel application monitoring.

Observer is a monitoring agent that collects system metrics (CPU, memory, disk, network) and Laravel-specific metrics (queue health, Horizon, log errors, HTTP health checks) and sends them to a central dashboard.

Features
--------

[](#features)

- **Minimal overhead** — The Go-based agent uses ~10MB RAM and near-zero CPU
- **Zero configuration** — Reads your existing `.env` and Laravel config automatically
- **Laravel native** — Install via Composer, run via Artisan
- **System metrics** — CPU usage, memory, disk space, network I/O, load averages
- **Process monitoring** — Top 10 processes by CPU and memory with 5-minute aggregated snapshots
- **Spike detection** — Captures CPU/memory spikes with culprit process identification for diagnosing OOM/resource issues
- **Laravel metrics** — Queue health, Horizon status, log error monitoring, HTTP health checks
- **Custom health checks** — Register arbitrary PHP callbacks (DB pings, Redis checks, etc.) alongside URL checks
- **External health checks** — Have Observer SaaS ping your endpoints from outside your network
- **Per-check leader gating** — Control whether each health check runs on the leader agent only or on all agents
- **Multi-agent aware** — Automatic leader election prevents duplicate system metrics when multiple apps share a server
- **Reliable delivery** — Buffers metrics locally if the API is unreachable

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

[](#requirements)

- PHP 8.2+
- Laravel 11 or 12
- Linux or macOS server

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

[](#installation)

```
composer require polarity-labs/observer-agent
```

Publish the configuration file (optional):

```
php artisan vendor:publish --tag=observer-config
```

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

[](#configuration)

Add your API key to your `.env` file:

```
OBSERVER_API_KEY=your-secret-api-key
```

That's it! The agent reads everything else from your existing Laravel configuration. The Go binary is downloaded automatically on first run.

### Optional Configuration

[](#optional-configuration)

```
# Server identification (defaults to machine hostname)
OBSERVER_SERVER_NAME=web-1

# Collection intervals in seconds (per-collector)
OBSERVER_INTERVAL_CPU=15
OBSERVER_INTERVAL_MEMORY=15
OBSERVER_INTERVAL_DISK=300
OBSERVER_INTERVAL_NETWORK=15
OBSERVER_INTERVAL_QUEUE=60
OBSERVER_INTERVAL_HEALTH=15

# Enable/disable specific collectors
OBSERVER_COLLECT_CPU=true
OBSERVER_COLLECT_MEMORY=true
OBSERVER_COLLECT_DISK=true
OBSERVER_COLLECT_NETWORK=true
OBSERVER_COLLECT_QUEUE=true
OBSERVER_COLLECT_LOGS=true
OBSERVER_COLLECT_HEALTH=true
OBSERVER_COLLECT_PROCESS=true
OBSERVER_COLLECT_TOP_PROCESSES=true  # Top 10 processes by CPU/memory
OBSERVER_COLLECT_SPIKE_EVENTS=true   # CPU/memory spike detection with culprit processes
OBSERVER_COLLECT_HORIZON=true        # Disable if not using Laravel Horizon
OBSERVER_COLLECT_SCHEDULER=true      # Disable if not monitoring scheduler health

# Top processes configuration
OBSERVER_INTERVAL_TOP_PROCESSES=300        # Emit interval in seconds (default: 300)
OBSERVER_TOP_PROCESSES_SAMPLE_INTERVAL=30  # Internal sampling rate (default: 30)
OBSERVER_TOP_PROCESSES_COUNT=10            # Number of top processes to track (default: 10)

# Spike detection configuration
OBSERVER_SPIKE_CPU_THRESHOLD=90.0        # CPU % that triggers a spike (default: 90)
OBSERVER_SPIKE_MEMORY_THRESHOLD=90.0     # Memory % that triggers a spike (default: 90)
OBSERVER_SPIKE_COOLDOWN=60               # Seconds between spike events of the same type (default: 60)
OBSERVER_SPIKE_TOP_N=5                   # Number of top processes to capture on spike (default: 5)

# Multi-agent coordination (default: "auto")
# auto = file-lock election, one agent sends system metrics per server
# enabled = always send system metrics (skip election)
# disabled = never send system metrics (app metrics only)
OBSERVER_SYSTEM_METRICS=auto

# Queue names to monitor (comma-separated, default: "default")
OBSERVER_QUEUE_NAMES=default,emails,notifications
```

Usage
-----

[](#usage)

### Check configuration

[](#check-configuration)

```
php artisan observer:status
```

This shows your current configuration and validates everything is set up correctly.

### Start monitoring

[](#start-monitoring)

```
php artisan observer:start
```

The agent will run continuously, collecting and sending metrics. Press `Ctrl+C` to stop.

### Restart after deployment

[](#restart-after-deployment)

```
php artisan observer:restart
```

This signals the running agent to exit cleanly. When running under Supervisor with `autorestart=true`, the agent restarts automatically and picks up the new binary.

Add this to your deploy script after `composer install`.

### Test mode (single collection)

[](#test-mode-single-collection)

```
php artisan observer:start --once
```

Collects metrics once and exits. Useful for testing your configuration.

Health Checks
-------------

[](#health-checks)

Observer supports three types of health checks:

### URL Health Checks (Agent)

[](#url-health-checks-agent)

Configured in `config/observer.php`. The Go agent pings these URLs from the server:

```
'health_endpoints' => [
    ['url' => env('APP_URL').'/up', 'name' => 'app'],
    ['url' => 'https://api.myapp.com/health', 'name' => 'api', 'headers' => ['Authorization' => 'Bearer token']],
],
```

### URL Health Checks (External)

[](#url-health-checks-external)

Same config format, but checked by Observer SaaS from outside your network:

```
'health_endpoints' => [
    ['url' => 'https://myapp.com', 'name' => 'public-site', 'check_from' => 'external'],
],
```

The agent sends the endpoint configuration to Observer SaaS, which pings the URL every minute from its own infrastructure. This verifies your app is reachable from the outside world.

### Custom Health Checks

[](#custom-health-checks)

Register arbitrary PHP callbacks to check anything — databases, Redis, external APIs, file systems, etc. Custom checks run inside your Laravel process (via the `observer:metrics` artisan command) rather than from the Go binary.

Register checks in a service provider's `boot()` method:

```
use PolarityLabs\ObserverAgent\Observer;
use PolarityLabs\ObserverAgent\HealthCheckResult;

public function boot(): void
{
    $observer = app(Observer::class);

    $observer->healthCheck('redis', function () {
        try {
            Redis::ping();
            return HealthCheckResult::healthy()->responseTime(1);
        } catch (\Exception $e) {
            return HealthCheckResult::unhealthy()->errorMessage($e->getMessage());
        }
    });

    $observer->healthCheck('database', function () {
        $start = hrtime(true);
        DB::select('SELECT 1');
        $ms = (int) ((hrtime(true) - $start) / 1_000_000);
        return HealthCheckResult::healthy()->responseTime($ms);
    });
}
```

#### HealthCheckResult API

[](#healthcheckresult-api)

```
// Static constructors
HealthCheckResult::healthy();
HealthCheckResult::unhealthy();
HealthCheckResult::make(isHealthy: true, responseTimeMs: 42, errorMessage: null);

// Chainable methods
HealthCheckResult::healthy()->responseTime(42);
HealthCheckResult::unhealthy()->responseTime(5000)->errorMessage('Connection refused');
```

If a callback throws an exception, Observer catches it and reports the check as unhealthy with the exception message.

### Per-Check Leader Gating

[](#per-check-leader-gating)

By default, all health checks (URL and custom) run only on the leader agent to avoid duplicate checks. Override this per-check:

```
// Config-based (URL checks)
['url' => 'http://localhost/up', 'name' => 'local', 'leader_only' => false],

// Code-based (custom checks)
$observer->healthCheck('redis', $callback, leaderOnly: false);
```

Set `leader_only: false` when you want every agent instance to run the check (e.g., checking a local service on each server).

Multiple Apps on One Server
---------------------------

[](#multiple-apps-on-one-server)

When multiple Laravel apps share a server, each runs its own Observer agent. System metrics (CPU, memory, disk, network) only need to be sent once per server, while app metrics (queues, logs, health checks) are unique to each app.

Observer handles this automatically via file-based leader election. The first agent to start acquires a lock and becomes the **leader** (sends system + app metrics). Other agents become **followers** (send app metrics only). If the leader stops, a follower is promoted within ~10 seconds.

No configuration is needed — the default `OBSERVER_SYSTEM_METRICS=auto` works transparently for both single-app and multi-app setups.

To override the automatic behavior:

```
# Force this agent to always send system metrics
OBSERVER_SYSTEM_METRICS=enabled

# Force this agent to never send system metrics
OBSERVER_SYSTEM_METRICS=disabled
```

Running in Production
---------------------

[](#running-in-production)

For production, run the agent under a process manager like Supervisor:

```
# /etc/supervisor/conf.d/observer.conf
[program:observer]
command=php /var/www/yourapp/artisan observer:start
directory=/var/www/yourapp
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/observer.log
```

Then:

```
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start observer
```

Testing
-------

[](#testing)

```
# PHP tests
composer install
vendor/bin/pest

# Go agent tests (see agent/README.md)
cd agent && make test
```

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance97

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

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 ~4 days

Total

7

Last Release

15d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6216c36a8a2b7b6afbd86366a19b8175542b37cdf305ea54c8c4cf71c9840fb5?d=identicon)[PhiloNL](/maintainers/PhiloNL)

---

Top Contributors

[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (8 commits)")

---

Tags

laravelmonitoringserverMetricsobservability

### Embed Badge

![Health badge](/badges/polarity-labs-observer-agent/health.svg)

```
[![Health](https://phpackages.com/badges/polarity-labs-observer-agent/health.svg)](https://phpackages.com/packages/polarity-labs-observer-agent)
```

###  Alternatives

[houdaslassi/vantage

Vantage: Strategic queue monitoring and observability for Laravel applications.

23326.5k](/packages/houdaslassi-vantage)

PHPackages © 2026

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