Git Product home page Git Product logo

influxdb-php-sdk's Introduction

InfluxDB PHP SDK

Build Status Code Coverage Scrutinizer Code Quality Latest Stable Version License

Send metrics to InfluxDB and query for any data.

This project support InfluxDB API >= 0.9 - For InfluxDB v0.8 checkout branch 0.3 (no longer supported)

Supported adapters:

  • UDP/IP
  • HTTP (via GuzzleHTTP versions: ~5, ~6) - For Guzzle 4 support checkout branch 0.9 (no longer supported)

Install it

Just use composer

$ composer require corley/influxdb-sdk:~1

Or add to your composer.json file

{
  "require": {
    "corley/influxdb-sdk": "~1"
  }
}

Use it

Add new points:

$client->mark("app-search", [
    "key" => "this is my search"
]);

Or use InfluxDB direct messages

$client->mark([
    "tags" => [
        "dc" => "eu-west-1",
    ],
    "points" => [
        [
            "measurement" => "instance",
            "fields" => [
                "cpu" => 18.12,
                "free" => 712423,
            ],
        ],
    ]
]);

Retrieve existing points:

$results = $client->query('select * from "app-search"');

InfluxDB client adapters

Actually we supports two network adapters

  • UDP/IP - in order to send data via UDP/IP (datagram)
  • HTTP - in order to send/retrieve using HTTP messages (connection oriented)

Using UDP/IP Adapter

In order to use the UDP/IP adapter your must have PHP compiled with the sockets extension.

Usage

$reader = ...

$options = new Udp\Options();
$writer = new Udp\Writer($options);

$client = new Client($reader, $writer);

UDP/IP option set have only host and port properties you configure database and retention policies directly in your InfluxDB configuration

Using HTTP Adapters

Actually Guzzle is used as HTTP client library

<?php
$http = new \GuzzleHttp\Client();

$writer = ...

$options = new Http\Options();
$reader = new Http\Reader($http, $options);

$client = new Client($reader, $writer);

Mixing readers and writers

Of course you can mix Udp\Ip and Http adapters in order to write data points with UDP/IP protocol but read information using HTTP.

$reader = new Http\Reader($http, $httpOptions);
$writer = new Udp\Writer($udpOptions);
$client = new Client($reader, $writer);

$client->mark(...); // Use UDP/IP support
$client->query("SELECT * FROM my_serie"); // Use HTTP support

Or use only the HTTP

$reader = new Http\Reader($http, $options);
$writer = new Http\Writer($http, $options);
$client = new Client($reader, $writer);

$client->mark(...); // Use HTTP support
$client->query("SELECT * FROM my_serie"); // Use HTTP support

Query InfluxDB

You can query the time series database using the query method.

$client->query('select * from "mine"');

The adapter returns the json decoded body of the InfluxDB response, something like:

array(1) {
  'results' =>
  array(1) {
    [0] =>
    array(1) {
      'series' =>
      array(1) {
        ...
      }
    }
  }
}

If you prefere a more simple response than the original one, you can use corley/influxdb-http-handlers that convert, the original InfluxDB response, in a more simple response, something like:

array(1) {
  'serie_name' => array(2) {
    [0] => array(4) {
      'time' => string(30) "2015-09-09T20:42:07.927267636Z"
      'value1' => int(1)
      'value2' => int(2)
      'valueS' => string(6) "string"
    }
    [1] => array(4) {
      'time' => string(30) "2015-09-09T20:42:51.332853369Z"
      'value1' => int(2)
      'value2' => int(4)
      'valueS' => string(11) "another-one"
    }
  }
}

Global tags and retention policy

You can set a set of default tags, that the SDK will add to your metrics:

$options = new Http\Options();
$options->setTags([
    "env" => "prod",
    "region" => "eu-west-1",
]);

The SDK mark all point adding those tags.

You can set a default retentionPolicy using

$options->setRetentionPolicy("myPolicy");

In that way the SDK use that policy instead of default policy.

Proxies and InfluxDB

If you proxy your InfluxDB typically you have a prefix in your endpoints.

$option->setHost("proxy.influxdb.tld");
$option->setPort(80);
$option->setPrefix("/influxdb"); // your prefix is: /influxdb

// final url will be: http://proxy.influxdb.tld:80/influxdb/write

$client->mark("serie", ["data" => "my-data"]);

Data type management

From InfluxDB version >=0.9.3 integer types are marked with a trailing i. This library supports data types, in particular PHP types are mapped to influxdb in this way by defaults:

And the resulting mapping will be:

PHP InfluxDB
int int64
double float64
boolean boolean
string string
$client->mark("serie", [
    "value" => 12,  // Marked as int64
    "elem" => 12.4, // Marked as float64
]);

Force data type

If you want to ensure that a type is effectively parsed correctly you can force it directly during the send operation

$client->mark("serie", [
    "value"  => new IntType(12),  // Marked as int64
    "elem"   => new FloatType(12.4), // Marked as float64
    "status" => new BoolType(true), // Marked as boolean
    "line"   => new StringType("12w"), // Marked as string
]);

Query Builder

Interested in a Query Builder?

https://github.com/corley/dbal-influxdb

Thanks to Doctrine DBAL (Abstract Layer) you can use the query builder

$qb = $conn->createQueryBuilder();

$qb->select("*")
    ->from("cpu_load_short")
    ->where("time = ?")
    ->setParameter(0, 1434055562000000000);

$data = $qb->execute();
foreach ($data->fetchAll() as $element) {
    // Use your element
}
$config = new \Doctrine\DBAL\Configuration();
//..
$connectionParams = array(
    'dbname' => 'mydb',
    'user' => 'root',
    'password' => 'root',
    'host' => 'localhost',
    'port' => 8086,
    "driverClass" => "Corley\\DBAL\\Driver\\InfluxDB",
);
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);

