ruby-grafana-reporter 0.4.0 → 0.4.1

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +185 -180
  3. data/lib/VERSION.rb +2 -2
  4. data/lib/grafana/abstract_datasource.rb +32 -12
  5. data/lib/grafana/errors.rb +1 -9
  6. data/lib/grafana/grafana.rb +3 -7
  7. data/lib/grafana/graphite_datasource.rb +6 -0
  8. data/lib/grafana/prometheus_datasource.rb +6 -0
  9. data/lib/grafana/sql_datasource.rb +6 -0
  10. data/lib/grafana/unsupported_datasource.rb +7 -0
  11. data/lib/grafana/webrequest.rb +1 -1
  12. data/lib/grafana_reporter/abstract_query.rb +20 -62
  13. data/lib/grafana_reporter/abstract_report.rb +66 -15
  14. data/lib/grafana_reporter/alerts_table_query.rb +5 -5
  15. data/lib/grafana_reporter/annotations_table_query.rb +4 -4
  16. data/lib/grafana_reporter/application/application.rb +10 -16
  17. data/lib/grafana_reporter/application/webservice.rb +34 -10
  18. data/lib/grafana_reporter/asciidoctor/alerts_table_include_processor.rb +5 -5
  19. data/lib/grafana_reporter/asciidoctor/annotations_table_include_processor.rb +5 -5
  20. data/lib/grafana_reporter/asciidoctor/panel_image_block_macro.rb +2 -1
  21. data/lib/grafana_reporter/asciidoctor/panel_image_inline_macro.rb +7 -5
  22. data/lib/grafana_reporter/asciidoctor/panel_property_inline_macro.rb +2 -1
  23. data/lib/grafana_reporter/asciidoctor/panel_query_table_include_processor.rb +6 -5
  24. data/lib/grafana_reporter/asciidoctor/panel_query_value_inline_macro.rb +5 -5
  25. data/lib/grafana_reporter/asciidoctor/processor_mixin.rb +43 -2
  26. data/lib/grafana_reporter/asciidoctor/report.rb +17 -41
  27. data/lib/grafana_reporter/asciidoctor/sql_table_include_processor.rb +4 -4
  28. data/lib/grafana_reporter/asciidoctor/sql_value_inline_macro.rb +4 -4
  29. data/lib/grafana_reporter/configuration.rb +14 -2
  30. data/lib/grafana_reporter/console_configuration_wizard.rb +2 -10
  31. data/lib/grafana_reporter/demo_report_wizard.rb +16 -2
  32. data/lib/grafana_reporter/erb/report.rb +43 -0
  33. data/lib/grafana_reporter/errors.rb +9 -1
  34. data/lib/grafana_reporter/help.rb +1 -5
  35. data/lib/grafana_reporter/logger/{two_way_logger.rb → two_way_delegate_logger.rb} +0 -0
  36. data/lib/grafana_reporter/panel_image_query.rb +2 -2
  37. data/lib/grafana_reporter/query_value_query.rb +4 -4
  38. data/lib/ruby_grafana_extension.rb +8 -0
  39. data/lib/ruby_grafana_reporter.rb +13 -0
  40. metadata +9 -6
@@ -57,21 +57,13 @@ module Grafana
57
57
  end
58
58
  end
59
59
 
60
- # Raised if no SQL query is specified in a {AbstractSqlQuery} object.
60
+ # Raised if no SQL query is specified.
61
61
  class MissingSqlQueryError < GrafanaError
62
62
  def initialize
63
63
  super('No SQL statement has been specified.')
64
64
  end
65
65
  end
66
66
 
67
- # Raised if a datasource shall be queried, which is not (yet) supported by the reporter
68
- class DatasourceTypeNotSupportedError < GrafanaError
69
- def initialize(name, type)
70
- super("The configured datasource with name '#{name}' is of type '#{type}', which is currently "\
71
- 'not supported by ruby-grafana-reporter. It will only be usable in panel image queries.')
72
- end
73
- end
74
-
75
67
  # Raised if a datasource shall be queried, which is not (yet) supported by the reporter
76
68
  class InvalidDatasourceQueryProvidedError < GrafanaError
