Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically chose retention policy based on time range #4262

Closed
dennisjac opened this issue Mar 5, 2016 · 47 comments
Closed

Automatically chose retention policy based on time range #4262

dennisjac opened this issue Mar 5, 2016 · 47 comments
Labels
area/datasource datasource/InfluxDB prio/medium Important over the long term, but may not be staffed and/or may need multiple releases to complete. type/feature-request

Comments

@dennisjac
Copy link

Hi,
I'm currently looking at how to make Grafana use the aggregated retention policies in InfluxDB.
Issue #3943 apparently adds a way to set the retention policy statically for a query but this only works if you have a hand full of queries. The moment you have more dashboards this is not really a viable option.

What I'd rather like to propose is the ability to add a table in the settings that defines a retention policy based on time ranges. For example you would define the values like this:

1 month => retention_one_value_per_day
1 week => retention_one_value_per_hour
1 day => retention_one_value_per_10s

All queries in all dashboards would then use the retention policy closest to the selected time range as default (which could still be overridden on a per-query basis by explicitly selecting a retention policy there?). If the user doesn't define this table then the default retention policy would always be used.

With this approach most people would be able to set up this table once and then all dashboards would automatically always use the right retention policy for their data which is I think what 99% of the people out there expect. Also for anyone who doesn't specify this value Grafana will behave just as before.

@torkelo torkelo added type/feature-request datasource/InfluxDB prio/low It's a good idea, but not scheduled for any release help wanted labels Mar 6, 2016
@dennisjac
Copy link
Author

So I started looking into this and did some prototyping for how this could work. I'm currently not focusing on the UI bits as that is dependent on how/where exactly this will be implemented.
I added the following code right now in the influxdb/datasource.ts query() function:

    var rangediff = options.range.to.diff(options.range.from) / 1000;
    options.targets.forEach(function(entry){
        console.log(entry.policy);
        //if (entry.policy === '_auto_') {
        if (rangediff >= 10800) {
            entry.policy = 'agg10m';
        } else {
            entry.policy = 'default';
        }
        //}
    });

This woks and forces all queries to use the 'agg10m' policy if the time range selected is >=3h and 'default' if it's not.
One thing I tried to do (as can be seen above) is to limit this only to queries where the policy is set to 'auto'. This would give the flexibility to have queries with an explicitly policy to work like normal and opt-in for others.
The problem I have right now is that the 'options' object is modified permanently so the 'auto' policy setting gets overwritten and I'm not sure how to get around this.
Any ideas how to best get around this problem?

@rubycut
Copy link
Contributor

rubycut commented May 19, 2016

@dennisjac , I am not sure if settings is best place to add this. This should go into the datasource definition. During the next week, I'll try to setup grafana development env and try to play with this.

@anlutro
Copy link

anlutro commented May 24, 2016

This should go into the datasource definition.

Can't retention policies be defined on a per-measurement (table) basis?

@dennisjac
Copy link
Author

@anlutro , I guess you could override them there but I'm not sure how many people define different retention policies for individual measurements.

The reason I'm interested in this is because right now I'd pretty much have to create each dashboard three times for each of the three retention policies I'm using and then then manually select the right one based on the amount of time I want to display. This is extremely cumbersome at best and if you have more than a few dashboards (or hosts) completely unfeasible.

This is what my retention policies and continuous queries currently look like:

ALTER RETENTION POLICY default ON metrics DURATION 4w REPLICATION 1 SHARD DURATION 1d DEFAULT
CREATE RETENTION POLICY agg5m ON metrics DURATION 24w REPLICATION 1 SHARD DURATION 1w
CREATE RETENTION POLICY agg1h ON metrics DURATION 144w REPLICATION 1 SHARD DURATION 4w

CREATE CONTINUOUS QUERY agg5m ON metrics BEGIN SELECT mean(value) AS value INTO metrics."agg5m".:MEASUREMENT FROM /.*/ GROUP BY time(5m), * END
CREATE CONTINUOUS QUERY agg1h ON metrics BEGIN SELECT mean(value) AS value INTO metrics."agg1h".:MEASUREMENT FROM /.*/ GROUP BY time(1h), * END

