ruby-grafana-reporter 0.2.1 → 0.4.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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +126 -85
  3. data/bin/ruby-grafana-reporter +2 -2
  4. data/lib/VERSION.rb +3 -2
  5. data/lib/grafana/abstract_datasource.rb +146 -0
  6. data/lib/grafana/dashboard.rb +21 -23
  7. data/lib/grafana/errors.rb +18 -3
  8. data/lib/grafana/grafana.rb +64 -66
  9. data/lib/grafana/grafana_alerts_datasource.rb +57 -0
  10. data/lib/grafana/grafana_annotations_datasource.rb +56 -0
  11. data/lib/grafana/grafana_property_datasource.rb +30 -0
  12. data/lib/grafana/graphite_datasource.rb +72 -0
  13. data/lib/grafana/image_rendering_datasource.rb +44 -0
  14. data/lib/grafana/influxdb_datasource.rb +70 -0
  15. data/lib/grafana/panel.rb +9 -3
  16. data/lib/grafana/prometheus_datasource.rb +67 -0
  17. data/lib/grafana/sql_datasource.rb +78 -0
  18. data/lib/grafana/unsupported_datasource.rb +7 -0
  19. data/lib/grafana/variable.rb +1 -1
  20. data/lib/grafana/webrequest.rb +71 -0
  21. data/lib/grafana_reporter/abstract_query.rb +460 -0
  22. data/lib/grafana_reporter/abstract_report.rb +139 -18
  23. data/lib/grafana_reporter/alerts_table_query.rb +39 -0
  24. data/lib/grafana_reporter/annotations_table_query.rb +38 -0
  25. data/lib/grafana_reporter/application/application.rb +34 -286
  26. data/lib/grafana_reporter/application/webservice.rb +50 -15
  27. data/lib/grafana_reporter/asciidoctor/alerts_table_include_processor.rb +91 -0
  28. data/lib/grafana_reporter/asciidoctor/annotations_table_include_processor.rb +90 -0
  29. data/lib/grafana_reporter/asciidoctor/panel_image_block_macro.rb +74 -0
  30. data/lib/grafana_reporter/asciidoctor/panel_image_inline_macro.rb +76 -0
  31. data/lib/grafana_reporter/asciidoctor/panel_property_inline_macro.rb +70 -0
  32. data/lib/grafana_reporter/asciidoctor/panel_query_table_include_processor.rb +95 -0
  33. data/lib/grafana_reporter/asciidoctor/panel_query_value_inline_macro.rb +90 -0
  34. data/lib/grafana_reporter/asciidoctor/processor_mixin.rb +49 -0
  35. data/lib/grafana_reporter/asciidoctor/report.rb +40 -81
  36. data/lib/grafana_reporter/asciidoctor/show_environment_include_processor.rb +46 -0
  37. data/lib/grafana_reporter/asciidoctor/show_help_include_processor.rb +35 -0
  38. data/lib/grafana_reporter/asciidoctor/sql_table_include_processor.rb +90 -0
  39. data/lib/grafana_reporter/asciidoctor/sql_value_inline_macro.rb +86 -0
  40. data/lib/grafana_reporter/asciidoctor/value_as_variable_include_processor.rb +90 -0
  41. data/lib/grafana_reporter/configuration.rb +59 -52
  42. data/lib/grafana_reporter/console_configuration_wizard.rb +311 -0
  43. data/lib/grafana_reporter/demo_report_wizard.rb +105 -0
  44. data/lib/grafana_reporter/erb/report.rb +30 -0
  45. data/lib/grafana_reporter/erb/report_jail.rb +21 -0
  46. data/lib/grafana_reporter/errors.rb +55 -0
  47. data/lib/grafana_reporter/help.rb +443 -0
  48. data/lib/grafana_reporter/logger/{two_way_logger.rb → two_way_delegate_logger.rb} +1 -1
  49. data/lib/grafana_reporter/panel_image_query.rb +25 -0
  50. data/lib/grafana_reporter/panel_property_query.rb +22 -0
  51. data/lib/grafana_reporter/query_value_query.rb +61 -0
  52. data/lib/grafana_reporter/report_webhook.rb +35 -0
  53. data/lib/ruby_grafana_extension.rb +8 -0
  54. data/lib/{ruby-grafana-reporter.rb → ruby_grafana_reporter.rb} +1 -2
  55. metadata +47 -38
  56. data/lib/grafana/abstract_panel_query.rb +0 -22
  57. data/lib/grafana/abstract_query.rb +0 -132
  58. data/lib/grafana/abstract_sql_query.rb +0 -51
  59. data/lib/grafana/panel_image_query.rb +0 -52
  60. data/lib/grafana_reporter/asciidoctor/alerts_table_query.rb +0 -104
  61. data/lib/grafana_reporter/asciidoctor/annotations_table_query.rb +0 -99
  62. data/lib/grafana_reporter/asciidoctor/errors.rb +0 -40
  63. data/lib/grafana_reporter/asciidoctor/extensions/alerts_table_include_processor.rb +0 -92
  64. data/lib/grafana_reporter/asciidoctor/extensions/annotations_table_include_processor.rb +0 -91
  65. data/lib/grafana_reporter/asciidoctor/extensions/panel_image_block_macro.rb +0 -69
  66. data/lib/grafana_reporter/asciidoctor/extensions/panel_image_inline_macro.rb +0 -68
  67. data/lib/grafana_reporter/asciidoctor/extensions/panel_property_inline_macro.rb +0 -61
  68. data/lib/grafana_reporter/asciidoctor/extensions/panel_query_table_include_processor.rb +0 -78
  69. data/lib/grafana_reporter/asciidoctor/extensions/panel_query_value_inline_macro.rb +0 -73
  70. data/lib/grafana_reporter/asciidoctor/extensions/processor_mixin.rb +0 -20
  71. data/lib/grafana_reporter/asciidoctor/extensions/show_environment_include_processor.rb +0 -43
  72. data/lib/grafana_reporter/asciidoctor/extensions/show_help_include_processor.rb +0 -228
  73. data/lib/grafana_reporter/asciidoctor/extensions/sql_table_include_processor.rb +0 -70
  74. data/lib/grafana_reporter/asciidoctor/extensions/sql_value_inline_macro.rb +0 -66
  75. data/lib/grafana_reporter/asciidoctor/extensions/value_as_variable_include_processor.rb +0 -86
  76. data/lib/grafana_reporter/asciidoctor/panel_first_value_query.rb +0 -34
  77. data/lib/grafana_reporter/asciidoctor/panel_image_query.rb +0 -25
  78. data/lib/grafana_reporter/asciidoctor/panel_property_query.rb +0 -44
  79. data/lib/grafana_reporter/asciidoctor/panel_table_query.rb +0 -38
  80. data/lib/grafana_reporter/asciidoctor/query_mixin.rb +0 -294
  81. data/lib/grafana_reporter/asciidoctor/sql_first_value_query.rb +0 -32
  82. data/lib/grafana_reporter/asciidoctor/sql_table_query.rb +0 -34
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grafana
4
- # @abstract
5
- #
6
- # Used as a superclass for all queries, which execute SQL queries against {Grafana}.
7
- #
8
- # @see AbstractQuery
9
- class AbstractSqlQuery < AbstractQuery
10
- attr_reader :sql, :datasource_id
11
-
12
- # @param raw_sql [String] raw sql statement, as it can be sent to a SQL database
13
- # @param datasource_id [Integer] ID of the datasource against which the query is run
14
- def initialize(raw_sql, datasource_id)
15
- super()
16
- @sql = raw_sql
17
- @datasource_id = datasource_id
18
- end
19
-
20
- # @return [String] relative URL, where the request has to be sent to.
21
- def url
22
- '/api/tsdb/query'
23
- end
24
-
25
- # @return [Hash] request, which executes the SQL statement against the specified datasource
26
- def request
27
- {
28
- body: {
29
- from: @from,
30
- to: @to,
31
- queries: [rawSql: @sql, datasourceId: @datasource_id.to_i, format: 'table']
32
- }.to_json,
33
- request: Net::HTTP::Post
34
- }
35
- end
36
-
37
- # Replaces all variables in the SQL statement.
38
- def pre_process(grafana)
39
- raise MissingSqlQueryError if @sql.nil?
40
- unless grafana.datasource_id_exists?(@datasource_id.to_i)
41
- raise DatasourceDoesNotExistError.new('id', @datasource_id)
42
- end
43
-
44
- @sql = replace_variables(@sql, grafana_variables)
45
- # remove comments in query
46
- @sql.gsub!(/--[^\r\n]*(?:[\r\n]+|$)/, ' ')
47
- @sql.gsub!(/\r\n/, ' ')
48
- @sql.gsub!(/\n/, ' ')
49
- end
50
- end
51
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grafana
4
- # Query, which allows to render a {Panel} as a PNG image.
5
- class PanelImageQuery < AbstractPanelQuery
6
- # Returns the URL for rendering the panel. Uses {Panel#render_url} and sets additional url
7
- # parameters according {https://grafana.com/docs/grafana/latest/reference/share_panel Grafana Share Panel}.
8
- #
9
- # @see AbstractQuery#url
10
- # @return [String] string for rendering the panel
11
- def url
12
- @panel.render_url + url_parameters
13
- end
14
-
15
- # Changes the result of the request to be of type +image/png+.
16
- #
17
- # @see AbstractQuery#request
18
- def request
19
- { accept: 'image/png' }
20
- end
21
-
22
- # Adds default variables for querying the image.
23
- #
24
- # @see AbstractQuery#pre_process
25
- def pre_process(_grafana)
26
- @variables['fullscreen'] = Variable.new(true)
27
- @variables['theme'] = Variable.new('light')
28
- @variables['timeout'] = Variable.new(timeout) if timeout
29
- @variables['timeout'] ||= Variable.new(60)
30
- end
31
-
32
- # Checks if the rendering has been performed properly.
33
- # If so, the resulting image is stored in the @result variable, otherwise an error is raised.
34
- #
35
- # @see AbstractQuery#post_process
36
- def post_process
37
- raise ImageCouldNotBeRenderedError, @panel if @result.body.include?('<html')
38
- end
39
-
40
- private
41
-
42
- def url_parameters
43
- url_vars = variables.select { |k, _v| k =~ /^(?:timeout|height|width|theme|fullscreen)/ || k =~ /^var-.+/ }
44
- url_vars['from'] = Variable.new(@from) if @from
45
- url_vars['to'] = Variable.new(@to) if @to
46
- url_params = URI.encode_www_form(url_vars.map { |k, v| [k, v.raw_value.to_s] })
47
- return '' if url_params.empty?
48
-
49
- "&#{url_params}"
50
- end
51
- end
52
- end
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'query_mixin'
4
-
5
- module GrafanaReporter
6
- module Asciidoctor
7
- # This class is used to query alerts from grafana.
8
- class AlertsTableQuery < Grafana::AbstractQuery
9
- include QueryMixin
10
-
11
- # @option opts [Grafana::Dashboard] :dashboard dashboard, if alerts shall be filtered for a dashboard
12
- # @option opts [Grafnaa::Oanel] :panel panel, if alerts shall be filtered for a panel
13
- def initialize(opts = {})
14
- super()
15
-
16
- @dashboard = opts[:dashboard]
17
- @panel = opts[:panel]
18
- @dashboard = @panel.dashboard if @panel
19
-
20
- extract_dashboard_variables(@dashboard) if @dashboard
21
- end
22
-
23
- # @return [String] URL for querying alerts
24
- def url
25
- "/api/alerts#{url_parameters}"
26
- end
27
-
28
- # @return [Hash] empty hash object
29
- def request
30
- {}
31
- end
32
-
33
- # Check if mandatory {Grafana::Variable} +columns+ is specified in variables.
34
- #
35
- # The value of the +columns+ variable has to be a comma separated list of column titles, which
36
- # need to be included in the following list:
37
- # - limit
38
- # - dashboardId
39
- # - panelId
40
- # - query
41
- # - state
42
- # - folderId
43
- # - dashboardQuery
44
- # - dashboardTag
45
- # @return [void]
46
- def pre_process(_grafana)
47
- raise MissingMandatoryAttributeError, 'columns' unless @variables['columns']
48
-
49
- @from = translate_date(@from, @variables['grafana-report-timestamp'], false)
50
- @to = translate_date(@to, @variables['grafana-report-timestamp'], true)
51
- end
52
-
53
- # Filter the query result for the given columns and sets the result in the preformatted SQL
54
- # result stlye.
55
-
56
- # Additionally it applies {QueryMixin#format_columns}, {QueryMixin#replace_values} and
57
- # {QueryMixin#filter_columns}.
58
- # @return [void]
59
- def post_process
60
- # extract data from returned json
61
- result = JSON.parse(@result.body)
62
- content = []
63
- begin
64
- result.each { |item| content << item.fetch_values(*@variables['columns'].raw_value.split(',')) }
65
- rescue KeyError => e
66
- raise MalformedAttributeContentError.new(e.message, 'columns', @variables['columns'])
67
- end
68
-
69
- result = {}
70
- result[:header] = [@variables['columns'].raw_value.split(',')]
71
- result[:content] = content
72
-
73
- result = format_columns(result, @variables['format'])
74
- result = replace_values(result, @variables.select { |k, _v| k =~ /^replace_values_\d+/ })
75
- result = filter_columns(result, @variables['filter_columns'])
76
- if @variables['filter_column']
77
- @report.logger.warn("DEPRECATED: Call of no longer supported function 'filter_column' has been found."\
78
- " Rename to 'filter_columns'")
79
- result = filter_columns(result, @variables['filter_column'])
80
- end
81
-
82
- @result = result[:content].map { |row| "| #{row.map { |item| item.to_s.gsub('|', '\\|') }.join(' | ')}" }
83
- end
84
-
85
- private
86
-
87
- def url_parameters
88
- url_vars = {}
89
- url_vars['dashboardId'] = ::Grafana::Variable.new(@dashboard.id) if @dashboard
90
- url_vars['panelId'] = ::Grafana::Variable.new(@panel.id) if @panel
91
-
92
- url_vars.merge!(variables.select do |k, _v|
93
- k =~ /^(?:limit|dashboardId|panelId|query|state|folderId|dashboardQuery|dashboardTag)/x
94
- end)
95
- url_vars['from'] = ::Grafana::Variable.new(@from) if @from
96
- url_vars['to'] = ::Grafana::Variable.new(@to) if @to
97
- url_params = URI.encode_www_form(url_vars.map { |k, v| [k, v.raw_value.to_s] })
98
- return '' if url_params.empty?
99
-
100
- "?#{url_params}"
101
- end
102
- end
103
- end
104
- end
@@ -1,99 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GrafanaReporter
4
- module Asciidoctor
5
- # This class is used to query annotations from grafana.
6
- class AnnotationsTableQuery < Grafana::AbstractQuery
7
- include QueryMixin
8
-
9
- # @option opts [Grafana::Dashboard] :dashboard dashboard, if annotations shall be filtered for a dashboard
10
- # @option opts [Grafana::Panel] :panel panel, if annotations shall be filtered for a panel
11
- def initialize(opts = {})
12
- super()
13
-
14
- @dashboard = opts[:dashboard]
15
- @panel = opts[:panel]
16
- @dashboard = @panel.dashboard if @panel
17
-
18
- extract_dashboard_variables(@dashboard) if @dashboard
19
- end
20
-
21
- # @return [String] URL for querying annotations
22
- def url
23
- "/api/annotations#{url_parameters}"
24
- end
25
-
26
- # @return [Hash] empty hash object
27
- def request
28
- {}
29
- end
30
-
31
- # Check if mandatory {Grafana::Variable} +columns+ is specified in variables.
32
- #
33
- # The value of the +columns+ variable has to be a comma separated list of column titles, which
34
- # need to be included in the following list:
35
- # - limit
36
- # - alertId
37
- # - userId
38
- # - type
39
- # - tags
40
- # - dashboardId
41
- # - panelId
42
- # @return [void]
43
- def pre_process(_grafana)
44
- raise MissingMandatoryAttributeError, 'columns' unless @variables['columns']
45
-
46
- @from = translate_date(@from, @variables['grafana-report-timestamp'], false)
47
- @to = translate_date(@to, @variables['grafana-report-timestamp'], true)
48
- end
49
-
50
- # Filters the query result for the given columns and sets the result
51
- # in the preformatted SQL result style.
52
- #
53
- # Additionally it applies {QueryMixin#format_columns}, {QueryMixin#replace_values} and
54
- # {QueryMixin#filter_columns}.
55
- # @return [void]
56
- def post_process
57
- # extract data from returned json
58
- result = JSON.parse(@result.body)
59
- content = []
60
- begin
61
- result.each { |item| content << item.fetch_values(*@variables['columns'].raw_value.split(',')) }
62
- rescue KeyError => e
63
- raise MalformedAttributeContentError.new(e.message, 'columns', @variables['columns'])
64
- end
65
-
66
- result = {}
67
- result[:header] = [@variables['columns'].raw_value.split(',')]
68
- result[:content] = content
69
-
70
- result = format_columns(result, @variables['format'])
71
- result = replace_values(result, @variables.select { |k, _v| k =~ /^replace_values_\d+/ })
72
- result = filter_columns(result, @variables['filter_columns'])
73
- if @variables['filter_column']
74
- @report.logger.warn("DEPRECATED: Call of no longer supported function 'filter_column' has been found."\
75
- " Rename to 'filter_columns'")
76
- result = filter_columns(result, @variables['filter_column'])
77
- end
78
-
79
- @result = result[:content].map { |row| "| #{row.map { |item| item.to_s.gsub('|', '\\|') }.join(' | ')}" }
80
- end
81
-
82
- private
83
-
84
- def url_parameters
85
- url_vars = {}
86
- url_vars['dashboardId'] = ::Grafana::Variable.new(@dashboard.id) if @dashboard
87
- url_vars['panelId'] = ::Grafana::Variable.new(@panel.id) if @panel
88
-
89
- url_vars.merge!(variables.select { |k, _v| k =~ /^(?:limit|alertId|dashboardId|panelId|userId|type|tags)/ })
90
- url_vars['from'] = ::Grafana::Variable.new(@from) if @from
91
- url_vars['to'] = ::Grafana::Variable.new(@to) if @to
92
- url_params = URI.encode_www_form(url_vars.map { |k, v| [k, v.raw_value.to_s] })
93
- return '' if url_params.empty?
94
-
95
- "?#{url_params}"
96
- end
97
- end
98
- end
99
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GrafanaReporter
4
- # This module contains all classes, which are necessary to use the grafana
5
- # reporter to be used in conjunction with asciidoctor.
6
- module Asciidoctor
7
- # Thrown, if the value configuration in {QueryMixin#replace_values} is
8
- # invalid.
9
- class MalformedReplaceValuesStatementError < GrafanaReporterError
10
- def initialize(statement)
11
- super("The specified replace_values statement '#{statement}' is invalid. Make sure it contains"\
12
- " exactly one not escaped ':' symbol.")
13
- end
14
- end
15
-
16
- # Thrown, if a configured parameter is malformed.
17
- class MalformedAttributeContentError < GrafanaReporterError
18
- def initialize(message, attribute, content)
19
- super("The content '#{content}' in attribute '#{attribute}' is malformed: #{message}")
20
- end
21
- end
22
-
23
- # Thrown, if a configured time range is not supported by the reporter.
24
- #
25
- # If this happens, most likely the reporter has to implement the new
26
- # time range definition.
27
- class TimeRangeUnknownError < GrafanaReporterError
28
- def initialize(time_range)
29
- super("The specified time range '#{time_range}' is unknown.")
30
- end
31
- end
32
-
33
- # Thrown, if a mandatory attribute is not set.
34
- class MissingMandatoryAttributeError < GrafanaReporterError
35
- def initialize(attribute)
36
- super("Missing mandatory attribute '#{attribute}'.")
37
- end
38
- end
39
- end
40
- end
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'processor_mixin'
4
-
5
- module GrafanaReporter
6
- module Asciidoctor
7
- module Extensions
8
- # Implements the hook
9
- # include::grafana_alerts[<options>]
10
- #
11
- # Returns the results of alerts query as a asciidoctor table.
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
- # +columns+ - see {AlertsTableQuery#pre_process} (*mandatory*)
24
- #
25
- # +instance+ - name of grafana instance, 'default' if not specified
26
- #
27
- # +dashboard+ - uid of grafana dashboard to query for, empty string if no filter is wanted
28
- #
29
- # +panel+ - id of the panel to query for
30
- #
31
- # +from+ - 'from' time for the sql query
32
- #
33
- # +to+ - 'to' time for the sql query
34
- #
35
- # +format+ - see {QueryMixin#format_columns}
36
- #
37
- # +replace_values+ - see {QueryMixin#replace_values}
38
- #
39
- # +filter_columns+ - see {QueryMixin#filter_columns}
40
- class AlertsTableIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
41
- include ProcessorMixin
42
-
43
- # :nodoc:
44
- def handles?(target)
45
- target.start_with? 'grafana_alerts'
46
- end
47
-
48
- # :nodoc:
49
- def process(doc, reader, _target, attrs)
50
- return if @report.cancel
51
-
52
- @report.next_step
53
- instance = attrs['instance'] || doc.attr('grafana_default_instance') || 'default'
54
- dashboard_id = attrs['dashboard'] || doc.attr('grafana_default_dashboard')
55
- panel_id = attrs['panel']
56
- @report.logger.debug("Processing AlertsTableIncludeProcessor (instance: #{instance},"\
57
- " dashboard: #{dashboard_id}, panel: #{panel_id})")
58
-
59
- query = if dashboard_id.to_s.empty?
60
- # no dashboard shall be used, so also the panel will be omitted
61
- AlertsTableQuery.new
62
- elsif panel_id.to_s.empty?
63
- # a dashboard is given, but no panel, so set filter for dashboard only
64
- AlertsTableQuery.new(dashboard: @report.grafana(instance).dashboard(dashboard_id))
65
- else
66
- # dashboard and panel is given, so set filter for panel
67
- AlertsTableQuery.new(panel: @report.grafana(instance).dashboard(dashboard_id).panel(panel_id))
68
- end
69
-
70
- query.merge_hash_variables(doc.attributes, attrs)
71
- selected_attrs = attrs.select do |k, _v|
72
- k =~ /(?:columns|limit|folderId|dashboardId|panelId|dahboardTag|dashboardQuery|state|query)/x
73
- end
74
- query.merge_variables(selected_attrs.each_with_object({}) { |(k,v), h| h[k] = ::Grafana::Variable.new(v) })
75
- @report.logger.debug("from: #{query.from}, to: #{query.to}")
76
-
77
- begin
78
- reader.unshift_lines query.execute(@report.grafana(instance))
79
- rescue GrafanaReporterError => e
80
- @report.logger.error(e.message)
81
- reader.unshift_line "|#{e.message}"
82
- rescue StandardError => e
83
- @report.logger.fatal(e.message)
84
- reader.unshift_line "|#{e.message}"
85
- end
86
-
87
- reader
88
- end
89
- end
90
- end
91
- end
92
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'processor_mixin'
4
-
5
- module GrafanaReporter
6
- module Asciidoctor
7
- module Extensions
8
- # Implements the hook
9
- # include::grafana_annotations[<options>]
10
- #
11
- # Returns the results of alerts query as a asciidoctor table.
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
- # +columns+ - see {AnnotationsTableQuery#pre_process} (*mandatory*)
24
- #
25
- # +instance+ - name of grafana instance, 'default' if not specified
26
- #
27
- # +dashboard+ - uid of grafana dashboard to query for, empty string if no filter is wanted
28
- #
29
- # +panel+ - id of the panel to query for
30
- #
31
- # +from+ - 'from' time for the sql query
32
- #
33
- # +to+ - 'to' time for the sql query
34
- #
35
- # +format+ - see {QueryMixin#format_columns}
36
- #
37
- # +replace_values+ - see {QueryMixin#replace_values}
38
- #
39
- # +filter_columns+ - see {QueryMixin#filter_columns}
40
- class AnnotationsTableIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
41
- include ProcessorMixin
42
-
43
- # :nodoc:
44
- def handles?(target)
45
- target.start_with? 'grafana_annotations'
46
- end
47
-
48
- # :nodoc:
49
- def process(doc, reader, _target, attrs)
50
- return if @report.cancel
51
-
52
- @report.next_step
53
- instance = attrs['instance'] || doc.attr('grafana_default_instance') || 'default'
54
- dashboard_id = attrs['dashboard'] || doc.attr('grafana_default_dashboard')
55
- panel_id = attrs['panel']
56
- @report.logger.debug("Processing AnnotationsTableIncludeProcessor (instance: #{instance})")
57
-
58
- query = if dashboard_id.to_s.empty?
59
- # no dashboard shall be used, so also the panel will be omitted
60
- AnnotationsTableQuery.new
61
- elsif panel_id.to_s.empty?
62
- # a dashboard is given, but no panel, so set filter for dashboard only
63
- AnnotationsTableQuery.new(dashboard: @report.grafana(instance).dashboard(dashboard_id))
64
- else
65
- # dashboard and panel is given, so set filter for panel
66
- AnnotationsTableQuery.new(panel: @report.grafana(instance).dashboard(dashboard_id).panel(panel_id))
67
- end
68
-
69
- query.merge_hash_variables(doc.attributes, attrs)
70
- selected_attrs = attrs.select do |k, _v|
71
- k =~ /(?:columns|limit|alertId|dashboardId|panelId|userId|type|tags)/
72
- end
73
- query.merge_variables(selected_attrs.each_with_object({}) { |(k,v), h| h[k] = ::Grafana::Variable.new(v) })
74
- @report.logger.debug("from: #{query.from}, to: #{query.to}")
75
-
76
- begin
77
- reader.unshift_lines query.execute(@report.grafana(instance))
78
- rescue GrafanaReporterError => e
79
- @report.logger.error(e.message)
80
- reader.unshift_line "|#{e.message}"
81
- rescue StandardError => e
82
- @report.logger.fatal(e.message)
83
- reader.unshift_line "|#{e.message}"
84
- end
85
-
86
- reader
87
- end
88
- end
89
- end
90
- end
91
- end