77
69
  def initialize(query)
@@ -9,6 +9,8 @@
9
9
  module Grafana
10
10
  # Main class for handling the interaction with one specific Grafana instance.
11
11
  class Grafana
12
+ attr_reader :logger
13
+
12
14
  # @param base_uri [String] full URI pointing to the specific grafana instance without
13
15
  # trailing slash, e.g. +https://localhost:3000+.
14
16
  # @param key [String] API key for the grafana instance, if required
@@ -116,13 +118,7 @@ module Grafana
116
118
 
117
119
  json = JSON.parse(settings.body)
118
120
  json['datasources'].select { |_k, v| v['id'].to_i.positive? }.each do |ds_name, ds_value|
119
- begin
120
- @datasources[ds_name] = AbstractDatasource.build_instance(ds_value)
121
- rescue DatasourceTypeNotSupportedError => e
122
- # an unsupported datasource type has been configured in the dashboard
123
- # - no worries here
124
- @logger.warn(e.message)
125
- end
121
+ @datasources[ds_name] = AbstractDatasource.build_instance(ds_value)
126
122
  end
127
123
  @datasources['default'] = @datasources[json['defaultDatasource']]
128
124
  end
@@ -3,6 +3,12 @@
3
3
  module Grafana
4
4
  # Implements the interface to graphite datasources.
5
5
  class GraphiteDatasource < AbstractDatasource
6
+ # @see AbstractDatasource#handles?
7
+ def self.handles?(model)
8
+ tmp = new(model)
9
+ tmp.type == 'graphite'
10
+ end
11
+
6
12
  # +:raw_query+ needs to contain a Graphite query as String
7
13
  # @see AbstractDatasource#request
8
14
  def request(query_description)
@@ -3,6 +3,12 @@
3
3
  module Grafana
4
4
  # Implements the interface to Prometheus datasources.
5
5
  class PrometheusDatasource < AbstractDatasource
6
+ # @see AbstractDatasource#handles?
7
+ def self.handles?(model)
8
+ tmp = new(model)
9
+ tmp.type == 'prometheus'
10
+ end
11
+
6
12
  # +:raw_query+ needs to contain a Prometheus query as String
7
13
  # @see AbstractDatasource#request
8
14
  def request(query_description)
@@ -3,6 +3,12 @@
3
3
  module Grafana
4
4
  # Implements the interface to all SQL based datasources (tested with PostgreSQL and MariaDB/MySQL).
5
5
  class SqlDatasource < AbstractDatasource
6
+ # @see AbstractDatasource#handles?
7
+ def self.handles?(model)
8
+ tmp = new(model)
9
+ tmp.category == 'sql'
10
+ end
11
+
6
12
  # +:raw_query+ needs to contain a SQL query as String in the respective database dialect
7
13
  # @see AbstractDatasource#request
8
14
  def request(query_description)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grafana
4
+ # Dummy class, which is used, if a datasource is currently unsupported.
5
+ class UnsupportedDatasource < AbstractDatasource
6
+ end
7
+ end
@@ -59,7 +59,7 @@ module Grafana
59
59
  def configure_ssl
60
60
  @http.use_ssl = true
61
61
  @http.verify_mode = OpenSSL::SSL::VERIFY_PEER
62
- if self.class.ssl_cert && !File.exist?(self.class.ssl_cert)
62
+ if self.class.ssl_cert && !File.file?(self.class.ssl_cert)
63
63
  @logger.warn('SSL certificate file does not exist.')
64
64
  elsif self.class.ssl_cert
65
65
  @http.cert_store = OpenSSL::X509::Store.new
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrafanaReporter
4
- # @abstract Override {#pre_process}, {#post_process} and {#self.build_demo_entry} in subclass.
4
+ # @abstract Override {#pre_process} and {#post_process} in subclass.
5
5
  #
6
6
  # Superclass containing everything for all queries towards grafana.
7
7
  class AbstractQuery
@@ -9,7 +9,7 @@ module GrafanaReporter
9
9
  attr_writer :raw_query
10
10
  attr_reader :variables, :result, :panel
11
11
 
12
- # @param grafana_or_panel [Object] {Grafana} or {Panel} object for which the query is executed
12
+ # @param grafana_or_panel [Object] {Grafana::Grafana} or {Grafana::Panel} object for which the query is executed
13
13
  def initialize(grafana_or_panel)
14
14
  if grafana_or_panel.is_a?(Grafana::Panel)
15
15
  @panel = grafana_or_panel
@@ -24,7 +24,7 @@ module GrafanaReporter
24
24
  #
25
25
  # Runs the whole process to receive values properly from this query:
26
26
  # - calls {#pre_process}
27
- # - executes this query against the {Grafana} instance
27
+ # - executes this query against the {Grafana::AbstractDatasource} implementation instance
28
28
  # - calls {#post_process}
29
29
  #
30
30
  # @return [Hash] result of the query in standardized format
@@ -32,25 +32,14 @@ module GrafanaReporter
32
32
  return @result unless @result.nil?
33
33
 
34
34
  pre_process
35
+ raise DatasourceNotSupportedError.new(@datasource, self) if @datasource.is_a?(Grafana::UnsupportedDatasource)
36
+
35
37
  @result = @datasource.request(from: @from, to: @to, raw_query: raw_query, variables: grafana_variables,
36
38
  prepared_request: @grafana.prepare_request, timeout: timeout)
37
39
  post_process
38
40
  @result
39
41
  end
40
42
 
41
- # Sets default configurations from the given {Dashboard} and store them as settings in the query.
42
- #
43
- # Following data is extracted:
44
- # - +from+, by {Dashboard#from_time}
45
- # - +to+, by {Dashboard#to_time}
46
- # - and all variables as {Variable}, prefixed with +var-+, as grafana also does it
47
- # @param dashboard [Dashboard] dashboard from which the defaults are captured
48
- def set_defaults_from_dashboard(dashboard)
49
- @from = dashboard.from_time
50
- @to = dashboard.to_time
51
- dashboard.variables.each { |item| merge_variables({ "var-#{item.name}": item }) }
52
- end
53
-
54
43
  # Overwrite this function to extract a proper raw query value from this object.
55
44
  #
56
45
  # If the property +@raw_query+ is not set manually by the calling object, this
@@ -77,35 +66,22 @@ module GrafanaReporter
77
66
  raise NotImplementedError
78
67
  end
79
68
 
80
- # Merges the given hashes to the current object by using the {#merge_variables} method.
81
- # It respects the priorities of the hashes and the object and allows only valid variables to be passed.
82
- # @param document_hash [Hash] variables from report template level
83
- # @param item_hash [Hash] variables from item configuration level, i.e. specific call, which may override document
84
- # @return [void]
85
- # TODO: rename method
86
- def merge_hash_variables(document_hash, item_hash)
87
- sel_doc_items = document_hash.select do |k, _v|
88
- k =~ /^var-/ || k == 'grafana-report-timestamp' || k =~ /grafana_default_(?:from|to)_timezone/
89
- end
90
- merge_variables(sel_doc_items.each_with_object({}) { |(k, v), h| h[k] = ::Grafana::Variable.new(v) })
91
-
92
- sel_items = item_hash.select do |k, _v|
93
- # TODO: specify accepted options in each class or check if simply all can be allowed with prefix +var-+
94
- k =~ /^var-/ || k =~ /^render-/ || k =~ /filter_columns|format|replace_values_.*|transpose|column_divider|
95
- row_divider|from_timezone|to_timezone|result_type|query/x
96
- end
97
- merge_variables(sel_items.each_with_object({}) { |(k, v), h| h[k] = ::Grafana::Variable.new(v) })
69
+ # Used to specify variables to be used for this query. This method ensures, that only the values of the
70
+ # {Grafana::Variable} stored in the +variables+ Array are overwritten.
71
+ # @param name [String] name of the variable to set
72
+ # @param variable [Grafana::Variable] variable from which the {Grafana::Variable#raw_value} will be assigned to the query variables
73
+ def assign_variable(name, variable)
74
+ raise GrafanaReporterError, "Provided variable is not of type Grafana::Variable (name: '#{name}', value: '#{value}')" unless variable.is_a?(Grafana::Variable)
98
75
 
