ruby-grafana-reporter 0.1.7 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +86 -245
- data/bin/ruby-grafana-reporter +3 -2
- data/lib/VERSION.rb +6 -3
- data/lib/grafana/abstract_datasource.rb +116 -0
- data/lib/grafana/dashboard.rb +75 -66
- data/lib/grafana/errors.rb +81 -61
- data/lib/grafana/grafana.rb +130 -131
- data/lib/grafana/grafana_alerts_datasource.rb +57 -0
- data/lib/grafana/grafana_annotations_datasource.rb +56 -0
- data/lib/grafana/grafana_property_datasource.rb +25 -0
- data/lib/grafana/graphite_datasource.rb +44 -0
- data/lib/grafana/image_rendering_datasource.rb +44 -0
- data/lib/grafana/panel.rb +47 -39
- data/lib/grafana/prometheus_datasource.rb +39 -0
- data/lib/grafana/sql_datasource.rb +65 -0
- data/lib/grafana/variable.rb +218 -259
- data/lib/grafana/webrequest.rb +71 -0
- data/lib/grafana_reporter/abstract_query.rb +401 -0
- data/lib/grafana_reporter/abstract_report.rb +163 -109
- data/lib/grafana_reporter/alerts_table_query.rb +44 -0
- data/lib/grafana_reporter/annotations_table_query.rb +43 -0
- data/lib/grafana_reporter/application/application.rb +162 -229
- data/lib/grafana_reporter/application/errors.rb +33 -30
- data/lib/grafana_reporter/application/webservice.rb +242 -0
- data/lib/grafana_reporter/asciidoctor/alerts_table_include_processor.rb +90 -0
- data/lib/grafana_reporter/asciidoctor/annotations_table_include_processor.rb +89 -0
- data/lib/grafana_reporter/asciidoctor/panel_image_block_macro.rb +76 -0
- data/lib/grafana_reporter/asciidoctor/panel_image_inline_macro.rb +77 -0
- data/lib/grafana_reporter/asciidoctor/panel_property_inline_macro.rb +72 -0
- data/lib/grafana_reporter/asciidoctor/panel_query_table_include_processor.rb +98 -0
- data/lib/grafana_reporter/asciidoctor/panel_query_value_inline_macro.rb +93 -0
- data/lib/grafana_reporter/asciidoctor/processor_mixin.rb +23 -0
- data/lib/grafana_reporter/asciidoctor/report.rb +172 -159
- data/lib/grafana_reporter/asciidoctor/show_environment_include_processor.rb +46 -0
- data/lib/grafana_reporter/asciidoctor/show_help_include_processor.rb +35 -0
- data/lib/grafana_reporter/asciidoctor/sql_table_include_processor.rb +92 -0
- data/lib/grafana_reporter/asciidoctor/sql_value_inline_macro.rb +88 -0
- data/lib/grafana_reporter/asciidoctor/value_as_variable_include_processor.rb +90 -0
- data/lib/grafana_reporter/configuration.rb +310 -326
- data/lib/grafana_reporter/console_configuration_wizard.rb +319 -0
- data/lib/grafana_reporter/demo_report_wizard.rb +87 -0
- data/lib/grafana_reporter/errors.rb +81 -38
- data/lib/grafana_reporter/help.rb +447 -0
- data/lib/grafana_reporter/logger/two_way_logger.rb +58 -52
- data/lib/grafana_reporter/panel_image_query.rb +29 -0
- data/lib/grafana_reporter/panel_property_query.rb +22 -0
- data/lib/grafana_reporter/query_value_query.rb +79 -0
- data/lib/grafana_reporter/report_webhook.rb +35 -0
- data/lib/{ruby-grafana-reporter.rb → ruby_grafana_reporter.rb} +29 -27
- metadata +48 -60
- data/lib/grafana/abstract_panel_query.rb +0 -20
- data/lib/grafana/abstract_query.rb +0 -127
- data/lib/grafana/abstract_sql_query.rb +0 -42
- data/lib/grafana/panel_image_query.rb +0 -49
- data/lib/grafana_reporter/asciidoctor/alerts_table_query.rb +0 -99
- data/lib/grafana_reporter/asciidoctor/annotations_table_query.rb +0 -96
- data/lib/grafana_reporter/asciidoctor/errors.rb +0 -37
- data/lib/grafana_reporter/asciidoctor/extensions/alerts_table_include_processor.rb +0 -86
- data/lib/grafana_reporter/asciidoctor/extensions/annotations_table_include_processor.rb +0 -86
- data/lib/grafana_reporter/asciidoctor/extensions/panel_image_block_macro.rb +0 -67
- data/lib/grafana_reporter/asciidoctor/extensions/panel_image_inline_macro.rb +0 -65
- data/lib/grafana_reporter/asciidoctor/extensions/panel_property_inline_macro.rb +0 -58
- data/lib/grafana_reporter/asciidoctor/extensions/panel_query_table_include_processor.rb +0 -75
- data/lib/grafana_reporter/asciidoctor/extensions/panel_query_value_inline_macro.rb +0 -70
- data/lib/grafana_reporter/asciidoctor/extensions/processor_mixin.rb +0 -18
- data/lib/grafana_reporter/asciidoctor/extensions/show_environment_include_processor.rb +0 -41
- data/lib/grafana_reporter/asciidoctor/extensions/show_help_include_processor.rb +0 -202
- data/lib/grafana_reporter/asciidoctor/extensions/sql_table_include_processor.rb +0 -67
- data/lib/grafana_reporter/asciidoctor/extensions/sql_value_inline_macro.rb +0 -65
- data/lib/grafana_reporter/asciidoctor/extensions/value_as_variable_include_processor.rb +0 -57
- data/lib/grafana_reporter/asciidoctor/panel_first_value_query.rb +0 -32
- data/lib/grafana_reporter/asciidoctor/panel_image_query.rb +0 -23
- data/lib/grafana_reporter/asciidoctor/panel_property_query.rb +0 -43
- data/lib/grafana_reporter/asciidoctor/panel_table_query.rb +0 -36
- data/lib/grafana_reporter/asciidoctor/query_mixin.rb +0 -309
- data/lib/grafana_reporter/asciidoctor/sql_first_value_query.rb +0 -34
- data/lib/grafana_reporter/asciidoctor/sql_table_query.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db7e3fbf0f8c1a3d7d9ce8d3e3e215b6f6bb5ec3c170252d575e0516b3312b20
|
4
|
+
data.tar.gz: b05cfa64a8d5bef650917df47ad9b84a140f302e87d2c6664c1fab3272e7212e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3925cc108c3cedc51d6a37926b4ba937296cfd55137d8af40b9254bb92383cf253713321e95e6cfcfeb50de9adf7acd11777cf108227527d2c87658d74173a51
|
7
|
+
data.tar.gz: 79c345933fd16d7c2acfa24715ef09119c1973c605bb5a7b2caa959fcf08ae748e087338717d6e4343281e68a9a3ed9440d5c74e57846691f7033ef2f41e4079
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[](https://github.com/divinity666/ruby-grafana-reporter/blob/master/LICENSE)
|
2
2
|
[](https://travis-ci.org/github/divinity666/ruby-grafana-reporter?branch=master)
|
3
3
|
[](https://coveralls.io/github/divinity666/ruby-grafana-reporter?branch=master)
|
4
|
+
[](https://badge.fury.io/rb/ruby-grafana-reporter)
|
4
5
|
|
5
6
|
# Ruby Grafana Reporter
|
6
7
|
Reporting Service for Grafana
|
@@ -8,18 +9,11 @@ Reporting Service for Grafana
|
|
8
9
|
## Table of Contents
|
9
10
|
|
10
11
|
* [About the project](#about-the-project)
|
11
|
-
* [Getting started](#getting-started)
|
12
|
-
* [Initial Configuration](#initial-configuration)
|
13
|
-
* [Option 1) "Baremetal" Ruby](#baremetal-ruby)
|
14
|
-
* [Option 2) As a GEM](#as-a-gem)
|
15
|
-
* [Option 3) Docker](#docker)
|
16
|
-
* [Grafana integration](#grafana-integration)
|
17
|
-
* [Webservice overview](#webservice-overview)
|
18
12
|
* [Features](#features)
|
13
|
+
* [Quick Start](#quick-start)
|
14
|
+
* [Grafana integration](#grafana-integration)
|
15
|
+
* [Webservice overview](#webservice-overview)
|
19
16
|
* [Roadmap](#roadmap)
|
20
|
-
* [Contributing](#contributing)
|
21
|
-
* [Licensing](#licensing)
|
22
|
-
* [Acknowledgements](#acknowledgements)
|
23
17
|
* [Donations](#donations)
|
24
18
|
|
25
19
|
## About the project
|
@@ -28,222 +22,88 @@ Did you ever want to create (professional) reports based on Grafana dashboards?
|
|
28
22
|
I did so in order to being able to automatically get monthly reports of my
|
29
23
|
home's energy usage. That's how it started.
|
30
24
|
|
31
|
-
|
32
|
-
(but not limited to) [asciidoctor](https://github.com/asciidoctor/asciidoctor)
|
33
|
-
report templates, which can dynamically integrate Grafana panels, queries,
|
34
|
-
images etc. to create dynamic PDF reports on the fly.
|
35
|
-
|
36
|
-
The report may also be returned in any other format that asciidoctor supports.
|
37
|
-
|
38
|
-
The reporter can run standalone or as a webservice. It is built to
|
39
|
-
integrate without further dependencies with the asciidoctor docker image.
|
40
|
-
|
41
|
-
The complete
|
42
|
-
[API documentation](https://rubydoc.info/gems/ruby-grafana-reporter) can be
|
43
|
-
found here.
|
44
|
-
|
45
|
-
## Getting started
|
46
|
-
|
47
|
-
There exist several ways of installing the reporter. All of them have in
|
48
|
-
common, that they require a working ruby environment. Check with the following
|
49
|
-
commands, that the tools are setup and run properly:
|
50
|
-
|
51
|
-
ruby -v
|
52
|
-
gem -v
|
53
|
-
|
54
|
-
### Initial Configuration
|
55
|
-
|
56
|
-
#### Configuration file
|
57
|
-
|
58
|
-
Create a first configuration file, named e.g. `myconfig` with the following
|
59
|
-
content:
|
60
|
-
|
61
|
-
grafana-reporter:
|
62
|
-
templates-folder: templates
|
63
|
-
reports-folder: reports
|
64
|
-
|
65
|
-
grafana:
|
66
|
-
default:
|
67
|
-
host: <<url to your grafana host, e.g. https://localhost:3000>>
|
68
|
-
api_key: <<api key to be used by the reporter>>
|
69
|
-
datasources: # mandatory, if the api_key has only viewer rights, optional otherwise
|
70
|
-
"<<data source name in grafana>>": <<data source id in grafana>>
|
71
|
-
|
72
|
-
default-document-attributes:
|
73
|
-
imagesdir: .
|
74
|
-
|
75
|
-
#### "Hello World" asciidoctor template
|
76
|
-
|
77
|
-
Create a first asciidoctor template file in your `templates-folder`, e.g.
|
78
|
-
`myfirsttemplate.adoc` with the following content:
|
79
|
-
|
80
|
-
= First Ruby Grafana Reporter Example
|
81
|
-
|
82
|
-
include::grafana_help[]
|
83
|
-
|
84
|
-
include::grafana_environment[]
|
85
|
-
|
86
|
-
Now you're ready to go! Let's check it out!
|
87
|
-
|
88
|
-
### "Baremetal" Ruby
|
89
|
-
|
90
|
-
To install on a plain ruby installation, make sure that the `ruby` command is
|
91
|
-
accessible from your command line and then follow these steps:
|
92
|
-
|
93
|
-
Download the ruby grafana reporter to a folder of your choice.
|
94
|
-
|
95
|
-
Install asciidoctor
|
96
|
-
|
97
|
-
gem install asciidoctor asciidoctor-pdf zip
|
98
|
-
|
99
|
-
or simply use
|
100
|
-
|
101
|
-
bundle install
|
102
|
-
|
103
|
-
To check if all dependencies are setup properly, run the following command
|
104
|
-
in that folder:
|
105
|
-
|
106
|
-
ruby bin/ruby-grafana-reporter -h
|
107
|
-
|
108
|
-
Check that your configured grafana instance can be accessed properly:
|
109
|
-
|
110
|
-
ruby bin/ruby-grafana-reporter myconfig --test default
|
111
|
-
|
112
|
-
Now you may want to check the conversion of your Hello World example:
|
113
|
-
|
114
|
-
ruby bin/ruby-grafana-reporter myconfig --template myfirsttemplate.adoc --output myfirstrender.pdf
|
115
|
-
|
116
|
-
You should now find a PDF document named `myfirstrender.pdf` which includes a detailed
|
117
|
-
help page on how to use the ruby grafana reporter functions in asciidoctor, as well
|
118
|
-
as a list of all environment variables that can be accessed.
|
119
|
-
|
120
|
-
If this has been working properly as well, you might want to run the reporter
|
121
|
-
as a webservice. Nothing easier than that. Just call:
|
122
|
-
|
123
|
-
ruby bin/ruby-grafana-reporter myconfig
|
124
|
-
|
125
|
-
Test your configuration by requesting the following URL in a browser of your
|
126
|
-
choice:
|
127
|
-
|
128
|
-
http://<<your-server-url>>:8815/render?var-template=myfirsttemplate.adoc
|
129
|
-
|
130
|
-
If this now also serves you the PDF document after a few seconds (remember to
|
131
|
-
reload the page), you are done with the reporter service and might want to go
|
132
|
-
to step into the integration with grafana.
|
133
|
-
|
134
|
-
### As a GEM
|
135
|
-
|
136
|
-
Installation as a gem is a simple way, if you don't want to mess with the
|
137
|
-
efforts of a barebone installation.
|
138
|
-
|
139
|
-
To install as a gem, simply run:
|
140
|
-
|
141
|
-
gem install ruby-grafana-reporter
|
142
|
-
|
143
|
-
To see if it works properly, you may run the application:
|
144
|
-
|
145
|
-
ruby-grafana-reporter
|
146
|
-
|
147
|
-
To check if your configured grafana instance can be accessed properly:
|
148
|
-
|
149
|
-
ruby-grafana-reporter myconfig --test default
|
150
|
-
|
151
|
-
Now you may want to check the conversion of your Hello World example:
|
152
|
-
|
153
|
-
ruby-grafana-reporter myconfig --template myfirsttemplate.adoc --output myfirstrender.pdf
|
154
|
-
|
155
|
-
You should now find a PDF document named `myfirstrender.pdf` which includes a detailed
|
156
|
-
help page on how to use the ruby grafana reporter functions in asciidoctor, as well
|
157
|
-
as a list of all environment variables that can be accessed.
|
158
|
-
|
159
|
-
If this has been working properly as well, you might want to run the reporter
|
160
|
-
as a webservice. Nothing easier than that. Just call:
|
161
|
-
|
162
|
-
ruby-grafana-reporter myconfig
|
163
|
-
|
164
|
-
Test your configuration by requesting the following URL in a browser of your
|
165
|
-
choice:
|
166
|
-
|
167
|
-
http://<<your-server-url>>:8815/render?var-template=myfirsttemplate.adoc
|
168
|
-
|
169
|
-
If this now also serves you the PDF document after a few seconds (remember to
|
170
|
-
reload the page), you are done with the reporter service and might want to go
|
171
|
-
to step into the integration with grafana.
|
172
|
-
|
173
|
-
### Docker
|
174
|
-
|
175
|
-
One of the key features of the reporter is, that it can work seemlessly with
|
176
|
-
the official `asciidoctor` docker container without further dependencies.
|
177
|
-
|
178
|
-
Assuming you have a `docker-compose` setup running, you may want to add the
|
179
|
-
following to your services secion in your `docker-compose.yml`:
|
180
|
-
|
181
|
-
asciidoctor:
|
182
|
-
image: asciidoctor/docker-asciidoctor
|
183
|
-
container_name: asciidoctor
|
184
|
-
hostname: asciidoctor
|
185
|
-
volumes:
|
186
|
-
- /<<an-empty-local-path>>:/documents
|
187
|
-
restart: unless-stopped
|
188
|
-
|
189
|
-
After running this container, you have to copy the reporter files. Download the
|
190
|
-
ruby grafana reporter to the folder `<<an-empty-local-path>>`. I tend to use
|
191
|
-
the single file application there.
|
192
|
-
|
193
|
-
To test the setup, you'll have to first step inside the container, e.g. by
|
194
|
-
calling `docker exec` with the appropriate parameters. Then you can simply
|
195
|
-
run
|
196
|
-
|
197
|
-
ruby bin/ruby-grafana-reporter -h
|
198
|
-
|
199
|
-
Check that your configured grafana instance can be accessed properly:
|
25
|
+
## Features
|
200
26
|
|
201
|
-
|
27
|
+
* Build PDF reports based on [grafana](https://github.com/grafana/grafana) dashboards
|
28
|
+
(other formats supported)
|
29
|
+
* Include dynamic content from grafana (see [function documentation](FUNCTION_CALLS.md)
|
30
|
+
as a detailed reference):
|
31
|
+
* panels as images
|
32
|
+
* tables based on grafana panel queries or custom database queries (no images!)
|
33
|
+
* single values to be integrated in text, based on grafana panel queries or custom
|
34
|
+
database queries
|
35
|
+
* Multi purpose use of the reporter
|
36
|
+
* webservice to be called directly from grafana - it also runs without further
|
37
|
+
dependencies in the standard asciidoctor docker container!
|
38
|
+
* standalone command line tool, e.g. to be automated with cron or bash scrips
|
39
|
+
* Comes with a complete configuration wizard, including functionality to build a
|
40
|
+
demo report on top of the configured grafana host
|
41
|
+
* Supports all SQL based datasources, as well as graphite and prometheus
|
42
|
+
* Solid as a rock, also in case of template errors and whatever else may happen
|
43
|
+
* Full [API documentation](https://rubydoc.info/gems/ruby-grafana-reporter) available
|
202
44
|
|
203
|
-
|
45
|
+
## Quick Start
|
204
46
|
|
205
|
-
|
47
|
+
You don't have a grafana setup runnning already? No worries, just configure
|
48
|
+
`https://play.grafana.org` in the configuration wizard and see the magic
|
49
|
+
happen for that!
|
206
50
|
|
207
|
-
|
208
|
-
|
209
|
-
|
51
|
+
If your grafana setup requires a login, you'll have to setup an api key for
|
52
|
+
the reporter. Please follow the steps
|
53
|
+
[described here](https://github.com/divinity666/ruby-grafana-reporter/issues/2#issuecomment-811836757)
|
54
|
+
first.
|
210
55
|
|
211
|
-
|
212
|
-
as a webservice always when starting the container. To do so, use the following
|
213
|
-
`docker-compose` configuration. Watch out for the added lines!
|
56
|
+
**Windows:**
|
214
57
|
|
215
|
-
|
216
|
-
|
217
|
-
container_name: asciidoctor
|
218
|
-
hostname: asciidoctor
|
219
|
-
volumes:
|
220
|
-
- /<<an-empty-local-path>>:/documents
|
221
|
-
command:
|
222
|
-
sh /documents/startup.sh
|
223
|
-
restart: unless-stopped
|
58
|
+
* [Download latest Windows executable](https://github.com/divinity666/ruby-grafana-reporter/releases/latest)
|
59
|
+
* `ruby-grafana-reporter -w`
|
224
60
|
|
225
|
-
|
226
|
-
|
61
|
+
Known issues:
|
62
|
+
* images are currently not included in PDF conversions due to missing support in Prawn gem for windows;
|
63
|
+
other target formats do work properly with images
|
227
64
|
|
228
|
-
|
229
|
-
ruby bin/ruby-grafana-reporter myconfig
|
65
|
+
**Raspberry Pi:**
|
230
66
|
|
231
|
-
|
67
|
+
* `sudo apt-get install ruby`
|
68
|
+
* `gem install ruby-grafana-reporter`
|
69
|
+
* `ruby-grafana-reporter -w`
|
232
70
|
|
233
|
-
|
234
|
-
choice:
|
71
|
+
**Ruby environment:**
|
235
72
|
|
236
|
-
|
73
|
+
* `gem install ruby-grafana-reporter`
|
74
|
+
* `ruby-grafana-reporter -w`
|
237
75
|
|
238
|
-
|
239
|
-
reload the page), you are done with the reporter service and might want to go
|
240
|
-
to step into the integration with grafana.
|
76
|
+
**Docker environment** (advanced users):
|
241
77
|
|
242
|
-
|
78
|
+
* [Download latest single-rb file](https://github.com/divinity666/ruby-grafana-reporter/releases/latest)
|
79
|
+
to an empty folder
|
80
|
+
* create a configuration file by calling `ruby ruby-grafana-reporter -w` (if in doubt,
|
81
|
+
run the command within your docker container)
|
82
|
+
* create file `/<<path-to-single-rb-file-folder>>/startup.sh` with the following
|
83
|
+
content:
|
243
84
|
|
244
|
-
|
245
|
-
|
246
|
-
|
85
|
+
```
|
86
|
+
cd /documents
|
87
|
+
ruby bin/ruby-grafana-reporter
|
88
|
+
```
|
89
|
+
* add asciidoctor your compose yaml:
|
90
|
+
|
91
|
+
```
|
92
|
+
asciidoctor:
|
93
|
+
image: asciidoctor/docker-asciidoctor
|
94
|
+
container_name: asciidoctor
|
95
|
+
hostname: asciidoctor
|
96
|
+
volumes:
|
97
|
+
- /<<path-to-single-rb-file-folder>>:/documents
|
98
|
+
command:
|
99
|
+
sh /documents/startup.sh
|
100
|
+
restart: unless-stopped
|
101
|
+
```
|
102
|
+
* start/restart the asciidoctor docker container
|
103
|
+
|
104
|
+
## Grafana integration
|
105
|
+
|
106
|
+
The key feature of the report is, that it can easily be integrated with grafana.
|
247
107
|
|
248
108
|
For accessing the reporter from grafana, you need to simply add a link to your
|
249
109
|
grafana dashboard:
|
@@ -253,27 +113,27 @@ grafana dashboard:
|
|
253
113
|
* Select `Add`
|
254
114
|
* Fill out as following:
|
255
115
|
* Type: `link`
|
256
|
-
* Url: `http://<<your-server-url
|
257
|
-
* Title: `
|
116
|
+
* Url: `http://<<your-server-url>>:<<your-webservice-port>>/render?var-template=demo_report`
|
117
|
+
* Title: `Demo Report`
|
258
118
|
* Select `Time range`
|
259
119
|
* Select `Variable values`
|
260
120
|
* Select `Add`
|
261
121
|
|
262
|
-
Now go back to your dashboard and click the newly generated
|
122
|
+
Now go back to your dashboard and click the newly generated `Demo Report`
|
263
123
|
link on it. Now the renderer should start it's task and show you the expected
|
264
124
|
results.
|
265
125
|
|
266
|
-
|
267
|
-
|
268
|
-
|
126
|
+
Please note, that the reporter won't automatically refresh your screen to update
|
127
|
+
the progress. Simply hit `F5` to refresh your browser. After the report has been
|
128
|
+
successfully built, it will show the PDF after the next refresh automatically.
|
269
129
|
|
270
|
-
|
130
|
+
You want to select a template in grafana, which shall then be rendered?
|
271
131
|
Piece of cake: Just add a dashboard variable to your grafana dashboard named
|
272
132
|
`template` and let the user select or enter a template name. To make use of it,
|
273
|
-
you should change the link of the
|
274
|
-
`http://<<your-server-url
|
275
|
-
|
276
|
-
|
133
|
+
you should change the link of the `Demo Report` link to
|
134
|
+
`http://<<your-server-url>>:<<your-webservice-port>>/render?`. On
|
135
|
+
hitting the new link in the dashboard, grafana will add the selected template as
|
136
|
+
a variable and forward it to the reporter.
|
277
137
|
|
278
138
|
## Webservice overview
|
279
139
|
|
@@ -284,24 +144,15 @@ Running the reporter as a webservice provides the following URLs
|
|
284
144
|
/view_report - for viewing the status or receving the result of a specific rendering, is automatically called after a successfull /render call
|
285
145
|
/cancel_report - for cancelling the rendering of a specific report, normally not called manually, but on user interaction in the /view_report or /overview URL
|
286
146
|
|
287
|
-
|
147
|
+
The main endpoint to call for report generation is configured in the previous chapter [Grafana integration](#grafana-integration).
|
288
148
|
|
289
|
-
|
290
|
-
* panels as images
|
291
|
-
* panel table query or custom query results as real document tables (not images!)
|
292
|
-
* single panel value or custom query single value result integrated in texts
|
293
|
-
* Solid as a rock, also in case of template errors (at least it aims to be)
|
294
|
-
* Runs standalone or as a webservice
|
295
|
-
* Seamlessly integrates with asciidoctor docker container
|
296
|
-
* Developed for being able to support other tools than asciidoctor as well
|
149
|
+
However, if you would like to see, currently running report generations and previously generated reports, you may want to call the endpoint `/overview`.
|
297
150
|
|
298
151
|
## Roadmap
|
299
152
|
|
300
153
|
This is just a collection of things, I am heading for in future, without a schedule.
|
301
154
|
|
302
|
-
*
|
303
|
-
* Add documentation for configuration file
|
304
|
-
* Add a simple plugin system to support specific asciidoctor modifications
|
155
|
+
* Support all grafana datasources
|
305
156
|
* Solve code TODOs
|
306
157
|
* Become [rubocop](https://rubocop.org/) ready
|
307
158
|
|
@@ -310,15 +161,6 @@ This is just a collection of things, I am heading for in future, without a sched
|
|
310
161
|
If you'd like to contribute, please fork the repository and use a feature
|
311
162
|
branch. Pull requests are warmly welcome.
|
312
163
|
|
313
|
-
Though not yet valid for my code, I'd like to see the project become
|
314
|
-
[rubocop](https://rubocop.org/) ready :-)
|
315
|
-
|
316
|
-
Definitely open spots from my side are:
|
317
|
-
|
318
|
-
* This README
|
319
|
-
* Clean and properly setup test cases
|
320
|
-
* An own webpage for this project
|
321
|
-
|
322
164
|
## Licensing
|
323
165
|
|
324
166
|
The code in this project is licensed under MIT license.
|
@@ -336,4 +178,3 @@ If this project saves you as much time as I hope it does, and if you'd like to
|
|
336
178
|
support my work, feel free donate, even a cup of coffee is appreciated :)
|
337
179
|
|
338
180
|
[](https://www.paypal.com/donate?hosted_button_id=35LH6JNLPHPHQ)
|
339
|
-
|
data/bin/ruby-grafana-reporter
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
4
|
+
require_relative '../lib/ruby_grafana_reporter'
|
5
|
+
GrafanaReporter::Application::Application.new.configure_and_run(ARGV) unless defined?(Ocra)
|
data/lib/VERSION.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Version information
|
4
|
+
GRAFANA_REPORTER_VERSION = [0, 4, 0].freeze
|
5
|
+
# Release date
|
6
|
+
GRAFANA_REPORTER_RELEASE_DATE = '2021-04-14'
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Grafana
|
4
|
+
# This abstract class defines the base functionalities for the common datasource implementations.
|
5
|
+
# Additionally it provides a factory method to build a real datasource from a given specification.
|
6
|
+
class AbstractDatasource
|
7
|
+
attr_reader :model
|
8
|
+
|
9
|
+
# Factory method to build a datasource from a given datasource Hash description.
|
10
|
+
# @param ds_model [Hash] grafana specification of a single datasource
|
11
|
+
# @return [AbstractDatasource] instance of a fitting datasource implementation
|
12
|
+
def self.build_instance(ds_model)
|
13
|
+
raise InvalidDatasourceQueryProvidedError, ds_model unless ds_model.is_a?(Hash)
|
14
|
+
raise InvalidDatasourceQueryProvidedError, ds_model unless ds_model['meta']
|
15
|
+
raise InvalidDatasourceQueryProvidedError, ds_model unless ds_model['meta']['id']
|
16
|
+
raise InvalidDatasourceQueryProvidedError, ds_model unless ds_model['meta']['category']
|
17
|
+
|
18
|
+
return SqlDatasource.new(ds_model) if ds_model['meta']['category'] == 'sql'
|
19
|
+
|
20
|
+
case ds_model['meta']['id']
|
21
|
+
when 'graphite'
|
22
|
+
return GraphiteDatasource.new(ds_model)
|
23
|
+
|
24
|
+
when 'prometheus'
|
25
|
+
return PrometheusDatasource.new(ds_model)
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
raise DatasourceTypeNotSupportedError.new(ds_model['name'], ds_model['meta']['id'])
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(model)
|
33
|
+
@model = model
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [String] name of the datasource
|
37
|
+
def name
|
38
|
+
@model['name']
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Integer] ID of the datasource
|
42
|
+
def id
|
43
|
+
@model['id'].to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
# @abstract
|
47
|
+
#
|
48
|
+
# Executes a request for the current database with the given options.
|
49
|
+
#
|
50
|
+
# Used format of the response will always be the following:
|
51
|
+
#
|
52
|
+
# {
|
53
|
+
# :header => [column_title_1, column_title_2],
|
54
|
+
# :content => [
|
55
|
+
# [row_1_column_1, row_1_column_2],
|
56
|
+
# [row_2_column_1, row_2_column_2]
|
57
|
+
# ]
|
58
|
+
# }
|
59
|
+
#
|
60
|
+
# @param query_description [Hash] query description, which will requested:
|
61
|
+
# @option [String] :from +from+ timestamp
|
62
|
+
# @option [String] :to +to+ timestamp
|
63
|
+
# @option [Integer] :timeout expected timeout for the request
|
64
|
+
# @option [WebRequest] :prepared_request prepared web request for relevant {Grafana} instance, if this is needed by datasource
|
65
|
+
# @option [String] :raw_query raw query, which shall be executed. May include variables, which will be replaced before execution
|
66
|
+
# @option [Hash<Variable>] :variables hash of variables, which can potentially be replaced in the given +:raw_query+
|
67
|
+
# @return [Hash] sql result formatted as stated above
|
68
|
+
def request(query_description)
|
69
|
+
raise NotImplementedError
|
70
|
+
end
|
71
|
+
|
72
|
+
# @abstract
|
73
|
+
#
|
74
|
+
# The different datasources supported by grafana use different ways to store the query in the
|
75
|
+
# panel's JSON model. This method extracts a query from that description, that can be used
|
76
|
+
# by the {AbstractDatasource} implementation of the datasource.
|
77
|
+
#
|
78
|
+
# @param panel_query_target [Hash] grafana panel target, which contains the query description
|
79
|
+
# @return [String] query string, which can be used as +raw_query+ in a {#request}
|
80
|
+
def raw_query_from_panel_model(panel_query_target)
|
81
|
+
raise NotImplementedError
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
# Replaces the grafana variables in the given string with their replacement value.
|
87
|
+
#
|
88
|
+
# @param string [String] string in which the variables shall be replaced
|
89
|
+
# @param variables [Hash<String,Variable>] Hash containing the variables, which shall be replaced in the
|
90
|
+
# given string
|
91
|
+
# @return [String] string in which all variables are properly replaced
|
92
|
+
def replace_variables(string, variables = {})
|
93
|
+
res = string
|
94
|
+
repeat = true
|
95
|
+
repeat_count = 0
|
96
|
+
|
97
|
+
# TODO: find a proper way to replace variables recursively instead of over and over again
|
98
|
+
# TODO: add tests for recursive replacement of variable
|
99
|
+
while repeat && (repeat_count < 3)
|
100
|
+
repeat = false
|
101
|
+
repeat_count += 1
|
102
|
+
variables.each do |var_name, obj|
|
103
|
+
# only set ticks if value is string
|
104
|
+
variable = var_name.gsub(/^var-/, '')
|
105
|
+
res = res.gsub(/(?:\$\{#{variable}(?::(?<format>\w+))?\}|\$#{variable})/) do
|
106
|
+
# TODO: respect datasource requirements for formatting here
|
107
|
+
obj.value_formatted($LAST_MATCH_INFO ? $LAST_MATCH_INFO[:format] : nil)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
repeat = true if res.include?('$')
|
111
|
+
end
|
112
|
+
|
113
|
+
res
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|