Coder Social home page Coder Social logo

influxgraph / influxgraph Goto Github PK

View Code? Open in Web Editor NEW
91.0 9.0 23.0 1.24 MB

Graphite InfluxDB backend. InfluxDB storage finder / plugin for Graphite API.

License: Apache License 2.0

Python 98.83% Shell 0.50% Dockerfile 0.67%
influxdb monitoring metrics grafana graphite timeseries visualisation graphite-api metrics-gathering metrics-library

influxgraph's Introduction

InfluxGraph

An InfluxDB storage plugin for Graphite-API. Graphite with InfluxDB data store from any kind of schema(s) used in the DB.

Latest Version

CI status

image

Documentation Status

image

image

This project started as a re-write of graphite influxdb, now a separate project.

Installation

Docker Compose

In compose directory can be found docker-compose configuration that will spawn all necessary services for a complete monitoring solution with:

  • InfluxDB
  • Telegraf
  • Graphite API with InfluxGraph
  • Grafana dashboard

To use, within compose directory run:

docker-compose up

Grafana will be running on http://localhost:3000 with Graphite datasource for InfluxDB data available at http://localhost. Add a new Graphite datasource to Grafana - default Grafana user/pass is admin/admin - to create dashboards with.

See compose configuration readme for more details.

Docker Image

docker pull influxgraph/influxgraph
docker create  --name=influxgraph -p 8000:80 influxgraph/influxgraph
docker start influxgraph

There will now be a Graphite-API running on localhost:8000 from the container with a default InfluxDB configuration and memcache enabled. Finder expects InfluxDB to be running on localhost:8086 by default.

The image will use a supplied graphite-api.yaml on build, when docker build is called on an InfluxGraph image.

Docker file used to build container can be found under docker directory of the repository.

Note

If 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 correct InfluxDB host:port destination.

Manual Installation

pip install influxgraph

Use of a local memcached service is highly recommended - see configuration section on how to enable.

Mimimal configuration for Graphite-API is below. See Full Configuration Example for all possible configuration options.

/etc/graphite-api.yaml

finders:
  - influxgraph.InfluxDBFinder

See the Wiki and Configuration section for details.

Table of Contents

Main features

  • InfluxDB Graphite template support - expose InfluxDB tagged data as Graphite metrics with configurable metric paths
  • Dynamically calculated group by intervals based on query date/time range - fast queries regardless of the date/time they span
  • Configurable per-query aggregation functions by regular expression pattern
  • Configurable per-query retention policies by query date/time range. Automatically use pre-calculated downsampled data in a retention policy for historical data
  • Fast in-memory index for Graphite metric path queries as a Python native code extension
  • Multi-fetch enabled - fetch data for multiple metrics with one query to InfluxDB
  • Memcached integration
  • Python 3 and PyPy compatibility
  • Good performance even with extremely large number of metrics in the DB - generated queries are guaranteed to have O(1) performance characteristics

Google User's Group

There is a Google user's group for discussion which is open to the public.

Goals

  • InfluxDB as a drop-in replacement data store to the Graphite query API
  • Backwards compatibility with existing Graphite API clients like Grafana and Graphite installations migrated to InfluxDB data stores using Graphite input service with or without Graphite template configuration
  • Expose native InfluxDB line protocol ingested data via the Graphite API
  • Clean, readable code with complete documentation for public endpoints
  • Complete code coverage with both unit and integration testing. Code has >90% test coverage and is integration tested against a real InfluxDB service
  • Good 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 both

  • A 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 the Graphite API which 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-Goals

  • Graphite-Web support from the official Graphite project

Dependencies

With the exception of InfluxDB itself, the other dependencies are installed automatically by pip.

  • influxdb Python module
  • Graphite-API
  • python-memcached Python module
  • InfluxDB service, versions 1.0 or higher

InfluxDB Graphite metric templates

InfluxGraph can 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 in InfluxGraph configuration - see Full Configuration Example section 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, native InfluxDB metrics collection agents like Telegraf are used, that data can too be exposed as Graphite metrics by writing appropriate template(s) in Graphite-API configuration alone.

See Telegraf default configuration template for 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 configuration

Pending 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 named default, 10min and 30min respectively:

retention_policies:
    60: default
    600: 10min
    1800: 30min

While not required, retention policy interval is best kept close to or identical to deltas interval for best influx query performance.

See Full Configuration Example file for additional details.

Configuration

Minimal Configuration

In graphite-api config file at /etc/graphite-api.yaml:

finders:
  - influxgraph.InfluxDBFinder

The folowing default Graphite-API configuration is used if not provided:

influxdb:
   db: graphite

Full Configuration Example

See Graphite-API example configuration file for a complete configuration example.

Aggregation function configuration

The finder supports configurable aggregation and selector functions to use per metric path regular expression pattern. This is the equivalent of storage-aggregation.conf in Graphite's carbon-cache.

Default aggregation function used is mean if no configuration provided nor any matching configuration.

InfluxGraph has pre-defined aggregation configuration matching carbon-cache defaults, namely:

aggregation_functions:
    \.min$ : min
    \.max$ : max
    \.last$ : last
    \.sum$ : sum

Defaults are overridden if aggregation_functions is configured in graphite-api.yaml as 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 per InfluxDB function list.

Transformation functions, for example derivative, 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 at influxgraph.constants.INFLUXDB_AGGREGATIONS and can be overriden if necessary.

Note

When querying identical fields from multiple measurements InfluxDB allows only one aggregation 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 example my_host.cpu.*.* have the same aggregation function configured.

When using neither tagged data nor template configuration, the InfluxDB field to be queried is always value. This is the case where this limitation is (most) relevant.

InfluxGraph will use the first aggregation function configured and log a warning message to that effect if a pattern query resolves to multiple aggregation functions.