99
- @timeout = item_hash['timeout'] || document_hash['grafana-default-timeout'] || @timeout
100
- @from = item_hash['from'] || document_hash['from'] || @from
101
- @to = item_hash['to'] || document_hash['to'] || @to
76
+ @variables[name] ||= variable
77
+ @variables[name].raw_value = variable.raw_value
102
78
  end
103
79
 
104
80
  # Transposes the given result.
105
81
  #
106
82
  # NOTE: Only the +:content+ of the given result hash is transposed. The +:header+ is ignored.
107
83
  #
108
- # @param result [Hash] preformatted sql hash, (see {Grafana::AbstractDatasource#preformat_response})
84
+ # @param result [Hash] preformatted sql hash, (see {Grafana::AbstractDatasource#request})
109
85
  # @param transpose_variable [Grafana::Variable] true, if the result hash shall be transposed
110
86
  # @return [Hash] transposed query result
111
87
  def transpose(result, transpose_variable)
@@ -121,7 +97,7 @@ module GrafanaReporter
121
97
  #
122
98
  # Multiple columns may be filtered. Therefore the column titles have to be named in the
123
99
  # {Grafana::Variable#raw_value} and have to be separated by +,+ (comma).
124
- # @param result [Hash] preformatted sql hash, (see {Grafana::AbstractDatasource#preformat_response})
100
+ # @param result [Hash] preformatted sql hash, (see {Grafana::AbstractDatasource#request})
125
101
  # @param filter_columns_variable [Grafana::Variable] column names, which shall be removed in the query result
126
102
  # @return [Hash] filtered query result
127
103
  def filter_columns(result, filter_columns_variable)
@@ -145,10 +121,9 @@ module GrafanaReporter
145
121
  # The formatting will be applied separately for every column. Therefore the column formats have to be named
146
122
  # in the {Grafana::Variable#raw_value} and have to be separated by +,+ (comma). If no value is specified for
147
123
  # a column, no change will happen.
148
- # @param result [Hash] preformatted sql hash, (see {Grafana::AbstractDatasource#preformat_response})
124
+ # @param result [Hash] preformatted sql hash, (see {Grafana::AbstractDatasource#request})
149
125
  # @param formats [Grafana::Variable] formats, which shall be applied to the columns in the query result
150
126
  # @return [Hash] formatted query result
151
- # TODO: make sure that caught errors are also visible in logger
152
127
  def format_columns(result, formats)
153
128
  return result unless formats
154
129
 
@@ -162,6 +137,7 @@ module GrafanaReporter
162
137
  begin
163
138
  row[i] = format % row[i] if row[i]
164
139
  rescue StandardError => e
140
+ @grafana.logger.error(e.message)
165
141
  row[i] = e.message
166
142
  end
167
143
  end
@@ -195,7 +171,7 @@ module GrafanaReporter
195
171
  # '42 is the answer'. Important to know: the regular expressions always have to start
196
172
  # with +^+ and end with +$+, i.e. the expression itself always has to match
197
173
  # the whole content in one field.
198
- # @param result [Hash] preformatted query result (see {Grafana::AbstractDatasource#preformat_response}.
174
+ # @param result [Hash] preformatted query result (see {Grafana::AbstractDatasource#request}.
199
175
  # @param configs [Array<Grafana::Variable>] one variable for replacing values in one column
200
176
  # @return [Hash] query result with replaced values
201
177
  # TODO: make sure that caught errors are also visible in logger
@@ -280,7 +256,8 @@ module GrafanaReporter
280
256
  # @param timezone [Grafana::Variable] timezone to use, if not system timezone
281
257
  # @return [String] translated date as timestamp string
282
258
  def translate_date(orig_date, report_time, is_to_time, timezone = nil)
283
- report_time ||= Variable.new(Time.now.to_s)
259
+ # TODO: add test case for creation of variable, if not given, maybe also print a warning
260
+ report_time ||= ::Grafana::Variable.new(Time.now.to_s)
284
261
  return (DateTime.parse(report_time.raw_value).to_time.to_i * 1000).to_s unless orig_date
285
262
  return orig_date if orig_date =~ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/
286
263
  return orig_date if orig_date =~ /^\d+$/
