├── README.md ├── restic2influx ├── restic2influx-grafana.json └── restic2influx-grafana.png /README.md: -------------------------------------------------------------------------------- 1 | # restic2influx 2 | 3 | Parse [Restic](https://restic.net/) status output and feed summary to influx db. 4 | 5 | As a bonus, the program also shows the progress of the backup in the process list: 6 | ``` 7 | $ ( restic backup --json -r /path/to/backup /path/to/MyMusic | restic2influx -s MyMusic grafana http://influxsrv:8086 ) & 8 | 9 | $ ps auwwf | grep restic 10 | 18:06 0:01 | restic backup --json -r /path/to/backup /path/to/MyMusic 11 | 18:06 0:01 | \_ restic2influx MyMusic [Done: 53.31% ETA: 04-09 18:07 Files: 8.452 MBytes: 149] 12 | ``` 13 | 14 | ## Usage 15 | 16 | ``` 17 | $ restic backup --json | restic2influx [-d] [-v] [-s] [influx host] 18 | 19 | -s, --status[=N] additionally send status information to influxdb every N seconds (default 30) during the backup job 20 | -v, --verbose print summary and other info to stdout 21 | -d, --debug output debug info, do not send data to influxdb 22 | -u, --user influxdb basic auth user 23 | -p, --password influxdb basic auth password 24 | 25 | 'influx host' defaults to http://localhost:8086 if omitted 26 | ``` 27 | 28 | Before using it, you need to install some non-core libraries, i.e. on Debian systems 29 | simply execute: `apt-get install libjson-perl libinfluxdb-lineprotocol-perl libwww-perl libtext-unidecode-perl`. 30 | 31 | ## Grafana 32 | 33 | With [Grafana](https://grafana.com/) one can realize beautiful diagrams of the 34 | data, feel free to [download dashboard example](restic2influx-grafana.json) 35 | and modify it according to your needs: 36 | 37 | ![Picture of an example Grafana dashboard](restic2influx-grafana.png "Grafana example dashboard") 38 | 39 | ## Credits 40 | 41 | - Forum user [griffon](https://forum.restic.net/u/griffon/) implemented a 42 | [similar approach](https://forum.restic.net/t/restic-grafana-dashboard/1662/8) using `jq`. 43 | 44 | - Similiar Grafana dashboards by [dmatt](https://grafana.com/grafana/dashboards/11064) and 45 | [Alexander](https://grafana.com/grafana/dashboards/4198) using 46 | [runrestic](https://pypi.org/project/runrestic/). 47 | 48 | - [Autorestic](https://github.com/cupcakearmy/autorestic) might be helpful 49 | as well. 50 | 51 | -------------------------------------------------------------------------------- /restic2influx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # restic2influx.pl -- parse restic status messages and feed them to influxdb 4 | # 5 | # (C) 2021 Hajo Noerenberg 6 | # 7 | # http://www.noerenberg.de/ 8 | # https://github.com/hn/restic2influx 9 | # 10 | # 11 | # This program is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License version 3.0 as 13 | # published by the Free Software Foundation. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along 21 | # with this program. If not, see . 22 | # 23 | 24 | # apt-get install libjson-perl libinfluxdb-lineprotocol-perl libwww-perl libtext-unidecode-perl 25 | 26 | use strict; 27 | use POSIX qw(strftime); 28 | use JSON qw(decode_json); 29 | use InfluxDB::LineProtocol qw(data2line); 30 | use LWP::UserAgent; 31 | use HTTP::Request::Common; 32 | use Getopt::Long; 33 | use Text::Unidecode; 34 | 35 | my $debug; 36 | my $verbose; 37 | my $status; 38 | my $repo; 39 | my $influxdb; 40 | my $influxhost = 'http://localhost:8086'; 41 | my $influxuser; 42 | my $influxpass; 43 | 44 | my $lastreq; 45 | 46 | GetOptions ("debug|d+" => \$debug, 47 | "verbose|v+" => \$verbose, 48 | "status|s:30" => \$status, 49 | "user|u=s" => \$influxuser, 50 | "password|p=s" => \$influxpass 51 | ) || die( "Error in command line arguments\n" ); 52 | 53 | $repo = shift(@ARGV); 54 | $influxdb = shift(@ARGV); 55 | $influxhost = shift(@ARGV) if (@ARGV); 56 | 57 | die("Usage: $0 [-d] [-v] [-s] [-u user] [-p password] [influx host]") if ( !$repo || !$influxdb); 58 | 59 | while ( my $line = ) { 60 | 61 | my $now = time(); 62 | my $message; 63 | eval { $message = decode_json($line); 1; } || next; 64 | 65 | my $type = delete ${$message}{'message_type'}; 66 | my $influxreq; 67 | 68 | if ( $type eq "status" ) { 69 | # message_type = "status" 70 | # seconds_elapsed = "2" : Time since backup started 71 | # seconds_remaining = "42" : Estimated time remaining 72 | # percent_done = "0.578058" : Percentage of data backed up (bytes_done/total_bytes) 73 | # total_files = "8864" : Total number of files detected 74 | # files_done = "2737" : Files completed (backed up or confirmed in repo) 75 | # total_bytes = "157955039" : Total number of bytes in backup set 76 | # bytes_done = "91307307" : Number of bytes completed (backed up or confirmed in repo) 77 | # error_count = "0" : Number of errors 78 | # current_files = ARRAY : List of files currently being backed up 79 | # 80 | my $total_files = $message->{"total_files"}; 81 | while ( $total_files =~ s/(\d+)(\d\d\d)/$1\.$2/ ) { }; # add thousands separator 82 | my $files_done = $message->{"files_done"} || 0; 83 | while ( $files_done =~ s/(\d+)(\d\d\d)/$1\.$2/ ) { }; 84 | my $total_mbytes = int ( $message->{"total_bytes"} / 1048576 ); 85 | while ( $total_mbytes =~ s/(\d+)(\d\d\d)/$1\.$2/ ) { } 86 | my $mbytes_done = int ( $message->{"bytes_done"} / 1048576 ); 87 | while ( $mbytes_done =~ s/(\d+)(\d\d\d)/$1\.$2/ ) { } 88 | my $percent = $message->{"percent_done"}; 89 | my $remaining = $message->{"seconds_remaining"}; 90 | $0 = "restic2influx " . $repo 91 | . " [Done: " . sprintf( "%.2f%%", $percent * 100 ) 92 | . " ETA: " . ( ( $remaining > 0 && $remaining < 42000042 ) ? strftime("%m-%d %H:%M", localtime( $now + $remaining )) : "unknown" ) 93 | . " Files: " . $files_done . "/" . $total_files 94 | . " MBytes: " . $mbytes_done . "/" . $total_mbytes . "]"; 95 | 96 | if ($status && (($now - $lastreq) > $status)) { 97 | $lastreq = $now; 98 | print $0 . "\n" if ($debug>1); 99 | $message->{"percent_done"} .= ".0" unless ($percent =~ /\./); # force float 100 | if (ref($message->{"current_files"}) eq 'ARRAY') { 101 | $message->{"current_files"} = join(", ", map { unidecode($_) } @{$message->{"current_files"}}); # flatten file list 102 | } 103 | $influxreq = data2line( 104 | 'restic', 105 | $message, 106 | { 'repo' => $repo, 'type' => $type } 107 | ); 108 | } 109 | 110 | } elsif ( $type eq "summary" ) { 111 | # message_type = "summary" 112 | # files_new = "2" : Number of new files 113 | # files_changed = "0" : Number of files that changed 114 | # files_unmodified = "8864" : Number of files that did not change 115 | # dirs_new = "0" : Number of new directories 116 | # dirs_changed = "0" : Number of directories that changed 117 | # dirs_unmodified = "986" : Number of directories that did not change 118 | # data_blobs = "0" : Number of data blobs 119 | # tree_blobs = "0" : Number of tree blobs 120 | # data_added = "123" : Amount of data added, in bytes 121 | # total_files_processed = "8864" : Total number of files processed 122 | # total_bytes_processed = "15795503" : Total number of bytes processed 123 | # total_duration = "3.742542" : Total time it took for the operation to complete 124 | # snapshot_id = "51a48509" : The short ID of the new snapshot 125 | 126 | if ($verbose) { 127 | printf "%23s: %s\n", "repository", $repo;; 128 | foreach my $key ( sort keys %{$message} ) { 129 | printf "%23s: %s\n", $key, $message->{$key}; 130 | } 131 | } 132 | my $snapshot = delete ${$message}{'snapshot_id'}; 133 | $influxreq = data2line( 134 | 'restic', 135 | $message, 136 | { 'repo' => $repo, 'type' => $type, 'snapshot' => $snapshot } 137 | ); 138 | 139 | } elsif ( $type eq "error" ) { 140 | # message_type = "error" 141 | # error = "..." : Error message 142 | # during = "..." : What restic was trying to do 143 | # item = "..." : Usually, the path of the problematic file 144 | # 145 | 146 | } elsif ( $type eq "verbose_status" ) { 147 | # message_type = "verbose_status" 148 | 149 | } 150 | 151 | next unless ($influxreq); 152 | 153 | if ($debug) { 154 | print $influxreq . "\n"; 155 | } else { 156 | my $ua = LWP::UserAgent->new(); 157 | my $request = POST $influxhost . '/write?precision=ns&db=' . $influxdb, Content => $influxreq; 158 | if ($influxuser && $influxpass) { 159 | $request->authorization_basic($influxuser, $influxpass); 160 | } 161 | my $response = $ua->request($request); 162 | if (!($response->is_success) || ($debug>1)) { 163 | print $response->status_line . "\n" . $response->headers()->as_string; # HTTP 204 is ok 164 | } 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /restic2influx-grafana.json: -------------------------------------------------------------------------------- 1 | { 2 | "__inputs": [], 3 | "__requires": [ 4 | { 5 | "type": "panel", 6 | "id": "gauge", 7 | "name": "Gauge", 8 | "version": "" 9 | }, 10 | { 11 | "type": "grafana", 12 | "id": "grafana", 13 | "name": "Grafana", 14 | "version": "7.5.4" 15 | }, 16 | { 17 | "type": "panel", 18 | "id": "graph", 19 | "name": "Graph", 20 | "version": "" 21 | }, 22 | { 23 | "type": "panel", 24 | "id": "stat", 25 | "name": "Stat", 26 | "version": "" 27 | }, 28 | { 29 | "type": "panel", 30 | "id": "table-old", 31 | "name": "Table (old)", 32 | "version": "" 33 | } 34 | ], 35 | "annotations": { 36 | "list": [ 37 | { 38 | "builtIn": 1, 39 | "datasource": "-- Grafana --", 40 | "enable": true, 41 | "hide": true, 42 | "iconColor": "rgba(0, 211, 255, 1)", 43 | "name": "Annotations & Alerts", 44 | "type": "dashboard" 45 | } 46 | ] 47 | }, 48 | "editable": true, 49 | "gnetId": null, 50 | "graphTooltip": 0, 51 | "id": null, 52 | "links": [], 53 | "panels": [ 54 | { 55 | "aliasColors": {}, 56 | "bars": true, 57 | "dashLength": 10, 58 | "dashes": false, 59 | "datasource": null, 60 | "fieldConfig": { 61 | "defaults": {}, 62 | "overrides": [] 63 | }, 64 | "fill": 1, 65 | "fillGradient": 0, 66 | "gridPos": { 67 | "h": 9, 68 | "w": 24, 69 | "x": 0, 70 | "y": 0 71 | }, 72 | "hiddenSeries": false, 73 | "id": 8, 74 | "legend": { 75 | "alignAsTable": true, 76 | "avg": false, 77 | "current": false, 78 | "max": false, 79 | "min": false, 80 | "rightSide": true, 81 | "show": true, 82 | "total": false, 83 | "values": false 84 | }, 85 | "lines": false, 86 | "linewidth": 1, 87 | "links": [], 88 | "nullPointMode": "null", 89 | "options": { 90 | "alertThreshold": true 91 | }, 92 | "percentage": false, 93 | "pluginVersion": "7.5.4", 94 | "pointradius": 1, 95 | "points": false, 96 | "renderer": "flot", 97 | "seriesOverrides": [], 98 | "spaceLength": 10, 99 | "stack": true, 100 | "steppedLine": false, 101 | "targets": [ 102 | { 103 | "alias": "$tag_repo", 104 | "groupBy": [ 105 | { 106 | "params": [ 107 | "1d" 108 | ], 109 | "type": "time" 110 | }, 111 | { 112 | "params": [ 113 | "repo" 114 | ], 115 | "type": "tag" 116 | }, 117 | { 118 | "params": [ 119 | "null" 120 | ], 121 | "type": "fill" 122 | } 123 | ], 124 | "measurement": "restic", 125 | "orderByTime": "ASC", 126 | "policy": "default", 127 | "query": "SELECT sum(\"value\") FROM \"restic_value\" WHERE (\"summary_attr\" = 'files_changed') AND $timeFilter GROUP BY time($__interval), \"snapshot\"", 128 | "rawQuery": false, 129 | "refId": "B", 130 | "resultFormat": "time_series", 131 | "select": [ 132 | [ 133 | { 134 | "params": [ 135 | "total_duration" 136 | ], 137 | "type": "field" 138 | }, 139 | { 140 | "params": [], 141 | "type": "sum" 142 | } 143 | ] 144 | ], 145 | "tags": [ 146 | { 147 | "key": "type", 148 | "operator": "=", 149 | "value": "summary" 150 | } 151 | ] 152 | } 153 | ], 154 | "thresholds": [], 155 | "timeFrom": null, 156 | "timeRegions": [], 157 | "timeShift": null, 158 | "title": "Backup Job Duration", 159 | "tooltip": { 160 | "shared": true, 161 | "sort": 0, 162 | "value_type": "individual" 163 | }, 164 | "type": "graph", 165 | "xaxis": { 166 | "buckets": null, 167 | "mode": "time", 168 | "name": null, 169 | "show": true, 170 | "values": [] 171 | }, 172 | "yaxes": [ 173 | { 174 | "format": "s", 175 | "label": null, 176 | "logBase": 1, 177 | "max": null, 178 | "min": "0", 179 | "show": true 180 | }, 181 | { 182 | "format": "short", 183 | "label": null, 184 | "logBase": 1, 185 | "max": null, 186 | "min": null, 187 | "show": true 188 | } 189 | ], 190 | "yaxis": { 191 | "align": false, 192 | "alignLevel": null 193 | } 194 | }, 195 | { 196 | "aliasColors": {}, 197 | "bars": true, 198 | "dashLength": 10, 199 | "dashes": false, 200 | "datasource": null, 201 | "fieldConfig": { 202 | "defaults": {}, 203 | "overrides": [] 204 | }, 205 | "fill": 1, 206 | "fillGradient": 0, 207 | "gridPos": { 208 | "h": 9, 209 | "w": 24, 210 | "x": 0, 211 | "y": 9 212 | }, 213 | "hiddenSeries": false, 214 | "id": 12, 215 | "legend": { 216 | "avg": false, 217 | "current": false, 218 | "max": false, 219 | "min": false, 220 | "rightSide": true, 221 | "show": true, 222 | "total": false, 223 | "values": false 224 | }, 225 | "lines": false, 226 | "linewidth": 1, 227 | "links": [], 228 | "nullPointMode": "null", 229 | "options": { 230 | "alertThreshold": true 231 | }, 232 | "percentage": false, 233 | "pluginVersion": "7.5.4", 234 | "pointradius": 5, 235 | "points": false, 236 | "renderer": "flot", 237 | "seriesOverrides": [], 238 | "spaceLength": 10, 239 | "stack": true, 240 | "steppedLine": false, 241 | "targets": [ 242 | { 243 | "alias": "$tag_repo", 244 | "groupBy": [ 245 | { 246 | "params": [ 247 | "1d" 248 | ], 249 | "type": "time" 250 | }, 251 | { 252 | "params": [ 253 | "repo" 254 | ], 255 | "type": "tag" 256 | }, 257 | { 258 | "params": [ 259 | "null" 260 | ], 261 | "type": "fill" 262 | } 263 | ], 264 | "measurement": "restic", 265 | "orderByTime": "ASC", 266 | "policy": "default", 267 | "refId": "A", 268 | "resultFormat": "time_series", 269 | "select": [ 270 | [ 271 | { 272 | "params": [ 273 | "data_added" 274 | ], 275 | "type": "field" 276 | }, 277 | { 278 | "params": [], 279 | "type": "sum" 280 | } 281 | ] 282 | ], 283 | "tags": [ 284 | { 285 | "key": "type", 286 | "operator": "=", 287 | "value": "summary" 288 | } 289 | ] 290 | } 291 | ], 292 | "thresholds": [], 293 | "timeFrom": null, 294 | "timeRegions": [], 295 | "timeShift": null, 296 | "title": "Backup data added", 297 | "tooltip": { 298 | "shared": true, 299 | "sort": 0, 300 | "value_type": "individual" 301 | }, 302 | "type": "graph", 303 | "xaxis": { 304 | "buckets": null, 305 | "mode": "time", 306 | "name": null, 307 | "show": true, 308 | "values": [] 309 | }, 310 | "yaxes": [ 311 | { 312 | "format": "decbytes", 313 | "label": null, 314 | "logBase": 1, 315 | "max": null, 316 | "min": "0", 317 | "show": true 318 | }, 319 | { 320 | "format": "short", 321 | "label": null, 322 | "logBase": 1, 323 | "max": null, 324 | "min": null, 325 | "show": true 326 | } 327 | ], 328 | "yaxis": { 329 | "align": false, 330 | "alignLevel": null 331 | } 332 | }, 333 | { 334 | "aliasColors": {}, 335 | "bars": true, 336 | "dashLength": 10, 337 | "dashes": false, 338 | "datasource": null, 339 | "fieldConfig": { 340 | "defaults": {}, 341 | "overrides": [] 342 | }, 343 | "fill": 1, 344 | "fillGradient": 0, 345 | "gridPos": { 346 | "h": 9, 347 | "w": 24, 348 | "x": 0, 349 | "y": 18 350 | }, 351 | "hiddenSeries": false, 352 | "id": 7, 353 | "legend": { 354 | "alignAsTable": true, 355 | "avg": false, 356 | "current": false, 357 | "max": false, 358 | "min": false, 359 | "rightSide": true, 360 | "show": true, 361 | "total": false, 362 | "values": false 363 | }, 364 | "lines": false, 365 | "linewidth": 1, 366 | "links": [], 367 | "nullPointMode": "null", 368 | "options": { 369 | "alertThreshold": true 370 | }, 371 | "percentage": false, 372 | "pluginVersion": "7.5.4", 373 | "pointradius": 1, 374 | "points": false, 375 | "renderer": "flot", 376 | "seriesOverrides": [], 377 | "spaceLength": 10, 378 | "stack": true, 379 | "steppedLine": false, 380 | "targets": [ 381 | { 382 | "alias": "$tag_repo", 383 | "groupBy": [ 384 | { 385 | "params": [ 386 | "1d" 387 | ], 388 | "type": "time" 389 | }, 390 | { 391 | "params": [ 392 | "repo" 393 | ], 394 | "type": "tag" 395 | }, 396 | { 397 | "params": [ 398 | "null" 399 | ], 400 | "type": "fill" 401 | } 402 | ], 403 | "measurement": "restic", 404 | "orderByTime": "ASC", 405 | "policy": "default", 406 | "query": "SELECT sum(\"value\") FROM \"restic_value\" WHERE (\"summary_attr\" = 'total_bytes_processed') AND $timeFilter GROUP BY time(1d), \"repo\" fill(null) ", 407 | "rawQuery": false, 408 | "refId": "B", 409 | "resultFormat": "time_series", 410 | "select": [ 411 | [ 412 | { 413 | "params": [ 414 | "total_bytes_processed" 415 | ], 416 | "type": "field" 417 | }, 418 | { 419 | "params": [], 420 | "type": "sum" 421 | } 422 | ] 423 | ], 424 | "tags": [ 425 | { 426 | "key": "type", 427 | "operator": "=", 428 | "value": "summary" 429 | } 430 | ] 431 | } 432 | ], 433 | "thresholds": [], 434 | "timeFrom": null, 435 | "timeRegions": [], 436 | "timeShift": null, 437 | "title": "Backuped data size", 438 | "tooltip": { 439 | "shared": true, 440 | "sort": 0, 441 | "value_type": "individual" 442 | }, 443 | "type": "graph", 444 | "xaxis": { 445 | "buckets": null, 446 | "mode": "time", 447 | "name": null, 448 | "show": true, 449 | "values": [] 450 | }, 451 | "yaxes": [ 452 | { 453 | "format": "decbytes", 454 | "label": null, 455 | "logBase": 1, 456 | "max": null, 457 | "min": "0", 458 | "show": true 459 | }, 460 | { 461 | "format": "short", 462 | "label": null, 463 | "logBase": 1, 464 | "max": null, 465 | "min": null, 466 | "show": true 467 | } 468 | ], 469 | "yaxis": { 470 | "align": false, 471 | "alignLevel": null 472 | } 473 | }, 474 | { 475 | "aliasColors": { 476 | "changed": "#ef843c", 477 | "new": "#7eb26d", 478 | "unmodified": "#65c5db" 479 | }, 480 | "bars": true, 481 | "dashLength": 10, 482 | "dashes": false, 483 | "datasource": null, 484 | "fieldConfig": { 485 | "defaults": {}, 486 | "overrides": [] 487 | }, 488 | "fill": 1, 489 | "fillGradient": 0, 490 | "gridPos": { 491 | "h": 5, 492 | "w": 24, 493 | "x": 0, 494 | "y": 27 495 | }, 496 | "hiddenSeries": false, 497 | "id": 2, 498 | "legend": { 499 | "alignAsTable": false, 500 | "avg": false, 501 | "current": false, 502 | "max": false, 503 | "min": false, 504 | "rightSide": true, 505 | "show": true, 506 | "total": false, 507 | "values": false 508 | }, 509 | "lines": false, 510 | "linewidth": 1, 511 | "links": [], 512 | "nullPointMode": "null", 513 | "options": { 514 | "alertThreshold": true 515 | }, 516 | "percentage": false, 517 | "pluginVersion": "7.5.4", 518 | "pointradius": 2, 519 | "points": false, 520 | "renderer": "flot", 521 | "seriesOverrides": [], 522 | "spaceLength": 10, 523 | "stack": true, 524 | "steppedLine": false, 525 | "targets": [ 526 | { 527 | "alias": "$col", 528 | "groupBy": [ 529 | { 530 | "params": [ 531 | "1d" 532 | ], 533 | "type": "time" 534 | } 535 | ], 536 | "measurement": "restic", 537 | "orderByTime": "ASC", 538 | "policy": "default", 539 | "query": "SELECT sum(\"files_unmodified\") AS \"unmodified\", sum(\"files_changed\") AS \"changed\", sum(\"files_new\") AS \"new\" FROM \"restic\" WHERE $timeFilter GROUP BY time(1d)", 540 | "rawQuery": false, 541 | "refId": "A", 542 | "resultFormat": "time_series", 543 | "select": [ 544 | [ 545 | { 546 | "params": [ 547 | "files_unmodified" 548 | ], 549 | "type": "field" 550 | }, 551 | { 552 | "params": [], 553 | "type": "sum" 554 | }, 555 | { 556 | "params": [ 557 | "unmodified" 558 | ], 559 | "type": "alias" 560 | } 561 | ], 562 | [ 563 | { 564 | "params": [ 565 | "files_changed" 566 | ], 567 | "type": "field" 568 | }, 569 | { 570 | "params": [], 571 | "type": "sum" 572 | }, 573 | { 574 | "params": [ 575 | "changed" 576 | ], 577 | "type": "alias" 578 | } 579 | ], 580 | [ 581 | { 582 | "params": [ 583 | "files_new" 584 | ], 585 | "type": "field" 586 | }, 587 | { 588 | "params": [], 589 | "type": "sum" 590 | }, 591 | { 592 | "params": [ 593 | "new" 594 | ], 595 | "type": "alias" 596 | } 597 | ] 598 | ], 599 | "tags": [ 600 | { 601 | "key": "type", 602 | "operator": "=", 603 | "value": "summary" 604 | } 605 | ] 606 | } 607 | ], 608 | "thresholds": [], 609 | "timeFrom": null, 610 | "timeRegions": [], 611 | "timeShift": null, 612 | "title": "Backuped files", 613 | "tooltip": { 614 | "shared": true, 615 | "sort": 0, 616 | "value_type": "individual" 617 | }, 618 | "type": "graph", 619 | "xaxis": { 620 | "buckets": null, 621 | "mode": "time", 622 | "name": null, 623 | "show": true, 624 | "values": [] 625 | }, 626 | "yaxes": [ 627 | { 628 | "format": "short", 629 | "label": null, 630 | "logBase": 1, 631 | "max": null, 632 | "min": "0", 633 | "show": true 634 | }, 635 | { 636 | "format": "short", 637 | "label": null, 638 | "logBase": 1, 639 | "max": null, 640 | "min": null, 641 | "show": true 642 | } 643 | ], 644 | "yaxis": { 645 | "align": false, 646 | "alignLevel": null 647 | } 648 | }, 649 | { 650 | "datasource": null, 651 | "fieldConfig": { 652 | "defaults": { 653 | "color": { 654 | "fixedColor": "rgb(181, 181, 181)", 655 | "mode": "fixed" 656 | }, 657 | "mappings": [], 658 | "noValue": "none", 659 | "thresholds": { 660 | "mode": "absolute", 661 | "steps": [ 662 | { 663 | "color": "green", 664 | "value": null 665 | } 666 | ] 667 | } 668 | }, 669 | "overrides": [] 670 | }, 671 | "gridPos": { 672 | "h": 4, 673 | "w": 6, 674 | "x": 0, 675 | "y": 32 676 | }, 677 | "hideTimeOverride": true, 678 | "id": 24, 679 | "options": { 680 | "colorMode": "value", 681 | "graphMode": "area", 682 | "justifyMode": "auto", 683 | "orientation": "auto", 684 | "reduceOptions": { 685 | "calcs": [ 686 | "lastNotNull" 687 | ], 688 | "fields": "/^restic\\.repo$/", 689 | "values": false 690 | }, 691 | "text": { 692 | "valueSize": 20 693 | }, 694 | "textMode": "value" 695 | }, 696 | "pluginVersion": "7.5.4", 697 | "targets": [ 698 | { 699 | "groupBy": [], 700 | "measurement": "restic", 701 | "orderByTime": "ASC", 702 | "policy": "default", 703 | "refId": "A", 704 | "resultFormat": "time_series", 705 | "select": [ 706 | [ 707 | { 708 | "params": [ 709 | "percent_done" 710 | ], 711 | "type": "field" 712 | }, 713 | { 714 | "params": [], 715 | "type": "last" 716 | } 717 | ], 718 | [ 719 | { 720 | "params": [ 721 | "repo" 722 | ], 723 | "type": "field" 724 | } 725 | ] 726 | ], 727 | "tags": [ 728 | { 729 | "key": "type", 730 | "operator": "=", 731 | "value": "status" 732 | } 733 | ] 734 | } 735 | ], 736 | "timeFrom": "3m", 737 | "timeShift": null, 738 | "title": "Current backup", 739 | "type": "stat" 740 | }, 741 | { 742 | "datasource": null, 743 | "description": "", 744 | "fieldConfig": { 745 | "defaults": { 746 | "color": { 747 | "fixedColor": "light-blue", 748 | "mode": "fixed" 749 | }, 750 | "mappings": [], 751 | "noValue": "-", 752 | "thresholds": { 753 | "mode": "absolute", 754 | "steps": [ 755 | { 756 | "color": "green", 757 | "value": null 758 | } 759 | ] 760 | }, 761 | "unit": "bytes" 762 | }, 763 | "overrides": [] 764 | }, 765 | "gridPos": { 766 | "h": 4, 767 | "w": 4, 768 | "x": 6, 769 | "y": 32 770 | }, 771 | "hideTimeOverride": true, 772 | "id": 18, 773 | "options": { 774 | "reduceOptions": { 775 | "calcs": [ 776 | "last" 777 | ], 778 | "fields": "/^restic\\.last$/", 779 | "values": false 780 | }, 781 | "showThresholdLabels": false, 782 | "showThresholdMarkers": false, 783 | "text": {} 784 | }, 785 | "pluginVersion": "7.5.4", 786 | "targets": [ 787 | { 788 | "groupBy": [ 789 | { 790 | "params": [ 791 | "$interval" 792 | ], 793 | "type": "time" 794 | } 795 | ], 796 | "measurement": "restic", 797 | "orderByTime": "ASC", 798 | "policy": "default", 799 | "refId": "A", 800 | "resultFormat": "time_series", 801 | "select": [ 802 | [ 803 | { 804 | "params": [ 805 | "bytes_done" 806 | ], 807 | "type": "field" 808 | }, 809 | { 810 | "params": [ 811 | "*0" 812 | ], 813 | "type": "math" 814 | } 815 | ], 816 | [ 817 | { 818 | "params": [ 819 | "total_bytes" 820 | ], 821 | "type": "field" 822 | } 823 | ], 824 | [ 825 | { 826 | "params": [ 827 | "bytes_done" 828 | ], 829 | "type": "field" 830 | }, 831 | { 832 | "params": [], 833 | "type": "last" 834 | } 835 | ] 836 | ], 837 | "tags": [ 838 | { 839 | "key": "type", 840 | "operator": "=", 841 | "value": "status" 842 | } 843 | ] 844 | } 845 | ], 846 | "timeFrom": "3m", 847 | "timeShift": null, 848 | "title": "Bytes processed", 849 | "type": "gauge" 850 | }, 851 | { 852 | "datasource": null, 853 | "description": "", 854 | "fieldConfig": { 855 | "defaults": { 856 | "color": { 857 | "fixedColor": "semi-dark-blue", 858 | "mode": "fixed" 859 | }, 860 | "mappings": [], 861 | "noValue": "-", 862 | "thresholds": { 863 | "mode": "absolute", 864 | "steps": [ 865 | { 866 | "color": "green", 867 | "value": null 868 | }, 869 | { 870 | "color": "#EAB839", 871 | "value": 1 872 | } 873 | ] 874 | }, 875 | "unit": "locale" 876 | }, 877 | "overrides": [] 878 | }, 879 | "gridPos": { 880 | "h": 4, 881 | "w": 4, 882 | "x": 10, 883 | "y": 32 884 | }, 885 | "hideTimeOverride": true, 886 | "id": 19, 887 | "options": { 888 | "reduceOptions": { 889 | "calcs": [ 890 | "last" 891 | ], 892 | "fields": "/^restic\\.last$/", 893 | "values": false 894 | }, 895 | "showThresholdLabels": false, 896 | "showThresholdMarkers": false, 897 | "text": {} 898 | }, 899 | "pluginVersion": "7.5.4", 900 | "targets": [ 901 | { 902 | "groupBy": [ 903 | { 904 | "params": [ 905 | "$interval" 906 | ], 907 | "type": "time" 908 | } 909 | ], 910 | "measurement": "restic", 911 | "orderByTime": "ASC", 912 | "policy": "default", 913 | "refId": "A", 914 | "resultFormat": "time_series", 915 | "select": [ 916 | [ 917 | { 918 | "params": [ 919 | "files_done" 920 | ], 921 | "type": "field" 922 | }, 923 | { 924 | "params": [ 925 | "*0" 926 | ], 927 | "type": "math" 928 | } 929 | ], 930 | [ 931 | { 932 | "params": [ 933 | "total_files" 934 | ], 935 | "type": "field" 936 | } 937 | ], 938 | [ 939 | { 940 | "params": [ 941 | "files_done" 942 | ], 943 | "type": "field" 944 | }, 945 | { 946 | "params": [], 947 | "type": "last" 948 | } 949 | ] 950 | ], 951 | "tags": [ 952 | { 953 | "key": "type", 954 | "operator": "=", 955 | "value": "status" 956 | } 957 | ] 958 | } 959 | ], 960 | "timeFrom": "3m", 961 | "timeShift": null, 962 | "title": "Files processed", 963 | "type": "gauge" 964 | }, 965 | { 966 | "datasource": null, 967 | "description": "", 968 | "fieldConfig": { 969 | "defaults": { 970 | "color": { 971 | "fixedColor": "rgb(180, 180, 180)", 972 | "mode": "fixed" 973 | }, 974 | "mappings": [], 975 | "noValue": "-", 976 | "thresholds": { 977 | "mode": "absolute", 978 | "steps": [ 979 | { 980 | "color": "green", 981 | "value": null 982 | } 983 | ] 984 | }, 985 | "unit": "dateTimeAsLocalNoDateIfToday" 986 | }, 987 | "overrides": [] 988 | }, 989 | "gridPos": { 990 | "h": 2, 991 | "w": 5, 992 | "x": 14, 993 | "y": 32 994 | }, 995 | "hideTimeOverride": true, 996 | "id": 21, 997 | "options": { 998 | "colorMode": "value", 999 | "graphMode": "area", 1000 | "justifyMode": "auto", 1001 | "orientation": "auto", 1002 | "reduceOptions": { 1003 | "calcs": [ 1004 | "lastNotNull" 1005 | ], 1006 | "fields": "/^ETA$/", 1007 | "values": false 1008 | }, 1009 | "text": {}, 1010 | "textMode": "auto" 1011 | }, 1012 | "pluginVersion": "7.5.4", 1013 | "targets": [ 1014 | { 1015 | "groupBy": [], 1016 | "measurement": "restic", 1017 | "orderByTime": "ASC", 1018 | "policy": "default", 1019 | "query": "SELECT time + 123 AS foo , \"seconds_remaining\" FROM \"restic\" WHERE (\"type\" = 'status') AND $timeFilter", 1020 | "rawQuery": false, 1021 | "refId": "A", 1022 | "resultFormat": "time_series", 1023 | "select": [ 1024 | [ 1025 | { 1026 | "params": [ 1027 | "seconds_remaining" 1028 | ], 1029 | "type": "field" 1030 | }, 1031 | { 1032 | "params": [], 1033 | "type": "last" 1034 | }, 1035 | { 1036 | "params": [ 1037 | "*1000" 1038 | ], 1039 | "type": "math" 1040 | }, 1041 | { 1042 | "params": [ 1043 | "remain" 1044 | ], 1045 | "type": "alias" 1046 | } 1047 | ] 1048 | ], 1049 | "tags": [ 1050 | { 1051 | "key": "type", 1052 | "operator": "=", 1053 | "value": "status" 1054 | } 1055 | ] 1056 | } 1057 | ], 1058 | "timeFrom": "3m", 1059 | "timeShift": null, 1060 | "title": "ETA", 1061 | "transformations": [ 1062 | { 1063 | "id": "calculateField", 1064 | "options": { 1065 | "alias": "ETA", 1066 | "binary": { 1067 | "left": "Time", 1068 | "operator": "+", 1069 | "reducer": "sum", 1070 | "right": "restic.remain" 1071 | }, 1072 | "mode": "binary", 1073 | "reduce": { 1074 | "include": [ 1075 | "Time", 1076 | "restic.remain" 1077 | ], 1078 | "reducer": "sum" 1079 | }, 1080 | "replaceFields": true 1081 | } 1082 | } 1083 | ], 1084 | "type": "stat" 1085 | }, 1086 | { 1087 | "datasource": null, 1088 | "description": "", 1089 | "fieldConfig": { 1090 | "defaults": { 1091 | "color": { 1092 | "fixedColor": "rgb(180, 180, 180)", 1093 | "mode": "thresholds" 1094 | }, 1095 | "mappings": [], 1096 | "noValue": "-", 1097 | "thresholds": { 1098 | "mode": "absolute", 1099 | "steps": [ 1100 | { 1101 | "color": "green", 1102 | "value": null 1103 | }, 1104 | { 1105 | "color": "red", 1106 | "value": 1 1107 | } 1108 | ] 1109 | }, 1110 | "unit": "short" 1111 | }, 1112 | "overrides": [] 1113 | }, 1114 | "gridPos": { 1115 | "h": 4, 1116 | "w": 5, 1117 | "x": 19, 1118 | "y": 32 1119 | }, 1120 | "hideTimeOverride": true, 1121 | "id": 25, 1122 | "options": { 1123 | "colorMode": "value", 1124 | "graphMode": "area", 1125 | "justifyMode": "auto", 1126 | "orientation": "auto", 1127 | "reduceOptions": { 1128 | "calcs": [ 1129 | "lastNotNull" 1130 | ], 1131 | "fields": "", 1132 | "values": false 1133 | }, 1134 | "text": {}, 1135 | "textMode": "auto" 1136 | }, 1137 | "pluginVersion": "7.5.4", 1138 | "targets": [ 1139 | { 1140 | "groupBy": [], 1141 | "measurement": "restic", 1142 | "orderByTime": "ASC", 1143 | "policy": "default", 1144 | "query": "SELECT last(\"seconds_remaining\") FROM \"restic\" WHERE (\"type\" = 'status') AND $timeFilter", 1145 | "rawQuery": false, 1146 | "refId": "A", 1147 | "resultFormat": "time_series", 1148 | "select": [ 1149 | [ 1150 | { 1151 | "params": [ 1152 | "error_count" 1153 | ], 1154 | "type": "field" 1155 | }, 1156 | { 1157 | "params": [], 1158 | "type": "last" 1159 | } 1160 | ] 1161 | ], 1162 | "tags": [ 1163 | { 1164 | "key": "type", 1165 | "operator": "=", 1166 | "value": "status" 1167 | } 1168 | ] 1169 | } 1170 | ], 1171 | "timeFrom": "3m", 1172 | "timeShift": null, 1173 | "title": "Error count", 1174 | "type": "stat" 1175 | }, 1176 | { 1177 | "datasource": null, 1178 | "description": "", 1179 | "fieldConfig": { 1180 | "defaults": { 1181 | "color": { 1182 | "fixedColor": "rgb(180, 180, 180)", 1183 | "mode": "fixed" 1184 | }, 1185 | "mappings": [], 1186 | "noValue": "-", 1187 | "thresholds": { 1188 | "mode": "absolute", 1189 | "steps": [ 1190 | { 1191 | "color": "green", 1192 | "value": null 1193 | }, 1194 | { 1195 | "color": "red", 1196 | "value": 80 1197 | } 1198 | ] 1199 | }, 1200 | "unit": "dtdurations" 1201 | }, 1202 | "overrides": [] 1203 | }, 1204 | "gridPos": { 1205 | "h": 2, 1206 | "w": 5, 1207 | "x": 14, 1208 | "y": 34 1209 | }, 1210 | "hideTimeOverride": true, 1211 | "id": 22, 1212 | "options": { 1213 | "colorMode": "value", 1214 | "graphMode": "area", 1215 | "justifyMode": "auto", 1216 | "orientation": "auto", 1217 | "reduceOptions": { 1218 | "calcs": [ 1219 | "lastNotNull" 1220 | ], 1221 | "fields": "", 1222 | "values": false 1223 | }, 1224 | "text": {}, 1225 | "textMode": "auto" 1226 | }, 1227 | "pluginVersion": "7.5.4", 1228 | "targets": [ 1229 | { 1230 | "groupBy": [], 1231 | "measurement": "restic", 1232 | "orderByTime": "ASC", 1233 | "policy": "default", 1234 | "query": "SELECT last(\"seconds_remaining\") FROM \"restic\" WHERE (\"type\" = 'status') AND $timeFilter", 1235 | "rawQuery": false, 1236 | "refId": "A", 1237 | "resultFormat": "time_series", 1238 | "select": [ 1239 | [ 1240 | { 1241 | "params": [ 1242 | "seconds_elapsed" 1243 | ], 1244 | "type": "field" 1245 | }, 1246 | { 1247 | "params": [], 1248 | "type": "last" 1249 | } 1250 | ] 1251 | ], 1252 | "tags": [ 1253 | { 1254 | "key": "type", 1255 | "operator": "=", 1256 | "value": "status" 1257 | } 1258 | ] 1259 | } 1260 | ], 1261 | "timeFrom": "3m", 1262 | "timeShift": null, 1263 | "title": "Total duration so far", 1264 | "type": "stat" 1265 | }, 1266 | { 1267 | "datasource": null, 1268 | "description": "", 1269 | "fieldConfig": { 1270 | "defaults": { 1271 | "color": { 1272 | "fixedColor": "rgb(180, 180, 180)", 1273 | "mode": "fixed" 1274 | }, 1275 | "mappings": [], 1276 | "noValue": "-", 1277 | "thresholds": { 1278 | "mode": "absolute", 1279 | "steps": [ 1280 | { 1281 | "color": "green", 1282 | "value": null 1283 | }, 1284 | { 1285 | "color": "red", 1286 | "value": 1 1287 | } 1288 | ] 1289 | }, 1290 | "unit": "none" 1291 | }, 1292 | "overrides": [] 1293 | }, 1294 | "gridPos": { 1295 | "h": 2, 1296 | "w": 24, 1297 | "x": 0, 1298 | "y": 36 1299 | }, 1300 | "hideTimeOverride": true, 1301 | "id": 26, 1302 | "options": { 1303 | "colorMode": "value", 1304 | "graphMode": "area", 1305 | "justifyMode": "auto", 1306 | "orientation": "auto", 1307 | "reduceOptions": { 1308 | "calcs": [ 1309 | "lastNotNull" 1310 | ], 1311 | "fields": "", 1312 | "values": false 1313 | }, 1314 | "text": {}, 1315 | "textMode": "auto" 1316 | }, 1317 | "pluginVersion": "7.5.4", 1318 | "targets": [ 1319 | { 1320 | "groupBy": [], 1321 | "measurement": "restic", 1322 | "orderByTime": "ASC", 1323 | "policy": "default", 1324 | "query": "SELECT last(\"seconds_remaining\") FROM \"restic\" WHERE (\"type\" = 'status') AND $timeFilter", 1325 | "rawQuery": false, 1326 | "refId": "A", 1327 | "resultFormat": "time_series", 1328 | "select": [ 1329 | [ 1330 | { 1331 | "params": [ 1332 | "current_files" 1333 | ], 1334 | "type": "field" 1335 | }, 1336 | { 1337 | "params": [], 1338 | "type": "last" 1339 | } 1340 | ] 1341 | ], 1342 | "tags": [ 1343 | { 1344 | "key": "type", 1345 | "operator": "=", 1346 | "value": "status" 1347 | } 1348 | ] 1349 | } 1350 | ], 1351 | "timeFrom": "3m", 1352 | "title": "Current file processed", 1353 | "type": "stat" 1354 | }, 1355 | { 1356 | "columns": [], 1357 | "datasource": null, 1358 | "fieldConfig": { 1359 | "defaults": {}, 1360 | "overrides": [] 1361 | }, 1362 | "fontSize": "100%", 1363 | "gridPos": { 1364 | "h": 11, 1365 | "w": 24, 1366 | "x": 0, 1367 | "y": 38 1368 | }, 1369 | "id": 10, 1370 | "links": [], 1371 | "pageSize": null, 1372 | "scroll": true, 1373 | "showHeader": true, 1374 | "sort": { 1375 | "col": 0, 1376 | "desc": true 1377 | }, 1378 | "styles": [ 1379 | { 1380 | "alias": "Time", 1381 | "align": "auto", 1382 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1383 | "pattern": "Time", 1384 | "type": "date" 1385 | }, 1386 | { 1387 | "alias": "Duration", 1388 | "align": "auto", 1389 | "colorMode": null, 1390 | "colors": [ 1391 | "rgba(245, 54, 54, 0.9)", 1392 | "rgba(237, 129, 40, 0.89)", 1393 | "rgba(50, 172, 45, 0.97)" 1394 | ], 1395 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1396 | "decimals": 0, 1397 | "mappingType": 1, 1398 | "pattern": "total_duration", 1399 | "thresholds": [], 1400 | "type": "number", 1401 | "unit": "dtdurations" 1402 | }, 1403 | { 1404 | "alias": "Backuped data size", 1405 | "align": "auto", 1406 | "colorMode": null, 1407 | "colors": [ 1408 | "rgba(245, 54, 54, 0.9)", 1409 | "rgba(237, 129, 40, 0.89)", 1410 | "rgba(50, 172, 45, 0.97)" 1411 | ], 1412 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1413 | "decimals": 2, 1414 | "mappingType": 1, 1415 | "pattern": "total_bytes_processed", 1416 | "thresholds": [], 1417 | "type": "number", 1418 | "unit": "decbytes" 1419 | }, 1420 | { 1421 | "alias": "Data added", 1422 | "align": "auto", 1423 | "colorMode": null, 1424 | "colors": [ 1425 | "rgba(245, 54, 54, 0.9)", 1426 | "rgba(237, 129, 40, 0.89)", 1427 | "rgba(50, 172, 45, 0.97)" 1428 | ], 1429 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1430 | "decimals": 2, 1431 | "mappingType": 1, 1432 | "pattern": "data_added", 1433 | "thresholds": [], 1434 | "type": "number", 1435 | "unit": "decbytes" 1436 | }, 1437 | { 1438 | "alias": "Files changed", 1439 | "align": "auto", 1440 | "colorMode": null, 1441 | "colors": [ 1442 | "rgba(245, 54, 54, 0.9)", 1443 | "rgba(237, 129, 40, 0.89)", 1444 | "rgba(50, 172, 45, 0.97)" 1445 | ], 1446 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 1447 | "decimals": 0, 1448 | "mappingType": 1, 1449 | "pattern": "files_changed", 1450 | "thresholds": [], 1451 | "type": "number", 1452 | "unit": "short" 1453 | }, 1454 | { 1455 | "alias": "", 1456 | "align": "auto", 1457 | "colorMode": null, 1458 | "colors": [ 1459 | "rgba(245, 54, 54, 0.9)", 1460 | "rgba(237, 129, 40, 0.89)", 1461 | "rgba(50, 172, 45, 0.97)" 1462 | ], 1463 | "decimals": 2, 1464 | "pattern": "/.*/", 1465 | "thresholds": [], 1466 | "type": "number", 1467 | "unit": "short" 1468 | } 1469 | ], 1470 | "targets": [ 1471 | { 1472 | "alias": "$col", 1473 | "groupBy": [], 1474 | "measurement": "restic", 1475 | "orderByTime": "ASC", 1476 | "policy": "default", 1477 | "query": "SELECT \"total_duration\", \"total_files_processed\", \"snapshot\", \"repo\" FROM \"restic\" WHERE $timeFilter", 1478 | "rawQuery": false, 1479 | "refId": "A", 1480 | "resultFormat": "time_series", 1481 | "select": [ 1482 | [ 1483 | { 1484 | "params": [ 1485 | "repo" 1486 | ], 1487 | "type": "field" 1488 | }, 1489 | { 1490 | "params": [ 1491 | "Repository" 1492 | ], 1493 | "type": "alias" 1494 | } 1495 | ], 1496 | [ 1497 | { 1498 | "params": [ 1499 | "snapshot" 1500 | ], 1501 | "type": "field" 1502 | }, 1503 | { 1504 | "params": [ 1505 | "Snapshot" 1506 | ], 1507 | "type": "alias" 1508 | } 1509 | ], 1510 | [ 1511 | { 1512 | "params": [ 1513 | "total_duration" 1514 | ], 1515 | "type": "field" 1516 | } 1517 | ], 1518 | [ 1519 | { 1520 | "params": [ 1521 | "total_bytes_processed" 1522 | ], 1523 | "type": "field" 1524 | } 1525 | ], 1526 | [ 1527 | { 1528 | "params": [ 1529 | "data_added" 1530 | ], 1531 | "type": "field" 1532 | } 1533 | ], 1534 | [ 1535 | { 1536 | "params": [ 1537 | "files_changed" 1538 | ], 1539 | "type": "field" 1540 | } 1541 | ] 1542 | ], 1543 | "tags": [ 1544 | { 1545 | "key": "type", 1546 | "operator": "=", 1547 | "value": "summary" 1548 | } 1549 | ] 1550 | } 1551 | ], 1552 | "timeFrom": "3d", 1553 | "title": "Latest backup jobs", 1554 | "transform": "timeseries_to_columns", 1555 | "type": "table-old" 1556 | } 1557 | ], 1558 | "refresh": false, 1559 | "schemaVersion": 27, 1560 | "style": "dark", 1561 | "tags": [], 1562 | "templating": { 1563 | "list": [] 1564 | }, 1565 | "time": { 1566 | "from": "now-7d", 1567 | "to": "now" 1568 | }, 1569 | "timepicker": { 1570 | "refresh_intervals": [ 1571 | "5s", 1572 | "10s", 1573 | "30s", 1574 | "1m", 1575 | "5m", 1576 | "15m", 1577 | "30m", 1578 | "1h", 1579 | "2h", 1580 | "1d" 1581 | ], 1582 | "time_options": [ 1583 | "5m", 1584 | "15m", 1585 | "1h", 1586 | "6h", 1587 | "12h", 1588 | "24h", 1589 | "2d", 1590 | "7d", 1591 | "30d" 1592 | ] 1593 | }, 1594 | "timezone": "", 1595 | "title": "Restic Backup", 1596 | "uid": "wEmkK4wMk", 1597 | "version": 44 1598 | } -------------------------------------------------------------------------------- /restic2influx-grafana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hn/restic2influx/2441b36d582b469f39b4558eeecb387b9b9b0415/restic2influx-grafana.png --------------------------------------------------------------------------------