Package: influxgraph
InfluxGraphAnInfluxDBstorage plugin forGraphite-API. Graphite with InfluxDB data store from any kind of schema(s) used in the DB.This project started as a re-write ofgraphite influxdb, now a separate project.InstallationDocker ComposeIncompose directorycan be found docker-compose configuration that will spawn all necessary services for a complete monitoring solution with:InfluxDBTelegrafGraphite API with InfluxGraphGrafana dashboardTo use, within compose directory run:docker-composeupGrafana will be running onhttp://localhost:3000with Graphite datasource for InfluxDB data available athttp://localhost. Add a new Graphite datasource to Grafana - default Grafana user/pass is admin/admin - to create dashboards with.Seecompose configuration readmefor more details.Docker Imagedockerpullinfluxgraph/influxgraphdockercreate--name=influxgraph-p8000:80influxgraph/influxgraphdockerstartinfluxgraphThere will now be a Graphite-API running onlocalhost:8000from the container with a default InfluxDB configuration and memcache enabled. Finder expects InfluxDB to be running onlocalhost:8086by default.The image will use a suppliedgraphite-api.yamlon build, whendocker buildis called on an InfluxGraph image.Docker fileused to build container can be found underdockerdirectory of the repository.NoteIf having issues with the container accessing the host’s InfluxDB service then either use--network="host"when launching the container or build a new image with a provided configuration file containing the correctInfluxDB host:portdestination.Manual InstallationpipinstallinfluxgraphUse of a localmemcachedservice is highly recommended - see configuration section on how to enable.Mimimal configuration for Graphite-API is below. SeeFull Configuration Examplefor all possible configuration options./etc/graphite-api.yamlfinders:-influxgraph.InfluxDBFinderSee theWikiandConfigurationsection for details.Table of ContentsInfluxGraphInstallationDocker ComposeDocker ImageManual InstallationMain featuresGoogle User’s GroupGoalsNon-GoalsDependenciesInfluxDB Graphite metric templatesRetention policy configurationConfigurationMinimal ConfigurationFull Configuration ExampleAggregation function configurationMemcached InfluxDBCalculated intervalsVarnish caching InfluxDB APIOptional C ExtensionsKnown LimitationsDatafillparameter and counter valuesIndex for Graphite metric pathsMain featuresInfluxDB Graphite template support - expose InfluxDB tagged data as Graphite metrics with configurable metric pathsDynamically calculated group by intervals based on query date/time range - fast queries regardless of the date/time they spanConfigurable per-query aggregation functions by regular expression patternConfigurable per-query retention policies by query date/time range. Automatically use pre-calculated downsampled data in a retention policy for historical dataFast in-memory index for Graphite metric path queries as a Python native code extensionMulti-fetch enabled - fetch data for multiple metrics with one query to InfluxDBMemcached integrationPython 3 and PyPy compatibilityGood performance even with extremely large number of metrics in the DB - generated queries are guaranteed to haveO(1)performance characteristicsGoogle User’s GroupThere is aGoogle user’s group for discussionwhich is open to the public.GoalsInfluxDB as a drop-in replacement data store to the Graphite query APIBackwards compatibility with existing Graphite API clients like Grafana and Graphite installations migrated to InfluxDB data stores using Graphite input servicewith or withoutGraphite template configurationExpose native InfluxDB line protocol ingested data via the Graphite APIClean, readable code with complete documentation for public endpointsComplete code coverage with both unit and integration testing. Code has>90%test coverage and is integration tested against a real InfluxDB serviceGood performance at large scale. InfluxGraph is used in production with good performance on InfluxDB nodes with cardinality exceeding 5M and a write rate of over 5M metrics/minute or 66K/second.The first three goals provide bothA backwards compatible migration path for existing Graphite installations to use InfluxDB as a drop-in storage back-end replacement with no API client side changes required, meaning existing Grafana or other dashboards continue to work as-is.A way for native InfluxDB collection agents to expose their data via theGraphite APIwhich allows the use of any Graphite API talking tool, the plethora of Graphite API functions, custom functions, functions across series, multi-series plotting and functions via Graphite glob expressions et al.As of this time of writing, no alternatives exist with similar functionality, performance and compatibility.Non-GoalsGraphite-Web support from the official Graphite projectDependenciesWith the exception ofInfluxDBitself, the other dependencies are installed automatically bypip.influxdbPython moduleGraphite-APIpython-memcachedPython moduleInfluxDBservice, versions1.0or higherInfluxDB Graphite metric templatesInfluxGraphcan make use of any InfluxDB data and expose them as Graphite API metrics, as well as make use of Graphite metrics added to InfluxDB as-is sans tags.Even data written to InfluxDB by native InfluxDB API clients can be exposed as Graphite metrics, allowing transparent to clients use of the Graphite API with InfluxDB acting as its storage back-end.To make use of tagged InfluxDB data, the finder needs to know how to generate a Graphite metric path from the tags used by InfluxDB.The easiest way to do this is to use the Graphite service in InfluxDB with configured templates which can be used as-is inInfluxGraphconfiguration - seeFull Configuration Examplesection for details. This presumes existing collection agents are using the Graphite line protocol to write to InfluxDB via its Graphite input service.If, on the other hand, nativeInfluxDBmetrics collection agents likeTelegrafare used, that data can too be exposed as Graphite metrics by writing appropriate template(s) in Graphite-API configuration alone.SeeTelegraf default configuration templatefor an example of this.By default, the storage plugin makes no assumptions that data is tagged, per InfluxDB default Graphite service template configuration as below:[[graphite]]
  <..>
  # templates = []Retention policy configurationPending implementation of a feature request that will allow InfluxDB to select and/or merge results from down-sampled data as appropriate, retention policy configuration is needed to support the use-case of down-sampled data being present in non default retention policies:retention_policies:<time interval of query>:<retention policy name>For example, to make a query with a group by interval of one minute or less, interval above one and less than thirty minutes and interval thirty minutes or above use the retention policies nameddefault,10minand30minrespectively:retention_policies:60:default600:10min1800:30minWhile not required, retention policy interval is best kept close to or identical todeltasinterval for best influx query performance.SeeFull Configuration Examplefile for additional details.ConfigurationMinimal ConfigurationIn graphite-api config file at/etc/graphite-api.yaml:finders:-influxgraph.InfluxDBFinderThe folowing default Graphite-API configuration is used if not provided:influxdb:db:graphiteFull Configuration ExampleSeeGraphite-API example configuration filefor a complete configuration example.Aggregation function configurationThe finder supports configurable aggregation and selector functions to use per metric path regular expression pattern. This is the equivalent ofstorage-aggregation.confin Graphite’scarbon-cache.Default aggregation function used ismeanif no configuration provided nor any matching configuration.InfluxGraph has pre-defined aggregation configuration matchingcarbon-cachedefaults, namely:aggregation_functions:\.min$:min\.max$:max\.last$:last\.sum$:sumDefaults are overridden ifaggregation_functionsis configured ingraphite-api.yamlas shown in configuration example.An error will be printed to stderr if a configured aggregation function is not a known valid InfluxDB aggregation or selector method perInfluxDB function list.Transformation functions, for examplederivative, may _not_ be used as they require a separate aggregation to be performed. Transformations are performed by Graphite-API instead, which also supports pluggable functions.Known InfluxDB aggregation and selector functions are defined atinfluxgraph.constants.INFLUXDB_AGGREGATIONSand can be overriden if necessary.NoteWhen querying identical fields from multiple measurements InfluxDB allows onlyoneaggregation function to be used for all identical fields in the query.In other words, make sure all identical InfluxDB fields matched by a Graphite query pattern, for examplemy_host.cpu.*.*have the same aggregation function configured.When using neither tagged data nor template configuration, the InfluxDB field to be queried is alwaysvalue. This is the case where this limitation is (most) relevant.InfluxGraphwill use the first aggregation function configured and log a warning message to that effect if a pattern query resolves to multiple aggregation functions.Memcached InfluxDBMemcached can be used to cache InfluxDB data so theGraphite-APIcan avoid querying the DB if it does not have to.TTL configuration for memcache as shown inFull Configuration Exampleis only for InfluxDB series list with data query TTL set to the grouping interval used.For example, for a query spanning twenty-four hours, a group by interval of one minute is used by default. TTL for memcache is set to one minute for that query.For a query spanning one month, a fifteen minute group by interval is used by default. TTL is also set to fifteen minutes for that query.Calculated intervalsA datagroup byinterval is automatically calculated depending on the date/time range of the query. This keeps data size in check regardless of query range and speeds up graph generation for large ranges.Default configuration mirrors whatGrafanauses with the native InfluxDB API.Overriding the automatically calculated intervals can be done via the optionaldeltasconfiguration. SeeFull Configuration Examplefile for all supported configuration options.Unlike other Graphite compatible data stores, InfluxDB performs aggregation on data query, not on ingestion. Queries made by InfluxGraph are therefore always aggregation queries with a group by clause.Users that wish to retrieve all, non-aggregated, data points regardless of date/time range are advised to queryInfluxDBdirectly.Varnish caching InfluxDB APIThe following is a sample configuration ofVarnishas an HTTP cache in front of InfluxDB’s HTTP API. It uses Varnish’s default TTL of 60 sec for all InfluxDB queries.The intention is for a local (to InfluxDB) Varnish service to cache frequently accessed data and protect the database from multiple identical requests, for example multiple users viewing the same dashboard.InfluxGraph configuration should use Varnish port to connect to InfluxDB.Unfortunately, given that clients like Grafana use POST requests for querying the Graphite API, which cannot be cached, using Varnish in front of a Graphite-API webapp would have no effect. Multiple requests for the same dashboard/graph will therefore still hit Graphite-API, but with Varnish in front of InfluxDB the more sensitive DB is spared from duplicated queries.Substitute the default8086backend port with the InfluxDB API port for your installation if needed:backenddefault{.host="127.0.0.1";.port="8086";}subvcl_recv{unsetreq.http.cookie;}Graphite API example configuration:finders:-influxgraph.InfluxDBFinderinfluxdb:port:<varnish port>Where<varnish_port>is Varnish’s listening port.Any other HTTP caching service will similarly work just as well.Optional C ExtensionsIn order of fastest to slowest, here is how the supported interpreters fare with and without C extensions. How much faster depends largely on hardware and compiler used - can expect at least15xand4xperformance increases for CPython with extensions and PyPy respectively compared to standard CPython without extensions.CPython with extensions will also use about20xless memory for the index than either PyPy or CPython without extensions.CPython with C extensionsPypyCPythonThere are two performance tests in the repository that can be used to see relative performance with and without extensions, forindexandtemplatefunctionality respectively. On PyPy extensions are purposefully disabled.Known LimitationsDatafillparameter and counter valuesChanged in version 1.3.6As of version1.3.6, the defaultfillparameter isnullso as to not add values that do not exist in data - waspreviousin prior versions.This default will break derivative calculated counter values when data sampling rate exceeds configured interval for the query - seeCalculated intervals.For example, with a data sampling rate of sixty (60) seconds and defaultdeltasconfiguration, queries of thirty (30) minutes and below will use a thirty (30) second interval and will contain null datapoints. This in turn causes Graphite functions likederivativeandnon_negative_derivativeto only contain null datapoints.The fill parameter is configurable - seeFull Configuration Example- but is currently common for all metric paths.Forderivativeand related functions to work, either setdeltasconfiguration to not go below data sampling rate or setfillconfiguration toprevious.Index for Graphite metric pathsThe index implementation via native code extension releases Python’s GIL as much as possible, however, there will still be a response time increase while index is being re-built.Without extensions response time increase will be much higher - building with extensions is highly recommended.That said, building extensions can be disabled by runningsetup.pywith theDISABLE_INFLUXGRAPH_CEXT=1environment variable set. A notice will be displayed bysetup.pythat extensions have been disabled.Note that without native extension, performance is much lower and memory use of index much higher.