ruby-grafana-reporter 0.4.5 → 0.5.2
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 +2 -2
- data/lib/VERSION.rb +2 -2
- data/lib/grafana/abstract_datasource.rb +8 -0
- data/lib/grafana/dashboard.rb +6 -1
- data/lib/grafana/errors.rb +9 -1
- data/lib/grafana/grafana.rb +35 -0
- data/lib/grafana/grafana_environment_datasource.rb +56 -0
- data/lib/grafana/graphite_datasource.rb +3 -0
- data/lib/grafana/image_rendering_datasource.rb +5 -1
- data/lib/grafana/influxdb_datasource.rb +11 -4
- data/lib/grafana/panel.rb +5 -1
- data/lib/grafana/prometheus_datasource.rb +71 -11
- data/lib/grafana/sql_datasource.rb +10 -4
- data/lib/grafana/variable.rb +46 -23
- data/lib/grafana/webrequest.rb +1 -0
- data/lib/grafana_reporter/abstract_query.rb +31 -24
- data/lib/grafana_reporter/abstract_report.rb +2 -0
- data/lib/grafana_reporter/abstract_table_format_strategy.rb +44 -4
- data/lib/grafana_reporter/alerts_table_query.rb +2 -1
- data/lib/grafana_reporter/annotations_table_query.rb +2 -1
- data/lib/grafana_reporter/application/webservice.rb +8 -4
- data/lib/grafana_reporter/asciidoctor/adoc_plain_table_format_strategy.rb +11 -9
- data/lib/grafana_reporter/asciidoctor/help.rb +53 -14
- data/lib/grafana_reporter/asciidoctor/panel_image_block_macro.rb +2 -4
- data/lib/grafana_reporter/asciidoctor/panel_image_inline_macro.rb +2 -4
- data/lib/grafana_reporter/asciidoctor/processor_mixin.rb +1 -1
- data/lib/grafana_reporter/asciidoctor/show_environment_include_processor.rb +37 -6
- data/lib/grafana_reporter/asciidoctor/sql_value_inline_macro.rb +11 -2
- data/lib/grafana_reporter/asciidoctor/value_as_variable_include_processor.rb +0 -5
- data/lib/grafana_reporter/configuration.rb +53 -22
- data/lib/grafana_reporter/console_configuration_wizard.rb +3 -1
- data/lib/grafana_reporter/csv_table_format_strategy.rb +11 -9
- data/lib/grafana_reporter/demo_report_wizard.rb +3 -6
- data/lib/grafana_reporter/errors.rb +2 -2
- data/lib/grafana_reporter/panel_image_query.rb +0 -1
- data/lib/grafana_reporter/query_value_query.rb +7 -1
- data/lib/grafana_reporter/reporter_environment_datasource.rb +24 -0
- data/lib/ruby_grafana_reporter.rb +7 -7
- metadata +8 -7
|
@@ -152,6 +152,32 @@ module GrafanaReporter
|
|
|
152
152
|
get_config('default-document-attributes') || {}
|
|
153
153
|
end
|
|
154
154
|
|
|
155
|
+
# Checks if this is the latest ruby-grafana-reporter version. If and how often the check if
|
|
156
|
+
# performed, depends on the configuration setting `check-for-updates`. By default this is
|
|
157
|
+
# 0 (=disabled). If a number >0 is specified, the checks are performed once every n-days on
|
|
158
|
+
# report creation or call of overview webpage.
|
|
159
|
+
# @return [Boolean] true, if is ok, false if a newer version exists
|
|
160
|
+
def latest_version_check_ok?
|
|
161
|
+
return false if @newer_version_exists
|
|
162
|
+
|
|
163
|
+
value = get_config('grafana-reporter:check-for-updates') || 0
|
|
164
|
+
return true if value <= 0
|
|
165
|
+
|
|
166
|
+
# repeat check only every n-th day
|
|
167
|
+
if @last_version_check
|
|
168
|
+
return true if (Time.now - @last_version_check) < (value * 24*60*60)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# check for newer version
|
|
172
|
+
@last_version_check = Time.now
|
|
173
|
+
url = 'https://github.com/divinity666/ruby-grafana-reporter/releases/latest'
|
|
174
|
+
response = Grafana::WebRequest.new(url).execute
|
|
175
|
+
return true if response['location'] =~ /.*[\/v]#{GRAFANA_REPORTER_VERSION.join('.')}$/
|
|
176
|
+
|
|
177
|
+
@newer_version_exists = true
|
|
178
|
+
return false
|
|
179
|
+
end
|
|
180
|
+
|
|
155
181
|
# This function shall be called, before the configuration object is used in the
|
|
156
182
|
# {Application::Application#run}. It ensures, that everything is setup properly
|
|
157
183
|
# and all necessary folders exist. Appropriate errors are raised in case of errors.
|
|
@@ -237,13 +263,13 @@ module GrafanaReporter
|
|
|
237
263
|
cur_pos
|
|
238
264
|
end
|
|
239
265
|
|
|
240
|
-
def validate_schema(schema, subject)
|
|
266
|
+
def validate_schema(schema, subject, pattern = nil)
|
|
241
267
|
return nil if subject.nil?
|
|
242
268
|
|
|
243
269
|
schema.each do |key, config|
|
|
244
|
-
type, min_occurence, next_level = config
|
|
270
|
+
type, min_occurence, pattern, next_level = config
|
|
245
271
|
|
|
246
|
-
validate_schema(next_level, subject[key]) if next_level
|
|
272
|
+
validate_schema(next_level, subject[key], pattern) if next_level
|
|
247
273
|
|
|
248
274
|
if key.nil?
|
|
249
275
|
# apply to all on this level
|
|
@@ -263,9 +289,13 @@ module GrafanaReporter
|
|
|
263
289
|
elsif subject.is_a?(Hash)
|
|
264
290
|
if !subject.key?(key) && min_occurence.positive?
|
|
265
291
|
raise ConfigurationDoesNotMatchSchemaError.new(key, 'occur', min_occurence, 0)
|
|
266
|
-
|
|
267
|
-
if !subject[key].is_a?(type) && subject.key?(key)
|
|
292
|
+
elsif !subject[key].is_a?(type) && subject.key?(key)
|
|
268
293
|
raise ConfigurationDoesNotMatchSchemaError.new(key, 'be a', type, subject[key].class)
|
|
294
|
+
elsif pattern
|
|
295
|
+
# validate for regex
|
|
296
|
+
unless subject[key].to_s =~ pattern
|
|
297
|
+
raise ConfigurationDoesNotMatchSchemaError.new(key, 'match pattern', pattern.inspect, subject[key].to_s)
|
|
298
|
+
end
|
|
269
299
|
end
|
|
270
300
|
|
|
271
301
|
else
|
|
@@ -286,34 +316,35 @@ module GrafanaReporter
|
|
|
286
316
|
{
|
|
287
317
|
'grafana' =>
|
|
288
318
|
[
|
|
289
|
-
Hash, 1,
|
|
319
|
+
Hash, 1, nil,
|
|
290
320
|
{
|
|
291
321
|
nil =>
|
|
292
322
|
[
|
|
293
|
-
Hash, 1,
|
|
323
|
+
Hash, 1, nil,
|
|
294
324
|
{
|
|
295
|
-
'host' => [String, 1],
|
|
296
|
-
'api_key' => [String, 0]
|
|
325
|
+
'host' => [String, 1, %r{^http(s)?://.+}],
|
|
326
|
+
'api_key' => [String, 0, %r{^(?:[\w]+[=]*)?$}]
|
|
297
327
|
}
|
|
298
328
|
]
|
|
299
329
|
}
|
|
300
330
|
],
|
|
301
|
-
'default-document-attributes' => [Hash, explicit ? 1 : 0],
|
|
302
|
-
'to_file' => [String, 0],
|
|
331
|
+
'default-document-attributes' => [Hash, explicit ? 1 : 0, nil],
|
|
332
|
+
'to_file' => [String, 0, nil],
|
|
303
333
|
'grafana-reporter' =>
|
|
304
334
|
[
|
|
305
|
-
Hash, 1,
|
|
335
|
+
Hash, 1, nil,
|
|
306
336
|
{
|
|
307
|
-
'
|
|
308
|
-
'
|
|
309
|
-
'
|
|
310
|
-
'
|
|
311
|
-
'
|
|
312
|
-
'
|
|
313
|
-
'
|
|
314
|
-
'
|
|
315
|
-
'
|
|
316
|
-
'
|
|
337
|
+
'check-for-updates' => [Integer, 0, /^[0-9]*$/],
|
|
338
|
+
'debug-level' => [String, 0, /^(?:DEBUG|INFO|WARN|ERROR|FATAL|UNKNOWN)?$/],
|
|
339
|
+
'run-mode' => [String, 0, /^(?:test|single-render|webservice)?$/],
|
|
340
|
+
'test-instance' => [String, 0, nil],
|
|
341
|
+
'templates-folder' => [String, explicit ? 1 : 0, nil],
|
|
342
|
+
'report-class' => [String, 1, nil],
|
|
343
|
+
'reports-folder' => [String, explicit ? 1 : 0, nil],
|
|
344
|
+
'report-retention' => [Integer, explicit ? 1 : 0, nil],
|
|
345
|
+
'ssl-cert' => [String, 0, nil],
|
|
346
|
+
'webservice-port' => [Integer, explicit ? 1 : 0, nil],
|
|
347
|
+
'callbacks' => [Hash, 0, nil, { nil => [String, 1, nil] }]
|
|
317
348
|
}
|
|
318
349
|
]
|
|
319
350
|
}
|
|
@@ -6,7 +6,6 @@ module GrafanaReporter
|
|
|
6
6
|
class ConsoleConfigurationWizard
|
|
7
7
|
# Provides a command line configuration wizard for setting up the necessary configuration
|
|
8
8
|
# file.
|
|
9
|
-
# TODO: refactor class
|
|
10
9
|
def start_wizard(config_file, console_config)
|
|
11
10
|
action = overwrite_or_use_config_file(config_file)
|
|
12
11
|
return if action == 'abort'
|
|
@@ -73,6 +72,9 @@ module GrafanaReporter
|
|
|
73
72
|
#{grafana}
|
|
74
73
|
|
|
75
74
|
grafana-reporter:
|
|
75
|
+
# Specifies how often the reporter shall check for newer versions [number of days].
|
|
76
|
+
# You may set check-for-updates to 0 to disable
|
|
77
|
+
check-for-updates: 1
|
|
76
78
|
report-class: GrafanaReporter::Asciidoctor::Report
|
|
77
79
|
templates-folder: #{templates}
|
|
78
80
|
reports-folder: #{reports}
|
|
@@ -9,15 +9,17 @@ module GrafanaReporter
|
|
|
9
9
|
'csv'
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
# @see AbstractTableFormatStrategy#
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
# @see AbstractTableFormatStrategy#format_rules
|
|
13
|
+
def format_rules
|
|
14
|
+
{
|
|
15
|
+
row_start: '',
|
|
16
|
+
row_end: "\n",
|
|
17
|
+
cell_start: '',
|
|
18
|
+
between_cells: ', ',
|
|
19
|
+
cell_end: '',
|
|
20
|
+
replace_string_or_regex: ',',
|
|
21
|
+
replacement: '\\,'
|
|
22
|
+
}
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
end
|
|
@@ -55,12 +55,6 @@ module GrafanaReporter
|
|
|
55
55
|
results = {}
|
|
56
56
|
|
|
57
57
|
dashboard.panels.shuffle.each do |panel|
|
|
58
|
-
begin
|
|
59
|
-
next if panel.datasource.is_a?(Grafana::UnsupportedDatasource)
|
|
60
|
-
rescue Grafana::DatasourceDoesNotExistError
|
|
61
|
-
next
|
|
62
|
-
end
|
|
63
|
-
|
|
64
58
|
query_classes.each do |query_class|
|
|
65
59
|
unless query_class.public_instance_methods.include?(:build_demo_entry)
|
|
66
60
|
results[query_class] = "Method 'build_demo_entry' not implemented for #{query_class.name}"
|
|
@@ -77,6 +71,9 @@ module GrafanaReporter
|
|
|
77
71
|
# currently not allowed
|
|
78
72
|
rescue StandardError => e
|
|
79
73
|
puts "#{e.message}\n#{e.backtrace.join("\n")}"
|
|
74
|
+
rescue NotImplementedError
|
|
75
|
+
# Ignore these errors, as it only means, that a class does not implement
|
|
76
|
+
# the demo entry
|
|
80
77
|
end
|
|
81
78
|
end
|
|
82
79
|
end
|
|
@@ -27,7 +27,7 @@ module GrafanaReporter
|
|
|
27
27
|
# Raised if the return value of a datasource request does not match the expected return hash.
|
|
28
28
|
class DatasourceRequestInvalidReturnValueError < GrafanaReporterError
|
|
29
29
|
def initialize(datasource, message)
|
|
30
|
-
super("The datasource request to '#{datasource.name}' (#{datasource.class})"\
|
|
30
|
+
super("The datasource request to '#{datasource.name}' (#{datasource.class}) "\
|
|
31
31
|
"returned an invalid value: '#{message}'")
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -65,7 +65,7 @@ module GrafanaReporter
|
|
|
65
65
|
# Details about how to fix that are provided in the message.
|
|
66
66
|
class ConfigurationDoesNotMatchSchemaError < ConfigurationError
|
|
67
67
|
def initialize(item, verb, expected, currently)
|
|
68
|
-
super("Configuration file does not match schema definition. Expected '#{item}' to #{verb} '#{expected}',"\
|
|
68
|
+
super("Configuration file does not match schema definition. Expected '#{item}' to #{verb} '#{expected}', "\
|
|
69
69
|
"but was '#{currently}'.")
|
|
70
70
|
end
|
|
71
71
|
end
|
|
@@ -15,7 +15,6 @@ module GrafanaReporter
|
|
|
15
15
|
# Returns the body of the http query, which contains the raw image.
|
|
16
16
|
def post_process
|
|
17
17
|
@result = @result[:content].first
|
|
18
|
-
raise ::Grafana::ImageCouldNotBeRenderedError, @panel if @result.include?('<html')
|
|
19
18
|
end
|
|
20
19
|
|
|
21
20
|
# @see AbstractQuery#raw_query
|
|
@@ -19,8 +19,14 @@ module GrafanaReporter
|
|
|
19
19
|
modify_results
|
|
20
20
|
|
|
21
21
|
case @variables['result_type'].raw_value
|
|
22
|
+
when 'object'
|
|
23
|
+
|
|
22
24
|
when /(?:panel_table|sql_table)/
|
|
23
|
-
@result = format_table_output(@result, row_divider: @variables['row_divider'],
|
|
25
|
+
@result = format_table_output(@result, row_divider: @variables['row_divider'],
|
|
26
|
+
column_divider: @variables['column_divider'],
|
|
27
|
+
table_formatter: @variables['table_formatter'],
|
|
28
|
+
include_headline: @variables['include_headline'],
|
|
29
|
+
transpose: @variables['transpose'])
|
|
24
30
|
|
|
25
31
|
when /(?:panel_value|sql_value)/
|
|
26
32
|
tmp = @result[:content] || []
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GrafanaReporter
|
|
4
|
+
# Implements a datasource to return environment related information about the reporter in a tabular format.
|
|
5
|
+
class ReporterEnvironmentDatasource < ::Grafana::AbstractDatasource
|
|
6
|
+
# @see AbstractDatasource#request
|
|
7
|
+
def request(query_description)
|
|
8
|
+
{
|
|
9
|
+
header: ['Version', 'Release Date'],
|
|
10
|
+
content: [[GRAFANA_REPORTER_VERSION.join('.'), GRAFANA_REPORTER_RELEASE_DATE]]
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @see AbstractDatasource#default_variable_format
|
|
15
|
+
def default_variable_format
|
|
16
|
+
nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @see AbstractDatasource#name
|
|
20
|
+
def name
|
|
21
|
+
self.class.to_s
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -18,16 +18,16 @@ require 'asciidoctor-pdf'
|
|
|
18
18
|
require 'zip'
|
|
19
19
|
require_relative 'VERSION'
|
|
20
20
|
|
|
21
|
-
# TODO: add test
|
|
22
|
-
# TODO:
|
|
23
|
-
# TODO:
|
|
21
|
+
# TODO: add test for variable replacement for sql
|
|
22
|
+
# TODO: check why value is All instead of $__all
|
|
23
|
+
# TODO: check why single sql values are replaced including ticks, whereas grafana does not do so
|
|
24
|
+
|
|
25
|
+
# TODO: add FAQ for fixing most common issues with the reporter
|
|
26
|
+
# TODO: implement an easy function to document a whole dashboard at once with different presentations
|
|
24
27
|
# TODO: add automated test against grafana playground before building a new release
|
|
25
28
|
# TODO: allow registration of files to be defined in config file
|
|
26
|
-
# TODO: PRIO: check in cloud - variables fetched from queries are replaced with SQL query instead of the resolved values, which can lead to issues, e.g. when using that in a function as SUBSTRING
|
|
27
|
-
# TODO: PRIO: allow multiple report classes in configuration file including possibility to decide for the individual class for each rendering call
|
|
28
|
-
# TODO: add configuration example to README
|
|
29
|
-
# TODO: find a way, how to automatically update test grafana responses with _real_ grafana responses
|
|
30
29
|
# TODO: append necessary variables on demo report creation for plain SQL queries, as they are lacking the grafana reference
|
|
30
|
+
# TODO: make demo report more readable
|
|
31
31
|
|
|
32
32
|
folders = [
|
|
33
33
|
%w[grafana],
|
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.
|
|
4
|
+
version: 0.5.2
|
|
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: 2022-03-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: asciidoctor
|
|
@@ -100,9 +100,9 @@ dependencies:
|
|
|
100
100
|
- - "~>"
|
|
101
101
|
- !ruby/object:Gem::Version
|
|
102
102
|
version: '3.9'
|
|
103
|
-
description: Build reports based on grafana dashboards in asciidoctor syntax.
|
|
104
|
-
as webservice for easy integration with grafana, or as a standalone, command
|
|
105
|
-
utility.
|
|
103
|
+
description: Build reports based on grafana dashboards in asciidoctor or ERB syntax.
|
|
104
|
+
Runs as webservice for easy integration with grafana, or as a standalone, command
|
|
105
|
+
line utility.
|
|
106
106
|
email: kohly@gmx.de
|
|
107
107
|
executables:
|
|
108
108
|
- ruby-grafana-reporter
|
|
@@ -118,6 +118,7 @@ files:
|
|
|
118
118
|
- "./lib/grafana/grafana.rb"
|
|
119
119
|
- "./lib/grafana/grafana_alerts_datasource.rb"
|
|
120
120
|
- "./lib/grafana/grafana_annotations_datasource.rb"
|
|
121
|
+
- "./lib/grafana/grafana_environment_datasource.rb"
|
|
121
122
|
- "./lib/grafana/grafana_property_datasource.rb"
|
|
122
123
|
- "./lib/grafana/graphite_datasource.rb"
|
|
123
124
|
- "./lib/grafana/image_rendering_datasource.rb"
|
|
@@ -165,6 +166,7 @@ files:
|
|
|
165
166
|
- "./lib/grafana_reporter/panel_property_query.rb"
|
|
166
167
|
- "./lib/grafana_reporter/query_value_query.rb"
|
|
167
168
|
- "./lib/grafana_reporter/report_webhook.rb"
|
|
169
|
+
- "./lib/grafana_reporter/reporter_environment_datasource.rb"
|
|
168
170
|
- "./lib/ruby_grafana_extension.rb"
|
|
169
171
|
- "./lib/ruby_grafana_reporter.rb"
|
|
170
172
|
- LICENSE
|
|
@@ -191,8 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
191
193
|
- !ruby/object:Gem::Version
|
|
192
194
|
version: '0'
|
|
193
195
|
requirements: []
|
|
194
|
-
|
|
195
|
-
rubygems_version: 2.7.6.2
|
|
196
|
+
rubygems_version: 3.2.5
|
|
196
197
|
signing_key:
|
|
197
198
|
specification_version: 4
|
|
198
199
|
summary: Reporter Service for Grafana
|