Memcached InfluxDB

Memcached can be used to cache InfluxDB data so the Graphite-API can avoid querying the DB if it does not have to.

TTL configuration for memcache as shown in Full Configuration Example is 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 intervals

A data group by interval 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 what Grafana uses with the native InfluxDB API.

Overriding the automatically calculated intervals can be done via the optional deltas configuration. See Full Configuration Example file 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 query InfluxDB directly.

Varnish caching InfluxDB API

The following is a sample configuration of Varnish as 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 default 8086 backend port with the InfluxDB API port for your installation if needed:

backend default {
  .host = "127.0.0.1";
  .port = "8086";
}

sub vcl_recv {
  unset req.http.cookie;
}

Graphite API example configuration:

finders:
  - influxgraph.InfluxDBFinder
influxdb:
  port: <varnish port>

Where <varnish_port> is Varnish's listening port.

Any other HTTP caching service will similarly work just as well.

Optional C Extensions

In 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 least 15x and 4x performance increases for CPython with extensions and PyPy respectively compared to standard CPython without extensions.

CPython with extensions will also use about 20x less memory for the index than either PyPy or CPython without extensions.

  1. CPython with C extensions
  2. Pypy
  3. CPython

There are two performance tests in the repository that can be used to see relative performance with and without extensions, for index and template functionality respectively. On PyPy extensions are purposefully disabled.

Known Limitations

Data fill parameter and counter values

Changed in version 1.3.6

As of version 1.3.6, the default fill parameter is null so as to not add values that do not exist in data - was previous in prior versions.

This default will break derivative calculated counter values when data sampling rate exceeds configured interval for the query - see Calculated intervals.

For example, with a data sampling rate of sixty (60) seconds and default deltas configuration, 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 like derivative and non_negative_derivative to only contain null datapoints.

The fill parameter is configurable - see Full Configuration Example - but is currently common for all metric paths.

For derivative and related functions to work, either set deltas configuration to not go below data sampling rate or set fill configuration to previous.

Index for Graphite metric paths

The 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 running setup.py with the DISABLE_INFLUXGRAPH_CEXT=1 environment variable set. A notice will be displayed by setup.py that extensions have been disabled.

Note that without native extension, performance is much lower and memory use of index much higher.

influxgraph's People

Contributors

beardpapa avatar breml avatar brutasse avatar dieterbe avatar juise avatar justin8 avatar lcharkiewicz avatar magec avatar mbell697 avatar mnuessler avatar pkittenis avatar tux1337 avatar vladimir-smirnov-sociomantic 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  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

influxgraph's Issues

Feature query

Cannot find any contact mail or info about this project oe the authors, so i'll try to reach to you from here...

I have a question: Since graphite itself doesn't support sub-second resolution (let's say 10 samples per second )on stored data, and you're using influxdb as the backend. Do you know/have tested what happens when you inject sub second data into influx and try to render it using graphite api? Does the graphite api preserve that resolution?

influxgraph makes gunicorn/graphiteapi fail to start

As soon as I add influxdb finder to graphite-api.yaml, gunicorn won't start:
[2016-11-14 16:36:31 +0000] [15934] [INFO] Starting gunicorn 19.6.0
[2016-11-14 16:36:31 +0000] [15934] [INFO] Listening at: http://127.0.0.1:8080 (15934)
[2016-11-14 16:36:31 +0000] [15934] [INFO] Using worker: sync
[2016-11-14 16:36:31 +0000] [15939] [INFO] Booting worker with pid: 15939
[2016-11-14 16:36:31 +0000] [15940] [INFO] Booting worker with pid: 15940
{"path": "/etc/graphite-api.yaml", "event": "loading configuration"}
/opt/graphite-api/lib/python2.7/site-packages/flask/exthook.py:71: ExtDeprecationWarning: Importing flask.ext.cache is deprecated, use flask_cache instead.
.format(x=modname), ExtDeprecationWarning
{"path": "/etc/graphite-api.yaml", "event": "loading configuration"}
/opt/graphite-api/lib/python2.7/site-packages/flask/exthook.py:71: ExtDeprecationWarning: Importing flask.ext.cache is deprecated, use flask_cache instead.
.format(x=modname), ExtDeprecationWarning
Traceback (most recent call last):
File "/opt/graphite-api/bin/gunicorn", line 11, in
load_entry_point('gunicorn==19.6.0', 'console_scripts', 'gunicorn')()
File "/opt/graphite-api/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 74, in run
WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
File "/opt/graphite-api/lib/python2.7/site-packages/gunicorn/app/base.py", line 192, in run
super(Application, self).run()
File "/opt/graphite-api/lib/python2.7/site-packages/gunicorn/app/base.py", line 72, in run
Arbiter(self).run()
File "/opt/graphite-api/lib/python2.7/site-packages/gunicorn/arbiter.py", line 218, in run
self.halt(reason=inst.reason, exit_status=inst.exit_status)
File "/opt/graphite-api/lib/python2.7/site-packages/gunicorn/arbiter.py", line 331, in halt
self.stop()
File "/opt/graphite-api/lib/python2.7/site-packages/gunicorn/arbiter.py", line 381, in stop
time.sleep(0.1)
File "/opt/graphite-api/lib/python2.7/site-packages/gunicorn/arbiter.py", line 231, in handle_chld
self.reap_workers()
File "/opt/graphite-api/lib/python2.7/site-packages/gunicorn/arbiter.py", line 506, in reap_workers
raise HaltServer(reason, self.WORKER_BOOT_ERROR)
gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>

