ruby-grafana-reporter 0.6.2 → 0.6.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9e3324f4e9d6fa3a47963a73ae4371122f603039284d0b453ac2f62881c5b93
4
- data.tar.gz: 535a8f6f2763a5689472a423090504bbd5eed6b5610a557c7d9452999694f52c
3
+ metadata.gz: a5e48d471e3c09009d65b08924a8d8ff1f4a2259fde86a2525f56554ee96f23a
4
+ data.tar.gz: 0e095029e10bd6bef2ae80ad866b243c13d3c1ebd5555c9b75d651d6da5ce15c
5
5
  SHA512:
6
- metadata.gz: e77dd83050e40196334058503c902ac6fc9285bf13a4ac8398ec9ffcf724160b30091ac6994cbff48326b4512499ccc7f0358f291e9af417a3903b8cfb2ac32d
7
- data.tar.gz: 2c46bc4ccdd59cd49588e292e1882662b40cde32a50898e14e33eb1f50fffdd5334c86c837bb3e249155002cd80c78af51bfd9897e176654eeece1ebd2d92084
6
+ metadata.gz: f6bc6604e3fed7fba3fe3057d42432098363f056c03afdf6c8f961d80abc0b0ad4505a01f895d44421774b5bb1a9227bb9bdef747cea7fe15669ebdf149b7611
7
+ data.tar.gz: fa8ec80a80e51d214c50d54e9d1dbf6d196c11e5320f749ac2f3d2c9b5ed5979ae3a71924ce5d47d43489e4e18c381b5d8d05ad47a3805122a5ba93d9947950f
data/README.md CHANGED
@@ -20,7 +20,22 @@ Reporting Service for Grafana
20
20
  * [Using webhooks](#using-webhooks)
21
21
  * [Developing your own plugin](#developing-your-own-plugin)
22
22
  * [Roadmap](#roadmap)
23
- * [Donations](#donations)
23
+ * [Contributing](#contributing)
24
+ * [Licensing](#licensing)
25
+ * [Acknowledgements](#acknowledgements)
26
+
27
+ ## Your support is appreciated!
28
+
29
+ Hey there! Let me spend some personal words here:
30
+
31
+ I provide you this software free of charge - and I'm happy, that I can do so. I have already
32
+ spend a lot of my private time in developing, maintaining and supporting it.
33
+
34
+ If you enjoy my work, I would feel greatly honoured, if you buy me a coffee:
35
+
36
+ [![buymeacoffee](https://az743702.vo.msecnd.net/cdn/kofi3.png?v=0)](https://ko-fi.com/divinity666)
37
+
38
+ Thanks for your support and keeping this project alive!
24
39
 
25
40
  ## About the project
26
41
 
@@ -136,8 +151,10 @@ asciidoctor:
136
151
 
137
152
  ### Grafana integration
138
153
 
139
- For using the reporter directly from grafana, you need to simply add a link to your
140
- grafana dashboard:
154
+ For using the reporter directly from grafana, the reporter has to run as webservice, i.e. it has to be
155
+ called without the `-t` parameter.
156
+
157
+ If this is the case, you simply simply need add a link to your grafana dashboard:
141
158
 
142
159
  * Open the dashboard configuration
143
160
  * Select `Links`
@@ -168,7 +185,32 @@ a variable and forward it to the reporter.
168
185
 
169
186
  ## Advanced information
170
187
 
171
- ### Webservice
188
+ ### Use grafana variables in templates
189
+ It is common practice to use dashboard variables in grafana, to allow users to show
190
+ the dashboard for a specific set of data only. This is where grafana variables are
191
+ used.
192
+
193
+ Those variables are then also used in panel queries, to react on selecting or entering
194
+ those variables.
195
+
196
+ You may provide those variables during report generation to the reporter. Therefore
197
+ you have to specify them in the individual calls.
198
+
199
+ Let's say, you have a variable called `serverid` in the dashboard. You may now want
200
+ to set this variable for a panel image rendering. This cann be done with the following
201
+ calls:
202
+
203
+ ````
204
+ grafana_panel_image:1[var-serverid=main-server]
205
+ grafana_panel_image:1[var-serverid=replica-server]
206
+ ````
207
+
208
+ This will render two images: one for `main-server` and one for `replica-server`.
209
+
210
+ So, to forward grafana variables to the reporter calls, you simply have to use the
211
+ form `var-<<your-variable-name>>` and specify those in your reporter template.
212
+
213
+ ### Webservice endpoints
172
214
 
173
215
  Running the reporter as a webservice provides the following URLs
174
216
 
@@ -329,9 +371,3 @@ The code in this project is licensed under MIT license.
329
371
  * [grafana](https://github.com/grafana/grafana)
330
372
 
331
373
  Inspired by [Izak Marai's grafana reporter](https://github.com/IzakMarais/reporter)
332
-
333
- ## Donations
334
-
335
- If you like this project and you would like to support my work, feel free to donate. :)
336
-
337
- [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/donate?hosted_button_id=35LH6JNLPHPHQ)
@@ -2,4 +2,4 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require_relative '../lib/ruby_grafana_reporter'
5
- GrafanaReporter::Application::Application.new.configure_and_run(ARGV) unless defined?(Ocra)
5
+ GrafanaReporter::Application::Application.new.configure_and_run(ARGV) unless defined?(Ocran)
data/lib/VERSION.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Version information
4
- GRAFANA_REPORTER_VERSION = [0, 6, 2].freeze
4
+ GRAFANA_REPORTER_VERSION = [0, 6, 6].freeze
5
5
  # Release date
6
- GRAFANA_REPORTER_RELEASE_DATE = '2022-09-14'
6
+ GRAFANA_REPORTER_RELEASE_DATE = '2024-02-22'
@@ -86,15 +86,8 @@ module Grafana
86
86
  # @param datasource_uid [String] unique id of the searched datasource
87
87
  # @return [Datasource] Datasource for the specified datasource unique id
88
88
  def datasource_by_uid(datasource_uid)
89
- datasource = @datasources.select do |ds_name, ds|
90
- if (ds.nil?)
91
- # print debug info for https://github.com/divinity666/ruby-grafana-reporter/issues/29
92
- @logger.warn("Datasource with name #{ds_name} is nil, which should never happen. Check logs for details.")
93
- false
94
- else
95
- ds.uid == datasource_uid
96
- end
97
- end.values.first
89
+ clean_nil_datasources
90
+ datasource = @datasources.select { |ds_name, ds| ds.uid == datasource_uid }.values.first
98
91
  raise DatasourceDoesNotExistError.new('uid', datasource_uid) unless datasource
99
92
 
100
93
  datasource
@@ -105,7 +98,8 @@ module Grafana
105
98
  # @param datasource_id [Integer] id of the searched datasource
106
99
  # @return [Datasource] Datasource for the specified datasource id
107
100
  def datasource_by_id(datasource_id)
108
- datasource = @datasources.select { |_name, ds| ds.id == datasource_id.to_i }.values.first
101
+ clean_nil_datasources
102
+ datasource = @datasources.select { |name, ds| ds.id == datasource_id.to_i }.values.first
109
103
  raise DatasourceDoesNotExistError.new('id', datasource_id) unless datasource
110
104
 
111
105
  datasource
@@ -171,7 +165,18 @@ module Grafana
171
165
  @datasources.delete(ds_name)
172
166
  end
173
167
  end
174
- @datasources['default'] = @datasources[json['defaultDatasource']]
168
+
169
+ @datasources['default'] = @datasources[json['defaultDatasource']] if not @datasources[json['defaultDatasource']].nil?
170
+ end
171
+
172
+ def clean_nil_datasources
173
+ @datasources.delete_if do |name, ds|
174
+ if ds.nil?
175
+ # print debug info for https://github.com/divinity666/ruby-grafana-reporter/issues/29
176
+ @logger.warn("Datasource with name #{name} is nil, which should never happen. Check logs for details.")
177
+ end
178
+ ds.nil?
179
+ end
175
180
  end
176
181
  end
177
182
  end
@@ -16,7 +16,7 @@ module Grafana
16
16
  webrequest.relative_url = panel.render_url + url_params(query_description)
17
17
  webrequest.options.merge!({ accept: 'image/png' })
18
18
 
19
- result = webrequest.execute
19
+ result = webrequest.execute(query_description[:timeout])
20
20
 
21
21
  raise ImageCouldNotBeRenderedError, panel if result.body.include?('<html')
22
22
 
@@ -26,7 +26,7 @@ module Grafana
26
26
  private
27
27
 
28
28
  def url_params(query_desc)
29
- url_vars = query_desc[:variables].select { |k, _v| k =~ /^(?:timeout|height|width|theme|fullscreen|var-.+)$/ }
29
+ url_vars = query_desc[:variables].select { |k, _v| k =~ /^(?:timeout|scale|height|width|theme|fullscreen|var-.+)$/ }
30
30
  url_vars = default_vars.merge(url_vars)
31
31
  url_vars['from'] = Variable.new(query_desc[:from])
32
32
  url_vars['to'] = Variable.new(query_desc[:to])
@@ -31,11 +31,36 @@ module Grafana
31
31
  query = query.gsub(/\$(?:__)?interval(?=\W|$)/, "#{interval.is_a?(String) ? interval : "#{(interval / 1000).to_i}s"}")
32
32
  query = query.gsub(/\$(?:__)?interval_ms(?=\W|$)/, "#{interval}")
33
33
 
34
- url = "/api/datasources/proxy/#{id}/query?db=#{@model['database']}&q=#{ERB::Util.url_encode(query)}&epoch=ms"
35
-
36
34
  webrequest = query_description[:prepared_request]
37
- webrequest.relative_url = url
38
- webrequest.options.merge!({ request: Net::HTTP::Get })
35
+ request = {}
36
+
37
+ ver = query_description[:grafana_version].split('.').map{|x| x.to_i}
38
+ if ver[0] >= 8
39
+ webrequest.relative_url = "/api/ds/query?ds_type=influxdb"
40
+
41
+ request = {
42
+ request: Net::HTTP::Post,
43
+ body: {
44
+ from: query_description[:from],
45
+ to: query_description[:to],
46
+ queries: [
47
+ {
48
+ datasource: {type: "influxdb"},
49
+ datasourceId: id,
50
+ intervalMs: interval,
51
+ query: query
52
+ }
53
+ ]}.to_json
54
+ }
55
+ else
56
+ webrequest.relative_url = "/api/datasources/proxy/#{id}/query?db=#{@model['database']}&q=#{ERB::Util.url_encode(query)}&epoch=ms"
57
+ request = {
58
+ request: Net::HTTP::Get
59
+ }
60
+ end
61
+
62
+ webrequest.options.merge!(request)
63
+
39
64
 
40
65
  result = webrequest.execute(query_description[:timeout])
41
66
  preformat_response(result.body)
@@ -43,7 +68,7 @@ module Grafana
43
68
 
44
69
  # @see AbstractDatasource#raw_query_from_panel_model
45
70
  def raw_query_from_panel_model(panel_query_target)
46
- return panel_query_target['query'] if panel_query_target['rawQuery']
71
+ return panel_query_target['query'] if panel_query_target['query'] or panel_query_target['rawQuery']
47
72
 
48
73
  # build composed queries
49
74
  build_select(panel_query_target['select']) + build_from(panel_query_target) + build_where(panel_query_target['tags']) + build_group_by(panel_query_target['groupBy'])
@@ -138,7 +138,7 @@ module GrafanaReporter
138
138
 
139
139
  # automatically add extension, if a file with default template extension exists
140
140
  @template = "#{@template}.#{self.class.default_template_extension}" if File.file?("#{@template}.#{self.class.default_template_extension}") && !File.file?(@template.to_s)
141
- raise MissingTemplateError, @template.to_s unless File.file?(@template.to_s)
141
+ raise MissingTemplateError, "#{@template}.#{self.class.default_template_extension}" unless File.file?(@template.to_s)
142
142
 
143
143
  notify(:on_before_create)
144
144
  @start_time = Time.new
@@ -34,8 +34,8 @@ module GrafanaReporter
34
34
  action_wizard = false
35
35
 
36
36
  parser = OptionParser.new do |opts|
37
- opts.banner = if ENV['OCRA_EXECUTABLE']
38
- "Usage: #{ENV['OCRA_EXECUTABLE'].gsub("#{Dir.pwd}/".gsub('/', '\\'), '')} [options]"
37
+ opts.banner = if ENV['OCRAN_EXECUTABLE']
38
+ "Usage: #{ENV['OCRAN_EXECUTABLE'].gsub("#{Dir.pwd}/".gsub('/', '\\'), '')} [options]"
39
39
  else
40
40
  "Usage: #{Gem.ruby} #{$PROGRAM_NAME} [options]"
41
41
  end
@@ -91,8 +91,8 @@ module GrafanaReporter
91
91
  @logger.error(e.message)
92
92
  socket.write http_response(400, 'Bad Request', e.message)
93
93
  rescue StandardError => e
94
- @logger.fatal(e.message)
95
- socket.write http_response(400, 'Bad Request', e.message)
94
+ @logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
95
+ socket.write http_response(400, 'Bad Request', "#{e.message}\n#{e.backtrace.join("\n")}")
96
96
  ensure
97
97
  socket.close
98
98
  end
@@ -76,8 +76,8 @@ module GrafanaReporter
76
76
  @report.logger.error(e.message)
77
77
  reader.unshift_line "|#{e.message}"
78
78
  rescue StandardError => e
79
- @report.logger.fatal(e.message)
80
- reader.unshift_line "|#{e.message}"
79
+ @report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
80
+ reader.unshift_line "|#{e.message}\n#{e.backtrace.join("\n")}"
81
81
  end
82
82
 
83
83
  reader
@@ -75,8 +75,8 @@ module GrafanaReporter
75
75
  @report.logger.error(e.message)
76
76
  reader.unshift_line "|#{e.message}"
77
77
  rescue StandardError => e
78
- @report.logger.fatal(e.message)
79
- reader.unshift_line "|#{e.message}"
78
+ @report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
79
+ reader.unshift_line "|#{e.message}\n#{e.backtrace.join("\n")}"
80
80
  end
81
81
 
82
82
  reader
@@ -391,6 +391,9 @@ end}
391
391
  render-width:
392
392
  description: can be used to override default `width` in which the panel shall be rendered
393
393
  call: render-width="<width>"
394
+ render-scale:
395
+ description: can be used to override default scale in which the panel shall be rendered
396
+ call: render-scale="<scale>"
394
397
  render-theme:
395
398
  description: can be used to override default `theme` in which the panel shall be rendered (light by default)
396
399
  call: render-theme="<theme>"
@@ -56,8 +56,8 @@ module GrafanaReporter
56
56
  @report.logger.error(e.message)
57
57
  return create_paragraph(parent, e.message, attrs)
58
58
  rescue StandardError => e
59
- @report.logger.fatal(e.message)
60
- return create_paragraph(parent, e.message, attrs)
59
+ @report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
60
+ return create_paragraph(parent, "#{e.message}\n#{e.backtrace.join("\n")}", attrs)
61
61
  end
62
62
 
63
63
  attrs['target'] = image_path
@@ -58,8 +58,8 @@ module GrafanaReporter
58
58
  @report.logger.error(e.message)
59
59
  return create_inline(parent, :quoted, e.message)
60
60
  rescue StandardError => e
61
- @report.logger.fatal(e.message)
62
- return create_inline(parent, :quoted, e.message)
61
+ @report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
62
+ return create_inline(parent, :quoted, "#{e.message}\n#{e.backtrace.join("\n")}")
63
63
  end
64
64
 
65
65
  create_inline(parent, :image, nil, { target: image_path, attributes: attrs })
@@ -50,8 +50,8 @@ module GrafanaReporter
50
50
  @report.logger.error(e.message)
51
51
  return create_inline(parent, :quoted, e.message)
52
52
  rescue StandardError => e
53
- @report.logger.fatal(e.message)
54
- return create_inline(parent, :quoted, e.message)
53
+ @report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
54
+ return create_inline(parent, :quoted, "#{e.message}\n#{e.backtrace.join("\n")}")
55
55
  end
56
56
 
57
57
  # translate linebreaks to asciidoctor syntax
@@ -70,8 +70,8 @@ module GrafanaReporter
70
70
  @report.logger.error(e.message)
71
71
  reader.unshift_line "|#{e.message}"
72
72
  rescue StandardError => e
73
- @report.logger.fatal(e.message)
74
- reader.unshift_line "|#{e.message}"
73
+ @report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
74
+ reader.unshift_line "|#{e.message}\n#{e.backtrace.join("\n")}"
75
75
  end
76
76
 
77
77
  reader
@@ -66,8 +66,8 @@ module GrafanaReporter
66
66
  @report.logger.error(e.message)
67
67
  create_inline(parent, :quoted, e.message)
68
68
  rescue StandardError => e
69
- @report.logger.fatal(e.message)
70
- create_inline(parent, :quoted, e.message)
69
+ @report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
70
+ create_inline(parent, :quoted, "#{e.message}\n#{e.backtrace.join("\n")}")
71
71
  end
72
72
  end
73
73
 
@@ -64,8 +64,8 @@ module GrafanaReporter
64
64
  @report.logger.error(e.message)
65
65
  reader.unshift_line "|#{e.message}"
66
66
  rescue StandardError => e
67
- @report.logger.fatal(e.message)
68
- reader.unshift_line "|#{e.message}"
67
+ @report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
68
+ reader.unshift_line "|#{e.message}\n#{e.backtrace.join("\n")}"
69
69
  end
70
70
 
71
71
  reader
@@ -71,8 +71,8 @@ module GrafanaReporter
71
71
  @report.logger.error(e.message)
72
72
  create_inline(parent, :quoted, e.message)
73
73
  rescue StandardError => e
74
- @report.logger.fatal(e.message)
75
- create_inline(parent, :quoted, e.message)
74
+ @report.logger.fatal("#{e.message}\n#{e.backtrace.join("\n")}")
75
+ create_inline(parent, :quoted, "#{e.message}\n#{e.backtrace.join("\n")}")
76
76
  end
77
77
  end
78
78
 
@@ -32,7 +32,7 @@ module GrafanaReporter
32
32
  demo_report ||= '<<your_report_name>>'
33
33
  config_param = config_file == Configuration::DEFAULT_CONFIG_FILE_NAME ? '' : " -c #{config_file}"
34
34
  program_call = "#{Gem.ruby} #{$PROGRAM_NAME}"
35
- program_call = ENV['OCRA_EXECUTABLE'].gsub("#{Dir.pwd}/".gsub('/', '\\'), '') if ENV['OCRA_EXECUTABLE']
35
+ program_call = ENV['OCRAN_EXECUTABLE'].gsub("#{Dir.pwd}/".gsub('/', '\\'), '') if ENV['OCRAN_EXECUTABLE']
36
36
 
37
37
  puts
38
38
  puts 'Now everything is setup properly. Create your reports as required in the templates '\
@@ -50,7 +50,7 @@ module GrafanaReporter
50
50
  # Thrown if a non existing template has been specified.
51
51
  class MissingTemplateError < ConfigurationError
52
52
  def initialize(template)
53
- super("Given report template '#{template}' is not a valid template.")
53
+ super("Accessing report template file '#{template}' is not possible. Check if file exists and is accessible.")
54
54
  end
55
55
  end
56
56
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rubygems'
4
+ require 'rubygems/ext'
3
5
  require 'net/http'
4
6
  require 'fileutils'
5
7
  require 'yaml'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-grafana-reporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Kohlmeyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-14 00:00:00.000000000 Z
11
+ date: 2024-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor