PHP application instrumentation toolkit
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
demo Use latest Grafana dashboard in demo May 26, 2016
.gitattributes Do not install codecov.yml Oct 9, 2016
.gitignore Run tests via composer Feb 21, 2017
.travis.yml First working concept Mar 3, 2016 Run tests via composer Feb 21, 2017
composer.json Run tests via composer Feb 21, 2017


Latest Version Software License Build Status HHVM Status Coverage

With Instrument you can monitor and measure your PHP application performance. It can collect and store metrics such as script execution time and memory usage or time spent in database.



Install using composer.

$ composer require tuupola/instrument

You also must have access to InfluxDB database to store the data. After installing connect to your database and start sending metrics.

require __DIR__ . "/vendor/autoload.php";

$influxdb = InfluxDB\Client::fromDSN("http+influxdb://user:pass@localhost:8086/instrument");
$instrument = new Instrument\Instrument([
    "adapter" => new Instrument\Adapter\InfluxDB($influxdb),
    "transformer" => new Instrument\Transformer\InfluxDB

$instrument->count("users", 100);


Optionally if you want to use the gauge datatype you need the shmop extension and klaussilveira/simple-shm library.

composer require klaussilveira/simple-shm

There is also a companion middleware which can automate basic instrumenting of application code if you are using PSR-7 based framework.


Example Grafana dashboard is included. To see Instrument in action start the Vagrant demo server and make some example requests.

$ cd demo
$ vagrant up
$ while sleep 1; do curl; done

The above commands start the server and inserts random Instrument data every second. You can now access the provided demo dashboard (admin:admin) to see this happening live.


Writing data

Documentation assumes you have working knowledge of InfluxDB data structures. Each measurement must have a name. Measurements should contain either one value or several value fields or both. Optionally measurement can have one or more tags.

For example to create a new count measurement with name users with one value of 100 use either of the following.

$instrument->count("users", 100);
> SELECT * FROM users
name: users
time                  value
1457067288109133121    100

To log several values and additionally tag the measurement.

    ->set("total", 100)
    ->set("active", 27)
    ->tags(["host" => "localhost"]);

> SELECT * FROM users
name: users
time                  total   active  host
1457067288109134122   100     27      localhost

The event datatype does not contain numerical measurements.

    ->event("deploy", "New version deployed")
    ->tags(["host" => "localhost"]);

> SELECT * FROM events;
name: events
time                  title    description           host
1464277178854200406   deploy   New version deployed  localhost



Count is the simplest datatype. In addition to setting the value you can also increment and decrement it.

$requests = $instrument->count("requests", 50); /* 50 */
$requests->increase(); /* 51 */
$requests->decrease(); /* 50 */
$requests->increase(5); /* 55 */


Or if you prefer fluent interfaces you can also do the following.

  ->set("active", 27) /* 27 */
  ->increase("active", 5) /* 32 */
  ->decrease("active", 2); /* 30 */



With timing you can measure execution time in milliseconds. You can either pass the value yourself or use the provided helpers to measure code execution time.

$instrument->timing("roundtrip")->set("firstbyte", 28);
$instrument->timing("roundtrip")->set("lastbyte", 40);

$instrument->timing("roundtrip")->set("processing", function () {
    /* Code to be measured */

/* Code to be measured */


Since timing internally uses symfony/stopwatch you can get PHP memory usage as a bonus. It is not automatically included in the measurement data, but you can include it manually.

$memory = $instrument->timing("roundtrip")->memory()
$instrument->timing("roundtrip")->set("memory", $memory);



Gauge is same as count. However it remembers the value between requests. Gauge values are zeroed when server restarts. You need the shmop extension and klaussilveira/simple-shm to be able to use gauges.

$errors = $instrument->gauge("errors");
$errors->increase("fatal"); /* 1 */
$errors->increase("critical"); /* 1 */


$errors = $instrument->gauge("errors");
$errors->increase("fatal"); /* 2 */
$errors->increase("critical", 4); /* 5 */


Single value can be deleted from shared memory with delete() method. All values of the named gauge can be deleted at once with clear() method.

$errors = $instrument->gauge("errors");
$errors->delete("fatal"); /* null */


Events can be used to display annotations in your dashboard. By default they do not contain numerical measurements. Instead it contains title and description fields. These should contain a short name and longer description for the event.

    ->event("deploy", "Version 0.9.0 deployed")
    ->tags(["host" => "localhost"]);

    ->event("deploy", "Version 0.9.1 deployed")
    ->tags(["host" => "localhost"]);

> SELECT * FROM events;
name: events
time                  title    description             host
1464277178854200406   deploy   Version 0.9.0 deployed  localhost
1464277178854201240   deploy   Version 0.9.1 deployed  localhost

If you are using Grafana you can use above data by using SELECT * FROM events WHERE $timeFilter as the annotation query. Also set the column mappings as shown below.



You can run tests either manually...

$ composer test

... or automatically on every code change. This requires entr to work.

$ composer watch


Please see CONTRIBUTING for details.


If you discover any security related issues, please email instead of using the issue tracker.


The MIT License (MIT). Please see License File for more information.