With this definition I get the appropriate "density" of data for low-, mid- and long-term views of the data and thanks to the back reference in the CQ's everything stays perfectly dynamic.

With the auto-selection in Grafana the last piece would fit into place to make all of this work end-to-end.

@anlutro
Copy link

anlutro commented May 24, 2016

Yep, I'm in the same situation. I think I might want to store different measurements for different lengths of time, but I'd be fine with keeping it consistent on the database level.

As an easier, temporary solution I was thinking about allowing template variables in the RP/measurement.

@dennisjac
Copy link
Author

I wasn't aware that you couldn't use template variables in the retention policy.
Even if this was possible though this would still mean you'd have to chose the policy manually and if you'd make a mistake and select e.g. a time range of 6 months before selecting the right policy you might end up pulling gigabytes of data from influxdb most likely overloading both influxdb and the browser with the data.

@dennisjac
Copy link
Author

btw here is an update version of the patch that I'm using right now.
I added the selection of the policy as a function (the array would later live in the datasource configuration):

  determineAutoPolicy(interval) {
    // >48h = agg5m
    // >1month = agg1h
    var retentionPolicies = [
      {interval: 0, policy: 'default'},
      {interval: 172800, policy: 'agg5m'},
      {interval: 2592000, policy: 'agg1h'}
    ];

    var prevEntry = retentionPolicies[0];
    for (var idx = 0; idx < retentionPolicies.length; idx++) {
      if (retentionPolicies[idx].interval > interval) {
        return prevEntry.policy;
      }
      prevEntry = retentionPolicies[idx];
    }
    return prevEntry.policy;
  }

and this bit at the beginning of the query() function:

    var rangediff = options.range.to.diff(options.range.from) / 1000;
    options = _.cloneDeep(options);
    for (var idx = 0; idx < options.targets.length; idx++) {
      if (options.targets[idx].policy === '_auto_') {
        options.targets[idx].policy = this.determineAutoPolicy(rangediff);
      }
    }

I'm cloning the options variable because I need to modify it yet also need to preserve the original "auto" value so that when a new time range is selected the correct policy can be chosen again.

@torkelo
Copy link
Member

torkelo commented May 28, 2016

@anlutro best check InfluxDB docs

@XANi
Copy link

XANi commented Oct 13, 2016

I think that could be solved more generically by having time range-dependent variable in template.

I can already set up templated variable and just use say $range as parameter for retention policy, all that would be needed is ability to specify if $time_start < now() - 7d { $range = "10m" } else { $range = "default"} via UI.

That way if that would be just generic variable it could be used for any data source, not only influx

@schmurfy
Copy link

I just stumbled on this problem trying to setup grafana, was there any progress on this ?

@XANi
Copy link

XANi commented Aug 18, 2017

AFAIK the best you can do is to make a template variable with your retention periods, then use it everywhere

@schmurfy
Copy link

but this is static, right ? the rentention policy needs to be chosen dependening on the range selected to really be useful.

@XANi
Copy link

XANi commented Aug 21, 2017

Yes. As I said, there is no other way to do it right now unless Grafana introduces conditional variables ( if time > ( now - 30 days) {$retention=short} else {$retention = long} or something ) or InfluxDB adds views or some smart way to auto-choose retention based on times.

@schmurfy
Copy link

I would prefer not but I have no issue patching my grafana installation, however I could not find where exactly I should add my custom code.
Could you point me to where is the query actually built when using proxy mode ? Looking at the network monitor it looks like the variables are replaced inside the javascript code but I have tried to add code on both sides (go and javascript) and can't seems to add a new replace pattern :(

I have tried (I searched for $timeFilter as reference):

  • pkg/tsdb/influxdb/query.go in Build
  • public/app/plugins/datasource/influxdb/datasource.ts in annotationQuery

