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,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
# This class is used to build a demo report based on a real grafana instance. Therefore
|
5
|
+
# it checks available grafana dashboards and panels and returns a final template file as
|
6
|
+
# string, which can then be used as a template.
|
7
|
+
class DemoReportWizard
|
8
|
+
# @param query_classes [Array] class objects, for which a demo report shall be created
|
9
|
+
def initialize(query_classes)
|
10
|
+
@query_classes = query_classes
|
11
|
+
end
|
12
|
+
|
13
|
+
# Invokes the build process for the given +grafana+ object. Progress is printed to
|
14
|
+
# STDOUT.
|
15
|
+
# @param grafana [Grafana] grafana instance, for which the demo report shall be built
|
16
|
+
# @return [String] demo template as string
|
17
|
+
def build(grafana)
|
18
|
+
results = {}
|
19
|
+
|
20
|
+
grafana.dashboard_ids.sample(15).each do |dashboard_id|
|
21
|
+
print "Evaluating dashboard '#{dashboard_id}' for building a demo report..."
|
22
|
+
dashboard = grafana.dashboard(dashboard_id)
|
23
|
+
|
24
|
+
results = evaluate_dashboard(dashboard, @query_classes - results.keys).merge(results)
|
25
|
+
|
26
|
+
puts "done - #{(@query_classes - results.keys).length} examples to go"
|
27
|
+
break if (@query_classes - results.keys).empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
if grafana.dashboard_ids.length > 15 && !(@query_classes - results.keys).empty?
|
31
|
+
puts 'Aborting evaluating further dashboards after 15 samples.'
|
32
|
+
end
|
33
|
+
|
34
|
+
unless (@query_classes - results.keys).empty?
|
35
|
+
puts "For #{(@query_classes - results.keys).length} reporter functionalities no appropriate "\
|
36
|
+
'examples could be found in the configured grafana instance.'
|
37
|
+
end
|
38
|
+
|
39
|
+
format_results(default_result(@query_classes - results.keys).merge(results))
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def default_result(query_classes)
|
45
|
+
results = {}
|
46
|
+
|
47
|
+
query_classes.each do |query_class|
|
48
|
+
results[query_class] = "No example found for #{query_class.name} in the dashboards."
|
49
|
+
end
|
50
|
+
|
51
|
+
results
|
52
|
+
end
|
53
|
+
|
54
|
+
def evaluate_dashboard(dashboard, query_classes)
|
55
|
+
results = {}
|
56
|
+
|
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
|
+
query_classes.each do |query_class|
|
65
|
+
unless query_class.public_instance_methods.include?(:build_demo_entry)
|
66
|
+
results[query_class] = "Method 'build_demo_entry' not implemented for #{query_class.name}"
|
67
|
+
next
|
68
|
+
end
|
69
|
+
|
70
|
+
begin
|
71
|
+
result = query_class.new.build_demo_entry(panel)
|
72
|
+
results[query_class] = result if result
|
73
|
+
rescue Grafana::DatasourceDoesNotExistError
|
74
|
+
# properly catch DatasourceDoesNotExist errors here, as they don't lead to a real issue
|
75
|
+
# during demo report creation
|
76
|
+
# This may e.g. happen if a panel asks e.g. for datasource '-- Dashboard --' which is
|
77
|
+
# currently not allowed
|
78
|
+
rescue StandardError => e
|
79
|
+
puts "#{e.message}\n#{e.backtrace.join("\n")}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
results
|
85
|
+
end
|
86
|
+
|
87
|
+
def format_results(raw_results)
|
88
|
+
results = ['= Demo report',
|
89
|
+
"Created by `+ruby-grafana-reporter+` version #{GRAFANA_REPORTER_VERSION.join('.')}",
|
90
|
+
'== Examples']
|
91
|
+
|
92
|
+
raw_results.each do |k, v|
|
93
|
+
results += if v =~ /^[A-Z]/
|
94
|
+
["=== #{k.to_s.gsub(/.*::/, '')}", v.to_s]
|
95
|
+
else
|
96
|
+
["=== #{k.to_s.gsub(/.*::/, '')}", 'Sample call:', " #{v.gsub(/\n/, "\n ")}",
|
97
|
+
'Result:', v.to_s]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
results.join("\n\n")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
module ERB
|
5
|
+
# This class builds a demo report for ERB templates
|
6
|
+
class DemoReportBuilder
|
7
|
+
# This method is called if a demo report shall be built for the given {Grafana::Panel}.
|
8
|
+
# @param panel [Grafana::Panel] panel object, for which a demo entry shall be created.
|
9
|
+
# @return [String] String containing the entry, or nil if not possible for given panel
|
10
|
+
def build_demo_entry(panel)
|
11
|
+
return nil unless panel
|
12
|
+
return nil unless panel.model['type'].include?('table')
|
13
|
+
|
14
|
+
ref_id = nil
|
15
|
+
panel.model['targets'].each do |item|
|
16
|
+
if !item['hide'] && !panel.query(item['refId']).to_s.empty?
|
17
|
+
ref_id = item['refId']
|
18
|
+
break
|
19
|
+
end
|
20
|
+
end
|
21
|
+
return nil unless ref_id
|
22
|
+
|
23
|
+
<<~DEMO_ERB_TEMPLATE
|
24
|
+
<%
|
25
|
+
dashboard = '#{panel.dashboard.id}'
|
26
|
+
instance = 'default'
|
27
|
+
# load the panel object from grafana instance
|
28
|
+
panel = @report.grafana(instance).dashboard(dashboard).panel(#{panel.id})
|
29
|
+
# build a complete attributes hash, including the variables set for this report call
|
30
|
+
# e.g. including command line parameters etc.
|
31
|
+
attrs = @attributes.merge({ 'result_type' => 'panel_table', 'query' => '#{ref_id}' })
|
32
|
+
query = QueryValueQuery.new(panel, variables: attrs)
|
33
|
+
%>
|
34
|
+
|
35
|
+
This is a test table for panel <%= panel.id %>:
|
36
|
+
|
37
|
+
<%= query.execute %>
|
38
|
+
|
39
|
+
For detailed API documentation you may start with:
|
40
|
+
1) the AbstractReport (https://rubydoc.info/gems/ruby-grafana-reporter/GrafanaReporter/AbstractReport), or
|
41
|
+
2) subclasses of the AbstractQuery (https://rubydoc.info/gems/ruby-grafana-reporter/GrafanaReporter/AbstractQuery)
|
42
|
+
DEMO_ERB_TEMPLATE
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module GrafanaReporter
|
6
|
+
module ERB
|
7
|
+
# Implementation of a specific {AbstractReport}. It is used to
|
8
|
+
# build reports specifically for erb templates.
|
9
|
+
class Report < ::GrafanaReporter::AbstractReport
|
10
|
+
# Starts to create an asciidoctor report. It utilizes all extensions in the {GrafanaReporter::Asciidoctor}
|
11
|
+
# namespace to realize the conversion.
|
12
|
+
# @see AbstractReport#build
|
13
|
+
def build
|
14
|
+
attrs = @config.default_document_attributes.merge(@custom_attributes).merge({ 'grafana_report_timestamp' => ::Grafana::Variable.new(Time.now.to_s) })
|
15
|
+
logger.debug("Document attributes: #{attrs}")
|
16
|
+
|
17
|
+
File.write(path, ::ERB.new(File.read(@template)).result(ReportJail.new(self, attrs).bind))
|
18
|
+
end
|
19
|
+
|
20
|
+
# @see AbstractReport#default_template_extension
|
21
|
+
def self.default_template_extension
|
22
|
+
'erb'
|
23
|
+
end
|
24
|
+
|
25
|
+
# @see AbstractReport#default_result_extension
|
26
|
+
def self.default_result_extension
|
27
|
+
'txt'
|
28
|
+
end
|
29
|
+
|
30
|
+
# @see AbstractReport#demo_report_classes
|
31
|
+
def self.demo_report_classes
|
32
|
+
[DemoReportBuilder]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
module ERB
|
5
|
+
# An instance of this class is used as binding for the ERB execution, i.e.
|
6
|
+
# this class contains everything known within the ERB template
|
7
|
+
class ReportJail
|
8
|
+
attr_reader :report, :attributes
|
9
|
+
|
10
|
+
def initialize(report, attributes)
|
11
|
+
@report = report
|
12
|
+
@attributes = attributes
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return binding to this object
|
16
|
+
def bind
|
17
|
+
binding
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -8,6 +8,30 @@ module GrafanaReporter
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
# Raised if a datasource shall be queried, which is not (yet) supported by the reporter
|
12
|
+
class DatasourceNotSupportedError < GrafanaReporterError
|
13
|
+
def initialize(datasource, query)
|
14
|
+
super("The datasource '#{datasource.name}' is of type '#{datasource.type}' which is currently "\
|
15
|
+
"not supported for the query type '#{query}'.")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Raised if some unhandled exception is raised during a datasource request execution.
|
20
|
+
class DatasourceRequestInternalError < GrafanaReporterError
|
21
|
+
def initialize(datasource, message)
|
22
|
+
super("The datasource request to '#{datasource.name}' (#{datasource.class}) failed with "\
|
23
|
+
"an internal error: #{message}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Raised if the return value of a datasource request does not match the expected return hash.
|
28
|
+
class DatasourceRequestInvalidReturnValueError < GrafanaReporterError
|
29
|
+
def initialize(datasource, message)
|
30
|
+
super("The datasource request to '#{datasource.name}' (#{datasource.class})"\
|
31
|
+
"returned an invalid value: '#{message}'")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
11
35
|
# Thrown, if the requested grafana instance does not have the mandatory 'host'
|
12
36
|
# setting configured.
|
13
37
|
class GrafanaInstanceWithoutHostError < GrafanaReporterError
|
@@ -45,4 +69,37 @@ module GrafanaReporter
|
|
45
69
|
"but was '#{currently}'.")
|
46
70
|
end
|
47
71
|
end
|
72
|
+
|
73
|
+
# Thrown, if the value configuration in {AbstractQuery#replace_values} is
|
74
|
+
# invalid.
|
75
|
+
class MalformedReplaceValuesStatementError < GrafanaReporterError
|
76
|
+
def initialize(statement)
|
77
|
+
super("The specified replace_values statement '#{statement}' is invalid. Make sure it contains"\
|
78
|
+
" exactly one not escaped ':' symbol.")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Thrown, if a configured parameter is malformed.
|
83
|
+
class MalformedAttributeContentError < GrafanaReporterError
|
84
|
+
def initialize(message, attribute, content)
|
85
|
+
super("The content '#{content}' in attribute '#{attribute}' is malformed: #{message}")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Thrown, if a configured time range is not supported by the reporter.
|
90
|
+
#
|
91
|
+
# If this happens, most likely the reporter has to implement the new
|
92
|
+
# time range definition.
|
93
|
+
class TimeRangeUnknownError < GrafanaReporterError
|
94
|
+
def initialize(time_range)
|
95
|
+
super("The specified time range '#{time_range}' is unknown.")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Thrown, if a mandatory attribute is not set.
|
100
|
+
class MissingMandatoryAttributeError < GrafanaReporterError
|
101
|
+
def initialize(attribute)
|
102
|
+
super("Missing mandatory attribute '#{attribute}'.")
|
103
|
+
end
|
104
|
+
end
|
48
105
|
end
|
@@ -25,7 +25,7 @@ module GrafanaReporter
|
|
25
25
|
end
|
26
26
|
|
27
27
|
# Sets the severity level of the additional logger to the given severity.
|
28
|
-
# @param severity one of
|
28
|
+
# @param severity one of Logger::Severity
|
29
29
|
def level=(severity)
|
30
30
|
@additional_logger.level = severity
|
31
31
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
# This class is used to create an image out of a {Grafana::Panel}.
|
5
|
+
class PanelImageQuery < AbstractQuery
|
6
|
+
# Sets the proper render variables.
|
7
|
+
def pre_process
|
8
|
+
# TODO: ensure that in case of timezones are specified, that they are also forwarded to the image renderer
|
9
|
+
# rename "render-" variables
|
10
|
+
@variables = @variables.each_with_object({}) { |(k, v), h| h[k.gsub(/^render-/, '')] = v }
|
11
|
+
@datasource = Grafana::ImageRenderingDatasource.new(nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the body of the http query, which contains the raw image.
|
15
|
+
def post_process
|
16
|
+
@result = @result[:content].first
|
17
|
+
raise ::Grafana::ImageCouldNotBeRenderedError, @panel if @result.include?('<html')
|
18
|
+
end
|
19
|
+
|
20
|
+
# @see AbstractQuery#raw_query
|
21
|
+
def raw_query
|
22
|
+
{ panel: @panel }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
# This class is used to query properties from a {Grafana::Panel}, such as +description+,
|
5
|
+
# +title+ etc.
|
6
|
+
class PanelPropertyQuery < AbstractQuery
|
7
|
+
# @see Grafana::AbstractQuery#pre_process
|
8
|
+
def pre_process
|
9
|
+
@datasource = Grafana::GrafanaPropertyDatasource.new(nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @see Grafana::AbstractQuery#post_process
|
13
|
+
def post_process
|
14
|
+
@result = @result[:content].first
|
15
|
+
end
|
16
|
+
|
17
|
+
# @see Grafana::AbstractQuery#raw_query
|
18
|
+
def raw_query
|
19
|
+
@raw_query.merge({ panel: @panel })
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
# This class provides a general query implementation for any kind of single value and table queries.
|
5
|
+
class QueryValueQuery < AbstractQuery
|
6
|
+
# @see Grafana::AbstractQuery#pre_process
|
7
|
+
def pre_process
|
8
|
+
@datasource = @panel.datasource if @panel
|
9
|
+
|
10
|
+
@variables['result_type'] ||= Variable.new('')
|
11
|
+
end
|
12
|
+
|
13
|
+
# Executes {AbstractQuery#format_columns}, {AbstractQuery#replace_values} and
|
14
|
+
# {AbstractQuery#filter_columns} on the query results.
|
15
|
+
#
|
16
|
+
# Finally the results are formatted as a asciidoctor table.
|
17
|
+
# @see Grafana::AbstractQuery#post_process
|
18
|
+
def post_process
|
19
|
+
modify_results
|
20
|
+
|
21
|
+
case @variables['result_type'].raw_value
|
22
|
+
when /(?:panel_table|sql_table)/
|
23
|
+
@result = format_table_output(@result, row_divider: @variables['row_divider'], column_divider: @variables['column_divider'], table_formatter: @variables['table_formatter'], include_headline: @variables['include_headline'])
|
24
|
+
|
25
|
+
when /(?:panel_value|sql_value)/
|
26
|
+
tmp = @result[:content] || []
|
27
|
+
@result = tmp.flatten.first
|
28
|
+
|
29
|
+
else
|
30
|
+
raise StandardError, "Unsupported 'result_type' received: '#{@variables['result_type'].raw_value}'"
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# @see Grafana::AbstractQuery#raw_query
|
36
|
+
def raw_query
|
37
|
+
return @raw_query if @raw_query
|
38
|
+
|
39
|
+
case @variables['result_type'].raw_value
|
40
|
+
when /(?:panel_table|panel_value)/
|
41
|
+
@variables['query'] ? @panel.query(@variables['query'].raw_value) : @panel.query(nil)
|
42
|
+
|
43
|
+
when /(?:sql_table|sql_value)/
|
44
|
+
nil
|
45
|
+
|
46
|
+
else
|
47
|
+
raise StandardError, "Unsupported 'result_type' received: '#{@variables['result_type'].raw_value}'"
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def modify_results
|
55
|
+
@result = format_columns(@result, @variables['format'])
|
56
|
+
@result = replace_values(@result, @variables.select { |k, _v| k =~ /^replace_values_\d+/ })
|
57
|
+
@result = filter_columns(@result, @variables['filter_columns'])
|
58
|
+
@result = transpose(@result, @variables['transpose'])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GrafanaReporter
|
4
|
+
# This class provides a default webhook implementation for report events. It sends out
|
5
|
+
# a webrequest to the configured +callback_url+ with all necessary information about the
|
6
|
+
# event and the report.
|
7
|
+
class ReportWebhook
|
8
|
+
def initialize(callback_url)
|
9
|
+
@callback_url = callback_url
|
10
|
+
end
|
11
|
+
|
12
|
+
# Implements the call of the configured webhook.
|
13
|
+
# Provides the following report information in JSON format:
|
14
|
+
#
|
15
|
+
# :object_id - id of the current report
|
16
|
+
# :path - file path to the report
|
17
|
+
# :status - report status as string, e.g. `cancelled`, `finished` or `in progress`
|
18
|
+
# :execution_time - execution time in seconds of the report
|
19
|
+
# :template - name of the used template
|
20
|
+
# :start_time - time when the report creation started
|
21
|
+
# :end_time - time when the report creation ended
|
22
|
+
# :event - event, which has happened, e.g. `on-before-create`
|
23
|
+
#
|
24
|
+
# Please note that this callback is a non-blocking event, i.e. the report
|
25
|
+
# generation is proceeding, no matter if the callback is successfull and
|
26
|
+
# no matter how long the execution of the callback does take.
|
27
|
+
def callback(event, report)
|
28
|
+
# build report information as JSON
|
29
|
+
data = { object_id: report.object_id, path: report.path, status: report.status,
|
30
|
+
execution_time: report.execution_time, template: report.template,
|
31
|
+
start_time: report.start_time, end_time: report.end_time, event: event }
|
32
|
+
|
33
|
+
request = { body: JSON.generate(data), accept: nil, content_type: nil }
|
34
|
+
res = ::Grafana::WebRequest.new(@callback_url, request).execute
|
35
|
+
|
36
|
+
"#{res} - Body: #{res.body}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|