ruby-grafana-reporter 0.2.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3ffea90aebd213a65781274b5825d3f47d2a68e804821dd4a887ebdaebd67ae
4
- data.tar.gz: 931c47a54cebe300a6f0b3e3dffb470ac6ce6f4faddc8558e90bd18d4273b1d5
3
+ metadata.gz: 2f95b8d5f6221cb369bf0d11671823394683a60299dff0e688da9c5f0eab3246
4
+ data.tar.gz: 245804ca1843422b29a8bf8866dfaf75ec916a329f2de05739436e580c32b6e8
5
5
  SHA512:
6
- metadata.gz: d0c187b97ec27c6ac374069d9253215d78c2b04d6e8ff10cc1bd660486d0f998c742cfd65a4d415cdb2b8045fed1c6800ccf2c64cbe21fc530b82527b4183f69
7
- data.tar.gz: b7b22e087b05c9c1bb6c0c92526755c1883ac9a57ca53c64e809de18e213421a2c65329618a42a75aa80b2ebdc0a38f48b28ac15eb2b9dd02c7c2250c838953c
6
+ metadata.gz: 84d7265803d6cfedec4f63b9a2938ed181bfdd9f9865bafbd3953c5a208de129e4029dd1bd8855c38ceefb9b215ea071a69242bb8ba6bfacd3f38c14e5a72e5e
7
+ data.tar.gz: a28e456174baae970bbe0d2abc76675e6900ce3e821b6e35a215f5ee81ff760a61ccf757bc1c5c5d7b79e8e5ac8488f7edde5d1c7f3d708399a60dade839c9dc
data/README.md CHANGED
@@ -1,166 +1,162 @@
1
- [![MIT License](https://img.shields.io/github/license/divinity666/ruby-grafana-reporter.svg?style=flat-square)](https://github.com/divinity666/ruby-grafana-reporter/blob/master/LICENSE)
2
- [![Build Status](https://travis-ci.org/divinity666/ruby-grafana-reporter.svg?branch=master)](https://travis-ci.org/github/divinity666/ruby-grafana-reporter?branch=master)
3
- [![Coverage Status](https://coveralls.io/repos/github/divinity666/ruby-grafana-reporter/badge.svg?branch=master)](https://coveralls.io/github/divinity666/ruby-grafana-reporter?branch=master)
4
-
5
- # Ruby Grafana Reporter
6
- Reporting Service for Grafana
7
-
8
- ## Table of Contents
9
-
10
- * [About the project](#about-the-project)
11
- * [Getting started](#getting-started)
12
- * [Grafana integration](#grafana-integration)
13
- * [Webservice overview](#webservice-overview)
14
- * [Features](#features)
15
- * [Roadmap](#roadmap)
16
- * [Contributing](#contributing)
17
- * [Licensing](#licensing)
18
- * [Acknowledgements](#acknowledgements)
19
- * [Donations](#donations)
20
-
21
- ## About the project
22
-
23
- Did you ever want to create (professional) reports based on Grafana dashboards?
24
- I did so in order to being able to automatically get monthly reports of my
25
- home's energy usage. That's how it started.
26
-
27
- The reporter provides reporting capabilities for Grafana. It is based on
28
- (but not limited to) [asciidoctor](https://github.com/asciidoctor/asciidoctor)
29
- report templates, which can dynamically integrate Grafana panels, queries,
30
- images etc. to create dynamic PDF reports on the fly.
31
-
32
- The report may also be returned in any other format that asciidoctor supports.
33
-
34
- The reporter can run standalone or as a webservice. It is built to
35
- integrate without further dependencies with the asciidoctor docker image.
36
-
37
- The complete
38
- [API documentation](https://rubydoc.info/gems/ruby-grafana-reporter) can be
39
- found here.
40
-
41
- ## Getting started
42
-
43
- There exist several ways of installing the reporter. Here I cover the easiest
44
- setup by using ruby gems. If you need further installation help, or want to use
45
- a "baremetal" ruby setup or a docker integration, please have a look at the more
46
- extended [installation documentation](INSTALL.md).
47
-
48
- To install the reporter as a gem, simply run:
49
-
50
- gem install ruby-grafana-reporter
51
-
52
- If no configuration file is in place, you might want to use the configuration
53
- wizard, which leads you through all necessary steps:
54
-
55
- ruby-grafana-reporter -w
56
-
57
- Now you're ready to go! Let's check it out!
58
-
59
- ruby-grafana-reporter -t demo_report -o my_first_render.pdf
60
-
61
- If everything works as expected, you should find a file named `my_first_render.pdf`
62
- in the current folder, which contains a detailed explanation of all available
63
- commands as well as your available configuration options.
64
-
65
- To run the reporter as a service, you only need to call it like this:
66
-
67
- ruby-grafana-reporter
68
-
69
- Neat, isn't it?
70
-
71
- ### Grafana integration
72
-
73
- The key feature of the report is, that it can easily be integrated with grafana
74
- (I've not even been talking about the features it is providing for that, but
75
- you'll find them having a look in the example results above).
76
-
77
- For accessing the reporter from grafana, you need to simply add a link to your
78
- grafana dashboard:
79
-
80
- * Open the dashboard configuration
81
- * Select `Links`
82
- * Select `Add`
83
- * Fill out as following:
84
- * Type: `link`
85
- * Url: `http://<<your-server-url>>:<<your-webservice-port>>/render?var-template=myfirsttemplate`
86
- * Title: `MyFirstReport`
87
- * Select `Time range`
88
- * Select `Variable values`
89
- * Select `Add`
90
-
91
- Now go back to your dashboard and click the newly generated 'MyFirstReport'
92
- link on it. Now the renderer should start it's task and show you the expected
93
- results.
94
-
95
- But now the fun just starts! Try out the functions stated in the
96
- 'MyFirstReport' PDF file, to include the dynamic content in your asciidoctor
97
- template.
98
-
99
- Additionally you might want to make the selection of the template variable.
100
- Piece of cake: Just add a dashboard variable to your grafana dashboard named
101
- `template` and let the user select or enter a template name. To make use of it,
102
- you should change the link of the 'MyFirstReport' link to
103
- `http://<<your-server-url>>:<<your-webservice-port>>/render?`
104
-
105
- That's it. Let me know your feedback!
106
-
107
- ## Webservice overview
108
-
109
- Running the reporter as a webservice provides the following URLs
110
-
111
- /overview - for all running or retained renderings
112
- /render - for rendering a template, 'var-template' is the only mandatory GET parameter
113
- /view_report - for viewing the status or receving the result of a specific rendering, is automatically called after a successfull /render call
114
- /cancel_report - for cancelling the rendering of a specific report, normally not called manually, but on user interaction in the /view_report or /overview URL
115
-
116
- ## Features
117
-
118
- * Build report template including all imaginable grafana content:
119
- * panels as images
120
- * panel table query or custom query results as real document tables (not images!)
121
- * single panel value or custom query single value result integrated in texts
122
- * Solid as a rock, also in case of template errors (at least it aims to be)
123
- * Runs standalone or as a webservice
124
- * Seamlessly integrates with asciidoctor docker container
125
- * Developed for being able to support other tools than asciidoctor as well
126
-
127
- ## Roadmap
128
-
129
- This is just a collection of things, I am heading for in future, without a schedule.
130
-
131
- * Add documentation of possible asciidoctor calls to grafana
132
- * Add a simple plugin system to support specific asciidoctor modifications
133
- * Solve code TODOs
134
- * Become [rubocop](https://rubocop.org/) ready
135
-
136
- ## Contributing
137
-
138
- If you'd like to contribute, please fork the repository and use a feature
139
- branch. Pull requests are warmly welcome.
140
-
141
- Though not yet valid for my code, I'd like to see the project become
142
- [rubocop](https://rubocop.org/) ready :-)
143
-
144
- Definitely open spots from my side are:
145
-
146
- * This README
147
- * Clean and properly setup test cases
148
-
149
- ## Licensing
150
-
151
- The code in this project is licensed under MIT license.
152
-
153
- ## Acknowledgements
154
- * [asciidoctor](https://github.com/asciidoctor/asciidoctor)
155
- * [asciidoctor-pdf](https://github.com/asciidoctor/asciidoctor-pdf)
156
- * [grafana](https://github.com/grafana/grafana)
157
-
158
- Inspired by [Izak Marai's grafana reporter](https://github.com/IzakMarais/reporter)
159
-
160
- ## Donations
161
-
162
- If this project saves you as much time as I hope it does, and if you'd like to
163
- support my work, feel free donate, even a cup of coffee is appreciated :)
164
-
165
- [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/donate?hosted_button_id=35LH6JNLPHPHQ)
166
-
1
+ [![MIT License](https://img.shields.io/github/license/divinity666/ruby-grafana-reporter.svg?style=flat-square)](https://github.com/divinity666/ruby-grafana-reporter/blob/master/LICENSE)
2
+ [![Build Status](https://travis-ci.org/divinity666/ruby-grafana-reporter.svg?branch=master)](https://travis-ci.org/github/divinity666/ruby-grafana-reporter?branch=master)
3
+ [![Coverage Status](https://coveralls.io/repos/github/divinity666/ruby-grafana-reporter/badge.svg?branch=master)](https://coveralls.io/github/divinity666/ruby-grafana-reporter?branch=master)
4
+ [![Gem Version](https://badge.fury.io/rb/ruby-grafana-reporter.svg)](https://badge.fury.io/rb/ruby-grafana-reporter)
5
+
6
+ # Ruby Grafana Reporter
7
+ Reporting Service for Grafana
8
+
9
+ ## Table of Contents
10
+
11
+ * [About the project](#about-the-project)
12
+ * [Getting started](#getting-started)
13
+ * [Grafana integration](#grafana-integration)
14
+ * [Webservice overview](#webservice-overview)
15
+ * [Features](#features)
16
+ * [Roadmap](#roadmap)
17
+ * [Contributing](#contributing)
18
+ * [Licensing](#licensing)
19
+ * [Acknowledgements](#acknowledgements)
20
+ * [Donations](#donations)
21
+
22
+ ## About the project
23
+
24
+ Did you ever want to create (professional) reports based on Grafana dashboards?
25
+ I did so in order to being able to automatically get monthly reports of my
26
+ home's energy usage. That's how it started.
27
+
28
+ The reporter provides reporting capabilities for Grafana. It is based on
29
+ (but not limited to) [asciidoctor](https://github.com/asciidoctor/asciidoctor)
30
+ report templates, which can dynamically integrate Grafana panels, queries,
31
+ images etc. to create dynamic PDF reports on the fly.
32
+
33
+ The report may also be returned in any other format that asciidoctor supports.
34
+
35
+ The reporter can run standalone or as a webservice. It is built to
36
+ integrate without further dependencies with the asciidoctor docker image.
37
+
38
+ The complete
39
+ [API documentation](https://rubydoc.info/gems/ruby-grafana-reporter) can be
40
+ found here.
41
+
42
+ ## Getting started
43
+
44
+ There exist several ways of installing the reporter. Here I cover the easiest
45
+ setup by using ruby gems. If you need further installation help, or want to use
46
+ a "baremetal" ruby setup or a docker integration, please have a look at the more
47
+ extended [installation documentation](INSTALL.md).
48
+
49
+ To install the reporter as a gem, simply run:
50
+
51
+ gem install ruby-grafana-reporter
52
+
53
+ If no configuration file is in place, you might want to use the configuration
54
+ wizard, which leads you through all necessary steps:
55
+
56
+ ruby-grafana-reporter -w
57
+
58
+ It is strongly recommended, to also create the demo PDF file, as stated at the end
59
+ of the procedure, to get a detailed documentation of all the reporter capabilities.
60
+
61
+ To run the reporter as a service, you only need to call it like this:
62
+
63
+ ruby-grafana-reporter
64
+
65
+ Neat, isn't it?
66
+
67
+ ### Grafana integration
68
+
69
+ The key feature of the report is, that it can easily be integrated with grafana
70
+ (I've not even been talking about the features it is providing for that, but
71
+ you'll find them having a look in the example results above).
72
+
73
+ For accessing the reporter from grafana, you need to simply add a link to your
74
+ grafana dashboard:
75
+
76
+ * Open the dashboard configuration
77
+ * Select `Links`
78
+ * Select `Add`
79
+ * Fill out as following:
80
+ * Type: `link`
81
+ * Url: `http://<<your-server-url>>:<<your-webservice-port>>/render?var-template=myfirsttemplate`
82
+ * Title: `MyFirstReport`
83
+ * Select `Time range`
84
+ * Select `Variable values`
85
+ * Select `Add`
86
+
87
+ Now go back to your dashboard and click the newly generated 'MyFirstReport'
88
+ link on it. Now the renderer should start it's task and show you the expected
89
+ results.
90
+
91
+ But now the fun just starts! Try out the functions stated in the
92
+ 'MyFirstReport' PDF file, to include the dynamic content in your asciidoctor
93
+ template.
94
+
95
+ Additionally you might want to make the selection of the template variable.
96
+ Piece of cake: Just add a dashboard variable to your grafana dashboard named
97
+ `template` and let the user select or enter a template name. To make use of it,
98
+ you should change the link of the 'MyFirstReport' link to
99
+ `http://<<your-server-url>>:<<your-webservice-port>>/render?`
100
+
101
+ That's it. Let me know your feedback!
102
+
103
+ ## Webservice overview
104
+
105
+ Running the reporter as a webservice provides the following URLs
106
+
107
+ /overview - for all running or retained renderings
108
+ /render - for rendering a template, 'var-template' is the only mandatory GET parameter
109
+ /view_report - for viewing the status or receving the result of a specific rendering, is automatically called after a successfull /render call
110
+ /cancel_report - for cancelling the rendering of a specific report, normally not called manually, but on user interaction in the /view_report or /overview URL
111
+
112
+ ## Features
113
+
114
+ * Build report template including all imaginable grafana content:
115
+ * panels as images
116
+ * panel table query or custom query results as real document tables (not images!)
117
+ * single panel value or custom query single value result integrated in texts
118
+ * Solid as a rock, also in case of template errors (at least it aims to be)
119
+ * Runs standalone or as a webservice
120
+ * Seamlessly integrates with asciidoctor docker container
121
+ * Developed for being able to support other tools than asciidoctor as well
122
+
123
+ ## Roadmap
124
+
125
+ This is just a collection of things, I am heading for in future, without a schedule.
126
+
127
+ * Add documentation of possible asciidoctor calls to grafana
128
+ * Add a simple plugin system to support specific asciidoctor modifications
129
+ * Solve code TODOs
130
+ * Become [rubocop](https://rubocop.org/) ready
131
+
132
+ ## Contributing
133
+
134
+ If you'd like to contribute, please fork the repository and use a feature
135
+ branch. Pull requests are warmly welcome.
136
+
137
+ Though not yet valid for my code, I'd like to see the project become
138
+ [rubocop](https://rubocop.org/) ready :-)
139
+
140
+ Definitely open spots from my side are:
141
+
142
+ * This README
143
+ * Clean and properly setup test cases
144
+
145
+ ## Licensing
146
+
147
+ The code in this project is licensed under MIT license.
148
+
149
+ ## Acknowledgements
150
+ * [asciidoctor](https://github.com/asciidoctor/asciidoctor)
151
+ * [asciidoctor-pdf](https://github.com/asciidoctor/asciidoctor-pdf)
152
+ * [grafana](https://github.com/grafana/grafana)
153
+
154
+ Inspired by [Izak Marai's grafana reporter](https://github.com/IzakMarais/reporter)
155
+
156
+ ## Donations
157
+
158
+ If this project saves you as much time as I hope it does, and if you'd like to
159
+ support my work, feel free donate, even a cup of coffee is appreciated :)
160
+
161
+ [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/donate?hosted_button_id=35LH6JNLPHPHQ)
162
+
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative '../lib/ruby-grafana-reporter'
5
- GrafanaReporter::Application::Application.new.configure_and_run(ARGV)
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/ruby-grafana-reporter'
5
+ GrafanaReporter::Application::Application.new.configure_and_run(ARGV)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Version information
4
- GRAFANA_REPORTER_VERSION = [0, 2, 0].freeze
5
- GRAFANA_REPORTER_RELEASE_DATE = '2020-11-30'
4
+ GRAFANA_REPORTER_VERSION = [0, 2, 1].freeze
5
+ GRAFANA_REPORTER_RELEASE_DATE = '2020-12-20'
@@ -87,7 +87,7 @@ module Grafana
87
87
  # only set ticks if value is string
88
88
  variable = var_name.gsub(/^var-/, '')
89
89
  res = res.gsub(/(?:\$\{#{variable}(?::(?<format>\w+))?\}|(?<!\.)\$#{variable}(?!\.))/) do
90
- obj.value_formatted($LAST_MATCH_INFO[:format])
90
+ obj.value_formatted($LAST_MATCH_INFO ? $LAST_MATCH_INFO[:format] : nil)
91
91
  end
92
92
  end
93
93
  repeat = true if res.include?('$')
@@ -40,7 +40,7 @@ module Grafana
40
40
  # check if we have lower rights
41
41
  return 'Failed' unless execute_http_request('/api/dashboards/home').is_a?(Net::HTTPOK)
42
42
 
43
- @logger.warn('Reporter is running with NON-Admin privileges on grafana. Make sure that necessary'\
43
+ @logger.info('Reporter is running with NON-Admin privileges on grafana. Make sure that necessary '\
44
44
  'datasources are specified in CONFIG_FILE, otherwise operation will fail')
45
45
  'NON-Admin'
46
46
  end
@@ -198,10 +198,10 @@ module Grafana
198
198
  h{1,2}|k{1,2}|m{1,2}|s{1,2}|S+|X)/x)
199
199
  if tmp.empty?
200
200
  matches << work_string[0]
201
- work_string.delete_prefix!(work_string[0])
201
+ work_string.sub!(/^#{work_string[0]}/, '')
202
202
  else
203
203
  matches << tmp[0]
204
- work_string.delete_prefix!(tmp[0])
204
+ work_string.sub!(/^#{tmp[0]}/, '')
205
205
  end
206
206
  end
207
207
 
@@ -16,22 +16,21 @@ module GrafanaReporter
16
16
  # Default file name for grafana reporter configuration file
17
17
  CONFIG_FILE = 'grafana_reporter.config'
18
18
 
19
- def initialize
20
- @logger = ::Logger.new($stdout, level: :unknown)
21
- end
22
-
23
19
  # Contains the {Configuration} object of the application.
24
20
  attr_accessor :config
25
21
 
22
+ def initialize
23
+ @config = Configuration.new
24
+ end
25
+
26
26
  # This is the main method, which is called, if the application is
27
27
  # run in standalone mode.
28
28
  # @param params [Array<String>] command line parameters, mainly ARGV can be used.
29
29
  # @return [Integer] 0 if everything is fine, -1 if execution aborted.
30
30
  def configure_and_run(params = [])
31
31
  config_file = CONFIG_FILE
32
- cli_config = {}
33
- cli_config ['grafana-reporter'] = {}
34
- cli_config ['default-document-attributes'] = {}
32
+ tmp_config = Configuration.new
33
+ action_wizard = false
35
34
 
36
35
  parser = OptionParser.new do |opts|
37
36
  opts.banner = "Usage: ruby #{$PROGRAM_NAME} [options]"
@@ -42,32 +41,30 @@ module GrafanaReporter
42
41
  end
43
42
 
44
43
  opts.on('-d', '--debug LEVEL', 'Specify detail level: FATAL, ERROR, WARN, INFO, DEBUG.') do |level|
45
- if level =~ /(?:FATAL|ERROR|WARN|INFO|DEBUG)/
46
- @logger.level = Object.const_get("::Logger::Severity::#{level}")
47
- end
44
+ tmp_config.set_param('grafana-reporter:debug-level', level)
48
45
  end
49
46
 
50
47
  opts.on('-o', '--output FILE', 'Output filename if only a single file is rendered') do |file|
51
- cli_config['to_file'] = file
48
+ tmp_config.set_param('to_file', file)
52
49
  end
53
50
 
54
51
  opts.on('-s', '--set VARIABLE,VALUE', Array, 'Set a variable value, which will be passed to the rendering') do |list|
55
52
  raise ParameterValueError.new(list.length) unless list.length == 2
56
- cli_config['default-document-attributes'][list[0]] = list[1]
53
+ tmp_config.set_param("default-document-attributes:#{list[0]}", list[1])
57
54
  end
58
55
 
59
56
  opts.on('--test GRAFANA_INSTANCE', 'test current configuration against given GRAFANA_INSTANCE') do |instance|
60
- cli_config['grafana-reporter']['run-mode'] = 'test'
61
- cli_config['grafana-reporter']['test-instance'] = instance
57
+ tmp_config.set_param('grafana-reporter:run-mode', 'test')
58
+ tmp_config.set_param('grafana-reporter:test-instance', instance)
62
59
  end
63
60
 
64
61
  opts.on('-t', '--template TEMPLATE', 'Render a single ASCIIDOC template to PDF and exit') do |template|
65
- cli_config['grafana-reporter']['run-mode'] = 'single-render'
66
- cli_config['default-document-attributes']['var-template'] = template
62
+ tmp_config.set_param('grafana-reporter:run-mode', 'single-render')
63
+ tmp_config.set_param('default-document-attributes:var-template', template)
67
64
  end
68
65
 
69
66
  opts.on('-w', '--wizard', 'Configuration wizard to prepare environment for the reporter.') do
70
- return config_wizard
67
+ action_wizard = true
71
68
  end
72
69
 
73
70
  opts.on('-v', '--version', 'Version information') do
@@ -83,6 +80,7 @@ module GrafanaReporter
83
80
 
84
81
  begin
85
82
  parser.parse!(params)
83
+ return config_wizard(config_file) if action_wizard
86
84
  rescue ApplicationError => e
87
85
  puts e.message
88
86
  return -1
@@ -96,8 +94,6 @@ module GrafanaReporter
96
94
  end
97
95
 
98
96
  # read config file
99
- @config = GrafanaReporter::Configuration.new
100
- config.logger = @logger
101
97
  config_hash = nil
102
98
  begin
103
99
  config_hash = YAML.load_file(config_file)
@@ -106,8 +102,8 @@ module GrafanaReporter
106
102
  end
107
103
 
108
104
  # merge command line configuration with read config file
109
- config_hash.merge!(cli_config) { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2) : v2 }
110
- config.config = config_hash
105
+ @config.config = config_hash
106
+ @config.merge!(tmp_config)
111
107
 
112
108
  run
113
109
  end
@@ -147,11 +143,11 @@ module GrafanaReporter
147
143
 
148
144
  # Provides a command line configuration wizard for setting up the necessary configuration
149
145
  # file.
150
- def config_wizard
151
- if File.exist?(CONFIG_FILE)
146
+ def config_wizard(config_file)
147
+ if File.exist?(config_file)
152
148
  input = nil
153
149
  until input
154
- input = user_input("Configuration file '#{CONFIG_FILE}' already exists. Do you want to overwrite it?", 'yN')
150
+ input = user_input("Configuration file '#{config_file}' already exists. Do you want to overwrite it?", 'yN')
155
151
  return if input =~ /^(?:n|N|yN)$/
156
152
  end
157
153
  end
@@ -161,6 +157,8 @@ module GrafanaReporter
161
157
  ' in the current folder. Please make sure to specify necessary paths'\
162
158
  ' either with a relative or an absolute path properly.'
163
159
  puts
160
+ puts "Wizard is creating configuration file '#{config_file}'."
161
+ puts
164
162
  port = ui_config_port
165
163
  grafana = ui_config_grafana
166
164
  templates = ui_config_templates_folder
@@ -173,6 +171,7 @@ module GrafanaReporter
173
171
  #{grafana}
174
172
 
175
173
  grafana-reporter:
174
+ report-class: GrafanaReporter::Asciidoctor::Report
176
175
  templates-folder: #{templates}
177
176
  reports-folder: #{reports}
178
177
  report-retention: #{retention}
@@ -184,7 +183,7 @@ default-document-attributes:
184
183
  )
185
184
 
186
185
  begin
187
- File.write(CONFIG_FILE, config_yaml, mode: 'w')
186
+ File.write(config_file, config_yaml, mode: 'w')
188
187
  puts 'Configuration file successfully created.'
189
188
  rescue StandardError => e
190
189
  raise e
@@ -192,11 +191,11 @@ default-document-attributes:
192
191
 
193
192
  config = Configuration.new
194
193
  begin
195
- config.config = YAML.load_file(CONFIG_FILE)
194
+ config.config = YAML.load_file(config_file)
196
195
  puts 'Configuration file validated successfully.'
197
196
  rescue StandardError => e
198
- raise ConfigurationError, "Could not read config file '#{CONFIG_FILE}' (Error: #{e.message})\n"\
199
- "Source:\n#{File.read(CONFIG_FILE)}"
197
+ raise ConfigurationError, "Could not read config file '#{config_file}' (Error: #{e.message})\n"\
198
+ "Source:\n#{File.read(config_file)}"
200
199
  end
201
200
 
202
201
  # create a demo report
@@ -223,9 +222,14 @@ include::grafana_environment[])
223
222
  end
224
223
 
225
224
  puts
226
- puts 'Now everything is setup properly. Run the grafana reporter without any command to start the service.'
225
+ puts 'Now everything is setup properly. To create an initial report including a manual of all reporter '\
226
+ 'capabilities with the newly created configuration, call the following command:'
227
+ puts
228
+ puts " ruby-grafana-reporter -c #{config_file} -t #{demo_report_file} -o demo_report_with_help.pdf"
229
+ puts
230
+ puts 'To start the reporter as a service, call the following command:'
227
231
  puts
228
- puts ' ruby-grafana-reporter'
232
+ puts " ruby-grafana-reporter -c #{config_file}"
229
233
  puts
230
234
  puts "Open 'http://localhost:#{config.webserver_port}/render?var-template=demo_report' in a webbrowser to"
231
235
  puts 'verify your configuration.'
@@ -242,7 +246,7 @@ include::grafana_environment[])
242
246
  begin
243
247
  res = Grafana::Grafana.new(url,
244
248
  api_key,
245
- logger: @logger).test_connection
249
+ logger: config.logger).test_connection
246
250
  rescue StandardError => e
247
251
  puts
248
252
  puts e.message
@@ -71,7 +71,7 @@ module GrafanaReporter
71
71
  selected_attrs = attrs.select do |k, _v|
72
72
  k =~ /(?:columns|limit|folderId|dashboardId|panelId|dahboardTag|dashboardQuery|state|query)/x
73
73
  end
74
- query.merge_variables(selected_attrs.transform_values { |item| ::Grafana::Variable.new(item) })
74
+ query.merge_variables(selected_attrs.each_with_object({}) { |(k,v), h| h[k] = ::Grafana::Variable.new(v) })
75
75
  @report.logger.debug("from: #{query.from}, to: #{query.to}")
76
76
 
77
77
  begin
@@ -70,7 +70,7 @@ module GrafanaReporter
70
70
  selected_attrs = attrs.select do |k, _v|
71
71
  k =~ /(?:columns|limit|alertId|dashboardId|panelId|userId|type|tags)/
72
72
  end
73
- query.merge_variables(selected_attrs.transform_values { |item| ::Grafana::Variable.new(item) })
73
+ query.merge_variables(selected_attrs.each_with_object({}) { |(k,v), h| h[k] = ::Grafana::Variable.new(v) })
74
74
  @report.logger.debug("from: #{query.from}, to: #{query.to}")
75
75
 
76
76
  begin
@@ -26,14 +26,20 @@ module GrafanaReporter
26
26
  # return if @report.cancel
27
27
  @report.next_step
28
28
  @report.logger.debug('Processing ShowHelpIncludeProcessor')
29
+ exec_order = 'Execution is applied in the following order: `format`, `replace_values`, `filter_columns`, `transpose`.'
29
30
 
30
31
  param_instance = '| `instance="<instance_name>"` | can be used to override global grafana instance, set in the report with `grafana_default_instance`. If nothing is set, the configured grafana instance with name `default` will be used.'
31
32
  param_dashboard = '| `dashboard="<dashboard_uid>"` | Specifies the dashboard to be used. If `grafana_default_dashboard` is specified in the report template, this value can be overridden with this option.'
32
33
  param_from = '| `from="<from_timestamp>"` | can be used to override default `from` time'
33
34
  param_to = '| `to="<to_timestamp>"` | can be used to override default `to` time'
34
- param_format = '| `format="<format_col1>,<format_col2>,..."` | Specify format in which the results shall be returned, e.g. `%.2f` for only two digit decimals of a float. Several columns are separated by `,`. For details see https://ruby-doc.org/core-2.4.0/Kernel.html#method-i-sprintf[Ruby documentation]. This action is always performed *before* `replace_values`and `filter_columns`.'
35
- param_replace_values = '| `replace_values="<replace_1>:<with_1>,<replace_2>:<with_2>,..."` | Specify result values which shall be replaced, e.g. `2:OK` will replace query values `2` with value `OK`. Replacing several values is possible by separating by `,`. Matches with regular expressions are also supported, but must be full matches, i.e. have to start with `^` and end with `$`, e.g. `^[012]$:OK`. For details see https://ruby-doc.org/core-2.7.1/Regexp.html#class-Regexp-label-Character+Classes[Ruby Regexp class]. Number replacements can also be performed, e.g. `<8.2` or `<>3`. This action if always performed *after* `format`and *before* `filter_columns`.'
36
- param_filter_columns = '| `filter_columns="<column_name_1>,<column_name_2>,..."` | Removes specified columns from result. This action is always performed *after* `format` and `replace_values`.'
35
+
36
+ param_format = '| `format="<format_col1>,<format_col2>,..."` | Specify format in which the results shall be returned, e.g. `%.2f` for only two digit decimals of a float. Several columns are separated by `,`. For details see https://ruby-doc.org/core-2.4.0/Kernel.html#method-i-sprintf[Ruby documentation].'
37
+ param_replace_values = "| `replace_values=\"<replace_1>:<with_1>,<replace_2>:<with_2>,...\"` | Specify result values which shall be replaced, e.g. `2:OK` will replace query values `2` with value `OK`. Replacing several values is possible by separating by `,`. Matches with regular expressions are also supported, but must be full matches, i.e. have to start with `^` and end with `$`, e.g. `^[012]$:OK`. For details see https://ruby-doc.org/core-2.7.1/Regexp.html#class-Regexp-label-Character+Classes[Ruby Regexp class]. Number replacements can also be performed, e.g. `<8.2` or `<>3`. #{exec_order}"
38
+ param_filter_columns = '| `filter_columns="<column_name_1>,<column_name_2>,..."` | Removes specified columns from result.'
39
+ param_transpose = '| `transpose="true"` | Transposes the query result, i.e. columns become rows and rows become columnns.'
40
+ param_column_divider = '| `column_divider="<divider>"` | Replace the default column divider with another one. Defaults to ` | ` for being interpreted as a asciidoctor column.'
41
+ param_row_divider = '| `row_divider="<divider>"` | Replace the default row divider with another one. Defaults to `| ` for being interpreted as a asciidoctor row.'
42
+ param_timeout = '| `timeout="<timeout_in_seconds>" | Set a timeout for the current query. If not overridden with `grafana-default-timeout` in the report template, this defaults to 60 seconds.'
37
43
 
38
44
  help = "
39
45
  == Grafana Reporter Functions
@@ -60,14 +66,18 @@ module GrafanaReporter
60
66
  [%autowidth.stretch, options=\"header\"]
61
67
  |===
62
68
  | Option | Description
69
+ #{param_column_divider}
63
70
  #{param_dashboard} If this option, or the global option `grafana_default_dashboard` is set, the resulting alerts will be limited to this dashboard. To show all alerts in this case, specify `dashboard=\"\"` as option.
64
- #{param_filter_columns}
65
- #{param_format}
71
+ #{param_filter_columns} #{exec_order}
72
+ #{param_format} #{exec_order}
66
73
  #{param_from}
67
74
  #{param_instance}
68
75
  | `panel=\"<panel_id>\"` | If specified, the resulting alerts are filtered for this panel. This option will only work, if a `dashboard` or `grafana_default_dashboard` is set.
69
- #{param_replace_values}
76
+ #{param_replace_values} #{exec_order}
77
+ #{param_row_divider}
78
+ #{param_timeout}
70
79
  #{param_to}
80
+ #{param_transpose} #{exec_order}
71
81
  |===
72
82
  Additionally all query parameters from the https://grafana.com/docs/grafana/latest/http_api/alerting/#get-alerts[Grafana Alerting API], such as `query`, `state`, `limit`, `folderId` and others are supported.
73
83
 
@@ -80,14 +90,18 @@ Additionally all query parameters from the https://grafana.com/docs/grafana/late
80
90
  [%autowidth.stretch, options=\"header\"]
81
91
  |===
82
92
  | Option | Description
93
+ #{param_column_divider}
83
94
  #{param_dashboard} If this option, or the global option `grafana_default_dashboard` is set, the resulting annotations will be limited to this dashboard. To show all annotations in this case, specify `dashboard=\"\"` as option.
84
- #{param_filter_columns}
85
- #{param_format}
95
+ #{param_filter_columns} #{exec_order}
96
+ #{param_format} #{exec_order}
86
97
  #{param_from}
87
98
  #{param_instance}
88
99
  | `panel=\"<panel_id>\"` | If specified, the resulting annotations are filtered for this panel. This option will only work, if a `dashboard` or `grafana_default_dashboard` is set.
89
- #{param_replace_values}
100
+ #{param_replace_values} #{exec_order}
101
+ #{param_row_divider}
102
+ #{param_timeout}
90
103
  #{param_to}
104
+ #{param_transpose} #{exec_order}
91
105
  |===
92
106
  Additionally all quer parameters from the https://grafana.com/docs/grafana/latest/http_api/annotations/#find_annotations[Grafana Alerting API], such as `limit`, `alertId`, `panelId` and others are supported.
93
107
 
@@ -117,6 +131,7 @@ Additionally all quer parameters from the https://grafana.com/docs/grafana/lates
117
131
  #{param_dashboard}
118
132
  #{param_from}
119
133
  #{param_instance}
134
+ #{param_timeout}
120
135
  #{param_to}
121
136
  | `render-height=\"<height>\"` | can be used to override default `height` in which the panel shall be rendered
122
137
  | `render-width=\"<width>\"` | can be used to override default `width` in which the panel shall be rendered
@@ -133,13 +148,17 @@ Additionally all quer parameters from the https://grafana.com/docs/grafana/lates
133
148
  [%autowidth.stretch, options=\"header\"]
134
149
  |===
135
150
  | Option | Description
151
+ #{param_column_divider}
136
152
  #{param_dashboard}
137
- #{param_filter_columns}
138
- #{param_format}
153
+ #{param_filter_columns} #{exec_order}
154
+ #{param_format} #{exec_order}
139
155
  #{param_from}
140
156
  #{param_instance}
141
- #{param_replace_values}
157
+ #{param_replace_values} #{exec_order}
158
+ #{param_row_divider}
159
+ #{param_timeout}
142
160
  #{param_to}
161
+ #{param_transpose} #{exec_order}
143
162
  |===
144
163
 
145
164
  === `grafana_panel_query_value`
@@ -152,11 +171,13 @@ Additionally all quer parameters from the https://grafana.com/docs/grafana/lates
152
171
  |===
153
172
  | Option | Description
154
173
  #{param_dashboard}
155
- #{param_filter_columns}
156
- #{param_format}
174
+ #{param_filter_columns} #{exec_order}
175
+ #{param_format} #{exec_order}
157
176
  #{param_from}
158
177
  #{param_instance}
159
- #{param_replace_values}
178
+ #{param_replace_values} #{exec_order}
179
+ #{param_row_divider}
180
+ #{param_timeout}
160
181
  #{param_to}
161
182
  |===
162
183
 
@@ -169,12 +190,16 @@ Additionally all quer parameters from the https://grafana.com/docs/grafana/lates
169
190
  [%autowidth.stretch, options=\"header\"]
170
191
  |===
171
192
  | Option | Description
172
- #{param_filter_columns}
173
- #{param_format}
193
+ #{param_column_divider}
194
+ #{param_filter_columns} #{exec_order}
195
+ #{param_format} #{exec_order}
174
196
  #{param_from}
175
197
  #{param_instance}
176
- #{param_replace_values}
198
+ #{param_replace_values} #{exec_order}
199
+ #{param_row_divider}
200
+ #{param_timeout}
177
201
  #{param_to}
202
+ #{param_transpose} #{exec_order}
178
203
  |===
179
204
 
180
205
  === `grafana_sql_value`
@@ -186,11 +211,12 @@ Additionally all quer parameters from the https://grafana.com/docs/grafana/lates
186
211
  [%autowidth.stretch, options=\"header\"]
187
212
  |===
188
213
  | Option | Description
189
- #{param_filter_columns}
190
- #{param_format}
214
+ #{param_filter_columns} #{exec_order}
215
+ #{param_format} #{exec_order}
191
216
  #{param_from}
192
217
  #{param_instance}
193
- #{param_replace_values}
218
+ #{param_replace_values} #{exec_order}
219
+ #{param_timeout}
194
220
  #{param_to}
195
221
  |==="
196
222
 
@@ -5,8 +5,33 @@ require_relative 'processor_mixin'
5
5
  module GrafanaReporter
6
6
  module Asciidoctor
7
7
  module Extensions
8
- # TODO: add documentation
9
- class ValueAsVariableIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
8
+ # Implements the hook
9
+ # include::grafana_value_as_variable[<options>]
10
+ #
11
+ # Returns an attribute definition in asciidoctor format. This is needed if you want to refer to values of
12
+ # a grafana query within a variable in asciidoctor. As this works without this function for the
13
+ # `IncludeProcessor`s values, it will not work for all the other processors.
14
+ #
15
+ # This method is just a proxy for all other hooks and will forward parameters accordingly.
16
+ #
17
+ # Example:
18
+ #
19
+ # include:grafana_value_as_variable[call="grafana_sql_value:1",variable_name="my_variable",sql="SELECT 'looks good'",<any_other_option>]
20
+ #
21
+ # This will call the {SqlValueInlineMacro} with `datasource_id` set to `1` and store the result in the
22
+ # variable. The resulting asciidoctor variable definition will be created as:
23
+ #
24
+ # :my_variable: looks good
25
+ #
26
+ # and can be refered to in your document easily as
27
+ #
28
+ # {my_variable}
29
+ #
30
+ # == Supported options
31
+ # +call+ - regular call to the reporter hook (*mandatory*)
32
+ #
33
+ # +variable_name+ - name of the variable, to which the result shall be assigned (*mandatory*)
34
+ class ValueAsVariableIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
10
35
  include ProcessorMixin
11
36
 
12
37
  # :nodoc:
@@ -12,7 +12,7 @@ module GrafanaReporter
12
12
  @from = translate_date(@from, @variables['grafana-report-timestamp'], false)
13
13
  @to = translate_date(@to, @variables['grafana-report-timestamp'], true)
14
14
  # rename "render-" variables
15
- @variables.transform_keys! { |k| k.gsub(/^render-/, '') }
15
+ @variables = @variables.each_with_object({}) { |(k,v), h| h[k.gsub(/^render-/, '')] = v }
16
16
  end
17
17
 
18
18
  # Returns the body of the http query, which contains the raw image.
@@ -8,10 +8,8 @@ module GrafanaReporter
8
8
  # @param item_hash [Hash] variables from item configuration level, i.e. specific call, which may override document
9
9
  # @return [void]
10
10
  def merge_hash_variables(document_hash, item_hash)
11
- merge_variables(document_hash.select { |k, _v| k =~ /^var-/ || k == 'grafana-report-timestamp' }.transform_values { |item| ::Grafana::Variable.new(item) })
12
- # TODO: add documentation for transpose, column_divider and row_divider
13
- merge_variables(item_hash.select { |k, _v| k =~ /^var-/ || k =~ /^render-/ || k =~ /filter_columns|format|replace_values_.*|transpose|column_divider|row_divider/ }.transform_values { |item| ::Grafana::Variable.new(item) })
14
- # TODO: add documentation for timeout and grafana-default-timeout
11
+ merge_variables(document_hash.select { |k, _v| k =~ /^var-/ || k == 'grafana-report-timestamp' }.each_with_object({}) { |(k,v), h| h[k] = ::Grafana::Variable.new(v) })
12
+ merge_variables(item_hash.select { |k, _v| k =~ /^var-/ || k =~ /^render-/ || k =~ /filter_columns|format|replace_values_.*|transpose|column_divider|row_divider/ }.each_with_object({}) { |(k,v), h| h[k] = ::Grafana::Variable.new(v) })
15
13
  self.timeout = item_hash['timeout'] || document_hash['grafana-default-timeout'] || timeout
16
14
  self.from = item_hash['from'] || document_hash['from'] || from
17
15
  self.to = item_hash['to'] || document_hash['to'] || to
@@ -30,7 +28,6 @@ module GrafanaReporter
30
28
  # }
31
29
  # @param raw_result [Hash] query result hash from grafana
32
30
  # @return [Hash] sql result formatted as stated above
33
- # TODO: support series query results properly
34
31
  def preformat_sql_result(raw_result)
35
32
  results = {}
36
33
  results.default = []
@@ -39,26 +36,13 @@ module GrafanaReporter
39
36
  if query_result.key?('error')
40
37
  results[:header] = results[:header] << ['SQL Error']
41
38
  results[:content] = [[query_result['error']]]
39
+
42
40
  elsif query_result['tables']
43
41
  query_result['tables'].each do |table|
44
42
  results[:header] = results[:header] << table['columns'].map { |header| header['text'] }
45
43
  results[:content] = table['rows']
46
44
  end
47
- else
48
- # TODO: add test for series results
49
- results[:header] = 'time'
50
- query_result['series'].each do |table|
51
- results[:header] << table[:name]
52
- results[:content] = []
53
- content_position = results[:header].length - 1
54
- table[:points].each do |point|
55
- result = []
56
- result << point[1]
57
- (content_position - 1).times { result << nil }
58
- result << point[0]
59
- results[:content][0] << result
60
- end
61
- end
45
+
62
46
  end
63
47
  end
64
48
 
@@ -18,11 +18,6 @@ module GrafanaReporter
18
18
  results = format_columns(results, @variables['format'])
19
19
  results = replace_values(results, @variables.select { |k, _v| k =~ /^replace_values_\d+/ })
20
20
  results = filter_columns(results, @variables['filter_columns'])
21
- if @variables['filter_column']
22
- @report.logger.warn("DEPRECATED: Call of no longer supported function 'filter_column' has been found."\
23
- " Rename to 'filter_columns'")
24
- results = filter_columns(results, @variables['filter_column'])
25
- end
26
21
 
27
22
  unless results[:content].empty?
28
23
  unless results[:content][0].empty?
@@ -17,11 +17,6 @@ module GrafanaReporter
17
17
  results = format_columns(results, @variables['format'])
18
18
  results = replace_values(results, @variables.select { |k, _v| k =~ /^replace_values_\d+/ })
19
19
  results = filter_columns(results, @variables['filter_columns'])
20
- if @variables['filter_column']
21
- @report.logger.warn("DEPRECATED: Call of no longer supported function 'filter_column' has been found."\
22
- " Rename to 'filter_columns'")
23
- results = filter_columns(results, @variables['filter_column'])
24
- end
25
20
  results = transpose(results, @variables['transpose'])
26
21
  row_divider = '| '
27
22
  row_divider = @variables['row_divider'].raw_value if @variables['row_divider'].is_a?(Grafana::Variable)
@@ -23,19 +23,21 @@ module GrafanaReporter
23
23
 
24
24
  # Used to access the configuration hash. To make sure, that the configuration is
25
25
  # valid, call {#validate}.
26
- #
27
- # NOTE: This function overwrites all existing configurations
28
- attr_accessor :config
26
+ attr_reader :config
29
27
 
30
28
  def initialize
31
29
  @config = {}
32
30
  @logger = ::Logger.new($stderr, level: :unknown)
33
- # TODO: set report class somewhere else, but make it known here
34
- self.report_class = Asciidoctor::Report
35
31
  end
36
32
 
37
33
  attr_accessor :logger
38
34
 
35
+ # Used to overwrite the current configuration.
36
+ def config=(new_config)
37
+ @config = new_config
38
+ update_configuration
39
+ end
40
+
39
41
  # @return [String] mode, in which the reporting shall be executed. One of {MODE_CONNECTION_TEST},
40
42
  # {MODE_SINGLE_RENDER} and {MODE_SERVICE}.
41
43
  def mode
@@ -50,6 +52,7 @@ module GrafanaReporter
50
52
  # @return [String] full path of configured report template. Only needed in {MODE_SINGLE_RENDER}.
51
53
  def template
52
54
  return nil if get_config('default-document-attributes:var-template').nil?
55
+
53
56
  "#{templates_folder}#{get_config('default-document-attributes:var-template')}.adoc"
54
57
  end
55
58
 
@@ -152,6 +155,7 @@ module GrafanaReporter
152
155
  # and all necessary folders exist. Appropriate errors are raised in case of errors.
153
156
  # @return [void]
154
157
  def validate
158
+ check_deprecation
155
159
  validate_schema(schema, @config)
156
160
 
157
161
  # check if set folders exist
@@ -160,8 +164,60 @@ module GrafanaReporter
160
164
  raise FolderDoesNotExistError.new(images_folder, 'images-folder') unless File.directory?(images_folder)
161
165
  end
162
166
 
167
+ # Can be used to configure or overwrite single parameters.
168
+ #
169
+ # @param path [String] path of the paramter to set, e.g. +grafana-reporter:webservice-port+
170
+ # @param value [Object] value to set
171
+ def set_param(path, value)
172
+ return if path.nil?
173
+
174
+ levels = path.split(':')
175
+ last_level = levels.pop
176
+
177
+ cur_pos = @config
178
+ levels.each do |subpath|
179
+ if cur_pos[subpath]
180
+ cur_pos = cur_pos[subpath]
181
+ else
182
+ cur_pos[subpath] = {}
183
+ cur_pos = cur_pos[subpath]
184
+ end
185
+ end
186
+
187
+ cur_pos[last_level] = value
188
+ update_configuration
189
+ end
190
+
191
+ # Merge the given configuration object settings with the current config, i.e. overwrite and add all
192
+ # settings from the given config, but keep the not specified configs from the current object.
193
+ #
194
+ # param other_config [Configuration] other configuration object
195
+ def merge!(other_config)
196
+ self.config.merge!(other_config.config) { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2) : v2 }
197
+ update_configuration
198
+ end
199
+
163
200
  private
164
201
 
202
+ def check_deprecation
203
+ return if report_class
204
+
205
+ logger.warn('DEPRECATION WARNING: Your configuration explicitly needs to specify the \'grafana-reporter:report-class\' value. '\
206
+ 'Currently this defaults to \'GrafanaReporter::Asciidoctor::Report\'. You can get rid of this warning, if you explicitly '\
207
+ 'set this configuration in your configuration file. Setting this default will be removed in a future version.')
208
+ set_param('grafana-reporter:report-class', 'GrafanaReporter::Asciidoctor::Report')
209
+ end
210
+
211
+ def update_configuration
212
+ if get_config('grafana-reporter:debug-level') =~ /DEBUG|INFO|WARN|ERROR|FATAL|UNKNOWN/
213
+ @logger.level = Object.const_get("::Logger::Severity::#{get_config('grafana-reporter:debug-level')}")
214
+ end
215
+
216
+ if get_config('grafana-reporter:report-class')
217
+ self.report_class = Object.const_get(get_config('grafana-reporter:report-class'))
218
+ end
219
+ end
220
+
165
221
  def get_config(path)
166
222
  return if path.nil?
167
223
 
@@ -241,11 +297,13 @@ module GrafanaReporter
241
297
  'default-document-attributes' => [Hash, 0],
242
298
  'grafana-reporter' =>
243
299
  [
244
- Hash, 0,
300
+ Hash, 1,
245
301
  {
302
+ 'debug-level' => [String, 0],
246
303
  'run-mode' => [String, 0],
247
304
  'test-instance' => [String, 0],
248
305
  'templates-folder' => [String, 0],
306
+ 'report-class' => [String, 1],
249
307
  'reports-folder' => [String, 0],
250
308
  'report-retention' => [Integer, 0],
251
309
  'webservice-port' => [Integer, 0]
@@ -27,3 +27,5 @@ folders = [
27
27
  %w[grafana_reporter application]
28
28
  ]
29
29
  folders.each { |folder| Dir[File.join(__dir__, *folder, '*.rb')].sort.each { |file| require_relative file } }
30
+
31
+ # TODO check if panel with ID exists before trying to render image
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.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Kohlmeyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-30 00:00:00.000000000 Z
11
+ date: 2020-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -47,7 +47,7 @@ dependencies:
47
47
  version: 1.1.1
48
48
  - - "<"
49
49
  - !ruby/object:Gem::Version
50
- version: '2.3'
50
+ version: '2.4'
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
@@ -57,7 +57,7 @@ dependencies:
57
57
  version: 1.1.1
58
58
  - - "<"
59
59
  - !ruby/object:Gem::Version
60
- version: '2.3'
60
+ version: '2.4'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: rspec
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -100,13 +100,10 @@ dependencies:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
102
  version: '3.9'
103
- description: |
104
- Provides a standalone and a webservice frontend for creating reports
105
- based on asciidoctor, including interfaces to integrate dynamic content
106
- captured from grafana.
107
-
108
- By default the reports will be converted to PDF documents, whereas other
109
- target formats can be used as well.
103
+ description: Provides a standalone and a webservice frontend for creating reportsbased
104
+ on asciidoctor, including interfaces to integrate dynamic contentcaptured from grafana.By
105
+ default the reports will be converted to PDF documents, whereas othertarget formats
106
+ can be used as well.
110
107
  email: kohly@gmx.de
111
108
  executables:
112
109
  - ruby-grafana-reporter
@@ -174,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
174
171
  requirements:
175
172
  - - ">="
176
173
  - !ruby/object:Gem::Version
177
- version: 1.9.3
174
+ version: 2.3.3
178
175
  required_rubygems_version: !ruby/object:Gem::Requirement
179
176
  requirements:
180
177
  - - ">="