@@ -378,24 +355,5 @@ module GrafanaReporter
378
355
 
379
356
  date
380
357
  end
381
-
382
- # Merges the given Hash with the stored variables.
383
- #
384
- # Can be used to easily set many values at once in the local variables hash.
385
- #
386
- # Please note, that the values of the Hash need to be of type {Variable}.
387
- #
388
- # @param hash [Hash<String,Variable>] Hash containing variable name as key and {Variable} as value
389
- # @return [AbstractQuery] this object
390
- # TODO: test if this method can be removed, or make it private at least
391
- def merge_variables(hash)
392
- hash.each do |k, v|
393
- if @variables[k.to_s].nil?
394
- @variables[k.to_s] = v
395
- else
396
- @variables[k.to_s].raw_value = v.raw_value
397
- end
398
- end
399
- end
400
358
  end
401
359
  end
@@ -35,21 +35,13 @@ module GrafanaReporter
35
35
  attr_reader :done
36
36
 
37
37
  # @param config [Configuration] configuration object
38
- # @param template [String] path to the template to be used
39
- # @param destination_file_or_path [String or File] path to the destination report or file object to use
40
- # @param custom_attributes [Hash] custom attributes, which shall be merged with priority over the configuration
41
- def initialize(config, template, destination_file_or_path = nil, custom_attributes = {})
38
+ def initialize(config)
42
39
  @config = config
43
40
  @logger = Logger::TwoWayDelegateLogger.new
44
41
  @logger.additional_logger = @config.logger
45
- @done = false
46
- @template = template
47
- @destination_file_or_path = destination_file_or_path
48
- @custom_attributes = custom_attributes
49
- @start_time = nil
50
- @end_time = nil
51
- @cancel = false
52
- raise MissingTemplateError, @template.to_s unless File.exist?(@template.to_s)
42
+ @grafana_instances = {}
43
+
44
+ init_before_create
53
45
  end
54
46
 
55
47
  # Registers a new event listener object.
@@ -66,6 +58,17 @@ module GrafanaReporter
66
58
  @@event_listeners.default = []
67
59
  end
68
60
 
61
+ # @param instance [String] requested grafana instance
62
+ # @return [Grafana::Grafana] the requested grafana instance.
63
+ def grafana(instance)
64
+ unless @grafana_instances[instance]
65
+ @grafana_instances[instance] = ::Grafana::Grafana.new(@config.grafana_host(instance),
66
+ @config.grafana_api_key(instance),
67
+ logger: @logger)
68
+ end
69
+ @grafana_instances[instance]
70
+ end
71
+
69
72
  # Call to request cancelling the report generation.
70
73
  # @return [void]
71
74
  def cancel!
@@ -122,25 +125,73 @@ module GrafanaReporter
122
125
  end
123
126
 
124
127
  # Is being called to start the report generation.
128
+ # @param template [String] path to the template to be used, trailing +.adoc+ extension may be omitted
129
+ # @param destination_file_or_path [String or File] path to the destination report or file object to use
130
+ # @param custom_attributes [Hash] custom attributes, which shall be merged with priority over the configuration
125
131
  # @return [void]
126
- def create_report
132
+ def create_report(template, destination_file_or_path = nil, custom_attributes = {})
133
+ init_before_create
134
+ @template = template
135
+ @destination_file_or_path = destination_file_or_path
136
+ @custom_attributes = custom_attributes
137
+
138
+ # automatically add extension, if a file with adoc extension exists
139
+ @template = "#{@template}.adoc" if File.file?("#{@template}.adoc") && !File.file?(@template.to_s)
140
+ raise MissingTemplateError, @template.to_s unless File.file?(@template.to_s)
141
+
127
142
  notify(:on_before_create)
128
143
  @start_time = Time.new
129
144
  logger.info("Report started at #{@start_time}")
130
145
  end
131
146
 
132
- # @abstract
147
+ # Used to calculate the progress of a report. By default expects +@total_steps+ to contain the total
148
+ # number of steps, which will be processed with each call of {#next_step}.
133
149
  # @return [Integer] number between 0 and 100, representing the current progress of the report creation.
134
150
  def progress
