Download the PHP package davos/graphy without Composer
On this page you can find all versions of the php package davos/graphy. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Package graphy
Short Description A PHP abstraction layer for creating, updating, and fetching RRDTool databases with fluent model-based APIs.
License MIT
Homepage https://github.com/dabulgar/graphy
Informations about the package graphy
Davos\Graphy
RRDTool knows fixed steps. It does not know what a calendar day, week, month, or year is.
Graphy is a typed, fluent PHP API for creating, updating, and fetching RRDTool databases. Its main addition is calendar-aligned, timezone- and DST-aware grouping on top of existing RRD archives.
https://github.com/user-attachments/assets/c3192ec3-a9f0-4f44-8030-82793f785dd7
Why Graphy?
Graphy gives you:
- model-based RRD definitions;
- fluent create, update, and fetch operations;
- automatic archive selection by consolidation function and resolution;
- bounded, chunked reads for large time ranges;
- calendar-aware grouping by second, minute, hour, day, week, month, or year;
- timezone- and DST-aware labels;
- typed exceptions instead of
falseor raw extension errors.
Graphy does not replace RRDTool. It provides a safer, higher-level PHP API around the ext-rrd extension.
Table of contents
- Installation
- Quick start
- Configuration
- Defining a model
- Creating an RRD
- Updating data
- Fetching data
- Grouping into calendar buckets
- Data source reference
- Archive reference
- Duration and time syntax
- Native RRDTool flags
- File organization with
path_mapper - Error handling
- Troubleshooting
- Examples
- Contributing
- License
Installation
Requirements
- PHP 8.3 or newer;
- the RRD PHP extension;
ext-mbstring;ext-ctype.
Verify that the RRD extension is loaded:
Quick start
Configure Graphy once during application bootstrap:
Define an RRD model:
Create the file and write a value:
Fetch the last day at one-minute resolution:
Graphy normalizes bare filenames to .rrd, so power and power.rrd address the same file.
Configuration
All configuration keys shown below are required by the current configuration object.
| Key | Type | Description |
|---|---|---|
path |
string |
Base directory for relative RRD filenames. |
path_mapper |
callable\|false |
Optionally maps a filename to a relative subpath. |
driver |
string |
RRD backend. Currently only ext is supported. |
permission |
int |
Mode applied to newly created .rrd files. |
create_directories |
bool |
Creates missing parent directories when enabled. |
directory_permission |
int |
Mode applied to newly created directories. |
timezone |
string |
Default IANA timezone used for grouping and labels. |
Calling ManagerFactory::configure() again replaces the current configuration for subsequent operations.
Defining a model
An RRD model describes:
- the primary data point step;
- the initial start time;
- one or more data sources;
- one or more round-robin archives.
The following RRDTool definition:
can be represented as:
dataSources() and roundRobinArchives() are abstract methods and must be implemented by every model.
Archive keys are optional, but naming them makes fromArchive() calls clearer and less fragile than numeric indexes.
Understanding archive resolution and retention
For every RRA:
With a model step of one second:
the archive has:
Creating an RRD
Graphy resolves the model definition and calls the RRD extension with the equivalent create options.
The operation throws an exception when the command definition is invalid or RRDTool rejects the operation.
Updating data
One sample at the current time
Samples keyed by Unix timestamp
Explicit batch format
When a defined data source is omitted from a sample, Graphy writes U (unknown) for that data source.
Use integer Unix timestamps for explicit sample times.
Fetching data
Select an archive by consolidation function and resolution
Available consolidation functions:
The requested consolidation function and resolution must match an archive defined by the model.
Graphy:
- finds the matching archive;
- clamps the request to the archive's available retention range and to the current time;
- aligns the request to the archive resolution;
- splits large ranges into bounded chunks;
- merges the chunks into one logical result.
The default chunk size is 10,000 data points. It can be changed per fetch:
Select a named archive
A named archive supplies its own consolidation function, resolution, and full retention window:
fromArchive() uses the archive key or numeric index from roundRobinArchives().
Result shape
get() returns:
Example:
RRD NaN values are converted to null by get().
Stream results with cursor()
Use cursor() when processing a large result row by row:
cursor() is lazy. It yields timestamps as keys and data-source maps as values.
Unlike get(), cursor() exposes raw numeric values from the fetch pipeline; normalize NaN yourself when needed.
Grouping into calendar buckets
An RRD archive stores fixed-resolution points. A one-minute archive knows about 60-second steps, not calendar days or months.
Graphy's group() aggregates those points into calendar-aligned buckets after fetching.
The timezone controls where calendar boundaries occur. This matters for local midnight and daylight-saving transitions.
Available intervals
Every interval accepts a positive multiplier:
Weeks start on Monday.
group() and labels() are independent
group() aggregates values:
labels() formats timestamp keys:
Labels can be used without grouping:
For points that are not on a label boundary, the default behaviour is to preserve the Unix timestamp.
The third labels() argument changes that behaviour:
Grouping constraints
The archive resolution must divide evenly into the requested grouping interval.
Valid examples:
Invalid example:
Invalid combinations throw CommandDefinitionException instead of producing silently misaligned results.
Complete buckets
A grouped bucket is emitted when its calendar boundary is reached. A trailing bucket that has not reached its closing boundary is not included in the grouped result.
For example, a daily query ending at 15:00 may return completed days but omit the still-incomplete current day.
Data source reference
Create a data source with:
Then choose exactly one data-source type.
| Method | RRD type | Typical use |
|---|---|---|
gauge() |
GAUGE |
Direct measurements such as temperature, load, or power. |
counter() |
COUNTER |
Continuously increasing counters with overflow handling. |
dcounter() |
DCOUNTER |
Double-precision counter values. |
derive() |
DERIVE |
Rates derived from increasing or decreasing values. |
dderive() |
DDERIVE |
Double-precision derive values. |
absolute() |
ABSOLUTE |
Counters reset after every read. |
compute($expression) |
COMPUTE |
Values calculated from other data sources using RPN. |
For non-COMPUTE data sources, configure:
heartbeat()is the maximum accepted gap between updates before the value becomes unknown;min()andmax()define accepted bounds;- use RRD-compatible values such as
'U'when a bound is unknown.
A computed data source uses an RPN expression:
Archive reference
Create archives with one of:
Then configure:
| Method | Meaning |
|---|---|
xff(float $value) |
XFiles factor: tolerated proportion of unknown primary data points. |
steps(int $steps) |
Primary data points consolidated into one archive row. |
rows(int $rows) |
Number of rows retained by the archive. |
The default XFiles factor is 0.5.
Duration and time syntax
Duration values
Graphy accepts integers or strings containing a non-negative integer and an optional unit:
| Unit | Meaning |
|---|---|
no suffix / s |
seconds |
m |
minutes |
h |
hours |
d |
fixed 24-hour days |
w |
fixed seven-day weeks |
M |
fixed 31-day months |
y |
fixed 366-day years |
Examples:
M and y are fixed-duration aliases used for RRD calculations. They are not calendar-aware units. Calendar months and years are handled by MonthInterval and YearInterval during grouping.
Fetch time references
start() and end() accept:
Supported RRD-style anchors are:
and can be combined with + or - and a duration.
Pass Unix timestamps as integers. A digits-only string passed through the fluent fetch API is interpreted as a relative duration, not as an absolute Unix timestamp.
When end() is omitted, it defaults to now.
Native RRDTool flags
Graphy exposes supported native options through Flag objects and operation-specific constants.
Create flags
Supported create constants:
Model-defined step and start are supplied automatically. User flags can override generated defaults where the operation permits it.
Update flags
Supported update constants:
Fetch flags
Fetch range and resolution options are normally generated by the fluent API and chunking pipeline.
Supported fetch constants are:
File organization with path_mapper
For a small number of files, keep:
Every relative filename will be stored directly under the configured path.
For many dynamically named files, use path_mapper to shard them into deterministic subdirectories:
Calling:
resolves to:
The mapper receives a filename already normalized to end in .rrd.
Important behaviour:
- absolute paths bypass both
pathandpath_mapper; - relative mapper results are resolved under
path; - when
create_directoriesistrue, missing parent directories are created recursively; - when
create_directoriesisfalse, a missing directory causesCommandDefinitionException; - new directories use
directory_permission; - newly created RRD files use
permission.
A mapper should be deterministic: the same logical filename must always return the same path.
Error handling
Graphy throws typed exceptions instead of returning false or raw error strings.
| Exception | Meaning |
|---|---|
CommandDefinitionException |
The requested operation cannot be represented safely or validly. |
RrdToolExecutionException |
RRDTool rejected the generated command. |
ConfigException |
Configuration is missing or invalid. |
Value-object-specific exceptions may also be thrown for invalid durations or time references.
Troubleshooting
ext-rrd is missing
Check:
The extension must be available to the same PHP binary that runs Composer, tests, workers, or the web application.
No matching archive was found
The requested consolidation function and resolution must match one model archive exactly.
For a model step of one second:
has a resolution of 60 seconds, so request:
Grouping throws a misalignment exception
Choose an archive resolution that divides evenly into the grouping interval.
For daily grouping, one minute, 30 minutes, or one hour are sensible choices. Seven hours is not.
The current day is missing
Grouped output contains completed buckets. A current day, week, month, or year may be omitted until its closing boundary is reached.
Values are null
RRDTool represents unknown values as NaN. get() converts those values to null.
Common causes include:
- missed updates beyond the data source heartbeat;
- values outside the configured minimum or maximum;
- insufficient known primary data points for the archive's XFiles factor.
Examples
The examples/ directory contains runnable examples.
Watts chart
The examples/watts example:
- defines a power model;
- creates and seeds a local RRD file;
- fetches and groups the data;
- serves a browser chart.
Run it with:
Then open:
Contributing
Install development dependencies:
Run the complete local quality suite:
Or run checks separately:
Apply coding-style fixes:
Pull requests and pushes to main are checked by GitHub Actions for coding style, PHPStan, and PHPUnit.
When changing public behaviour, update or add:
- unit tests;
- integration tests when the RRD extension is involved;
- README examples and API notes.
License
Graphy is released under the MIT License.
MIT © David Ivanov
All versions of graphy with dependencies
ext-rrd Version *
ext-mbstring Version *
ext-ctype Version *