I tried putting in "full config" from your example - but still no change. switching nothing except back to whisper finder - and it works again :(

Any hints on where to look? (its a CentOS 7 box)

Umm. am I an idiot?!

So I am a BIT noobish to Graphite, but not to python or Influx.

I cloned the repo....great.

Ran python setup.py install....great.

So...how do I run this? All I see is Versioneer.py???

Build _manylinux_ binary wheels of releases

Currently only source distributions are deployed to PyPi.

  • Make it possible to build manylinux binary wheels via Travis-CI builds
  • Publish those to PyPi

This will make binary wheels available for most linux distributions, so they do not have to build from source to get native code extensions when installing via pip.

See manylinux branch for a WIP.

multiple target query fails with IndexError

I populated my influxdb with:

> insert test,stat=count value=1 
> insert test,stat=upper_90 value=10 
> insert test2,stat=count value=20 
> insert test2,stat=upper_90 value=15 

Then using grafana the following query is produced:

target=test.count
&target=test2.upper_90
&from=1495610419&until=1495610636&format=json&maxDataPoints=1912

the data is then returned as:

test.count = 10 where it should be 1
test.upper_90 is correct

My template is:

- "measurement.stat"

From my trace the query to influxdb is:

/query?q=select mean("value") as "value" from "test", "test2" where (time > 1495610419s and time <= 1495610636s) AND (("stat" = 'count' OR "stat" = 'upper_90')) GROUP BY time(10s), "stat" fill(previous)&epoch=s&db=stats

Fields for measurement appear in all metric paths that contain measurement

With a template like

env.host.measurement.field*

And metrics test.host1.net.eth0 and test.host2.net.eth1

The metrics/find query test.host1.net.* will return both eth0 and eth1 even though eth1 is not a host1 metric.

As the measurement produced by the template is net in this case, net is common to both the host1 and host2 tags and there is no way in influx to query for field keys only for a specific tag value, this is likely a limitation that will remain unless the influx query language makes it possible.

Blocked by 8363

Improve InfluxDB response parsing performance

Feature request

As of 1.5.0, the biggest performance bottleneck is influxdb-python json de-serialisation performance. For large number of series, it can take minutes for influxdb-python to parse the json response (5-10MB is typical), while influxdb responds in a few seconds. This is more of an issue for index building which needs to query all series from the DB but also for large amounts of data, eg when date period requested is very large.

A new client can be written in influxgraph with the limited functionality needed by influxgraph - querying and writing for tests - using ujson as the json serialiser which is an order of magnitude faster than the requests module built-in serialiser.

Multiple targets in query at once come back with mixed-up labels

When I make a request like the following, I get back results with the labels in the same order I requested, but the data comes back in a different order. So the labels are attached to the wrong data.

curl -v 'http://graphite-api:8000/render?
target=scaleToSeconds(nonNegativeDerivative(0769ecf3.*/cpu/total/user),1)&
target=scaleToSeconds(nonNegativeDerivative(0769ecf3.*/cpu/total/system),1)&
target=scaleToSeconds(nonNegativeDerivative(0769ecf3.*/cpu/total/iowait),1)&
target=scaleToSeconds(nonNegativeDerivative(0769ecf3.*/cpu/total/steal),1)&format=json&maxDataPoints=1'

Updates of Docker Image

The docker image that is mentioned in the readme seems to be unmaintained: ikuosu/influxgraph

The last push to Docker Hub was with the release of 1.3.7 one year ago.
Are there any plans to change this situation?

In my opinion the best would be an automated build triggered on new releases and updates of the baseimage used in the dockerfile. Ideally as a repo Influxgraph/Influxgraph, the own Namespace is more trustworthy.

Values are not fetched

I use the docker instance, hosted on a server collecting data from sensors. Data as collected through influxdb http API calls.

My influxdb series look like :

yoctopuce,ip=10.120.237.131,name=YHUBGSM3-70AA4
yoctopuce,ip=10.120.249.139,name=YHUBGSM3-70AA4
...

My fields Keys are :

> SHOW FIELD KEYS FROM yoctopuce
name: yoctopuce
fieldKey                      fieldType
--------                      ---------
pm1                           float
pm10                          float
pm25                          float
value1                        float

Render output is truncated as follows : (no values after | )
http://xxx.xxx.xxx.xxx:8000/render?from=-1h&target=*.yoctopuce.*.pm25&format=raw

10.109.242.23.yoctopuce.YHUBGSM3-70AE0.pm25,1491818207,1491821807,10|
10.120.237.131.yoctopuce.YHUBGSM3-70AA4.pm25,1491818207,1491821807,10|

Whereas the request :
SELECT mean("pm25") FROM "yoctopuce" WHERE time > now() - 1h GROUP BY TIME(10s)
would send back :

name: yoctopuce
time                mean
----                ----
1491819050000000000 8.864
1491819060000000000 9.34
1491819070000000000 9.131
1491819080000000000 8.975
1491819090000000000 8.977
1491819100000000000 8.854
1491819110000000000 9.286
1491819120000000000 8.791
1491819130000000000 10.268
1491819140000000000 9.761
1491819150000000000 10.616
1491819160000000000 11.169333333333334

My graphite-api.yaml is :

finders:
  - influxgraph.InfluxDBFinder
influxdb:
  host: dockerhost
  db: XXXXX
  user: XXXXX
  pass: XXXXX
  templates:
    # Default telegraf agent measurement types                                  
    #- "*.diskio. host.measurement.name.field*"                                 
    #- "*.disk. host.measurement.path.fstype.field*"                            
    #- "*.cpu. host.measurement.cpu.field*"                                     
    - "*.yoctopuce. *.measurement.name.field*"
    - ip.measurement.name.field*
  memcache:
    host: localhost
  log_file: /var/log/influxgraph/influxgraph.log
  log_level: debug
  deltas:
    86400 : 10
  aggregation_functions:
    \.min$ : min
    \.max$ : max
    \.last$ : last
    \.sum$ : sum
    \.mean$ : mean

What can possibly be wrong ?

Support for multiple databases as prefix

We're looking to use many different databases with influx due to privilege separation and creating a graphite-api instance for each seems infeasible. I'd like to ask if it is possible to use multiple databases and select them as the prefix as opposed to hardcoding the database in the config file.

So by way of example, say we have db1 db2 and db3 in influx, with a measurement called temperature with field celcius in each. I'd like to use

db1.temperature.celcius
db2.temperature.celcius
db3.temperature.celcius

Are there any reasons why this would not be possible? I've quickly scanned the code but didn't see a quick and dirty way to do this.

No handlers could be found for logger "influxgraph"

Hi,
I run under ubuntu 16.04, using nginx and uwsgi to connect to graphite-api
All the services are starting, anyway uwsgi complains that :

No handlers could be found for logger "influxgraph"

I have carrefully followed instructions for the install. What kind of info can I provide to help to sort this out ?

Julien

504 Gateway Timeout with Influx Cloud Integration

I am having problem connecting to influx Cloud cluster:
I keep getting 504 Gateway Time-out when querying. It seems that Gunicorn workers are timing out, but there's not specific explanations why it happened:
from /var/log/graphite-api.log:

[2017-05-08 20:58:55 +0000] [22] [CRITICAL] WORKER TIMEOUT (pid:292)
[2017-05-08 20:58:55 +0000] [22] [CRITICAL] WORKER TIMEOUT (pid:293)

Here is my graphite-api.yaml:

finders:
  - influxgraph.InfluxDBFinder
influxdb:
  db: graphite
  host: my-influxcloud.net
  port: 8086
  user: my-username
  pass: my-password
  ssl: true

I also keep getting certificate verification warning in the log, but I am not sure what's the behaviour of urllib (whether it terminates the connection or not):

/srv/graphite-pypy/site-packages/requests/packages/urllib3/connectionpool.py:852: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

Building and refreshing of index happens in every worker process putting high load on Influx

Hello,

We're implementing influxgraph in our stack. We've found that building and refreshing index in InfluxDBFinder class happens in every worker that is spawned. For e.g if I run gunicorn with 10 processes like bin/gunicorn -w 10 I get 10 workers all of them which will query influx and build index concurrently. This puts a lot of unneeded pressure on InfluxDB. On a single server, we could build it once and make workers load/refresh it from the file.

I'd like to contribute a solution to this but don't want to do anything that is not aligned with the vision of the authors.

How about we make a configurable option to run a worker in a mode which only loads an index from disk and then we could create a separate worker that creates and refreshes the index.

Partial series and field keys from InfluxDB 1.2.0

We have ~75k series and when requesting the series list influxdb, 1.1.0, is returning a partial set of results, I think due to memory limits. influxgraph is then not noticing this that just saving the partial results.
I tried increacing the http_row_limit in influxdb to no effect.
Reducing the LOADER_LIMIT in constants.py to 5000 has fixed it for me but seems more of a hack.
It should handle the server setting the partial flag.
I think the partial flag may be returned in a different place in the json returned if it's a server side limit that you have hit. Maybe this is really a bug in python-influxdb?

Allow configurable prefix for retention policies

Feature Request

With the current InfluxDB down-sampling via continuous queries implementation, fields get a prefix added to them corresponding to the aggregation function used.

This breaks querying data in retention policies when using named fields (non value fields) as the field names do not match the original.

Add a configurable, per existing retention policy configuration, regex based field prefix to use for retention policy queries so that down sampled data in retention policies can be queried transparently.

Segfaults on building the index

Running Influxgraph 1.5.0

Started getting segfaults yesterday during index creation. Pretty sure it's choking on one or more bad series, but there are over 150,000 of them. I'll attach a debug dump from gunicorn/graphite-api. The segfault appear to happen when the initial series data is passed to parse_series() at classes/finder.py:566.

As I don't know what data is causing the problem I'm looking for help on determining that.

TypeError: object of type 'NoneType' has no len()

I'm trying to set it up with icinga2 - but I always get:

# gunicorn graphite_api.app:app 
[2018-04-04 18:33:27 +0000] [31596] [INFO] Starting gunicorn 19.4.5
[2018-04-04 18:33:27 +0000] [31596] [INFO] Listening at: http://127.0.0.1:8000 (31596)
[2018-04-04 18:33:27 +0000] [31596] [INFO] Using worker: sync
[2018-04-04 18:33:27 +0000] [31600] [INFO] Booting worker with pid: 31600
{"path": "/etc/graphite-api.yaml", "event": "loading configuration"}
[DEBUG] 2018-04-04 18:33:28,080 - finder.__init__() - Configured aggregation functions - {<_sre.SRE_Pattern object at 0x7f1880fa82a0>: 'last', <_sre.SRE_Pattern object at 0x7f1880f9f930>: 'min', <_sre.SRE_Pattern object at 0x7f1880f9fab0>: 'sum', <_sre.SRE_Pattern object at 0x7f1880f9f9f0>: 'max'}
[INFO] 2018-04-04 18:33:28,081 - finder._start_loader() - Starting initial series list load - this may take several minutes on databases with a large number of series..
[DEBUG] 2018-04-04 18:33:28,082 - finder.get_field_keys() - Found cached field keys
[DEBUG] 2018-04-04 18:33:28,082 - finder._get_series() - Series loader calling influxdb with query - SHOW SERIES LIMIT 100000 OFFSET 0
[INFO] 2018-04-04 18:33:28,190 - finder.build_index() - Starting index build
[INFO] 2018-04-04 18:33:28,190 - finder._series_loader() - Starting background series loader with interval 900
[DEBUG] 2018-04-04 18:33:28,191 - finder.get_series() - Found cached series for limit 100000, offset 0
[DEBUG] 2018-04-04 18:33:28,192 - finder.get_field_keys() - Found cached field keys
INFO] 2018-04-04 18:33:28,192 - finder.build_index() - Building index..
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/graphite_api/app.py", line 68, in <module>
    configure(app)
  File "/usr/local/lib/python2.7/dist-packages/graphite_api/config.py", line 141, in configure
    finders.append(load_by_path(finder)(config))
  File "/usr/local/lib/python2.7/dist-packages/influxgraph/classes/finder.py", line 123, in __init__
    self._start_reindexer(reindex_interval)
  File "/usr/local/lib/python2.7/dist-packages/influxgraph/classes/finder.py", line 163, in _start_reindexer
    self.build_index()
  File "/usr/local/lib/python2.7/dist-packages/influxgraph/classes/finder.py", line 567, in build_index
    separator=separator)
  File "influxgraph/ext/templates.pyx", line 195, in influxgraph.ext.templates.parse_series
  File "influxgraph/ext/templates.pyx", line 84, in influxgraph.ext.templates._parse_serie_with_tags