151
+ return @current_pos.to_i if @total_steps.to_i.zero?
152
+
153
+ @current_pos.to_f / @total_steps
154
+ end
155
+
156
+ # Increments the progress.
157
+ # @return [Integer] number of the current progress position.
158
+ def next_step
159
+ @current_pos += 1
160
+ @current_pos
161
+ end
162
+
163
+ # @abstract
164
+ # Provided class objects need to implement a method +build_demo_entry(panel)+.
165
+ # @return [Array<Class>] array of class objects, which shall be included in a demo report
166
+ def self.demo_report_classes
135
167
  raise NotImplementedError
136
168
  end
137
169
 
138
170
  private
139
171
 
172
+ # Called, if the report generation has died with an error.
173
+ # @param error [StandardError] occured error
174
+ # @return [void]
175
+ def died_with_error(error)
176
+ @error = [error.message] << [error.backtrace]
177
+ done!
178
+ end
179
+
180
+ def init_before_create
181
+ @done = false
182
+ @start_time = nil
183
+ @end_time = nil
184
+ @cancel = false
185
+ @current_pos = 0
186
+ end
187
+
140
188
  def done!
189
+ return if @done
190
+
141
191
  @done = true
142
192
  @end_time = Time.new
143
- logger.info("Report creation ended after #{@end_time - @start_time} seconds with status '#{status}'")
193
+ @start_time ||= @end_time
194
+ logger.info("Report creation ended after #{@end_time.to_i - @start_time.to_i} seconds with status '#{status}'")
144
195
  notify(:on_after_finish)
145
196
  end
146
197
 
@@ -19,18 +19,18 @@ module GrafanaReporter
19
19
  def pre_process
20
20
  raise MissingMandatoryAttributeError, 'columns' unless @raw_query['columns']
21
21
 