After that I rebuilt the assets with grunt and rebuilt the go sources but neither my fm.Println or console.log logs anything, I also tried to directly add the replace (for $policy) in case the logs where sent somewhere else but no luck either with that.

@XANi
Copy link

XANi commented Aug 22, 2017

Sorry, writing JS wants me want to vomit so all we have is just a template field in each dashboard with "default" and "longterm" options for retention

@schmurfy
Copy link

I not a big fan of javascript but the build process used is grafana is not helping either...

I finally found where is the replace code for my use case, it was shadowed by the fact that $timeFilter replacement is done in two locations on the javascript side and once in the go side, I really don't like that design but it does not matter much, I now have what I need to patch this myself.

@nicolas17
Copy link

I don't think implementing this at the datasource level would work. It doesn't seem so far-fetched to have multiple or different retention policies for individual measurements. For example you could have a RP+CQ storing the average of a measurement and a separate RP+CQ storing the maximum. In that case, a graph for max(foo) would want to use the aggregated-max RP.

I thought of trying to implement this a while ago but I don't know Go at all. I now realize it might be possible with JS code alone, maybe I should give it a try.

@XANi
Copy link

XANi commented Mar 23, 2018

It would help to look at what people do with it.

We have 2 , "default" that keeps full resolution for last month and "longerm" that has downsampled data (to 10 minute intervals) and keeps it for much longer but I dunno how common setup like that is

@schmurfy
Copy link

schmurfy commented Mar 26, 2018

In my case I use influxdb as datasource, in in I have multiple retention policies to reduce the number of datapoints for older records:
raw stores a point every 10s for 3 weeks
down_1min stores a point every minute for 3 months
down_5min stores a point every 5 minute for 6 months

Depending on the size of the range I want to show and/or the periodI want to show I want to use the best retention policy, If I want to show the last 2 weeks there is not much point usind data from raw since it will fetch way too much points, also I I want to show data from last month raw simply will not return any data.

For now I just patched grafana to implement this logic in the influxdb datasource but this is not configurable, I also expose a few scopedVars to be able to create the correct queries.

If you are interested I can show you my patch, it might help find a more generic solution.

@awaw
Copy link

awaw commented Jul 25, 2018

I'm also running a patched grafana for some time now. Influxdb with more than a single retention policy is infeasible to use without such a modification. With this patch against v5.2.1 you can scroll sideways or zoom and correct retention policy and interval (as configured) is chosen automatically. I'm posting it here as this issue is often referenced in other discussions.

