ruby-grafana-reporter 0.1.7 → 0.2.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 +166 -339
- data/bin/ruby-grafana-reporter +5 -4
- data/lib/VERSION.rb +5 -3
- data/lib/grafana/abstract_panel_query.rb +22 -20
- data/lib/grafana/abstract_query.rb +132 -127
- data/lib/grafana/abstract_sql_query.rb +51 -42
- data/lib/grafana/dashboard.rb +77 -66
- data/lib/grafana/errors.rb +66 -61
- data/lib/grafana/grafana.rb +130 -131
- data/lib/grafana/panel.rb +41 -39
- data/lib/grafana/panel_image_query.rb +52 -49
- data/lib/grafana/variable.rb +217 -259
- data/lib/grafana_reporter/abstract_report.rb +112 -109
- data/lib/grafana_reporter/application/application.rb +404 -229
- data/lib/grafana_reporter/application/errors.rb +33 -30
- data/lib/grafana_reporter/application/webservice.rb +231 -0
- data/lib/grafana_reporter/asciidoctor/alerts_table_query.rb +104 -99
- data/lib/grafana_reporter/asciidoctor/annotations_table_query.rb +99 -96
- data/lib/grafana_reporter/asciidoctor/errors.rb +40 -37
- data/lib/grafana_reporter/asciidoctor/extensions/alerts_table_include_processor.rb +92 -86
- data/lib/grafana_reporter/asciidoctor/extensions/annotations_table_include_processor.rb +91 -86
- data/lib/grafana_reporter/asciidoctor/extensions/panel_image_block_macro.rb +69 -67
- data/lib/grafana_reporter/asciidoctor/extensions/panel_image_inline_macro.rb +68 -65
- data/lib/grafana_reporter/asciidoctor/extensions/panel_property_inline_macro.rb +61 -58
- data/lib/grafana_reporter/asciidoctor/extensions/panel_query_table_include_processor.rb +78 -75
- data/lib/grafana_reporter/asciidoctor/extensions/panel_query_value_inline_macro.rb +73 -70
- data/lib/grafana_reporter/asciidoctor/extensions/processor_mixin.rb +20 -18
- data/lib/grafana_reporter/asciidoctor/extensions/show_environment_include_processor.rb +43 -41
- data/lib/grafana_reporter/asciidoctor/extensions/sql_table_include_processor.rb +70 -67
- data/lib/grafana_reporter/asciidoctor/extensions/sql_value_inline_macro.rb +66 -65
- data/lib/grafana_reporter/asciidoctor/extensions/value_as_variable_include_processor.rb +61 -57
- data/lib/grafana_reporter/asciidoctor/panel_first_value_query.rb +34 -32
- data/lib/grafana_reporter/asciidoctor/panel_image_query.rb +25 -23
- data/lib/grafana_reporter/asciidoctor/panel_property_query.rb +44 -43
- data/lib/grafana_reporter/asciidoctor/panel_table_query.rb +38 -36
- data/lib/grafana_reporter/asciidoctor/query_mixin.rb +310 -309
- data/lib/grafana_reporter/asciidoctor/report.rb +177 -159
- data/lib/grafana_reporter/asciidoctor/sql_first_value_query.rb +37 -34
- data/lib/grafana_reporter/asciidoctor/sql_table_query.rb +39 -32
- data/lib/grafana_reporter/configuration.rb +257 -326
- data/lib/grafana_reporter/errors.rb +48 -38
- data/lib/grafana_reporter/logger/two_way_logger.rb +58 -52
- data/lib/ruby-grafana-reporter.rb +29 -27
- metadata +10 -23
@@ -1,65 +1,66 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Implements the hook
|
7
|
-
# grafana_sql_value:<datasource_id>[<options>]
|
8
|
-
#
|
9
|
-
# Returns the first value of the resulting SQL query.
|
10
|
-
#
|
11
|
-
# == Used document parameters
|
12
|
-
# +grafana_default_instance+ - name of grafana instance, 'default' if not specified
|
13
|
-
#
|
14
|
-
# +from+ - 'from' time for the sql query
|
15
|
-
#
|
16
|
-
# +to+ - 'to' time for the sql query
|
17
|
-
#
|
18
|
-
# All other variables starting with +var-+ will be used to replace grafana templating strings
|
19
|
-
# in the given SQL query.
|
20
|
-
#
|
21
|
-
# == Supported options
|
22
|
-
# +sql+ - sql statement (*mandatory*)
|
23
|
-
#
|
24
|
-
# +instance+ - name of grafana instance, 'default' if not specified
|
25
|
-
#
|
26
|
-
# +from+ - 'from' time for the sql query
|
27
|
-
#
|
28
|
-
# +to+ - 'to' time for the sql query
|
29
|
-
#
|
30
|
-
# +format+ - see {QueryMixin#format_columns}
|
31
|
-
#
|
32
|
-
# +replace_values+ - see {QueryMixin#replace_values}
|
33
|
-
#
|
34
|
-
# +filter_columns+ - see {QueryMixin#filter_columns}
|
35
|
-
class SqlValueInlineMacro < ::Asciidoctor::Extensions::InlineMacroProcessor
|
36
|
-
include ProcessorMixin
|
37
|
-
use_dsl
|
38
|
-
|
39
|
-
named :grafana_sql_value
|
40
|
-
|
41
|
-
# @see GrafanaReporter::Asciidoctor::SqlFirstValueQuery
|
42
|
-
def process(parent, target, attrs)
|
43
|
-
return if @report.cancel
|
44
|
-
|
45
|
-
@report.next_step
|
46
|
-
instance = attrs['instance'] || parent.document.attr('grafana_default_instance') || 'default'
|
47
|
-
@report.logger.debug("Processing SqlValueInlineMacro (instance: #{instance}, datasource: #{target},
|
48
|
-
|
49
|
-
query.
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
module Asciidoctor
|
5
|
+
module Extensions
|
6
|
+
# Implements the hook
|
7
|
+
# grafana_sql_value:<datasource_id>[<options>]
|
8
|
+
#
|
9
|
+
# Returns the first value of the resulting SQL query.
|
10
|
+
#
|
11
|
+
# == Used document parameters
|
12
|
+
# +grafana_default_instance+ - name of grafana instance, 'default' if not specified
|
13
|
+
#
|
14
|
+
# +from+ - 'from' time for the sql query
|
15
|
+
#
|
16
|
+
# +to+ - 'to' time for the sql query
|
17
|
+
#
|
18
|
+
# All other variables starting with +var-+ will be used to replace grafana templating strings
|
19
|
+
# in the given SQL query.
|
20
|
+
#
|
21
|
+
# == Supported options
|
22
|
+
# +sql+ - sql statement (*mandatory*)
|
23
|
+
#
|
24
|
+
# +instance+ - name of grafana instance, 'default' if not specified
|
25
|
+
#
|
26
|
+
# +from+ - 'from' time for the sql query
|
27
|
+
#
|
28
|
+
# +to+ - 'to' time for the sql query
|
29
|
+
#
|
30
|
+
# +format+ - see {QueryMixin#format_columns}
|
31
|
+
#
|
32
|
+
# +replace_values+ - see {QueryMixin#replace_values}
|
33
|
+
#
|
34
|
+
# +filter_columns+ - see {QueryMixin#filter_columns}
|
35
|
+
class SqlValueInlineMacro < ::Asciidoctor::Extensions::InlineMacroProcessor
|
36
|
+
include ProcessorMixin
|
37
|
+
use_dsl
|
38
|
+
|
39
|
+
named :grafana_sql_value
|
40
|
+
|
41
|
+
# @see GrafanaReporter::Asciidoctor::SqlFirstValueQuery
|
42
|
+
def process(parent, target, attrs)
|
43
|
+
return if @report.cancel
|
44
|
+
|
45
|
+
@report.next_step
|
46
|
+
instance = attrs['instance'] || parent.document.attr('grafana_default_instance') || 'default'
|
47
|
+
@report.logger.debug("Processing SqlValueInlineMacro (instance: #{instance}, datasource: #{target},"\
|
48
|
+
" sql: #{attrs['sql']})")
|
49
|
+
query = SqlFirstValueQuery.new(attrs['sql'], target)
|
50
|
+
query.merge_hash_variables(parent.document.attributes, attrs)
|
51
|
+
@report.logger.debug("from: #{query.from}, to: #{query.to}")
|
52
|
+
|
53
|
+
begin
|
54
|
+
create_inline(parent, :quoted, query.execute(@report.grafana(instance)))
|
55
|
+
rescue GrafanaReporterError => e
|
56
|
+
@report.logger.error(e.message)
|
57
|
+
create_inline(parent, :quoted, e.message)
|
58
|
+
rescue StandardError => e
|
59
|
+
@report.logger.fatal(e.message)
|
60
|
+
create_inline(parent, :quoted, e.message)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -1,57 +1,61 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
@report.logger.debug("ValueAsVariableIncludeProcessor:
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'processor_mixin'
|
4
|
+
|
5
|
+
module GrafanaReporter
|
6
|
+
module Asciidoctor
|
7
|
+
module Extensions
|
8
|
+
# TODO: add documentation
|
9
|
+
class ValueAsVariableIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
|
10
|
+
include ProcessorMixin
|
11
|
+
|
12
|
+
# :nodoc:
|
13
|
+
def handles?(target)
|
14
|
+
target.start_with? 'grafana_value_as_variable'
|
15
|
+
end
|
16
|
+
|
17
|
+
# :nodoc:
|
18
|
+
def process(doc, reader, target, attrs)
|
19
|
+
return if @report.cancel
|
20
|
+
|
21
|
+
# do NOT increase step, as this is done by sub processor
|
22
|
+
# @report.next_step
|
23
|
+
|
24
|
+
call_attr = attrs.delete('call')
|
25
|
+
call, target = call_attr.split(':') if call_attr
|
26
|
+
attribute = attrs.delete('variable_name')
|
27
|
+
@report.logger.debug("Processing ValueAsVariableIncludeProcessor (call: #{call}, target: #{target},"\
|
28
|
+
" variable_name: #{attribute}, attrs: #{attrs})")
|
29
|
+
if !call || !attribute
|
30
|
+
@report.logger.error("Missing mandatory attribute 'call' or 'variable_name'.")
|
31
|
+
return reader
|
32
|
+
end
|
33
|
+
|
34
|
+
# TODO: remove dirty hack to allow the document as parameter for other processors
|
35
|
+
def doc.document
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: properly show error messages also in document
|
40
|
+
ext = doc.extensions.find_inline_macro_extension(call) if doc.extensions.inline_macros?
|
41
|
+
if !ext
|
42
|
+
@report.logger.error("Could not find inline macro extension for '#{call}'.")
|
43
|
+
else
|
44
|
+
@report.logger.debug('ValueAsVariableIncludeProcessor: Calling sub-method.')
|
45
|
+
item = ext.process_method.call(doc, target, attrs)
|
46
|
+
if !item.text.to_s.empty?
|
47
|
+
result = ":#{attribute}: #{item.text}"
|
48
|
+
@report.logger.debug("ValueAsVariableIncludeProcessor: Adding '#{result}' to document.")
|
49
|
+
reader.unshift_line(result)
|
50
|
+
else
|
51
|
+
@report.logger.debug("ValueAsVariableIncludeProcessor: Not adding variable '#{attribute}',"\
|
52
|
+
' as query result was empty.')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
reader
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,32 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@
|
25
|
-
|
26
|
-
|
27
|
-
@
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'sql_first_value_query'
|
4
|
+
|
5
|
+
module GrafanaReporter
|
6
|
+
module Asciidoctor
|
7
|
+
# (see SqlFirstValueQuery)
|
8
|
+
#
|
9
|
+
# The SQL query as well as the datasource configuration are thereby captured from a
|
10
|
+
# {Grafana::Panel}.
|
11
|
+
class PanelFirstValueQuery < SqlFirstValueQuery
|
12
|
+
include QueryMixin
|
13
|
+
|
14
|
+
# (see PanelTableQuery#initialize)
|
15
|
+
def initialize(panel, query_letter)
|
16
|
+
super(nil, nil)
|
17
|
+
@panel = panel
|
18
|
+
@query_letter = query_letter
|
19
|
+
extract_dashboard_variables(@panel.dashboard)
|
20
|
+
end
|
21
|
+
|
22
|
+
# (see PanelTableQuery#pre_process)
|
23
|
+
def pre_process(grafana)
|
24
|
+
@sql = @panel.query(@query_letter)
|
25
|
+
# resolve datasource name
|
26
|
+
@datasource = @panel.field('datasource')
|
27
|
+
@datasource_id = grafana.datasource_id(@datasource)
|
28
|
+
super(grafana)
|
29
|
+
@from = translate_date(@from, @variables['grafana-report-timestamp'], false)
|
30
|
+
@to = translate_date(@to, @variables['grafana-report-timestamp'], true)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,23 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
module Asciidoctor
|
5
|
+
# This class is used to create an image out of a {Grafana::Panel}.
|
6
|
+
class PanelImageQuery < Grafana::PanelImageQuery
|
7
|
+
include QueryMixin
|
8
|
+
|
9
|
+
# Sets the proper render variables.
|
10
|
+
def pre_process(grafana)
|
11
|
+
super
|
12
|
+
@from = translate_date(@from, @variables['grafana-report-timestamp'], false)
|
13
|
+
@to = translate_date(@to, @variables['grafana-report-timestamp'], true)
|
14
|
+
# rename "render-" variables
|
15
|
+
@variables.transform_keys! { |k| k.gsub(/^render-/, '') }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns the body of the http query, which contains the raw image.
|
19
|
+
def post_process
|
20
|
+
super
|
21
|
+
@result = @result.body
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,43 +1,44 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# @
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
module Asciidoctor
|
5
|
+
# This class is used to query properties from a {Grafana::Panel}, such as +description+,
|
6
|
+
# +title+ etc.
|
7
|
+
class PanelPropertyQuery < ::Grafana::AbstractPanelQuery
|
8
|
+
include QueryMixin
|
9
|
+
|
10
|
+
# @param panel [Grafana::Panel] panel object, for which the property shall be retrieved
|
11
|
+
# @param property [String] queried property, e.g. +title+
|
12
|
+
def initialize(panel, property)
|
13
|
+
super(panel)
|
14
|
+
@property = property
|
15
|
+
end
|
16
|
+
|
17
|
+
# Overrides the default method, as the query does not have to run against a SQL table,
|
18
|
+
# but rather against the panel model.
|
19
|
+
# @param grafana [Grafana::Grafana] grafana instance against which the panel property is queried
|
20
|
+
# @return [String] fetched property
|
21
|
+
def execute(grafana)
|
22
|
+
return @result unless @result.nil?
|
23
|
+
|
24
|
+
pre_process(grafana)
|
25
|
+
@result = panel.field(@property)
|
26
|
+
post_process
|
27
|
+
@result
|
28
|
+
|
29
|
+
# TODO: handle text (markdown and similar) properly
|
30
|
+
end
|
31
|
+
|
32
|
+
# Prepare query. Mainly here nothing special has to take place.
|
33
|
+
def pre_process(_grafana)
|
34
|
+
@from = nil
|
35
|
+
@to = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
# Replaces variables in the property field, if any are available.
|
39
|
+
def post_process
|
40
|
+
@result = replace_variables(@result, grafana_variables)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|