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.
- checksums.yaml +4 -4
- data/README.md +185 -180
- data/lib/VERSION.rb +2 -2
- data/lib/grafana/abstract_datasource.rb +32 -12
- data/lib/grafana/errors.rb +1 -9
- data/lib/grafana/grafana.rb +3 -7
- data/lib/grafana/graphite_datasource.rb +6 -0
- data/lib/grafana/prometheus_datasource.rb +6 -0
- data/lib/grafana/sql_datasource.rb +6 -0
- data/lib/grafana/unsupported_datasource.rb +7 -0
- data/lib/grafana/webrequest.rb +1 -1
- data/lib/grafana_reporter/abstract_query.rb +20 -62
- data/lib/grafana_reporter/abstract_report.rb +66 -15
- data/lib/grafana_reporter/alerts_table_query.rb +5 -5
- data/lib/grafana_reporter/annotations_table_query.rb +4 -4
- data/lib/grafana_reporter/application/application.rb +10 -16
- data/lib/grafana_reporter/application/webservice.rb +34 -10
- data/lib/grafana_reporter/asciidoctor/alerts_table_include_processor.rb +5 -5
- data/lib/grafana_reporter/asciidoctor/annotations_table_include_processor.rb +5 -5
- data/lib/grafana_reporter/asciidoctor/panel_image_block_macro.rb +2 -1
- data/lib/grafana_reporter/asciidoctor/panel_image_inline_macro.rb +7 -5
- data/lib/grafana_reporter/asciidoctor/panel_property_inline_macro.rb +2 -1
- data/lib/grafana_reporter/asciidoctor/panel_query_table_include_processor.rb +6 -5
- data/lib/grafana_reporter/asciidoctor/panel_query_value_inline_macro.rb +5 -5
- data/lib/grafana_reporter/asciidoctor/processor_mixin.rb +43 -2
- data/lib/grafana_reporter/asciidoctor/report.rb +17 -41
- data/lib/grafana_reporter/asciidoctor/sql_table_include_processor.rb +4 -4
- data/lib/grafana_reporter/asciidoctor/sql_value_inline_macro.rb +4 -4
- data/lib/grafana_reporter/configuration.rb +14 -2
- data/lib/grafana_reporter/console_configuration_wizard.rb +2 -10
- data/lib/grafana_reporter/demo_report_wizard.rb +16 -2
- data/lib/grafana_reporter/erb/report.rb +43 -0
- data/lib/grafana_reporter/errors.rb +9 -1
- data/lib/grafana_reporter/help.rb +1 -5
- data/lib/grafana_reporter/logger/{two_way_logger.rb → two_way_delegate_logger.rb} +0 -0
- data/lib/grafana_reporter/panel_image_query.rb +2 -2
- data/lib/grafana_reporter/query_value_query.rb +4 -4
- data/lib/ruby_grafana_extension.rb +8 -0
- data/lib/ruby_grafana_reporter.rb +13 -0
- metadata +9 -6
data/lib/grafana/errors.rb
CHANGED
@@ -57,21 +57,13 @@ module Grafana
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
# Raised if no SQL query is specified
|
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)
|
data/lib/grafana/grafana.rb
CHANGED
@@ -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
|
-
|
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)
|
data/lib/grafana/webrequest.rb
CHANGED
@@ -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.
|
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}
|
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
|
-
#
|
81
|
-
#
|
82
|
-
# @param
|
83
|
-
# @param
|
84
|
-
|
85
|
-
|
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
|
-
@
|
100
|
-
@
|
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#
|
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#
|
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#
|
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#
|
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
|
-
|
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
|
-
|
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
|
-
@
|
46
|
-
|
47
|
-
|
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
|
-
#
|
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
|
-
|
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['
|
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['
|
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 {
|
33
|
-
# {
|
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['
|
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['
|
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 {
|
32
|
-
# {
|
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 =
|
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 #{
|
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.
|
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.
|
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.
|
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
|
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
|