diff --git a/public/app/plugins/datasource/influxdb/datasource.ts b/public/app/plugins/datasource/influxdb/datasource.ts
index f971ac2..3f05ae5 100644
--- a/public/app/plugins/datasource/influxdb/datasource.ts
+++ b/public/app/plugins/datasource/influxdb/datasource.ts
@@ -16,6 +16,9 @@ export default class InfluxDatasource {
   basicAuth: any;
   withCredentials: any;
   interval: any;
+  retentionPolicy: any;
+  retentionBefore: any;
+  retentionInterval: any;
   supportAnnotations: boolean;
   supportMetrics: boolean;
   responseParser: any;
@@ -34,6 +37,9 @@ export default class InfluxDatasource {
     this.basicAuth = instanceSettings.basicAuth;
     this.withCredentials = instanceSettings.withCredentials;
     this.interval = (instanceSettings.jsonData || {}).timeInterval;
+    this.retentionPolicy = (instanceSettings.jsonData || {}).retentionPolicy;
+    this.retentionBefore = (instanceSettings.jsonData || {}).retentionBefore;
+    this.retentionInterval = (instanceSettings.jsonData || {}).retentionInterval;
     this.supportAnnotations = true;
     this.supportMetrics = true;
     this.responseParser = new ResponseParser();
@@ -47,6 +53,20 @@ export default class InfluxDatasource {
     var queryModel;
     var i, y;
 
+    var timestamp = new Date().getTime() / 1000;
+    var beforeTs = timestamp - options.range.from.unix();
+    var retentionPolicy = this.retentionPolicy ? this.retentionPolicy.split(";") : {};
+    var retentionBefore = this.retentionBefore ? this.retentionBefore.split(";") : {};
+    var retentionInterval = this.retentionInterval ? this.retentionInterval.split(";") : {};
+    var policy, interval;
+
+    for (y = 0; y < retentionBefore.length; y++) {
+      if (beforeTs > parseInt(retentionBefore[y])) {
+        policy = retentionPolicy[y];
+        interval = retentionInterval[y];
+      }
+    }
+
     var allQueries = _.map(targets, target => {
       if (target.hide) {
         return '';
@@ -54,6 +74,11 @@ export default class InfluxDatasource {
 
       queryTargets.push(target);
 
+      if (policy) {
+        scopedVars.autopolicy = { value: policy };
+        scopedVars.autointerval = { value: interval };
+      }
+
       // backward compatibility
       scopedVars.interval = scopedVars.__interval;
 
diff --git a/public/app/plugins/datasource/influxdb/influx_query.ts b/public/app/plugins/datasource/influxdb/influx_query.ts
index 2ef7417..f4395c3 100644
--- a/public/app/plugins/datasource/influxdb/influx_query.ts
+++ b/public/app/plugins/datasource/influxdb/influx_query.ts
@@ -23,6 +23,18 @@ export default class InfluxQuery {
     target.groupBy = target.groupBy || [{ type: 'time', params: ['$__interval'] }, { type: 'fill', params: ['null'] }];
     target.select = target.select || [[{ type: 'field', params: ['value'] }, { type: 'mean', params: [] }]];
 
+    if (target.policy === 'auto') {
+      target.policy = 'default';
+      if (typeof scopedVars !== 'undefined' && typeof scopedVars.autopolicy !== 'undefined') {
+        target.policy = scopedVars.autopolicy.value;
+        var interval = kbn.interval_to_seconds(scopedVars.autointerval.value);
+        if (interval > kbn.interval_to_seconds(scopedVars.__interval.value)) {
+          scopedVars.__interval = { value: kbn.secondsToHms(interval) };
+          scopedVars.interval = scopedVars.__interval;
+        }
+      }
+    }
+
     this.updateProjection();
   }
 
diff --git a/public/app/plugins/datasource/influxdb/partials/config.html b/public/app/plugins/datasource/influxdb/partials/config.html
index a70a1de..19d80a7 100644
--- a/public/app/plugins/datasource/influxdb/partials/config.html
+++ b/public/app/plugins/datasource/influxdb/partials/config.html
@@ -49,3 +49,23 @@
 		</div>
 	</div>
 </div>
+
+<h4 class="page-heading">Retention Policy &quot;auto&quot;</h4>
+
+<div class="gf-form-group">
+	<div class="gf-form max-width-32">
+		<span class="gf-form-label width-11">Retention Policy</span>
+		<input type="text" class="gf-form-input width-20" ng-model="ctrl.current.jsonData.retentionPolicy" spellcheck='false' placeholder="sample5m;sample1h;sample1d"></input>
+		<i class="fa fa-question-circle" bs-tooltip="'Retention policies (delimited by semicolons)'" data-placement="right"></i>
+	</div>
+	<div class="gf-form max-width-32">
+		<span class="gf-form-label width-11">Before Timestamp</span>
+		<input type="text" class="gf-form-input width-20" ng-model="ctrl.current.jsonData.retentionBefore" spellcheck='false' placeholder="86400;2592000;31536000"></input>
+		<i class="fa fa-question-circle" bs-tooltip="'Before which timestamp to use above retention polices (in seconds, delimited by semicolons)'" data-placement="right"></i>
+	</div>
+	<div class="gf-form max-width-32">
+		<span class="gf-form-label width-11">Minimum Interval</span>
+		<input type="text" class="gf-form-input width-20" ng-model="ctrl.current.jsonData.retentionInterval" spellcheck='false' placeholder="30s;5m;1h"></input>
+		<i class="fa fa-question-circle" bs-tooltip="'Mimimum group by time interval to use with above policies (delimited by semicolons)'" data-placement="right"></i>
+	</div>
+</div>
diff --git a/public/app/plugins/datasource/influxdb/query_builder.ts b/public/app/plugins/datasource/influxdb/query_builder.ts
index 2b19aa8..84ba90b 100644
--- a/public/app/plugins/datasource/influxdb/query_builder.ts
+++ b/public/app/plugins/datasource/influxdb/query_builder.ts
@@ -52,7 +52,7 @@ export class InfluxQueryBuilder {
       if (!measurement.match('^/.*/')) {
         measurement = '"' + measurement + '"';
 
-        if (policy && policy !== 'default') {
+        if (policy && policy !== 'default' && policy !== 'auto') {
           policy = '"' + policy + '"';
           measurement = policy + '.' + measurement;
         }
@@ -69,7 +69,7 @@ export class InfluxQueryBuilder {
         measurement = '"' + measurement + '"';
       }
 
-      if (policy && policy !== 'default') {
+      if (policy && policy !== 'default' && policy !== 'auto') {
         policy = '"' + policy + '"';
         measurement = policy + '.' + measurement;
       }

@talek
Copy link

talek commented Mar 22, 2019

In Grafana v6.0.2 I'm using an workaround which seems to work pretty well. The system I use has four retention policies defined:

> show retention policies
name    duration  shardGroupDuration replicaN default
----    --------  ------------------ -------- -------
autogen 1h0m0s    1h0m0s             1        true
d       24h0m0s   1h0m0s             1        false
m       744h0m0s  24h0m0s            1        false
y       8928h0m0s 168h0m0s           1        false

Because in Grafana there is no conditional variable, the idea was to have in InfluxDB a mapping between the time interval and the corresponding retention policy and to return the proper retention policy in Grafana via a "Query" variable.

So, in InfluxDB I've created an unlimited duration retention policy where I've manually defined a measurement to keep this mapping:

CREATE RETENTION POLICY "forever" ON telegraf DURATION INF REPLICATION 1
INSERT INTO forever rp_config,idx=1 rp="autogen",start=0i,end=3600000i -9223372036854775806
INSERT INTO forever rp_config,idx=2 rp="d",start=3600000i,end=86400000i -9223372036854775806
INSERT INTO forever rp_config,idx=3 rp="m",start=86400000i,end=2592000000i -9223372036854775806
INSERT INTO forever rp_config,idx=4 rp="y",start=2592000000i,end=3110400000000i -9223372036854775806

The mapping measurement is the following:

> select * from forever.rp_config
name: rp_config
time                           end           idx rp      start
----                           ---           --- --      -----
1677-09-21T00:12:43.145224194Z 3600000       1   autogen 0
1677-09-21T00:12:43.145224194Z 3110400000000 4   y       2592000000
1677-09-21T00:12:43.145224194Z 2592000000    3   m       86400000
1677-09-21T00:12:43.145224194Z 86400000      2   d       3600000

Then, in Grafana I've defined the following variable:
image

The $rp variable should change its value according to the time range interval selected in the dashboard. Then, it's just a matter of prefixing all measurements with the $rp variable.

@danielllek
Copy link

danielllek commented Apr 3, 2019

@talek Awesome! No patching needed, works for me!

@kotls
Copy link

kotls commented Apr 3, 2019

@talek I can't figure out the last step you mentioned, namely prefixing all measurements with the $rp variable. Do you have same field names between retention policies? Or are they like field, d_field, m_field, etc.

@tvwerkhoven
Copy link

In Grafana v6.0.2 I'm using an workaround which seems to work pretty well. The system I use has four retention policies defined:

This works nicely, thanks @talek ! I found one minor bug however, your variable checks the time range while influxdb retention policies care about time since now, i.e. this works if $__to == now() but fails when looking at e.g. 1 day of data 1 year ago, since this will trigger the 1d RP.

Any ideas on how to improve this? I had the following in mind, but I can't compare ints and time:

SELECT rp FROM always.rp_config WHERE (now() - $__from) > "start" AND (now() - $__from) < "end"

@rwalli
Copy link

rwalli commented Oct 9, 2019

I'm very beginner with influxdb and grafana and tried your workaround:

CREATE RETENTION POLICY "forever" ON telegraf DURATION INF REPLICATION 1
INSERT INTO forever rp_config,idx=1 rp="autogen",start=0i,end=3600000i -9223372036854775806
INSERT INTO forever rp_config,idx=2 rp="d",start=3600000i,end=86400000i -9223372036854775806
INSERT INTO forever rp_config,idx=3 rp="m",start=86400000i,end=2592000000i -9223372036854775806
INSERT INTO forever rp_config,idx=4 rp="y",start=2592000000i,end=3110400000000i -9223372036854775806

which works very good but when restarting influxdb the retention policy "forever" is still there but all inserts are gone.

Can someone point me in the right direction?

@KristianLyng
Copy link

In Grafana v6.0.2 I'm using an workaround which seems to work pretty well. The system I use has four retention policies defined:

This works nicely, thanks @talek ! I found one minor bug however, your variable checks the time range while influxdb retention policies care about time since now, i.e. this works if $__to == now() but fails when looking at e.g. 1 day of data 1 year ago, since this will trigger the 1d RP.

I ran into this myself, and ended up with a slightly more complex variant that uses two variables: period and time.

Here's the table of retention policies:

precision s
drop measurement retentions
insert retentions agg="ret_raw",resolution=0,period=90000 1209600
insert retentions agg="ret_1m",resolution=60,period=691200 32832000
insert retentions agg="ret_1h",resolution=3600,period=3153600000 3153600000

The important bit is "period" - this is the upper bound for when to use this retention policy. If I'm looking at 24h or less, using "raw" data is fine. If I'm looking at 90d of data, use hourly data, etc.

Next is time. This just matches the retention time.

With this, I can use the following query:

select first(agg) from autogen.retentions where period >= ($__to - $__from)/1000 and time > (now() - $__from*1000000)

Because influx will sort by time, this means it will pick the highest resolution (first aggregate) available that is still in range.

This means if I view 90 days of data, I will use the ret_1h aggregate, but if I zoom in on a single day 60 days ago, I'll use ret_1m.

The "Resolution" field is redundant, mainly for my personal sanity.

I'm honestly not sure what the Correct solution to this bug is. The only downside with what I've got now is that I need to define this variable in every dashboard, but if there was a global templating variable thingamajing, that might be a better solution in general than trying to find a single one-size-fits all for picking retention policies.

@hackery
Copy link
Contributor

hackery commented Jan 30, 2020

I found one minor bug however, your variable checks the time range while influxdb retention policies care about time since now

I've been digging into this one as well, as it's an important use case for us - I don't know why it's not a fundamental use case for which a method should be expected out of the box. It's completely natural to expect a dashboard view where the same query can be used regardless of time period selected, and have the tsdb responsible for rollups in a way that allows it. Score one for the venerable RRDtool and Graphite 😄

As you say, $__from and $__to aren't the relevant values for an arbitrary timepicker selection - $__from and now() are what's needed - but it seems there's no date/interval calculation construct that allows us to compare this to a stored numeric field. Assuming that longer retention periods hold coarser (rolled-up) data, the comparison is this:

image

  • wherever $__to moves in this picture, you still need to select the "Medium" RP
  • even if $__from and $__to are close together in the distant past, you still need to pick the longer RP - you can't get the fine granularity data

I tried all sorts of combinations before various lightbulb moments came together: you can compare against the time of a data point rather than a field - as long as you synthesize it to be something suitable - and you have to use nanosecond intervals (or convert using time unit specifiers) for comparisons.

Create points whose time values are offsets from the epoch, of the ns values of the retention policies you've created:

create retention policy "persistent" ON telegraf duration inf replication 1
insert into persistent grafana_rp rp="1_hour"  3600000000000
insert into persistent grafana_rp rp="1_day"  86400000000000
insert into persistent grafana_rp rp="31_days"  2678400000000000
insert into persistent grafana_rp rp="365_days" 31536000000000000
insert into persistent grafana_rp rp="forever" 9223372036854775806 -- max ns value in a 64-bit int

> select * from persistent.grafana_rp
name: grafana_rp
time                           rp
----                           --
1970-01-01T01:00:00Z           1_hour
1970-01-02T00:00:00Z           1_day
1970-02-01T00:00:00Z           31_days
1971-01-01T00:00:00Z           365_days
2262-04-11T23:47:16.854775806Z forever

Shame about the verbose numerics - they can't be abbreviated using time unit specifiers [ed: Kristian used precision s which would ease that]. And yes, it makes ridiculous-looking dates on the points, but now InfluxQL can compare them to (now-from).

We need the name of the RP which is the smallest one satisfying length(RP) > (now() - $__from) - i.e. "which retention periods hold the whole of the data I want to display? ... let's have the finest-granularity one." So, in Grafana, create a variable $rp (with Refresh On Time Range Change !):

select time,rp from persistent.grafana_rp where time > now() - ${__from}ms order by time asc limit 1

That ms is critical! You can't multiply Grafana's millisecond value to get nanoseconds using math in the query, but the unit specifier will do it for you.

The Grafana query for the InfluxDB datasource looks like

SELECT mean("value") AS "value" FROM "$rp"."my_measurement" WHERE ... AND $timeFilter GROUP BY time($__interval) fill(linear)

This feels like a disgraceful hack - but might be the only workaround at the moment.

It does seem to work quite smoothly. In my tests, as I step out to a 1 hour view, I see fine granularity (10s) data from my 1_hour RP; as I go over 61m, it switches to the 1_day RP and 1m granularity (Grafana needs fill(linear) then). I haven't synthesized data into the larger RPs, I'm still running CQs to fill them up, so haven't verified further zoom, but the existing transition suggests it works.

@awaw
Copy link

awaw commented Jan 31, 2020

I think you meant to write

create retention policy "persistent" ON telegraf duration 0 replication 1

and I had to set precision ns before inserting the values. But after some testing this seems to be the easiest solution and I can delete my grafana fork at last.

@hackery
Copy link
Contributor

hackery commented Jan 31, 2020

I think you meant to write

Not only that, but duration inf - how did that get through cut&paste? Fixed, thanks.

@bisontim
Copy link

bisontim commented Jun 5, 2020

Hallo
I tried to insert into retention policies but I obtain the error:
INSERT INTO forever rp_config,idx=1 rp="DATI_SETTE_GIORNI",start=0i,end=‭604800000‬i -9223372036854775806
ERR: {"error":"unable to parse 'rp_config,idx=1 rp="DATI_SETTE_GIORNI",start=0i,end=‭604800000‬i -9223372036854775806': invalid boolean"}

@MarcoPignati
Copy link

It seems to me that you have a negative timestamp. Remove the minus.

@bisontim
Copy link

bisontim commented Jun 5, 2020

I tried, but I have the same error:
INSERT INTO forever rp_config,idx=1 rp="DATI_SETTE_GIORNI",start=0i,end=‭604800000‬i 9223372036854775806
ERR: {"error":"unable to parse 'rp_config,idx=1 rp="DATI_SETTE_GIORNI",start=0i,end=‭604800000‬i 9223372036854775806': invalid boolean"}

@MarcoPignati
Copy link

mmm does it work if you remove the following: ,idx=1?

@bisontim
Copy link

bisontim commented Jun 5, 2020

without idx=1 the error changes:
INSERT INTO forever rp_config,rp=DATI_SETTE_GIORNI,start=0i,end=‭604800000‬i -9223372036854775806
ERR: {"error":"unable to parse 'rp_config,rp=DATI_SETTE_GIORNI,start=0i,end=‭604800000‬i -9223372036854775806': invalid field format"}

@MarcoPignati
Copy link

this might not be the best place to fix this. Anyway, try copying this. If it does not work, I can't help you. sorry.
INSERT INTO forever rp_config rp="DATI_SETTE_GIORNI",start=0i,end=‭604800000‬i 9223372036854775806

@VladSnap
Copy link

Thanks @hackery for the easy fix problem!

@aocenas aocenas added prio/medium Important over the long term, but may not be staffed and/or may need multiple releases to complete. and removed prio/low It's a good idea, but not scheduled for any release labels Sep 2, 2020
@R-Studio
Copy link

R-Studio commented Jan 6, 2021

In additionally to @hackery's workaround I write a quite similar workaround in Flux for InfluxDB 2.x:

//Bucketfilter to filter only buckets beginning with name telegraf..
bucketfilter = /telegraf.*/

buckets()
  |> filter(fn: (r) => r.name =~ bucketfilter)
  //convert retentionperiod from nanosecond to days
  |> map(fn: (r) => ({r with 
    retentionPeriodinDays: r.retentionPeriod / 86400000000000}) 
  )
  //replace retentionpolicy infinity with a high number in NS
  |> map(fn: (r) => ({r with
    retentionPeriod: if r.retentionPeriod == 0 then 999999999999999999
    else r.retentionPeriod})
  )
  //calculate the duration from "to" and "from" timespan and convert it to nanosecond
  |> map(fn: (r) => ({r with 
    DashboardDurationinNS: (${__to} - ${__from}) * 1000000})
  )
  |> filter(fn: (r) => 
    r.DashboardDurationinNS <= r.retentionPeriod and
    r.retentionPeriod >= uint(v: now()) - uint(v: ${__from} * 1000000)
  )
  |> sort(columns: ["retentionPeriod"], desc: false)
  |> limit(n: 1)
  |> keep(columns: ["name"]) //remove all fields except for "name"

I hope this helps someone! :-)
More informations are documented on my wiki: http://wiki.webperfect.ch/index.php?title=Grafana:_Dynamic_Retentions_(InfluxDB)

@gabzim
Copy link

gabzim commented Jan 24, 2021

I know we have workarounds detailed here but this seems like a basic requirement I keep running into. Is there any chance this is prioritized at some point?

@MarcoPignati
Copy link

MarcoPignati commented Jan 24, 2021 via email

@gabor gabor removed the help wanted label Jun 1, 2021
@andybaumgar
Copy link

This would be handy for us as well. We currently use a custom intermediate Grafana datasource which handles the rollup selection, but it seems like this should be a very common use case.

jabbors added a commit to jabbors/ruuviscanner that referenced this issue Nov 8, 2021
Additionally update the grafana dashboard to automatically select
retention period according to selected time range.

grafana/grafana#4262 (comment)
@R-Studio
Copy link

@torkelo is this on the roadmap for Grafana?

@gabor
Copy link
Contributor

gabor commented Nov 30, 2021

hi @R-Studio , as far as i know, this is not on the roadmap currently.

@gabor
Copy link
Contributor

gabor commented Nov 30, 2021

(as the current approach is to handle feature requests in the discussions-section, we are moving this issue to the discussions)

@grafana grafana locked and limited conversation to collaborators Nov 30, 2021
@gabor gabor closed this as completed Nov 30, 2021
Observability (deprecated, use Observability Squad) automation moved this from Backlog features to Done Nov 30, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
area/datasource datasource/InfluxDB prio/medium Important over the long term, but may not be staffed and/or may need multiple releases to complete. type/feature-request
Development

No branches or pull requests