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