ruby-grafana-reporter 0.6.2 → 0.6.6
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 +46 -10
- data/bin/ruby-grafana-reporter +1 -1
- data/lib/VERSION.rb +2 -2
- data/lib/grafana/grafana.rb +16 -11
- data/lib/grafana/image_rendering_datasource.rb +2 -2
- data/lib/grafana/influxdb_datasource.rb +30 -5
- data/lib/grafana_reporter/abstract_report.rb +1 -1
- data/lib/grafana_reporter/application/application.rb +2 -2
- data/lib/grafana_reporter/application/webservice.rb +2 -2
- data/lib/grafana_reporter/asciidoctor/alerts_table_include_processor.rb +2 -2
- data/lib/grafana_reporter/asciidoctor/annotations_table_include_processor.rb +2 -2
- data/lib/grafana_reporter/asciidoctor/help.rb +3 -0
- data/lib/grafana_reporter/asciidoctor/panel_image_block_macro.rb +2 -2
- data/lib/grafana_reporter/asciidoctor/panel_image_inline_macro.rb +2 -2
- data/lib/grafana_reporter/asciidoctor/panel_property_inline_macro.rb +2 -2
- data/lib/grafana_reporter/asciidoctor/panel_query_table_include_processor.rb +2 -2
- data/lib/grafana_reporter/asciidoctor/panel_query_value_inline_macro.rb +2 -2
- data/lib/grafana_reporter/asciidoctor/sql_table_include_processor.rb +2 -2
- data/lib/grafana_reporter/asciidoctor/sql_value_inline_macro.rb +2 -2
- data/lib/grafana_reporter/console_configuration_wizard.rb +1 -1
- data/lib/grafana_reporter/errors.rb +1 -1
- data/lib/ruby_grafana_reporter.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5e48d471e3c09009d65b08924a8d8ff1f4a2259fde86a2525f56554ee96f23a
|
4
|
+
data.tar.gz: 0e095029e10bd6bef2ae80ad866b243c13d3c1ebd5555c9b75d651d6da5ce15c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6bc6604e3fed7fba3fe3057d42432098363f056c03afdf6c8f961d80abc0b0ad4505a01f895d44421774b5bb1a9227bb9bdef747cea7fe15669ebdf149b7611
|
7
|
+
data.tar.gz: fa8ec80a80e51d214c50d54e9d1dbf6d196c11e5320f749ac2f3d2c9b5ed5979ae3a71924ce5d47d43489e4e18c381b5d8d05ad47a3805122a5ba93d9947950f
|
data/README.md
CHANGED
@@ -20,7 +20,22 @@ Reporting Service for Grafana
|
|
20
20
|
* [Using webhooks](#using-webhooks)
|
21
21
|
* [Developing your own plugin](#developing-your-own-plugin)
|
22
22
|
* [Roadmap](#roadmap)
|
23
|
-
* [
|
23
|
+
* [Contributing](#contributing)
|
24
|
+
* [Licensing](#licensing)
|
25
|
+
* [Acknowledgements](#acknowledgements)
|
26
|
+
|
27
|
+
## Your support is appreciated!
|
28
|
+
|
29
|
+
Hey there! Let me spend some personal words here:
|
30
|
+
|
31
|
+
I provide you this software free of charge - and I'm happy, that I can do so. I have already
|
32
|
+
spend a lot of my private time in developing, maintaining and supporting it.
|
33
|
+
|
34
|
+
If you enjoy my work, I would feel greatly honoured, if you buy me a coffee:
|
35
|
+
|
36
|
+
[](https://ko-fi.com/divinity666)
|
37
|
+
|
38
|
+
Thanks for your support and keeping this project alive!
|
24
39
|
|
25
40
|
## About the project
|
26
41
|
|
@@ -136,8 +151,10 @@ asciidoctor:
|
|
136
151
|
|
137
152
|
### Grafana integration
|
138
153
|
|
139
|
-
For using the reporter directly from grafana,
|
140
|
-
|
154
|
+
For using the reporter directly from grafana, the reporter has to run as webservice, i.e. it has to be
|
155
|
+
called without the `-t` parameter.
|
156
|
+
|
157
|
+
If this is the case, you simply simply need add a link to your grafana dashboard:
|
141
158
|
|
142
159
|
* Open the dashboard configuration
|
143
160
|
* Select `Links`
|
@@ -168,7 +185,32 @@ a variable and forward it to the reporter.
|
|
168
185
|
|
169
186
|
## Advanced information
|
170
187
|
|
171
|
-
###
|
188
|
+
### Use grafana variables in templates
|
189
|
+
It is common practice to use dashboard variables in grafana, to allow users to show
|
190
|
+
the dashboard for a specific set of data only. This is where grafana variables are
|
191
|
+
used.
|
192
|
+
|
193
|
+
Those variables are then also used in panel queries, to react on selecting or entering
|
194
|
+
those variables.
|
195
|
+
|
196
|
+
You may provide those variables during report generation to the reporter. Therefore
|
197
|
+
you have to specify them in the individual calls.
|
198
|
+
|
199
|
+
Let's say, you have a variable called `serverid` in the dashboard. You may now want
|
200
|
+
to set this variable for a panel image rendering. This cann be done with the following
|
201
|
+
calls:
|
202
|
+
|
203
|
+
````
|
204
|
+
grafana_panel_image:1[var-serverid=main-server]
|
205
|
+
grafana_panel_image:1[var-serverid=replica-server]
|
206
|
+
````
|
207
|
+
|
208
|
+
This will render two images: one for `main-server` and one for `replica-server`.
|
209
|
+
|
210
|
+
So, to forward grafana variables to the reporter calls, you simply have to use the
|
211
|
+
form `var-<<your-variable-name>>` and specify those in your reporter template.
|
212
|
+
|
213
|
+
### Webservice endpoints
|
172
214
|
|
173
215
|
Running the reporter as a webservice provides the following URLs
|
174
216
|
|
@@ -329,9 +371,3 @@ The code in this project is licensed under MIT license.
|
|
329
371
|
* [grafana](https://github.com/grafana/grafana)
|
330
372
|
|
331
373
|
Inspired by [Izak Marai's grafana reporter](https://github.com/IzakMarais/reporter)
|
332
|
-
|
333
|
-
## Donations
|
334
|
-
|
335
|
-
If you like this project and you would like to support my work, feel free to donate. :)
|
336
|
-
|
337
|
-
[](https://www.paypal.com/donate?hosted_button_id=35LH6JNLPHPHQ)
|
data/bin/ruby-grafana-reporter
CHANGED
data/lib/VERSION.rb
CHANGED
data/lib/grafana/grafana.rb
CHANGED
@@ -86,15 +86,8 @@ module Grafana
|
|
86
86
|
# @param datasource_uid [String] unique id of the searched datasource
|
87
87
|
# @return [Datasource] Datasource for the specified datasource unique id
|
88
88
|
def datasource_by_uid(datasource_uid)
|
89
|
-
|
90
|
-
|
91
|
-
# print debug info for https://github.com/divinity666/ruby-grafana-reporter/issues/29
|
92
|
-
@logger.warn("Datasource with name #{ds_name} is nil, which should never happen. Check logs for details.")
|
93
|
-
false
|
94
|
-
else
|
95
|
-
ds.uid == datasource_uid
|
96
|
-
end
|
97
|
-
end.values.first
|
89
|
+
clean_nil_datasources
|
90
|
+
datasource = @datasources.select { |ds_name, ds| ds.uid == datasource_uid }.values.first
|
98
91
|
raise DatasourceDoesNotExistError.new('uid', datasource_uid) unless datasource
|
99
92
|
|
100
93
|
datasource
|
@@ -105,7 +98,8 @@ module Grafana
|
|
105
98
|
# @param datasource_id [Integer] id of the searched datasource
|
106
99
|
# @return [Datasource] Datasource for the specified datasource id
|
107
100
|
def datasource_by_id(datasource_id)
|
108
|
-
|
101
|
+
clean_nil_datasources
|
102
|
+
datasource = @datasources.select { |name, ds| ds.id == datasource_id.to_i }.values.first
|
109
103
|
raise DatasourceDoesNotExistError.new('id', datasource_id) unless datasource
|
110
104
|
|
111
105
|
datasource
|
@@ -171,7 +165,18 @@ module Grafana
|
|
171
165
|
@datasources.delete(ds_name)
|
172
166
|
end
|
173
167
|
end
|
174
|
-
|
168
|
+
|
169
|
+
@datasources['default'] = @datasources[json['defaultDatasource']] if not @datasources[json['defaultDatasource']].nil?
|
170
|
+
end
|
171
|
+
|
172
|
+
def clean_nil_datasources
|
173
|
+
@datasources.delete_if do |name, ds|
|
174
|
+
if ds.nil?
|
175
|
+
# print debug info for https://github.com/divinity666/ruby-grafana-reporter/issues/29
|
176
|
+
@logger.warn("Datasource with name #{name} is nil, which should never happen. Check logs for details.")
|
177
|
+
end
|
178
|
+
ds.nil?
|
179
|
+
end
|
175
180
|
end
|
176
181
|
end
|
177
182
|
end
|
@@ -16,7 +16,7 @@ module Grafana
|
|
16
16
|
webrequest.relative_url = panel.render_url + url_params(query_description)
|
17
17
|
webrequest.options.merge!({ accept: 'image/png' })
|
18
18
|
|
19
|
-
result = webrequest.execute
|
19
|
+
result = webrequest.execute(query_description[:timeout])
|
20
20
|
|
21
21
|
raise ImageCouldNotBeRenderedError, panel if result.body.include?('<html')
|
22
22
|
|
@@ -26,7 +26,7 @@ module Grafana
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def url_params(query_desc)
|
29
|
-
url_vars = query_desc[:variables].select { |k, _v| k =~ /^(?:timeout|height|width|theme|fullscreen|var-.+)$/ }
|
29
|
+
url_vars = query_desc[:variables].select { |k, _v| k =~ /^(?:timeout|scale|height|width|theme|fullscreen|var-.+)$/ }
|
30
30
|
url_vars = default_vars.merge(url_vars)
|
31
31
|
url_vars['from'] = Variable.new(query_desc[:from])
|
32
32
|
url_vars['to'] = Variable.new(query_desc[:to])
|
@@ -31,11 +31,36 @@ module Grafana
|
|
31
31
|
query = query.gsub(/\$(?:__)?interval(?=\W|$)/, "#{interval.is_a?(String) ? interval : "#{(interval / 1000).to_i}s"}")
|
32
32
|
query = query.gsub(/\$(?:__)?interval_ms(?=\W|$)/, "#{interval}")
|
33
33
|
|
34
|
-
url = "/api/datasources/proxy/#{id}/query?db=#{@model['database']}&q=#{ERB::Util.url_encode(query)}&epoch=ms"
|
35
|
-
|
36
34
|
webrequest = query_description[:prepared_request]
|
37
|
-
|
38
|
-
|
35
|
+
request = {}
|
36
|
+
|
37
|
+
ver = query_description[:grafana_version].split('.').map{|x| x.to_i}
|
38
|
+
if ver[0] >= 8
|
39
|
+
webrequest.relative_url = "/api/ds/query?ds_type=influxdb"
|
40
|
+
|
41
|
+
request = {
|
42
|
+
request: Net::HTTP::Post,
|
43
|
+
body: {
|
44
|
+
from: query_description[:from],
|
45
|
+
to: query_description[:to],
|
46
|
+
queries: [
|
47
|
+
{
|
48
|
+
datasource: {type: "influxdb"},
|
49
|
+
datasourceId: id,
|
50
|
+
intervalMs: interval,
|
51
|
+
query: query
|
52
|
+
}
|
53
|
+
]}.to_json
|
54
|
+
}
|
55
|
+
else
|
56
|
+
webrequest.relative_url = "/api/datasources/proxy/#{id}/query?db=#{@model['database']}&q=#{ERB::Util.url_encode(query)}&epoch=ms"
|
57
|
+
request = {
|
58
|
+
request: Net::HTTP::Get
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
webrequest.options.merge!(request)
|
63
|
+
|
39
64
|
|
40
65
|
result = webrequest.execute(query_description[:timeout])
|
41
66
|
preformat_response(result.body)
|
@@ -43,7 +68,7 @@ module Grafana
|
|
43
68
|
|
44
69
|
# @see AbstractDatasource#raw_query_from_panel_model
|
45
70
|
def raw_query_from_panel_model(panel_query_target)
|
46
|
-
return panel_query_target['query'] if panel_query_target['rawQuery']
|
71
|
+
return panel_query_target['query'] if panel_query_target['query'] or panel_query_target['rawQuery']
|
47
72
|
|
48
73
|
# build composed queries
|
49
74
|
build_select(panel_query_target['select']) + build_from(panel_query_target) + build_where(panel_query_target['tags']) + build_group_by(panel_query_target['groupBy'])
|
@@ -138,7 +138,7 @@ module GrafanaReporter
|
|
138
138
|
|
139
139
|
# automatically add extension, if a file with default template extension exists
|
140
140
|
@template = "#{@template}.#{self.class.default_template_extension}" if File.file?("#{@template}.#{self.class.default_template_extension}") && !File.file?(@template.to_s)
|
141
|
-
raise MissingTemplateError, @template.
|
141
|
+
raise MissingTemplateError, "#{@template}.#{self.class.default_template_extension}" unless File.file?(@template.to_s)
|
142
142
|
|
143
143
|
notify(:on_before_create)
|
144
144
|
@start_time = Time.new
|
@@ -34,8 +34,8 @@ module GrafanaReporter
|
|
34
34
|
action_wizard = false
|
35
35
|
|
36
36
|
parser = OptionParser.new do |opts|
|
37
|
-
opts.banner = if ENV['
|
38
|
-
"Usage: #{ENV['
|
37
|
+
opts.banner = if ENV['OCRAN_EXECUTABLE']
|
38
|
+
"Usage: #{ENV['OCRAN_EXECUTABLE'].gsub("#{Dir.pwd}/".gsub('/', '\\'), '')} [options]"
|
39
39
|
else
|
40
40
|
"Usage: #{Gem.ruby} #{$PROGRAM_NAME} [options]"
|
41
41
|
end
|
@@ -91,8 +91,8 @@ module GrafanaReporter
|
|
91
91
|
@logger.error(e.message)
|
92
92
|
socket.write http_response(400, 'Bad Request', e.message)
|
93
93
|
rescue StandardError => e
|
94
|
-
@logger.fatal(e.message)
|
95
|
-
socket.write http_response(400, 'Bad Request', e.message)
|
94
|
+
@logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
95
|
+
socket.write http_response(400, 'Bad Request', "#{e.message}\n#{e.backtrace.join("\n")}")
|
96
96
|
ensure
|
97
97
|
socket.close
|
98
98
|
end
|
@@ -76,8 +76,8 @@ module GrafanaReporter
|
|
76
76
|
@report.logger.error(e.message)
|
77
77
|
reader.unshift_line "|#{e.message}"
|
78
78
|
rescue StandardError => e
|
79
|
-
@report.logger.fatal(e.message)
|
80
|
-
reader.unshift_line "|#{e.message}"
|
79
|
+
@report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
80
|
+
reader.unshift_line "|#{e.message}\n#{e.backtrace.join("\n")}"
|
81
81
|
end
|
82
82
|
|
83
83
|
reader
|
@@ -75,8 +75,8 @@ module GrafanaReporter
|
|
75
75
|
@report.logger.error(e.message)
|
76
76
|
reader.unshift_line "|#{e.message}"
|
77
77
|
rescue StandardError => e
|
78
|
-
@report.logger.fatal(e.message)
|
79
|
-
reader.unshift_line "|#{e.message}"
|
78
|
+
@report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
79
|
+
reader.unshift_line "|#{e.message}\n#{e.backtrace.join("\n")}"
|
80
80
|
end
|
81
81
|
|
82
82
|
reader
|
@@ -391,6 +391,9 @@ end}
|
|
391
391
|
render-width:
|
392
392
|
description: can be used to override default `width` in which the panel shall be rendered
|
393
393
|
call: render-width="<width>"
|
394
|
+
render-scale:
|
395
|
+
description: can be used to override default scale in which the panel shall be rendered
|
396
|
+
call: render-scale="<scale>"
|
394
397
|
render-theme:
|
395
398
|
description: can be used to override default `theme` in which the panel shall be rendered (light by default)
|
396
399
|
call: render-theme="<theme>"
|
@@ -56,8 +56,8 @@ module GrafanaReporter
|
|
56
56
|
@report.logger.error(e.message)
|
57
57
|
return create_paragraph(parent, e.message, attrs)
|
58
58
|
rescue StandardError => e
|
59
|
-
@report.logger.fatal(e.message)
|
60
|
-
return create_paragraph(parent, e.message, attrs)
|
59
|
+
@report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
60
|
+
return create_paragraph(parent, "#{e.message}\n#{e.backtrace.join("\n")}", attrs)
|
61
61
|
end
|
62
62
|
|
63
63
|
attrs['target'] = image_path
|
@@ -58,8 +58,8 @@ module GrafanaReporter
|
|
58
58
|
@report.logger.error(e.message)
|
59
59
|
return create_inline(parent, :quoted, e.message)
|
60
60
|
rescue StandardError => e
|
61
|
-
@report.logger.fatal(e.message)
|
62
|
-
return create_inline(parent, :quoted, e.message)
|
61
|
+
@report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
62
|
+
return create_inline(parent, :quoted, "#{e.message}\n#{e.backtrace.join("\n")}")
|
63
63
|
end
|
64
64
|
|
65
65
|
create_inline(parent, :image, nil, { target: image_path, attributes: attrs })
|
@@ -50,8 +50,8 @@ module GrafanaReporter
|
|
50
50
|
@report.logger.error(e.message)
|
51
51
|
return create_inline(parent, :quoted, e.message)
|
52
52
|
rescue StandardError => e
|
53
|
-
@report.logger.fatal(e.message)
|
54
|
-
return create_inline(parent, :quoted, e.message)
|
53
|
+
@report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
54
|
+
return create_inline(parent, :quoted, "#{e.message}\n#{e.backtrace.join("\n")}")
|
55
55
|
end
|
56
56
|
|
57
57
|
# translate linebreaks to asciidoctor syntax
|
@@ -70,8 +70,8 @@ module GrafanaReporter
|
|
70
70
|
@report.logger.error(e.message)
|
71
71
|
reader.unshift_line "|#{e.message}"
|
72
72
|
rescue StandardError => e
|
73
|
-
@report.logger.fatal(e.message)
|
74
|
-
reader.unshift_line "|#{e.message}"
|
73
|
+
@report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
74
|
+
reader.unshift_line "|#{e.message}\n#{e.backtrace.join("\n")}"
|
75
75
|
end
|
76
76
|
|
77
77
|
reader
|
@@ -66,8 +66,8 @@ module GrafanaReporter
|
|
66
66
|
@report.logger.error(e.message)
|
67
67
|
create_inline(parent, :quoted, e.message)
|
68
68
|
rescue StandardError => e
|
69
|
-
@report.logger.fatal(e.message)
|
70
|
-
create_inline(parent, :quoted, e.message)
|
69
|
+
@report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
70
|
+
create_inline(parent, :quoted, "#{e.message}\n#{e.backtrace.join("\n")}")
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -64,8 +64,8 @@ module GrafanaReporter
|
|
64
64
|
@report.logger.error(e.message)
|
65
65
|
reader.unshift_line "|#{e.message}"
|
66
66
|
rescue StandardError => e
|
67
|
-
@report.logger.fatal(e.message)
|
68
|
-
reader.unshift_line "|#{e.message}"
|
67
|
+
@report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
68
|
+
reader.unshift_line "|#{e.message}\n#{e.backtrace.join("\n")}"
|
69
69
|
end
|
70
70
|
|
71
71
|
reader
|
@@ -71,8 +71,8 @@ module GrafanaReporter
|
|
71
71
|
@report.logger.error(e.message)
|
72
72
|
create_inline(parent, :quoted, e.message)
|
73
73
|
rescue StandardError => e
|
74
|
-
@report.logger.fatal(e.message)
|
75
|
-
create_inline(parent, :quoted, e.message)
|
74
|
+
@report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
|
75
|
+
create_inline(parent, :quoted, "#{e.message}\n#{e.backtrace.join("\n")}")
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -32,7 +32,7 @@ module GrafanaReporter
|
|
32
32
|
demo_report ||= '<<your_report_name>>'
|
33
33
|
config_param = config_file == Configuration::DEFAULT_CONFIG_FILE_NAME ? '' : " -c #{config_file}"
|
34
34
|
program_call = "#{Gem.ruby} #{$PROGRAM_NAME}"
|
35
|
-
program_call = ENV['
|
35
|
+
program_call = ENV['OCRAN_EXECUTABLE'].gsub("#{Dir.pwd}/".gsub('/', '\\'), '') if ENV['OCRAN_EXECUTABLE']
|
36
36
|
|
37
37
|
puts
|
38
38
|
puts 'Now everything is setup properly. Create your reports as required in the templates '\
|
@@ -50,7 +50,7 @@ module GrafanaReporter
|
|
50
50
|
# Thrown if a non existing template has been specified.
|
51
51
|
class MissingTemplateError < ConfigurationError
|
52
52
|
def initialize(template)
|
53
|
-
super("
|
53
|
+
super("Accessing report template file '#{template}' is not possible. Check if file exists and is accessible.")
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-grafana-reporter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Kohlmeyer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|