tuupola/instrument-middleware

PSR-7 Middleware for instrumenting PHP applications

Maintainers

👁 tuupola

Package info

github.com/tuupola/instrument-middleware

pkg:composer/tuupola/instrument-middleware

Statistics

Installs: 2 867

Dependents: 0

Suggesters: 0

Stars: 10

Open Issues: 0

0.5.0 2016-10-09 17:59 UTC

Requires

Suggests

None

Provides

None

Conflicts

None

Replaces

None

MIT b9624b45845c047578171beb0f28df5b7c6eca45

Metricsmiddlewareinstrumentinfluxdbpsr-7

This package is auto-updated.

Last update: 2026-06-29 01:20:40 UTC


README

👁 Latest Version
👁 Software License
👁 Build Status
👁 Coverage

Companion middleware for Instrument. Automates basic instrumenting of PSR-7 based application code.

👁 Instrument Middleware

Install

Install using composer.

$ composer require tuupola/instrument-middleware

Usage

You must have access to InfluxDB database to store the data. Configure the Instrument instance and pass it to the middleware. This is the only mandatory parameter. Heads up! The order of middlewares is important. Instrument middleware must be the last one added.

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

$app = new \Slim\App;

$influxdb = InfluxDB\Client::fromDSN("http+influxdb://foo:bar@localhost:8086/instrument");

$app->add(new Instrument\Middleware([
 "instrument" => new Instrument\Instrument([
 "adapter" => new Instrument\Adapter\InfluxDB($influxdb),
 "transformer" => new Instrument\Transformer\InfluxDB
 ])
]));

Or if you are using Slim 3 containers which is a bit cleaner.

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

$app = new \Slim\App;
$container = $app->getContainer();

$container["influxdb"] = function ($container) {
 return InfluxDB\Client::fromDSN("http+influxdb://foo:bar@localhost:8086/instrument");
};

$container["instrument"] = function ($container) {
 return new Instrument\Instrument([
 "adapter" => new Instrument\Adapter\InfluxDB($container["influxdb"]),
 "transformer" => new Instrument\Transformer\InfluxDB
 ]);
};

$container["instrumentMiddleware"] = function ($container) {
 return new Instrument\Middleware([
 "instrument" => $container["instrument"]
 ]);
};

$app->add("instrumentMiddleware");

What is logged?

Let's assume you have the following routes.

$app->get("/", function ($request, $response, $arguments) {
 return $response->write("Here be dragons...\n");
});

$app->get("/hello/{name}", function ($request, $response, $arguments) {
 return $response->write("Hello {$arguments['name']}!\n");
});

When request is made the middleware saves basic instrumentation data to the database.

$ curl http://192.168.50.53/
Here be dragons...
$ curl http://192.168.50.53/hello/foo
Hello foo!
> select * from instrument
name: instrument
----------------
time bootstrap memory method process route status total
1475316633441185508 158 1048576 GET 53 / 200 213
1475316763025260932 140 1048576 GET 69 /hello/foo 200 211

Field bootstrap is the time elapsed between start of the request and executing the first middleware. Field total is the time elapsed between starting the request and exiting the last middleware. Note again that Instrument middleware must be the last one added so it will be executed first when entering and last when exiting the middleware stack.

Fields memory and process are the peak PHP memory usage and elapsed time during the processing of the request. This includes the route or controller and all other middlewares.

Tags method and status are the request method and the HTTP status code of the response. Tag route is the requested URI without query string.

Adding or overriding tags

You can add tags by using tags parameter. It can be either an array or anonymous function returning an array. Function receives both $request and $response objects as parameters. If you return any of the default tags it will override the value otherwise set by the middleware.

$app->add(new Instrument\Middleware([
 "instrument" => $instrument,
 "tags" => ["host" => "localhost", "method" => "XXX"]
]));

Is essentially the same as code below.

$app->add(new Instrument\Middleware([
 "instrument" => $instrument,
 "tags" => function ($request, $response) {
 return ["host" => "localhost", "method" => "XXX"];
 }
]));
> select * from instrument
name: instrument
----------------
time bootstrap memory host method process route status total
1475316633441185508 158 1048576 localhost XXX 53 / 200 213
1475316763025260932 140 1048576 localhost XXX 69 /hello/foo 200 211

Customising field and tag names

All field and tag names can be customized. Following example changes all tag and field names. It also changes the measurement name. In InfluxDB lingo MEASUREMENT is the same as TABLE in SQL world.

$app->add(new Instrument\Middleware([
 "instrument" => $instrument,
 "measurement" = "api",
 "bootstrap" = "startup",
 "process" = "execution",
 "total" = "all",
 "memory" = "mem",
 "status" = "code",
 "route" = "uri",
 "method" = "verb"
]));
> select * from api
name: api
----------------
time startup mem verb execution uri code all
1475316633441185508 158 1048576 GET 53 / 200 213
1475316763025260932 140 1048576 GET 69 /hello/foo 200 211

To disable a tag or field set it to false.

$app->add(new Instrument\Middleware([
 "instrument" => $instrument,
 "measurement" = "api",
 "bootstrap" = "startup",
 "process" = false,
 "total" = "total",
 "memory" = false,
 "status" = false,
 "route" = false,
 "method" = false
]));
> select * from api
name: api
----------------
time startup total
1475316633441185508 158 213
1475316763025260932 140 211

Manually adding data

You can also manually add additional data to the measurement.

$app->get("/manual", function ($request, $response, $arguments) {
 $timing = $this->instrument->timing("instrument");
 $timing->start("db");
 /* Some expensive database queries. */
 $timing->stop("db");
 return $response->write("Manually adding additional data...\n");
});
$ curl http://192.168.50.53/manual
Manually adding additional data...
> select * from instrument
name: instrument
----------------
time bootstrap db memory method process route status total
1475318315949095876 155 411 1048576 GET 466 /manual 200 623

Testing

You can run tests either manually...

$ make test

... or automatically on every code change.

$ make watch

Contributing

Please see CONTRIBUTING for details.

Security

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

License

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