ruby-grafana-reporter 0.3.0 → 0.4.4
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 +337 -170
- data/bin/ruby-grafana-reporter +5 -5
- data/lib/VERSION.rb +3 -2
- data/lib/grafana/abstract_datasource.rb +149 -0
- data/lib/grafana/dashboard.rb +1 -3
- data/lib/grafana/errors.rb +20 -5
- data/lib/grafana/grafana.rb +52 -57
- 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 +37 -0
- data/lib/grafana/graphite_datasource.rb +72 -0
- data/lib/grafana/image_rendering_datasource.rb +44 -0
- data/lib/grafana/influxdb_datasource.rb +70 -0
- data/lib/grafana/panel.rb +10 -4
- data/lib/grafana/prometheus_datasource.rb +67 -0
- data/lib/grafana/sql_datasource.rb +70 -0
- data/lib/grafana/unsupported_datasource.rb +7 -0
- data/lib/grafana/variable.rb +27 -21
- data/lib/grafana/webrequest.rb +71 -0
- data/lib/grafana_reporter/abstract_query.rb +478 -0
- data/lib/grafana_reporter/abstract_report.rb +152 -18
- data/lib/grafana_reporter/abstract_table_format_strategy.rb +34 -0
- data/lib/grafana_reporter/alerts_table_query.rb +43 -0
- data/lib/grafana_reporter/annotations_table_query.rb +42 -0
- data/lib/grafana_reporter/application/application.rb +28 -25
- data/lib/grafana_reporter/application/webservice.rb +80 -39
- data/lib/grafana_reporter/asciidoctor/adoc_plain_table_format_strategy.rb +25 -0
- data/lib/grafana_reporter/asciidoctor/alerts_table_include_processor.rb +92 -0
- data/lib/grafana_reporter/asciidoctor/annotations_table_include_processor.rb +91 -0
- data/lib/grafana_reporter/asciidoctor/help.rb +336 -313
- data/lib/grafana_reporter/asciidoctor/panel_image_block_macro.rb +78 -0
- data/lib/grafana_reporter/asciidoctor/panel_image_inline_macro.rb +80 -0
- data/lib/grafana_reporter/asciidoctor/panel_property_inline_macro.rb +74 -0
- data/lib/grafana_reporter/asciidoctor/panel_query_table_include_processor.rb +99 -0
- data/lib/grafana_reporter/asciidoctor/panel_query_value_inline_macro.rb +93 -0
- data/lib/grafana_reporter/asciidoctor/processor_mixin.rb +50 -0
- data/lib/grafana_reporter/asciidoctor/report.rb +41 -82
- 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 +94 -0
- data/lib/grafana_reporter/asciidoctor/sql_value_inline_macro.rb +90 -0
- data/lib/grafana_reporter/asciidoctor/value_as_variable_include_processor.rb +90 -0
- data/lib/grafana_reporter/configuration.rb +26 -8
- data/lib/grafana_reporter/console_configuration_wizard.rb +109 -67
- data/lib/grafana_reporter/csv_table_format_strategy.rb +23 -0
- data/lib/grafana_reporter/demo_report_wizard.rb +104 -0
- data/lib/grafana_reporter/erb/demo_report_builder.rb +46 -0
- data/lib/grafana_reporter/erb/report.rb +36 -0
- data/lib/grafana_reporter/erb/report_jail.rb +21 -0
- data/lib/grafana_reporter/errors.rb +57 -0
- data/lib/grafana_reporter/logger/{two_way_logger.rb → two_way_delegate_logger.rb} +1 -1
- data/lib/grafana_reporter/panel_image_query.rb +25 -0
- data/lib/grafana_reporter/panel_property_query.rb +22 -0
- data/lib/grafana_reporter/query_value_query.rb +61 -0
- data/lib/grafana_reporter/report_webhook.rb +39 -0
- data/lib/ruby_grafana_extension.rb +8 -0
- data/lib/{ruby-grafana-reporter.rb → ruby_grafana_reporter.rb} +1 -3
- metadata +49 -38
- data/lib/grafana/abstract_panel_query.rb +0 -22
- data/lib/grafana/abstract_query.rb +0 -132
- data/lib/grafana/abstract_sql_query.rb +0 -51
- data/lib/grafana/panel_image_query.rb +0 -52
- data/lib/grafana_reporter/asciidoctor/alerts_table_query.rb +0 -101
- data/lib/grafana_reporter/asciidoctor/annotations_table_query.rb +0 -96
- data/lib/grafana_reporter/asciidoctor/errors.rb +0 -40
- data/lib/grafana_reporter/asciidoctor/extensions/alerts_table_include_processor.rb +0 -92
- data/lib/grafana_reporter/asciidoctor/extensions/annotations_table_include_processor.rb +0 -91
- data/lib/grafana_reporter/asciidoctor/extensions/panel_image_block_macro.rb +0 -69
- data/lib/grafana_reporter/asciidoctor/extensions/panel_image_inline_macro.rb +0 -68
- data/lib/grafana_reporter/asciidoctor/extensions/panel_property_inline_macro.rb +0 -61
- data/lib/grafana_reporter/asciidoctor/extensions/panel_query_table_include_processor.rb +0 -78
- data/lib/grafana_reporter/asciidoctor/extensions/panel_query_value_inline_macro.rb +0 -73
- data/lib/grafana_reporter/asciidoctor/extensions/processor_mixin.rb +0 -20
- data/lib/grafana_reporter/asciidoctor/extensions/show_environment_include_processor.rb +0 -43
- data/lib/grafana_reporter/asciidoctor/extensions/show_help_include_processor.rb +0 -30
- data/lib/grafana_reporter/asciidoctor/extensions/sql_table_include_processor.rb +0 -70
- data/lib/grafana_reporter/asciidoctor/extensions/sql_value_inline_macro.rb +0 -66
- data/lib/grafana_reporter/asciidoctor/extensions/value_as_variable_include_processor.rb +0 -88
- data/lib/grafana_reporter/asciidoctor/panel_first_value_query.rb +0 -36
- data/lib/grafana_reporter/asciidoctor/panel_image_query.rb +0 -28
- data/lib/grafana_reporter/asciidoctor/panel_property_query.rb +0 -44
- data/lib/grafana_reporter/asciidoctor/panel_table_query.rb +0 -40
- data/lib/grafana_reporter/asciidoctor/query_mixin.rb +0 -312
- data/lib/grafana_reporter/asciidoctor/sql_first_value_query.rb +0 -42
- data/lib/grafana_reporter/asciidoctor/sql_table_query.rb +0 -44
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'processor_mixin'
|
4
|
+
|
5
|
+
module GrafanaReporter
|
6
|
+
module Asciidoctor
|
7
|
+
# Implements the hook
|
8
|
+
# grafana_panel_image::<panel_id>[<options>]
|
9
|
+
#
|
10
|
+
# Stores the queried panel as a temporary image file and returns an asciidoctor link
|
11
|
+
# to be included in the report.
|
12
|
+
#
|
13
|
+
# == Used document parameters
|
14
|
+
# +grafana_default_instance+ - name of grafana instance, 'default' if not specified
|
15
|
+
#
|
16
|
+
# +grafana_default_dashboard+ - uid of grafana default dashboard to use
|
17
|
+
#
|
18
|
+
# +from+ - 'from' time for the sql query
|
19
|
+
#
|
20
|
+
# +to+ - 'to' time for the sql query
|
21
|
+
#
|
22
|
+
# == Supported options
|
23
|
+
# +field+ - property to query for, e.g. +description+ or +title+ (*mandatory*)
|
24
|
+
#
|
25
|
+
# +instance+ - name of grafana instance, 'default' if not specified
|
26
|
+
#
|
27
|
+
# +dashboard+ - uid of grafana dashboard to use
|
28
|
+
#
|
29
|
+
# +from+ - 'from' time for the sql query
|
30
|
+
#
|
31
|
+
# +to+ - 'to' time for the sql query
|
32
|
+
class PanelImageBlockMacro < ::Asciidoctor::Extensions::BlockMacroProcessor
|
33
|
+
include ProcessorMixin
|
34
|
+
use_dsl
|
35
|
+
|
36
|
+
named :grafana_panel_image
|
37
|
+
|
38
|
+
# :nodoc:
|
39
|
+
def process(parent, target, attrs)
|
40
|
+
return if @report.cancel
|
41
|
+
|
42
|
+
@report.next_step
|
43
|
+
instance = attrs['instance'] || parent.document.attr('grafana_default_instance') || 'default'
|
44
|
+
dashboard = attrs['dashboard'] || parent.document.attr('grafana_default_dashboard')
|
45
|
+
@report.logger.debug("Processing PanelImageBlockMacro (instance: #{instance}, dashboard: #{dashboard},"\
|
46
|
+
" panel: #{target})")
|
47
|
+
|
48
|
+
begin
|
49
|
+
query = PanelImageQuery.new(@report.grafana(instance).dashboard(dashboard).panel(target),
|
50
|
+
variables: build_attribute_hash(parent.document.attributes, attrs))
|
51
|
+
|
52
|
+
image = query.execute
|
53
|
+
image_path = @report.save_image_file(image)
|
54
|
+
rescue GrafanaError => e
|
55
|
+
@report.logger.error(e.message)
|
56
|
+
return create_paragraph(parent, e.message, attrs)
|
57
|
+
rescue GrafanaReporterError => e
|
58
|
+
@report.logger.error(e.message)
|
59
|
+
return create_paragraph(parent, e.message, attrs)
|
60
|
+
rescue StandardError => e
|
61
|
+
@report.logger.fatal(e.message)
|
62
|
+
return create_paragraph(parent, e.message, attrs)
|
63
|
+
end
|
64
|
+
|
65
|
+
attrs['target'] = image_path
|
66
|
+
create_image_block(parent, attrs)
|
67
|
+
end
|
68
|
+
|
69
|
+
# @see ProcessorMixin#build_demo_entry
|
70
|
+
def build_demo_entry(panel)
|
71
|
+
return nil unless panel
|
72
|
+
return nil unless panel.model['type'] == 'graph'
|
73
|
+
|
74
|
+
"grafana_panel_image::#{panel.id}[dashboard=\"#{panel.dashboard.id}\",width=\"50%\"]"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'processor_mixin'
|
4
|
+
|
5
|
+
module GrafanaReporter
|
6
|
+
module Asciidoctor
|
7
|
+
# Implements the hook
|
8
|
+
# grafana_panel_image:<panel_id>[<options>]
|
9
|
+
#
|
10
|
+
# Stores the queried panel as a temporary image file and returns an asciidoctor link
|
11
|
+
# to be included in the report.
|
12
|
+
#
|
13
|
+
# == Used document parameters
|
14
|
+
# +grafana_default_instance+ - name of grafana instance, 'default' if not specified
|
15
|
+
#
|
16
|
+
# +grafana_default_dashboard+ - uid of grafana default dashboard to use
|
17
|
+
#
|
18
|
+
# +from+ - 'from' time for the sql query
|
19
|
+
#
|
20
|
+
# +to+ - 'to' time for the sql query
|
21
|
+
#
|
22
|
+
# == Supported options
|
23
|
+
# +field+ - property to query for, e.g. +description+ or +title+ (*mandatory*)
|
24
|
+
#
|
25
|
+
# +instance+ - name of grafana instance, 'default' if not specified
|
26
|
+
#
|
27
|
+
# +dashboard+ - uid of grafana dashboard to use
|
28
|
+
#
|
29
|
+
# +from+ - 'from' time for the sql query
|
30
|
+
#
|
31
|
+
# +to+ - 'to' time for the sql query
|
32
|
+
class PanelImageInlineMacro < ::Asciidoctor::Extensions::InlineMacroProcessor
|
33
|
+
include ProcessorMixin
|
34
|
+
use_dsl
|
35
|
+
|
36
|
+
named :grafana_panel_image
|
37
|
+
|
38
|
+
# :nodoc:
|
39
|
+
def process(parent, target, attrs)
|
40
|
+
return if @report.cancel
|
41
|
+
|
42
|
+
@report.next_step
|
43
|
+
instance = attrs['instance'] || parent.document.attr('grafana_default_instance') || 'default'
|
44
|
+
dashboard = attrs['dashboard'] || parent.document.attr('grafana_default_dashboard')
|
45
|
+
@report.logger.debug("Processing PanelImageInlineMacro (instance: #{instance}, dashboard: #{dashboard},"\
|
46
|
+
" panel: #{target})")
|
47
|
+
|
48
|
+
begin
|
49
|
+
# set alt text to a default, because otherwise asciidoctor fails
|
50
|
+
attrs['alt'] = '' unless attrs['alt']
|
51
|
+
query = PanelImageQuery.new(@report.grafana(instance).dashboard(dashboard).panel(target),
|
52
|
+
variables: build_attribute_hash(parent.document.attributes, attrs))
|
53
|
+
|
54
|
+
image = query.execute
|
55
|
+
image_path = @report.save_image_file(image)
|
56
|
+
rescue GrafanaError => e
|
57
|
+
@report.logger.error(e.message)
|
58
|
+
return create_inline(parent, :quoted, e.message)
|
59
|
+
rescue GrafanaReporterError => e
|
60
|
+
@report.logger.error(e.message)
|
61
|
+
return create_inline(parent, :quoted, e.message)
|
62
|
+
rescue StandardError => e
|
63
|
+
@report.logger.fatal(e.message)
|
64
|
+
return create_inline(parent, :quoted, e.message)
|
65
|
+
end
|
66
|
+
|
67
|
+
create_inline(parent, :image, nil, { target: image_path, attributes: attrs })
|
68
|
+
end
|
69
|
+
|
70
|
+
# @see ProcessorMixin#build_demo_entry
|
71
|
+
def build_demo_entry(panel)
|
72
|
+
return nil unless panel
|
73
|
+
return nil unless panel.model['type'] == 'graph'
|
74
|
+
|
75
|
+
"see here: grafana_panel_image:#{panel.id}[dashboard=\"#{panel.dashboard.id}\","\
|
76
|
+
'width="90%"] - a working inline image'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'processor_mixin'
|
4
|
+
|
5
|
+
module GrafanaReporter
|
6
|
+
module Asciidoctor
|
7
|
+
# Implements the hook
|
8
|
+
# grafana_panel_property:<panel_id>[<options>]
|
9
|
+
#
|
10
|
+
# Returns the requested panel property.
|
11
|
+
#
|
12
|
+
# == Used document parameters
|
13
|
+
# +grafana_default_instance+ - name of grafana instance, 'default' if not specified
|
14
|
+
#
|
15
|
+
# +grafana_default_dashboard+ - uid of grafana default dashboard to use
|
16
|
+
#
|
17
|
+
# == Supported options
|
18
|
+
# +field+ - property to query for, e.g. +description+ or +title+ (*mandatory*)
|
19
|
+
#
|
20
|
+
# +instance+ - name of grafana instance, 'default' if not specified
|
21
|
+
#
|
22
|
+
# +dashboard+ - uid of grafana dashboard to use
|
23
|
+
class PanelPropertyInlineMacro < ::Asciidoctor::Extensions::InlineMacroProcessor
|
24
|
+
include ProcessorMixin
|
25
|
+
use_dsl
|
26
|
+
|
27
|
+
named :grafana_panel_property
|
28
|
+
name_positional_attributes :field
|
29
|
+
|
30
|
+
# :nodoc:
|
31
|
+
def process(parent, target, attrs)
|
32
|
+
return if @report.cancel
|
33
|
+
|
34
|
+
@report.next_step
|
35
|
+
instance = attrs['instance'] || parent.document.attr('grafana_default_instance') || 'default'
|
36
|
+
dashboard = attrs['dashboard'] || parent.document.attr('grafana_default_dashboard')
|
37
|
+
@report.logger.debug("Processing PanelPropertyInlineMacro (instance: #{instance}, dashboard: #{dashboard},"\
|
38
|
+
" panel: #{target}, property: #{attrs[:field]})")
|
39
|
+
|
40
|
+
begin
|
41
|
+
query = PanelPropertyQuery.new(@report.grafana(instance).dashboard(dashboard).panel(target),
|
42
|
+
variables: build_attribute_hash(parent.document.attributes, attrs))
|
43
|
+
query.raw_query = { property_name: attrs[:field] }
|
44
|
+
|
45
|
+
description = query.execute
|
46
|
+
rescue GrafanaError => e
|
47
|
+
@report.logger.error(e.message)
|
48
|
+
return create_inline(parent, :quoted, e.message)
|
49
|
+
rescue GrafanaReporterError => e
|
50
|
+
@report.logger.error(e.message)
|
51
|
+
return create_inline(parent, :quoted, e.message)
|
52
|
+
rescue StandardError => e
|
53
|
+
@report.logger.fatal(e.message)
|
54
|
+
return create_inline(parent, :quoted, e.message)
|
55
|
+
end
|
56
|
+
|
57
|
+
# translate linebreaks to asciidoctor syntax
|
58
|
+
# and HTML encode to make sure, that HTML formattings are respected
|
59
|
+
create_inline(parent, :quoted, CGI.escapeHTML(description.gsub(%r{//[^\n]*(?:\n)?}, '').gsub(/\n/, " +\n")))
|
60
|
+
end
|
61
|
+
|
62
|
+
# @see ProcessorMixin#build_demo_entry
|
63
|
+
def build_demo_entry(panel)
|
64
|
+
return nil unless panel
|
65
|
+
return nil unless panel.model['title']
|
66
|
+
return nil if panel.model['title'].strip == ''
|
67
|
+
return nil if panel.model['title'].strip == 'Panel Title'
|
68
|
+
|
69
|
+
"this text includes the panel with title grafana_panel_property:#{panel.id}[\"title\","\
|
70
|
+
"dashboard=\"#{panel.dashboard.id}\"]"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'processor_mixin'
|
4
|
+
|
5
|
+
module GrafanaReporter
|
6
|
+
module Asciidoctor
|
7
|
+
# Implements the hook
|
8
|
+
# include::grafana_panel_query_table:<panel_id>[<options>]
|
9
|
+
#
|
10
|
+
# Returns the results of the SQL query as a asciidoctor table.
|
11
|
+
#
|
12
|
+
# == Used document parameters
|
13
|
+
# +grafana_default_instance+ - name of grafana instance, 'default' if not specified
|
14
|
+
#
|
15
|
+
# +grafana_default_dashboard+ - uid of grafana default dashboard to use
|
16
|
+
#
|
17
|
+
# +from+ - 'from' time for the sql query
|
18
|
+
#
|
19
|
+
# +to+ - 'to' time for the sql query
|
20
|
+
#
|
21
|
+
# All other variables starting with +var-+ will be used to replace grafana templating strings
|
22
|
+
# in the given SQL query.
|
23
|
+
#
|
24
|
+
# == Supported options
|
25
|
+
# +query+ - query letter, which shall be used, e.g. +C+ (*mandatory*)
|
26
|
+
#
|
27
|
+
# +instance+ - name of grafana instance, 'default' if not specified
|
28
|
+
#
|
29
|
+
# +dashboard+ - uid of grafana dashboard to use
|
30
|
+
#
|
31
|
+
# +from+ - 'from' time for the sql query
|
32
|
+
#
|
33
|
+
# +to+ - 'to' time for the sql query
|
34
|
+
#
|
35
|
+
# +format+ - see {AbstractQuery#format_columns}
|
36
|
+
#
|
37
|
+
# +replace_values+ - see {AbstractQuery#replace_values}
|
38
|
+
#
|
39
|
+
# +filter_columns+ - see {AbstractQuery#filter_columns}
|
40
|
+
class PanelQueryTableIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
|
41
|
+
include ProcessorMixin
|
42
|
+
|
43
|
+
# :nodoc:
|
44
|
+
def handles?(target)
|
45
|
+
target.start_with? 'grafana_panel_query_table:'
|
46
|
+
end
|
47
|
+
|
48
|
+
# :nodoc:
|
49
|
+
def process(doc, reader, target, attrs)
|
50
|
+
return if @report.cancel
|
51
|
+
|
52
|
+
@report.next_step
|
53
|
+
panel_id = target.split(':')[1]
|
54
|
+
instance = attrs['instance'] || doc.attr('grafana_default_instance') || 'default'
|
55
|
+
dashboard = attrs['dashboard'] || doc.attr('grafana_default_dashboard')
|
56
|
+
attrs['result_type'] = 'panel_table'
|
57
|
+
@report.logger.debug("Processing PanelQueryTableIncludeProcessor (instance: #{instance}, "\
|
58
|
+
"dashboard: #{dashboard}, panel: #{panel_id}, query: #{attrs['query']})")
|
59
|
+
|
60
|
+
begin
|
61
|
+
panel = @report.grafana(instance).dashboard(dashboard).panel(panel_id)
|
62
|
+
vars = { 'table_formatter' => 'adoc_plain' }.merge(build_attribute_hash(doc.attributes, attrs))
|
63
|
+
query = QueryValueQuery.new(panel, variables: vars)
|
64
|
+
|
65
|
+
reader.unshift_lines query.execute
|
66
|
+
rescue GrafanaError => e
|
67
|
+
@report.logger.error(e.message)
|
68
|
+
reader.unshift_line "|#{e.message}"
|
69
|
+
rescue GrafanaReporterError => e
|
70
|
+
@report.logger.error(e.message)
|
71
|
+
reader.unshift_line "|#{e.message}"
|
72
|
+
rescue StandardError => e
|
73
|
+
@report.logger.fatal(e.message)
|
74
|
+
reader.unshift_line "|#{e.message}"
|
75
|
+
end
|
76
|
+
|
77
|
+
reader
|
78
|
+
end
|
79
|
+
|
80
|
+
# @see ProcessorMixin#build_demo_entry
|
81
|
+
def build_demo_entry(panel)
|
82
|
+
return nil unless panel
|
83
|
+
return nil unless panel.model['type'].include?('table')
|
84
|
+
|
85
|
+
ref_id = nil
|
86
|
+
panel.model['targets'].each do |item|
|
87
|
+
if !item['hide'] && !panel.query(item['refId']).to_s.empty?
|
88
|
+
ref_id = item['refId']
|
89
|
+
break
|
90
|
+
end
|
91
|
+
end
|
92
|
+
return nil unless ref_id
|
93
|
+
|
94
|
+
"|===\ninclude::grafana_panel_query_table:#{panel.id}[query=\"#{ref_id}\",filter_columns=\"time\","\
|
95
|
+
"dashboard=\"#{panel.dashboard.id}\"]\n|==="
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'processor_mixin'
|
4
|
+
|
5
|
+
module GrafanaReporter
|
6
|
+
module Asciidoctor
|
7
|
+
# Implements the hook
|
8
|
+
# grafana_panel_query_value:<panel_id>[<options>]
|
9
|
+
#
|
10
|
+
# Returns the first value of the resulting SQL query.
|
11
|
+
#
|
12
|
+
# == Used document parameters
|
13
|
+
# +grafana_default_instance+ - name of grafana instance, 'default' if not specified
|
14
|
+
#
|
15
|
+
# +grafana_default_dashboard+ - uid of grafana default dashboard to use
|
16
|
+
#
|
17
|
+
# +from+ - 'from' time for the sql query
|
18
|
+
#
|
19
|
+
# +to+ - 'to' time for the sql query
|
20
|
+
#
|
21
|
+
# All other variables starting with +var-+ will be used to replace grafana templating strings
|
22
|
+
# in the given SQL query.
|
23
|
+
#
|
24
|
+
# == Supported options
|
25
|
+
# +query+ - query letter, which shall be used, e.g. +C+ (*mandatory*)
|
26
|
+
#
|
27
|
+
# +instance+ - name of grafana instance, 'default' if not specified
|
28
|
+
#
|
29
|
+
# +dashboard+ - uid of grafana dashboard to use
|
30
|
+
#
|
31
|
+
# +from+ - 'from' time for the sql query
|
32
|
+
#
|
33
|
+
# +to+ - 'to' time for the sql query
|
34
|
+
#
|
35
|
+
# +format+ - see {AbstractQuery#format_columns}
|
36
|
+
#
|
37
|
+
# +replace_values+ - see {AbstractQuery#replace_values}
|
38
|
+
#
|
39
|
+
# +filter_columns+ - see {AbstractQuery#filter_columns}
|
40
|
+
class PanelQueryValueInlineMacro < ::Asciidoctor::Extensions::InlineMacroProcessor
|
41
|
+
include ProcessorMixin
|
42
|
+
use_dsl
|
43
|
+
|
44
|
+
named :grafana_panel_query_value
|
45
|
+
|
46
|
+
# :nodoc:
|
47
|
+
def process(parent, target, attrs)
|
48
|
+
return if @report.cancel
|
49
|
+
|
50
|
+
@report.next_step
|
51
|
+
instance = attrs['instance'] || parent.document.attr('grafana_default_instance') || 'default'
|
52
|
+
dashboard = attrs['dashboard'] || parent.document.attr('grafana_default_dashboard')
|
53
|
+
attrs['result_type'] = 'panel_value'
|
54
|
+
@report.logger.debug("Processing PanelQueryValueInlineMacro (instance: #{instance}, dashboard: #{dashboard},"\
|
55
|
+
" panel: #{target}, query: #{attrs['query']})")
|
56
|
+
|
57
|
+
begin
|
58
|
+
panel = @report.grafana(instance).dashboard(dashboard).panel(target)
|
59
|
+
query = QueryValueQuery.new(panel, variables: build_attribute_hash(parent.document.attributes, attrs))
|
60
|
+
|
61
|
+
create_inline(parent, :quoted, query.execute)
|
62
|
+
rescue GrafanaError => e
|
63
|
+
@report.logger.error(e.message)
|
64
|
+
create_inline(parent, :quoted, e.message)
|
65
|
+
rescue GrafanaReporterError => e
|
66
|
+
@report.logger.error(e.message)
|
67
|
+
create_inline(parent, :quoted, e.message)
|
68
|
+
rescue StandardError => e
|
69
|
+
@report.logger.fatal(e.message)
|
70
|
+
create_inline(parent, :quoted, e.message)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# @see ProcessorMixin#build_demo_entry
|
75
|
+
def build_demo_entry(panel)
|
76
|
+
return nil unless panel
|
77
|
+
return nil unless panel.model['type'] == 'singlestat'
|
78
|
+
|
79
|
+
ref_id = nil
|
80
|
+
panel.model['targets'].each do |item|
|
81
|
+
if !item['hide'] && !panel.query(item['refId']).to_s.empty?
|
82
|
+
ref_id = item['refId']
|
83
|
+
break
|
84
|
+
end
|
85
|
+
end
|
86
|
+
return nil unless ref_id
|
87
|
+
|
88
|
+
"it's easily possible to include the query value: grafana_panel_query_value:#{panel.id}[query=\"#{ref_id}\""\
|
89
|
+
",dashboard=\"#{panel.dashboard.id}\"] - just within this text."
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
module Asciidoctor
|
5
|
+
# This module contains common methods for all asciidoctor extensions.
|
6
|
+
module ProcessorMixin
|
7
|
+
# Used when initializing a object instance, to set the report object, which is currently in progress.
|
8
|
+
# @param report [GrafanaReporter::Asciidoctor::Report] current report
|
9
|
+
# @return [::Asciidoctor::Extensions::Processor] self
|
10
|
+
def current_report(report)
|
11
|
+
@report = report
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
# This method is called if a demo report shall be built for the given {Grafana::Panel}.
|
16
|
+
# @param panel [Grafana::Panel] panel object, for which a demo entry shall be created.
|
17
|
+
# @return [String] String containing the entry, or nil if not possible for given panel
|
18
|
+
def build_demo_entry(panel)
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
# Merges the given hashes to a common attribute Hash. It respects the priorities of the hashes and the
|
23
|
+
# object and allows only valid variables to be used.
|
24
|
+
# @param document_hash [Hash] variables from report template level
|
25
|
+
# @param item_hash [Hash] variables from item configuration level, i.e. specific call, which may override document
|
26
|
+
# @return [Hash] containing accepted variable names including values
|
27
|
+
def build_attribute_hash(document_hash, item_hash)
|
28
|
+
result = {}
|
29
|
+
|
30
|
+
result['grafana_report_timestamp'] = document_hash['localdatetime']
|
31
|
+
result.merge!(document_hash.select do |k, _v|
|
32
|
+
k =~ /^var-/ ||
|
33
|
+
k =~ /^(?:from|to)$/ ||
|
34
|
+
k =~ /^grafana_default_(?:from_timezone|to_timezone|timeout)$/
|
35
|
+
end)
|
36
|
+
|
37
|
+
result.merge!(item_hash.select do |k, _v|
|
38
|
+
# TODO: specify accepted options for each processor class individually
|
39
|
+
k =~ /^(?:var-|render-)/ ||
|
40
|
+
k =~ /^(?:timeout|from|to)$/ ||
|
41
|
+
k =~ /filter_columns|format|replace_values_.*|transpose|from_timezone|
|
42
|
+
to_timezone|result_type|query|table_formatter|include_headline|
|
43
|
+
column_divider|row_divider/x
|
44
|
+
end)
|
45
|
+
|
46
|
+
result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|