Database operations and custom queries

The class InfluxDB\Client does not support any database operation by itself. That means that you don't have any helper function for create new databases, or list actual databases and so on. Thanks to InfluxDB\Manager you can use a preset of queries and create your own personal queries that will run against the Influxdb instance.

Create the manager

The Manager instance is very simple, you have to create it with a client instance.

$manager = new Manager($client); // InfluxDB\Client instance

Attach new queries

The manager allows to attach new queries via an helper method addQuery.

$manager->addQuery("getExceptionsInMinutes", function($minutes) {
    return "SELECT * FROM app_exceptions WHERE time > now() - {$minutes}m";
});

$manager->getExceptionsInMinutes(10); // The callable name

As you can see you have to label your anonymous function and reuse it via the manager.

In order to collect and reuse custom queries you can define query objects:

class GetExceptionsInMinutes
{
    public function __invoke($minutes)
    {
        return "SELECT * FROM app_exceptions WHERE time > now() - {$minutes}m";
    }

    public function __toString()
    {
        return "getExceptionsInMinutes";
    }
}

$manager->addQuery(new GetExceptionsInMinutes());

$manager->getExceptionsInMinutes(10); //Use the query

As you can see valid query command should be callable via the __invoke method and should be also serializable as strings via __toString method

Existing queries

This project comes out with a preset of valid queries:

  • Create new database InfluxDB\Query\CreateDatabase
  • Drop existing databases InfluxDB\Query\DeleteDatabase
  • List existing databases InfluxDB\Query\GetDatabases
$manager->addQuery(new CreateDatabase());
$manager->addQuery(new DeleteDatabase());
$manager->addQuery(new GetDatabases());

FAQ

Add sockets support to your PHP

To verify if you have the sockets extension just issue a:

php -m | grep sockets

If you don't have the sockets extension, you can proceed in two ways:

  • Recompile your PHP whith the --enable-sockets flag
  • Or just compile the sockets extension extracting it from the PHP source.
  1. Download the source relative to the PHP version that you on from here
  2. Enter in the ext/sockets directory
  3. Issue a phpize && ./configure && make -j && sudo make install
  4. Add extension=sockets.so to your php.ini

Guzzle 4 support

We drop the Guzzle 4 support, but we tested it as working HTTP adapter in up to PHP 7.0 and is stable with this project with version 0.9.3.

If you need Guzzle 4 as HTTP adapter require for 0.9.3 version

compose require corley/influxdb-sdk:0.9.*

influxdb-php-sdk's People

Contributors

5outh avatar evandarwin avatar fntlnz avatar joostfaassen avatar scrutinizer-auto-fixer avatar wdalmut avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

influxdb-php-sdk's Issues

Specify PRECISION

Hi,

How can you specify the PRECISION when you write datas (PRECISION_SECONDS, PRECISION_MINUTES, and so on) ?

Bulk inserts

Not sure how to bulk insert using the package. I tried nested arrays, but it didn't like it.

Are you able to provide an example?

Thanks

ColumnsPointsFilter is broken

The response that you get back from the InfluxDB is a JSON string, however, both your adapters transform this JSON string into an array. When using the ColumnsPointsFilter, it throws an error, as it's expecting a JSON object, not an array. This is all according to, at least, the Guzzle documentation which states:

Guzzle uses the json_decode() method of PHP and uses arrays rather than stdClass objects for objects.

I would suggest abandoning the filter classes that you have created and using Fractals, as this would follow the SOLID design principle more effectively.

Handle/suppress socket errors in UdpClient

There's no point in using UDP if it's going to throw an error if the InfluxDB database is down.

Message: socket_sendto(): unable to write to socket [64]: Host is down

#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'socket_sendto()...', '...', 37, Array)
#1 /.../vendor/corley/influxdb-sdk/src/InfluxDB/Adapter/UdpAdapter.php(37): socket_sendto(Resource id #350, '[{"name":"www.r...', 135, 0, '172.16.1.121', 4444)
#2 /.../vendor/corley/influxdb-sdk/src/InfluxDB/Client.php(80): InfluxDB\Adapter\UdpAdapter->send(Array, false)
#3 /.../public/index.php(89): InfluxDB\Client->mark('www.request', Array)
#4 /.../server.php(21): require_once('/Users/eedarwin...')
#5 {main}

HTTP adapter url prefix

If you use a proxy in front of InfluxDB maybe you have also prefixes in URLs.

Eg.

http://proxy.location:{port}/{prefìx}/write   --->  http://influxdb.location:{port}/write

checkout feature for v0.3 at #33 thanks to @sroze

Upgrade to Guzzle ~5.0

I'm trying to use this package but am having dep. conflicts with other packages using 5.0.

I didn't submit a PR because it's a one-line change.

Data returner decorator

Actually data is returned as is. It could be interesting if we can select a strategy in order to prepare the data before use it.

InfluxDB\Decorator\ArrayObject

This should clarifies the way of use it

$results = $client->query("select * from serie1");
foreach ($results as $result) {
  echo $result->time . " " . $result->myValue
}

Instead of

foreach ($results[0]["points"] as $result) {
  echo $result[0] . " " . $result[3]; // cryptic third value...
}

Separate `Options`

Actually HTTP options and UDP/IP options are different options set. Maybe could be useful separate those elements in separate classes.

Line protocol

Do you have plans to move to the Line Protocol as JSON has been depreciated?

Add a factory to prepare the client

Generate the client is not simple, add a factory method in order to create a valid client instance from a list of options.

Something like:

Client::factory([
  "adapter" => [
    "name" => "GuzzleAdapter",
  ],
  "options" => [
    "host" => "localhost",
    "port" => 8086
  ]
]);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.