22
- @from = translate_date(@from, @variables['grafana-report-timestamp'], false, @variables['from_timezone'] ||
22
+ @from = translate_date(@from, @variables['grafana_report_timestamp'], false, @variables['from_timezone'] ||
23
23
  @variables['grafana_default_from_timezone'])
24
- @to = translate_date(@to, @variables['grafana-report-timestamp'], true, @variables['to_timezone'] ||
24
+ @to = translate_date(@to, @variables['grafana_report_timestamp'], true, @variables['to_timezone'] ||
25
25
  @variables['grafana_default_to_timezone'])
26
26
  @datasource = Grafana::GrafanaAlertsDatasource.new(nil)
27
27
  end
28
28
 
29
29
  # Filter the query result for the given columns and sets the result in the preformatted SQL
30
30
  # result stlye.
31
-
32
- # Additionally it applies {QueryMixin#format_columns}, {QueryMixin#replace_values} and
33
- # {QueryMixin#filter_columns}.
31
+ #
32
+ # Additionally it applies {AbstractQuery#format_columns}, {AbstractQuery#replace_values} and
33
+ # {AbstractQuery#filter_columns}.
34
34
  # @return [void]
35
35
  def post_process
36
36
  @result = format_columns(@result, @variables['format'])
@@ -18,9 +18,9 @@ module GrafanaReporter
18
18
  def pre_process
19
19
  raise MissingMandatoryAttributeError, 'columns' unless @raw_query['columns']
20
20
 
21
- @from = translate_date(@from, @variables['grafana-report-timestamp'], false, @variables['from_timezone'] ||
21
+ @from = translate_date(@from, @variables['grafana_report_timestamp'], false, @variables['from_timezone'] ||
22
22
  @variables['grafana_default_from_timezone'])
23
- @to = translate_date(@to, @variables['grafana-report-timestamp'], true, @variables['to_timezone'] ||
23
+ @to = translate_date(@to, @variables['grafana_report_timestamp'], true, @variables['to_timezone'] ||
24
24
  @variables['grafana_default_to_timezone'])
25
25
  @datasource = Grafana::GrafanaAnnotationsDatasource.new(nil)
26
26
  end
@@ -28,8 +28,8 @@ module GrafanaReporter
28
28
  # Filters the query result for the given columns and sets the result
29
29
  # in the preformatted SQL result style.
30
30
  #
31
- # Additionally it applies {QueryMixin#format_columns}, {QueryMixin#replace_values} and
32
- # {QueryMixin#filter_columns}.
31
+ # Additionally it applies {AbstractQuery#format_columns}, {AbstractQuery#replace_values} and
32
+ # {AbstractQuery#filter_columns}.
33
33
  # @return [void]
34
34
  def post_process
35
35
  @result = format_columns(@result, @variables['format'])
@@ -13,8 +13,6 @@ module GrafanaReporter
13
13
  # It can be run to test the grafana connection, render a single template
14
14
  # or run as a service.
15
15
  class Application
16
- # Default file name for grafana reporter configuration file
17
- CONFIG_FILE = 'grafana_reporter.config'
18
16
 
19
17
  # Contains the {Configuration} object of the application.
20
18
  attr_accessor :config
@@ -32,7 +30,7 @@ module GrafanaReporter
32
30
  # @param params [Array<String>] command line parameters, mainly ARGV can be used.
33
31
  # @return [Integer] 0 if everything is fine, -1 if execution aborted.
34
32
  def configure_and_run(params = [])
35
- config_file = CONFIG_FILE
33
+ config_file = Configuration::DEFAULT_CONFIG_FILE_NAME
36
34
  tmp_config = Configuration.new
37
35
  action_wizard = false
38
36
 
@@ -44,10 +42,14 @@ module GrafanaReporter
44
42
  end
45
43
 
46
44
  opts.on('-c', '--config CONFIG_FILE_NAME', 'Specify custom configuration file,'\
47
- " instead of #{CONFIG_FILE}.") do |file_name|
45
+ " instead of #{Configuration::DEFAULT_CONFIG_FILE_NAME}.") do |file_name|
48
46
  config_file = file_name
49
47
  end
50
48
 
49
+ opts.on('-r', '--register FILE', 'Register a custom plugin, e.g. your own Datasource implementation') do |plugin|
50
+ require plugin
51
+ end
52
+
51
53
  opts.on('-d', '--debug LEVEL', 'Specify detail level: FATAL, ERROR, WARN, INFO, DEBUG.') do |level|
52
54
  tmp_config.set_param('grafana-reporter:debug-level', level)
53
55
  end
@@ -65,7 +67,7 @@ module GrafanaReporter
65
67
 
66
68
  opts.on('--ssl-cert FILE', 'Manually specify a SSL cert file for HTTPS connection to grafana. Only '\
67
69
  'needed if not working properly otherwise.') do |file|
68
- if File.exist?(file)
70
+ if File.file?(file)
69
71
  tmp_config.set_param('grafana-reporter:ssl-cert', file)
70
72
  else
71
73
  config.logger.warn("SSL certificate file #{file} does not exist. Setting will be ignored.")
@@ -106,22 +108,14 @@ module GrafanaReporter
106
108
  end
107
109
 
108
110
  # abort if config file does not exist
109
- unless File.exist?(config_file)
111
+ unless File.file?(config_file)
110
112
  puts "Config file '#{config_file}' does not exist. Consider calling the configuration wizard"\
111
113
  ' with option \'-w\' or use \'-h\' to see help message. Aborting.'
112
114
  return -1
113
115
  end
114
116
 
115
- # read config file
116
- config_hash = nil
117
- begin
118
- config_hash = YAML.load_file(config_file)
119
- rescue StandardError => e
120
- raise ConfigurationError, "Could not read config file '#{config_file}' (Error: #{e.message})"
121
- end
122
-
123
117
  # merge command line configuration with read config file
124
- @config.config = config_hash
118
+ @config.load_config_from_file(config_file)
125
119
  @config.merge!(tmp_config)
126
120
 
127
121
  run
@@ -146,7 +140,7 @@ module GrafanaReporter
146
140
 
147
141
  when Configuration::MODE_SINGLE_RENDER
148
142
  begin
149
- config.report_class.new(config, config.template, config.to_file).create_report
143
+ config.report_class.new(config).create_report(config.template, config.to_file)
150
144
  rescue StandardError => e
151
145
  puts "#{e.message}\n#{e.backtrace.join("\n")}"
152
146
  end