TypeError: object of type 'NoneType' has no len()

Can somebody give me a hint what could cause this problem?

Auto-conversion of tag values containing dots

Tags that contain dot-separated values, for example instance=172.16.179.252:8080 are not handled correctly upon loading from InfluxDB. When such metrics are fed to graphite via carbon, they are automatically converted to instance=172%2E16%2E179%2E252:8080 and further handled correctly. I would expect the same behaviour from influxgraph.

Use modified graphite-api package

Feature Request

Graphite-API seems to be getting less maintenance these days and there are finished bug fixes and feature PRs that would benefit this project that have not been reviewed nor merged.

Proposed changes

  • Fork and embed graphite-api as a submodule to this project, remove from requirements
  • Add following changes to forked graphite-api
    • Remove consolidation of data points by hard coded consolidateBy graphite function used by default in graphite-api before data is returned ( #42 )
    • Make cairo optional
    • Remove index file must exist requirement as it's not used by either graphite-api or influxgraph
    • asPercent not accepting multiple series - graphite-api/#150

influxgraph mixes target names and data

As graphite-influxdb is deprecated we've tried switching to inlfuxgraph, but we hit an issue along the way.
When requesting multiple targets, influxgraph seems to confuse the target names and the data, so that the returned result has wrong names.

For instance, the following query returns wrong data when using influxgraph, but correct data when using graphite-influxdb:

curl 'https://graphite.internal/render' -H 'Host: graphite.internal' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36' -H 'Accept: application/json, text/plain, */*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Referer: https://graphite.enableit.dk/grafana/' -H 'Content-Type: application/x-www-form-urlencoded' -H 'DNT: 1' -H 'Authorization: Basic cnVuZUBlbmFibGVpdC5kazoxNDgxMTkyMTg1ITdCbHNGdjFodFRWSGY5NDdzaE9sMEhFNmlOMG50a3FCVk0zQmg0U0taT3NlWHdtcU9hTE9TcFZhY1d4R2daaGM=' -H 'Connection: keep-alive' --data $'from=10%3A25_20161208&until=11%3A07_20161208&target=alias(c1mdewxeah.haproxy01.cpu.total.iowait%2C%20\'IO%20Wait\')&target=alias(c1mdewxeah.haproxy01.cpu.total.system%2C%20\'System\')&target=alias(c1mdewxeah.haproxy01.cpu.total.user%2C%20\'User\')&target=alias(c1mdewxeah.haproxy01.cpu.total.idle%2C%20\'Idle\')&format=json&maxDataPoints=316'

With influxgraph:

 [
  {"target": "IO Wait", "datapoints": [
    [186, 1481189100], [190, 1481189160], [190, 1481189220], [191, 1481189280], [191, 1481189340], [189, 1481189400], [191, 1481189460], [191, 1481189520], [190, 1481189580], [192, 1481189640], [190, 1481189700], [189, 1481189760], [190, 1481189820], [191, 1481189880], [190, 1481189940], [188, 1481190000], [191, 1481190060], [189, 1481190120], [188, 1481190180], [189, 1481190240], [177, 1481190300], [190, 1481190360], [190, 1481190420], [191, 1481190480], [192, 1481190540], [187, 1481190600], [189, 1481190660], [191, 1481190720], [190, 1481190780], [191, 1481190840], [190, 1481190900], [188, 1481190960], [190, 1481191020], [188, 1481191080], [189, 1481191140], [188, 1481191200], [189, 1481191260], [192, 1481191320], [190, 1481191380], [189, 1481191440], [186, 1481191500], [191, 1481191560], [191, 1481191620]]},
  {"target": "System", "datapoints": [
    [0, 1481189100], [0, 1481189160], [0, 1481189220], [0, 1481189280], [0, 1481189340], [0, 1481189400], [0, 1481189460], [0, 1481189520], [0, 1481189580], [0, 1481189640], [0, 1481189700], [0, 1481189760], [0, 1481189820], [0, 1481189880], [0, 1481189940], [0, 1481190000], [0, 1481190060], [0, 1481190120], [0, 1481190180], [0, 1481190240], [0, 1481190300], [0, 1481190360], [0, 1481190420], [0, 1481190480], [0, 1481190540], [0, 1481190600], [0, 1481190660], [0, 1481190720], [0, 1481190780], [0, 1481190840], [0, 1481190900], [0, 1481190960], [0, 1481191020], [0, 1481191080], [0, 1481191140], [0, 1481191200], [0, 1481191260], [0, 1481191320], [0, 1481191380], [0, 1481191440], [0, 1481191500], [0, 1481191560], [0, 1481191620]]},
  {"target": "User", "datapoints": [
    [2, 1481189100], [1, 1481189160], [1, 1481189220], [1, 1481189280], [1, 1481189340], [2, 1481189400], [1, 1481189460], [1, 1481189520], [1, 1481189580], [1, 1481189640], [2, 1481189700], [1, 1481189760], [1, 1481189820], [1, 1481189880], [1, 1481189940], [2, 1481190000], [1, 1481190060], [1, 1481190120], [1, 1481190180], [1, 1481190240], [3, 1481190300], [1, 1481190360], [1, 1481190420], [1, 1481190480], [1, 1481190540], [2, 1481190600], [1, 1481190660], [1, 1481190720], [1, 1481190780], [1, 1481190840], [2, 1481190900], [1, 1481190960], [1, 1481191020], [1, 1481191080], [1, 1481191140], [2, 1481191200], [1, 1481191260], [1, 1481191320], [1, 1481191380], [1, 1481191440], [2, 1481191500], [1, 1481191560], [1, 1481191620]]},
  {"target": "Idle", "datapoints": [
    [8, 1481189100], [6, 1481189160], [6, 1481189220], [4, 1481189280], [5, 1481189340], [6, 1481189400], [5, 1481189460], [5, 1481189520], [6, 1481189580], [5, 1481189640], [5, 1481189700], [6, 1481189760], [5, 1481189820], [5, 1481189880], [5, 1481189940], [6, 1481190000], [5, 1481190060], [6, 1481190120], [7, 1481190180], [7, 1481190240], [13, 1481190300], [6, 1481190360], [6, 1481190420], [5, 1481190480], [4, 1481190540], [7, 1481190600], [6, 1481190660], [5, 1481190720], [6, 1481190780], [5, 1481190840], [5, 1481190900], [6, 1481190960], [6, 1481191020], [7, 1481191080], [7, 1481191140], [7, 1481191200], [6, 1481191260], [5, 1481191320], [5, 1481191380], [7, 1481191440], [8, 1481191500], [5, 1481191560], [5, 1481191620]]}]

With graphite-influxdb:

[
  {"target": "IO Wait", "datapoints": [
    [0, 1481189100], [0, 1481189160], [0, 1481189220], [0, 1481189280], [0, 1481189340], [0, 1481189400], [0, 1481189460], [0, 1481189520], [0, 1481189580], [0, 1481189640], [0, 1481189700], [0, 1481189760], [0, 1481189820], [0, 1481189880], [0, 1481189940], [0, 1481190000], [0, 1481190060], [0, 1481190120], [0, 1481190180], [0, 1481190240], [0, 1481190300], [0, 1481190360], [0, 1481190420], [0, 1481190480], [0, 1481190540], [0, 1481190600], [0, 1481190660], [0, 1481190720], [0, 1481190780], [0, 1481190840], [0, 1481190900], [0, 1481190960], [0, 1481191020], [0, 1481191080], [0, 1481191140], [0, 1481191200], [0, 1481191260], [0, 1481191320], [0, 1481191380], [0, 1481191440], [0, 1481191500], [0, 1481191560], [null, 1481191620]]},
  {"target": "System", "datapoints": [
    [2, 1481189100], [1, 1481189160], [1, 1481189220], [1, 1481189280], [1, 1481189340], [2, 1481189400], [1, 1481189460], [1, 1481189520], [1, 1481189580], [1, 1481189640], [2, 1481189700], [1, 1481189760], [1, 1481189820], [1, 1481189880], [1, 1481189940], [2, 1481190000], [1, 1481190060], [1, 1481190120], [1, 1481190180], [1, 1481190240], [3, 1481190300], [1, 1481190360], [1, 1481190420], [1, 1481190480], [1, 1481190540], [2, 1481190600], [1, 1481190660], [1, 1481190720], [1, 1481190780], [1, 1481190840], [2, 1481190900], [1, 1481190960], [1, 1481191020], [1, 1481191080], [1, 1481191140], [2, 1481191200], [1, 1481191260], [1, 1481191320], [1, 1481191380], [1, 1481191440], [2, 1481191500], [1, 1481191560], [null, 1481191620]]},
  {"target": "User", "datapoints": [
    [8, 1481189100], [6, 1481189160], [6, 1481189220], [4, 1481189280], [5, 1481189340], [6, 1481189400], [5, 1481189460], [5, 1481189520], [6, 1481189580], [5, 1481189640], [5, 1481189700], [6, 1481189760], [5, 1481189820], [5, 1481189880], [5, 1481189940], [6, 1481190000], [5, 1481190060], [6, 1481190120], [7, 1481190180], [7, 1481190240], [13, 1481190300], [6, 1481190360], [6, 1481190420], [5, 1481190480], [4, 1481190540], [7, 1481190600], [6, 1481190660], [5, 1481190720], [6, 1481190780], [5, 1481190840], [5, 1481190900], [6, 1481190960], [6, 1481191020], [7, 1481191080], [7, 1481191140], [7, 1481191200], [6, 1481191260], [5, 1481191320], [5, 1481191380], [7, 1481191440], [8, 1481191500], [5, 1481191560], [null, 1481191620]]},
  {"target": "Idle", "datapoints": [
    [186, 1481189100], [190, 1481189160], [190, 1481189220], [191, 1481189280], [191, 1481189340], [189, 1481189400], [191, 1481189460], [191, 1481189520], [190, 1481189580], [192, 1481189640], [190, 1481189700], [189, 1481189760], [190, 1481189820], [191, 1481189880], [190, 1481189940], [188, 1481190000], [191, 1481190060], [189, 1481190120], [188, 1481190180], [189, 1481190240], [177, 1481190300], [190, 1481190360], [190, 1481190420], [191, 1481190480], [192, 1481190540], [187, 1481190600], [189, 1481190660], [191, 1481190720], [190, 1481190780], [191, 1481190840], [190, 1481190900], [188, 1481190960], [190, 1481191020], [188, 1481191080], [189, 1481191140], [188, 1481191200], [189, 1481191260], [192, 1481191320], [190, 1481191380], [189, 1481191440], [186, 1481191500], [191, 1481191560], [null, 1481191620]]}]

As you can see, the names and data are swapped. We've tried the current HEAD (317e2c3) and 1.0.0rc7 which both exhibit this behavior.

Make `fill` parameter configurable

Prepared queries use fill(previous) to ensure correct amount of data is returned to the Graphite API.

Make the parameter to the fill function configurable so that other values like previous, null et al can be configured by user.

Python 3.7 wheel build failing

Bug report

Steps to reproduce:

  1. python setup.py install
  2. python -c 'import influxgraph.ext.nodetrie'

Expected behaviour: Import works.

Actual behaviour:

+ /opt/python/cp37-cp37m/bin/python -c 'from influxgraph.ext.nodetrie import Node; Node()'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'influxgraph.ext.nodetrie

Additional info: Happens when building binary wheels on releases.

Couple things to do:

  • Enable wheel building on non-master branches so that they are tested with any changes - things can change in the upstream manylinux docker image that will cause these to fail even without any changes in code as has happened now. Currently wheel builds are only done on tagged builds.
  • The actual issue is I believe related to Cython support for python 3.7 Re-generating the C sources with latest cython version should fix this.

504 Gateway Time-out w/ docker container

I started up a docker container, but get no UI.

$ docker run --name=influxgraph -p 8000:80 ikuosu/influxgraph:1.3.3
*** Running /etc/my_init.d/00_regen_ssh_host_keys.sh...
*** Running /etc/my_init.d/dockerhost.sh...
*** Running /etc/rc.local...
*** Booting runit daemon...
*** Runit started as PID 14
May  8 22:49:59 bee307f9ae4d syslog-ng[23]: syslog-ng starting up; version='3.5.6'

Influxdb is available locally

$ curl -v localhost:8086/ping
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8086 (#0)
> GET /ping HTTP/1.1
> Host: localhost:8086
> User-Agent: curl/7.50.1
> Accept: */*
> 
< HTTP/1.1 204 No Content
< Content-Type: application/json
< Request-Id: 2e0a32db-3441-11e7-a07b-000000000000
< X-Influxdb-Version: 1.2.2
< Date: Mon, 08 May 2017 22:53:40 GMT
< 
* Connection #0 to host localhost left intact

But not available in the container. Running w/ host networking fixes that

$ docker run --name=influxgraph -p 8000:80 --network=host ikuosu/influxgraph:1.3.3
$ docker exec -it influxgraph bash
root@mathewslaptop:/# curl -v localhost:8086/ping
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8086 (#0)
> GET /ping HTTP/1.1
> Host: localhost:8086
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 204 No Content
< Content-Type: application/json
< Request-Id: 7c0ad0a1-3441-11e7-a090-000000000000
< X-Influxdb-Version: 1.2.2
< Date: Mon, 08 May 2017 22:55:51 GMT
< 
* Connection #0 to host localhost left intact

Either way though, nothing is returned from a web request. It just hangs.

The docker logs have nothing in them. /var/log/graphite-api.log may tell you something.

[2017-05-08 22:55:42 +0000] [23] [DEBUG] Current configuration:
  config: None
  bind: ['0.0.0.0:8000']
  backlog: 2048
  workers: 2
  worker_class: sync
  threads: 1
  worker_connections: 1000
  max_requests: 0
  max_requests_jitter: 0
  timeout: 120
  graceful_timeout: 30
  keepalive: 2
  limit_request_line: 4094
  limit_request_fields: 100
  limit_request_field_size: 8190
  reload: False
  reload_engine: auto
  spew: False
  check_config: False
  preload_app: False
  sendfile: None
  chdir: /etc/service/graphite-api
  daemon: False
  raw_env: []
  pidfile: None
  worker_tmp_dir: None
  user: 0
  group: 0
  umask: 0
  initgroups: False
  tmp_upload_dir: None
  secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
  forwarded_allow_ips: ['127.0.0.1']
  accesslog: None
  access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
  errorlog: -
  loglevel: debug
  capture_output: False
  logger_class: gunicorn.glogging.Logger
  logconfig: None
  syslog_addr: udp://localhost:514
  syslog: False
  syslog_prefix: None
  syslog_facility: user
  enable_stdio_inheritance: False
  statsd_host: None
  statsd_prefix: 
  proc_name: None
  default_proc_name: graphite_api.app:app
  pythonpath: None
  paste: None
  on_starting: <function on_starting at 0x00007fc63b4ebad8>
  on_reload: <function on_reload at 0x00007fc63b4eb970>
  when_ready: <function when_ready at 0x00007fc63b4eb808>
  pre_fork: <function pre_fork at 0x00007fc63b4eb6a0>
  post_fork: <function post_fork at 0x00007fc63b4eb538>
  post_worker_init: <function post_worker_init at 0x00007fc63b4eb3d0>
  worker_int: <function worker_int at 0x00007fc63b4eb268>
  worker_abort: <function worker_abort at 0x00007fc63b4eb100>
  pre_exec: <function pre_exec at 0x00007fc63b4eaf98>
  pre_request: <function pre_request at 0x00007fc63b4eae30>
  post_request: <function post_request at 0x00007fc63b4ead40>
  child_exit: <function child_exit at 0x00007fc63b4eabd8>
  worker_exit: <function worker_exit at 0x00007fc63b4eaa70>
  nworkers_changed: <function nworkers_changed at 0x00007fc63b4ea908>
  on_exit: <function on_exit at 0x00007fc63b4ea7a0>
  proxy_protocol: False
  proxy_allow_ips: ['127.0.0.1']
  keyfile: None
  certfile: None
  ssl_version: 2
  cert_reqs: 0
  ca_certs: None
  suppress_ragged_eofs: True
  do_handshake_on_connect: False
  ciphers: TLSv1
  raw_paste_global_conf: []
[2017-05-08 22:55:42 +0000] [23] [INFO] Starting gunicorn 19.7.1
[2017-05-08 22:55:42 +0000] [23] [DEBUG] Arbiter booted
[2017-05-08 22:55:42 +0000] [23] [INFO] Listening at: http://0.0.0.0:8000 (23)
[2017-05-08 22:55:42 +0000] [23] [INFO] Using worker: sync
[2017-05-08 22:55:42 +0000] [47] [INFO] Booting worker with pid: 47
[2017-05-08 22:55:42 +0000] [48] [INFO] Booting worker with pid: 48
[2017-05-08 22:55:42 +0000] [23] [DEBUG] 2 workers
{"path": "/etc/graphite-api.yaml", "event": "loading configuration"}
{"path": "/etc/graphite-api.yaml", "event": "loading configuration"}
[2017-05-08 22:57:43 +0000] [23] [CRITICAL] WORKER TIMEOUT (pid:47)
[2017-05-08 22:57:43 +0000] [23] [CRITICAL] WORKER TIMEOUT (pid:48)
[2017-05-08 22:57:43 +0000] [75] [INFO] Booting worker with pid: 75
[2017-05-08 22:57:43 +0000] [23] [DEBUG] 1 workers
[2017-05-08 22:57:43 +0000] [76] [INFO] Booting worker with pid: 76
[2017-05-08 22:57:43 +0000] [23] [DEBUG] 2 workers
{"path": "/etc/graphite-api.yaml", "event": "loading configuration"}
{"path": "/etc/graphite-api.yaml", "event": "loading configuration"}

Docker: make memcache max value configurable

I found no way to configure the memcache max value size in the official docker container.

We have a really large InfluxDB and have to increase the max value size (Parameter -I) to prevent following error message:

[ERROR] 2018-09-13 11:23:47,245 - finder.get_field_keys() - Could not add field key list to memcache - likely field list size over max memcache value

Change of /etc/default/memcached with MAXITEMSIZE="128m" has no effect,
also /etc/memcached.conf to -I 128m has no effect.
I guess the two files are ignored when the memcached service is not started over /etc/init.d/memcached as it is done with the own startup script memcached.sh.

So I changed the memcached.sh Script:

#!/bin/sh
exec /sbin/setuser memcache /usr/bin/memcached -I 128m -v >>/var/log/memcached.log 2>&1

My suggestion is to make the parameter configurable over an environment variable. Maybe it is possible to export the value from the graphite-api.yml and use them also for startup of memcached

memcache:
host: localhost
max_value: 128

What do you think about this? Am I wrong in one point?

Missing 'measurement' in template configuration causes invalid queries to be generated

Restarting docker container today, wanted to render : http://localhost:8000/render?from=-1h&target=*.cpu.cpu-total.{usage_user,usage_system}&format=svg

This was working before. But today I'm replied :

Traceback (most recent call last):
  File "/srv/graphite-pypy/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/srv/graphite-pypy/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/srv/graphite-pypy/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/srv/graphite-pypy/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/srv/graphite-pypy/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/srv/graphite-pypy/site-packages/graphite_api/app.py", line 375, in render
    data_store = fetchData(context, paths)
  File "/srv/graphite-pypy/site-packages/graphite_api/render/datalib.py", line 160, in fetchData
    time_info, series = finder.fetch_multi(nodes, startTime, endTime)
  File "/srv/graphite-pypy/site-packages/influxgraph/classes/finder.py", line 495, in fetch_multi
    data = self._run_infl_query(query, paths, measurement_data)
  File "/srv/graphite-pypy/site-packages/influxgraph/classes/finder.py", line 511, in _run_infl_query
    data = self.client.query(query, params=_INFLUXDB_CLIENT_PARAMS)
  File "/srv/graphite-pypy/site-packages/influxdb/client.py", line 347, in query
    in data.get('results', [])
  File "/srv/graphite-pypy/site-packages/influxdb/resultset.py", line 23, in __init__
    raise InfluxDBClientError(self.error)
InfluxDBClientError: invalid measurement

What can be this ?

Double consolidation/aggregation of data points by graphite-api

Bug reports

This is a graphite-api issue, which has ported graphite-web changes that target carbon back-ends but impact all other alternative back-ends including influx. Changing it on graphite-api upstream is not likely to be accepted as it would then diverge from graphite-web upstream.

Steps to reproduce:

  1. Default settings
  2. Query with interval < 60 sec, eg 1 hour query

Expected behaviour:

Data is aggregated by influxdb only from influxgraph aggregation configuration.

Actual behaviour:

Data is in addition aggregated by graphite-api consolidateBy and hard coded avg function on top of the already consolidated by influxdb data.

Additional info:

This results in loss of precision and incorrect data being returned to client as well as overhead due to multiple aggregations of same data. Data accuracy is further reduced when the configured influxgraph aggregation function is not mean or average where data is still consolidated by average before being returned by graphite-api.

Multiple request target paths with unique queries not returning data for all paths

Not sure if this is a problem with influxgraph, graphite-api, grafana or the combination, but when I define more than one query only the last one displays. The legend shows all of the queries, however, and in the debug log I can see all of the queries being run.

Grafana v3.1.1
Influxgraph 1.0.0rc7
Graphite-api v1.1.3

Thanks,

Bill

Per metric path configurable fill parameters

Currently there can only be one fill parameter configured for all metrics.

Ideally it would be configurable per metric path via regular expressions provided in config file, like aggregation functions are configured.

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.