PHPackages                             jarir-ahmed/server-stats - 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. jarir-ahmed/server-stats

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

jarir-ahmed/server-stats
========================

A simple server stats package: counters, gauges, timers and system metrics over MySQL or SQLite.

v1.1.0(1mo ago)0221MITPHPPHP &gt;=8.0CI passing

Since Jun 6Pushed 1mo agoCompare

[ Source](https://github.com/jarir2020/jarir-ahmed-server-stats)[ Packagist](https://packagist.org/packages/jarir-ahmed/server-stats)[ RSS](/packages/jarir-ahmed-server-stats/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (1)Versions (4)Used By (1)

server-stats
============

[](#server-stats)

[![CI](https://github.com/jarir2020/jarir-ahmed-server-stats/actions/workflows/ci.yml/badge.svg)](https://github.com/jarir2020/jarir-ahmed-server-stats/actions/workflows/ci.yml)

A small PHP metrics library: **counters**, **gauges**, **timers**, and **system metrics**, stored in **MySQL** (with automatic **SQLite** fallback). No external services required.

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

[](#requirements)

- PHP &gt;= 8.0
- `ext-pdo`, `ext-json`
- `ext-pdo_mysql` (optional — falls back to SQLite if MySQL is unavailable)

Install
-------

[](#install)

```
composer require jarir-ahmed/server-stats
```

Quick start
-----------

[](#quick-start)

```
use JarirAhmed\ServerStats\{Storage, Metrics, MetricCollector};

$storage = new Storage(); // MySQL if reachable, else SQLite in the system temp dir
Metrics::init($storage);

// Counter — atomic, durable across requests/processes
Metrics::counter('page_views.home')->increment();

// Gauge — point-in-time value (latest wins)
Metrics::gauge('queue.depth')->set(42);

// Timer — measure a block; stops even if the callback throws
$result = Metrics::measure('request.processing', function () {
    return doWork();
});

// System metrics (CPU load, memory, disk)
(new MetricCollector($storage))->recordSystemMetrics();
```

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

[](#configuration)

`Storage` reads, in order: the `$config` array → `SERVER_STATS_*` environment variables → defaults.

```
$storage = new Storage([
    'host'             => '127.0.0.1',
    'port'             => '3306',
    'database'         => 'server_stats',
    'username'         => 'root',
    'password'         => '',
    'charset'          => 'utf8mb4',
    'sqlite_path'      => '/var/data/server_stats.db', // SQLite fallback location
    'retention_seconds'=> 7 * 86400,  // auto-prune samples older than this (0 = off)
    'gc_probability'   => 0.01,        // chance per save() of running a prune sweep
    'logger'           => fn(string $m) => error_log($m),
]);
```

Equivalent env vars: `SERVER_STATS_HOST`, `SERVER_STATS_PORT`, `SERVER_STATS_DATABASE`, `SERVER_STATS_USERNAME`, `SERVER_STATS_PASSWORD`, `SERVER_STATS_CHARSET`, `SERVER_STATS_SQLITE_PATH`, `SERVER_STATS_RETENTION_SECONDS`.

Labels
------

[](#labels)

Counters, gauges and timers accept labels. For counters, labels are part of the identity (order-independent), so each label set is tracked separately.

```
Metrics::counter('http.requests', ['status' => 200])->increment();
Metrics::counter('http.requests', ['status' => 500])->increment();

Metrics::counter('http.requests', ['status' => 200])->getValue(); // 1.0
```

Querying
--------

[](#querying)

```
$storage->getLatest(20);                       // recent time-series samples (newest first)
$storage->getCounters();                       // all counters
$storage->query(['name' => 'request.processing_ms', 'since' => time() - 3600]);
$storage->aggregate('request.processing_ms', 'avg', time() - 3600); // avg|min|max|sum|count
$storage->prune(7 * 86400);                    // delete samples older than 7 days
```

Without global state
--------------------

[](#without-global-state)

Use `Registry` directly instead of the static `Metrics` facade — handy for multiple backends or test isolation:

```
use JarirAhmed\ServerStats\{Registry, InMemoryStorage};

$registry = new Registry(new InMemoryStorage());
$registry->counter('hits')->increment();
$registry->gauge('temp')->set(21.5);
```

`InMemoryStorage` implements the same `StorageInterface` and persists nothing — ideal for tests.

Architecture
------------

[](#architecture)

- `StorageInterface` — backend contract.
- `Storage` — PDO backend (MySQL + SQLite). Two tables: `metrics` (time series) and `counters` (atomic aggregate state).
- `InMemoryStorage` — non-persistent backend.
- `Registry` — instance API; `Metrics` — static facade over a default registry.
- `Counter`, `Gauge`, `Timer`, `MetricCollector`.

Testing
-------

[](#testing)

```
composer install
composer test
```

The suite runs against `InMemoryStorage` and the SQLite backend. Set `SERVER_STATS_TEST_MYSQL=1`(with MySQL connection env vars) to additionally run the MySQL contract tests.

License
-------

[](#license)

MIT

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance90

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

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

Total

3

Last Release

49d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/20700f34ff813055154e843bbdbe04d33320c1e6a81bbb3301cad67cb8350fd3?d=identicon)[jarircse16](/maintainers/jarircse16)

---

Tags

monitoringMetricstimercountergaugeserver-stats

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/jarir-ahmed-server-stats/health.svg)

```
[![Health](https://phpackages.com/badges/jarir-ahmed-server-stats/health.svg)](https://phpackages.com/packages/jarir-ahmed-server-stats)
```

###  Alternatives

[slickdeals/statsd

a PHP client for statsd

274.9M13](/packages/slickdeals-statsd)[krenor/prometheus-client

A PHP Client for Prometheus

1021.6k](/packages/krenor-prometheus-client)[lamoda/metrics

Library for handling and displaying custom project metrics

361.9k](/packages/lamoda-metrics)

PHPackages © 2026

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