ruby-grafana-reporter 0.4.5 → 0.5.0
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 +2 -2
 - data/lib/VERSION.rb +2 -2
 - data/lib/grafana/abstract_datasource.rb +3 -0
 - data/lib/grafana/dashboard.rb +6 -1
 - data/lib/grafana/errors.rb +2 -1
 - data/lib/grafana/grafana.rb +24 -0
 - data/lib/grafana/grafana_environment_datasource.rb +56 -0
 - data/lib/grafana/image_rendering_datasource.rb +5 -1
 - data/lib/grafana/influxdb_datasource.rb +0 -2
 - data/lib/grafana/sql_datasource.rb +2 -0
 - data/lib/grafana/variable.rb +46 -23
 - data/lib/grafana/webrequest.rb +1 -0
 - data/lib/grafana_reporter/abstract_query.rb +31 -23
 - data/lib/grafana_reporter/abstract_report.rb +2 -0
 - data/lib/grafana_reporter/abstract_table_format_strategy.rb +44 -4
 - data/lib/grafana_reporter/alerts_table_query.rb +2 -1
 - data/lib/grafana_reporter/annotations_table_query.rb +2 -1
 - data/lib/grafana_reporter/application/webservice.rb +8 -4
 - data/lib/grafana_reporter/asciidoctor/adoc_plain_table_format_strategy.rb +11 -9
 - data/lib/grafana_reporter/asciidoctor/help.rb +24 -12
 - data/lib/grafana_reporter/asciidoctor/panel_image_block_macro.rb +2 -4
 - data/lib/grafana_reporter/asciidoctor/panel_image_inline_macro.rb +2 -4
 - data/lib/grafana_reporter/asciidoctor/show_environment_include_processor.rb +37 -6
 - data/lib/grafana_reporter/asciidoctor/value_as_variable_include_processor.rb +0 -5
 - data/lib/grafana_reporter/configuration.rb +27 -0
 - data/lib/grafana_reporter/console_configuration_wizard.rb +3 -1
 - data/lib/grafana_reporter/csv_table_format_strategy.rb +11 -9
 - data/lib/grafana_reporter/demo_report_wizard.rb +3 -6
 - data/lib/grafana_reporter/panel_image_query.rb +0 -1
 - data/lib/grafana_reporter/query_value_query.rb +7 -1
 - data/lib/grafana_reporter/reporter_environment_datasource.rb +24 -0
 - data/lib/ruby_grafana_reporter.rb +0 -11
 - metadata +4 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: '06912db0a0635560dca75c00c01c047deac42741c7c6ba2ee717cbccdf26cb19'
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 8d09e509266737bf1b73c3f6ad5c03255de461c116a6e5ec7b45bfaef56520b7
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 66e81686e253f8e98101f97b0b08db97f955cd1c274f2ed683f597b675c228adf198cd2c66f9ce3df05506a760564643e43b94c40fa952b13748122ecc8d6890
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 916ec07231acf19c20b0f01d7bfe9a47d5825a8e0c3a6c67a9fa615e2b993343d1506fb129cc72b66e2be9b02102c15e338a6e8b5746286494de4164a9678c38
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -30,7 +30,7 @@ professional reporting functionality. And this is, where the ruby grafana report 
     | 
|
| 
       30 
30 
     | 
    
         
             
            steps in.
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
            The key functionality of the reporter is to capture data and images from grafana
         
     | 
| 
       33 
     | 
    
         
            -
            dashboards and to use it in your custom templates to finally create reports in PDF
         
     | 
| 
      
 33 
     | 
    
         
            +
            dashboards and to use it in your custom templates to finally create reports in PDF
         
     | 
| 
       34 
34 
     | 
    
         
             
            (default), HTML, or any other format.
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
            By default (an extended version of) Asciidoctor is enabled as template language.
         
     | 
| 
         @@ -65,7 +65,7 @@ Database                  | Image rendering | Raw queries   | Composed queries 
     | 
|
| 
       65 
65 
     | 
    
         
             
            ------------------------- | :-------------: | :-----------: | :------------:
         
     | 
| 
       66 
66 
     | 
    
         
             
            all SQL based datasources | supported       | supported     | supported
         
     | 
| 
       67 
67 
     | 
    
         
             
            Graphite                  | supported       | supported     | supported
         
     | 
| 
       68 
     | 
    
         
            -
            InfluxDB                  | supported       | supported     |  
     | 
| 
      
 68 
     | 
    
         
            +
            InfluxDB                  | supported       | supported     | supported
         
     | 
| 
       69 
69 
     | 
    
         
             
            Prometheus                | supported       | supported     | n/a in grafana
         
     | 
| 
       70 
70 
     | 
    
         
             
            other datasources         | supported       | not supported | not supported
         
     | 
| 
       71 
71 
     | 
    
         | 
    
        data/lib/VERSION.rb
    CHANGED
    
    
| 
         @@ -128,6 +128,9 @@ module Grafana 
     | 
|
| 
       128 
128 
     | 
    
         
             
                    repeat_count += 1
         
     | 
| 
       129 
129 
     | 
    
         | 
| 
       130 
130 
     | 
    
         
             
                    variables.each do |name, variable|
         
     | 
| 
      
 131 
     | 
    
         
            +
                      # do not replace with non grafana variables
         
     | 
| 
      
 132 
     | 
    
         
            +
                      next unless name =~ /^var-/
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
       131 
134 
     | 
    
         
             
                      # only set ticks if value is string
         
     | 
| 
       132 
135 
     | 
    
         
             
                      var_name = name.gsub(/^var-/, '')
         
     | 
| 
       133 
136 
     | 
    
         
             
                      next unless var_name =~ /^\w+$/
         
     | 
    
        data/lib/grafana/dashboard.rb
    CHANGED
    
    | 
         @@ -35,6 +35,11 @@ module Grafana 
     | 
|
| 
       35 
35 
     | 
    
         
             
                  @model['uid']
         
     | 
| 
       36 
36 
     | 
    
         
             
                end
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
      
 38 
     | 
    
         
            +
                # @return [String] dashboard title
         
     | 
| 
      
 39 
     | 
    
         
            +
                def title
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @model['title']
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       38 
43 
     | 
    
         
             
                # @return [Panel] panel for the specified ID
         
     | 
| 
       39 
44 
     | 
    
         
             
                def panel(id)
         
     | 
| 
       40 
45 
     | 
    
         
             
                  panels = @panels.select { |item| item.field('id') == id.to_i }
         
     | 
| 
         @@ -53,7 +58,7 @@ module Grafana 
     | 
|
| 
       53 
58 
     | 
    
         
             
                  list = @model['templating']['list']
         
     | 
| 
       54 
59 
     | 
    
         
             
                  return unless list.is_a? Array
         
     | 
| 
       55 
60 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                  list.each { |item| @variables << Variable.new(item) }
         
     | 
| 
      
 61 
     | 
    
         
            +
                  list.each { |item| @variables << Variable.new(item, self) }
         
     | 
| 
       57 
62 
     | 
    
         
             
                end
         
     | 
| 
       58 
63 
     | 
    
         | 
| 
       59 
64 
     | 
    
         
             
                # read panels
         
     | 
    
        data/lib/grafana/errors.rb
    CHANGED
    
    | 
         @@ -53,7 +53,8 @@ module Grafana 
     | 
|
| 
       53 
53 
     | 
    
         
             
              class ImageCouldNotBeRenderedError < GrafanaError
         
     | 
| 
       54 
54 
     | 
    
         
             
                def initialize(panel)
         
     | 
| 
       55 
55 
     | 
    
         
             
                  super("The specified panel '#{panel.id}' from dashboard '#{panel.dashboard.id}' could not be "\
         
     | 
| 
       56 
     | 
    
         
            -
                    'rendered to an image.' 
     | 
| 
      
 56 
     | 
    
         
            +
                    'rendered to an image. Check if rendering is possible manually by selecting "Share" and then '\
         
     | 
| 
      
 57 
     | 
    
         
            +
                    '"Direct link rendered image" from a panel\'s options menu.')
         
     | 
| 
       57 
58 
     | 
    
         
             
                end
         
     | 
| 
       58 
59 
     | 
    
         
             
              end
         
     | 
| 
       59 
60 
     | 
    
         | 
    
        data/lib/grafana/grafana.rb
    CHANGED
    
    | 
         @@ -25,6 +25,30 @@ module Grafana 
     | 
|
| 
       25 
25 
     | 
    
         
             
                  initialize_datasources unless @base_uri.empty?
         
     | 
| 
       26 
26 
     | 
    
         
             
                end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
      
 28 
     | 
    
         
            +
                # @return [Hash] Information about the current organization
         
     | 
| 
      
 29 
     | 
    
         
            +
                def organization
         
     | 
| 
      
 30 
     | 
    
         
            +
                  return @organization if @organization
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  response = prepare_request({ relative_url: '/api/org/' }).execute
         
     | 
| 
      
 33 
     | 
    
         
            +
                  if response.is_a?(Net::HTTPOK)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    @organization = JSON.parse(response.body)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  @organization
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                # @return [String] grafana version
         
     | 
| 
      
 41 
     | 
    
         
            +
                def version
         
     | 
| 
      
 42 
     | 
    
         
            +
                  return @version if @version
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  response = prepare_request({ relative_url: '/api/health' }).execute
         
     | 
| 
      
 45 
     | 
    
         
            +
                  if response.is_a?(Net::HTTPOK)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @version = JSON.parse(response.body)['version']
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  @version
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
       28 
52 
     | 
    
         
             
                # Used to test a connection to the grafana instance.
         
     | 
| 
       29 
53 
     | 
    
         
             
                #
         
     | 
| 
       30 
54 
     | 
    
         
             
                # Running this function also determines, if the API configured here has Admin or NON-Admin privileges,
         
     | 
| 
         @@ -0,0 +1,56 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Grafana
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Implements a datasource to return environment related information about the grafana instance in a tabular format.
         
     | 
| 
      
 5 
     | 
    
         
            +
              class GrafanaEnvironmentDatasource < ::Grafana::AbstractDatasource
         
     | 
| 
      
 6 
     | 
    
         
            +
                # +:raw_query+ needs to contain a Hash with the following structure:
         
     | 
| 
      
 7 
     | 
    
         
            +
                #
         
     | 
| 
      
 8 
     | 
    
         
            +
                #   {
         
     | 
| 
      
 9 
     | 
    
         
            +
                #     grafana:  {Grafana} object to query
         
     | 
| 
      
 10 
     | 
    
         
            +
                #     mode:     'general' (default) or 'dashboards' for receiving different environment information
         
     | 
| 
      
 11 
     | 
    
         
            +
                #   }
         
     | 
| 
      
 12 
     | 
    
         
            +
                # @see AbstractDatasource#request
         
     | 
| 
      
 13 
     | 
    
         
            +
                def request(query_description)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  raise MissingSqlQueryError if query_description[:raw_query].nil?
         
     | 
| 
      
 15 
     | 
    
         
            +
                  raw_query = {mode: 'general'}.merge(query_description[:raw_query])
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  return dashboards_data(raw_query[:grafana]) if raw_query[:mode] == 'dashboards'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  general_data(raw_query[:grafana])
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # @see AbstractDatasource#default_variable_format
         
     | 
| 
      
 23 
     | 
    
         
            +
                def default_variable_format
         
     | 
| 
      
 24 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                # @see AbstractDatasource#name
         
     | 
| 
      
 28 
     | 
    
         
            +
                def name
         
     | 
| 
      
 29 
     | 
    
         
            +
                  self.class.to_s
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                private
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def general_data(grafana)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  {
         
     | 
| 
      
 36 
     | 
    
         
            +
                    header: ['Version', 'Organization Name', 'Organization ID', 'Access permissions'],
         
     | 
| 
      
 37 
     | 
    
         
            +
                    content: [[grafana.version,
         
     | 
| 
      
 38 
     | 
    
         
            +
                               grafana.organization['name'],
         
     | 
| 
      
 39 
     | 
    
         
            +
                               grafana.organization['id'],
         
     | 
| 
      
 40 
     | 
    
         
            +
                               grafana.test_connection]]
         
     | 
| 
      
 41 
     | 
    
         
            +
                  }
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def dashboards_data(grafana)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  content = []
         
     | 
| 
      
 46 
     | 
    
         
            +
                  grafana.dashboard_ids.each do |id|
         
     | 
| 
      
 47 
     | 
    
         
            +
                    content << [id, grafana.dashboard(id).title, grafana.dashboard(id).panels.length]
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  {
         
     | 
| 
      
 51 
     | 
    
         
            +
                    header: ['Dashboard ID', 'Dashboard Name', '# Panels'],
         
     | 
| 
      
 52 
     | 
    
         
            +
                    content: content
         
     | 
| 
      
 53 
     | 
    
         
            +
                  }
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -10,12 +10,16 @@ module Grafana 
     | 
|
| 
       10 
10 
     | 
    
         
             
                #   }
         
     | 
| 
       11 
11 
     | 
    
         
             
                # @see AbstractDatasource#request
         
     | 
| 
       12 
12 
     | 
    
         
             
                def request(query_description)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  panel = query_description[:raw_query][:panel]
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       13 
15 
     | 
    
         
             
                  webrequest = query_description[:prepared_request]
         
     | 
| 
       14 
     | 
    
         
            -
                  webrequest.relative_url =  
     | 
| 
      
 16 
     | 
    
         
            +
                  webrequest.relative_url = panel.render_url + url_params(query_description)
         
     | 
| 
       15 
17 
     | 
    
         
             
                  webrequest.options.merge!({ accept: 'image/png' })
         
     | 
| 
       16 
18 
     | 
    
         | 
| 
       17 
19 
     | 
    
         
             
                  result = webrequest.execute
         
     | 
| 
       18 
20 
     | 
    
         | 
| 
      
 21 
     | 
    
         
            +
                  raise ImageCouldNotBeRenderedError, panel if result.body.include?('<html')
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
       19 
23 
     | 
    
         
             
                  { header: ['image'], content: [result.body] }
         
     | 
| 
       20 
24 
     | 
    
         
             
                end
         
     | 
| 
       21 
25 
     | 
    
         | 
| 
         @@ -24,8 +24,6 @@ module Grafana 
     | 
|
| 
       24 
24 
     | 
    
         
             
                  query = query.gsub(/\$timeFilter(?=\W|$)/, "time >= #{query_description[:from]}ms and time <= #{query_description[:to]}ms")
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                  # replace grafana variables $__interval and $__interval_ms in query
         
     | 
| 
       27 
     | 
    
         
            -
                  # TODO: influx datasource currently uses a fixed values of 1000 width for interval variables specified in a query - it should be possible to calculate this according to grafana
         
     | 
| 
       28 
     | 
    
         
            -
                  # TODO: check where calculation and replacement of interval variable should take place
         
     | 
| 
       29 
27 
     | 
    
         
             
                  query = query.gsub(/\$(?:__)?interval(?=\W|$)/, "#{((query_description[:to].to_i - query_description[:from].to_i) / 1000 / 1000).to_i}s")
         
     | 
| 
       30 
28 
     | 
    
         
             
                  query = query.gsub(/\$(?:__)?interval_ms(?=\W|$)/, "#{((query_description[:to].to_i - query_description[:from].to_i) / 1000).to_i}")
         
     | 
| 
       31 
29 
     | 
    
         | 
    
        data/lib/grafana/variable.rb
    CHANGED
    
    | 
         @@ -29,15 +29,14 @@ module Grafana 
     | 
|
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
                # @param config_or_value [Hash, Object] configuration hash of a variable out of an {Dashboard} instance
         
     | 
| 
       31 
31 
     | 
    
         
             
                #  or a value of any kind.
         
     | 
| 
       32 
     | 
    
         
            -
                 
     | 
| 
      
 32 
     | 
    
         
            +
                # @param dashboard [Dashboard] parent dashboard, if applicable; especially needed for query variable
         
     | 
| 
      
 33 
     | 
    
         
            +
                #  evaluation.
         
     | 
| 
      
 34 
     | 
    
         
            +
                def initialize(config_or_value, dashboard = nil)
         
     | 
| 
       33 
35 
     | 
    
         
             
                  if config_or_value.is_a? Hash
         
     | 
| 
      
 36 
     | 
    
         
            +
                    @dashboard = dashboard
         
     | 
| 
       34 
37 
     | 
    
         
             
                    @config = config_or_value
         
     | 
| 
       35 
38 
     | 
    
         
             
                    @name = @config['name']
         
     | 
| 
       36 
     | 
    
         
            -
                     
     | 
| 
       37 
     | 
    
         
            -
                    unless @config['current'].nil?
         
     | 
| 
       38 
     | 
    
         
            -
                      @raw_value = @config['current']['value']
         
     | 
| 
       39 
     | 
    
         
            -
                      @text = @config['current']['text']
         
     | 
| 
       40 
     | 
    
         
            -
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
                    init_values
         
     | 
| 
       41 
40 
     | 
    
         
             
                  else
         
     | 
| 
       42 
41 
     | 
    
         
             
                    @config = {}
         
     | 
| 
       43 
42 
     | 
    
         
             
                    @raw_value = config_or_value
         
     | 
| 
         @@ -68,14 +67,19 @@ module Grafana 
     | 
|
| 
       68 
67 
     | 
    
         
             
                  if value == '$__all'
         
     | 
| 
       69 
68 
     | 
    
         
             
                    if !@config['options'].empty?
         
     | 
| 
       70 
69 
     | 
    
         
             
                      # this query contains predefined values, so capture them and format the values accordingly
         
     | 
| 
       71 
     | 
    
         
            -
                      # this happens either  
     | 
| 
       72 
     | 
    
         
            -
                      value = @config['options'].map { |item| item['value'] }
         
     | 
| 
      
 70 
     | 
    
         
            +
                      # this happens either for type='custom' or type 'query', if it is never updated
         
     | 
| 
      
 71 
     | 
    
         
            +
                      value = @config['options'].reject { |item| item['value'] == '$__all' }.map { |item| item['value'] }
         
     | 
| 
       73 
72 
     | 
    
         | 
| 
       74 
73 
     | 
    
         
             
                    elsif @config['type'] == 'query' && !@config['query'].empty?
         
     | 
| 
       75 
     | 
    
         
            -
                      #  
     | 
| 
       76 
     | 
    
         
            -
                      #  
     | 
| 
       77 
     | 
    
         
            -
                       
     | 
| 
       78 
     | 
    
         
            -
                       
     | 
| 
      
 74 
     | 
    
         
            +
                      # variables in this configuration are not stored in grafana, i.e. if all is selected here,
         
     | 
| 
      
 75 
     | 
    
         
            +
                      # the values have to be fetched from the datasource
         
     | 
| 
      
 76 
     | 
    
         
            +
                      query = ::GrafanaReporter::QueryValueQuery.new(@dashboard)
         
     | 
| 
      
 77 
     | 
    
         
            +
                      query.datasource = @dashboard.grafana.datasource_by_name(@config['datasource'])
         
     | 
| 
      
 78 
     | 
    
         
            +
                      query.variables['result_type'] = Variable.new('object')
         
     | 
| 
      
 79 
     | 
    
         
            +
                      query.raw_query = @config['query']
         
     | 
| 
      
 80 
     | 
    
         
            +
                      result = query.execute
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                      value = result[:content].map { |item| item[0].to_s }
         
     | 
| 
       79 
83 
     | 
    
         | 
| 
       80 
84 
     | 
    
         
             
                    else
         
     | 
| 
       81 
85 
     | 
    
         
             
                      # TODO: add support for variable type: 'datasource' and 'adhoc'
         
     | 
| 
         @@ -149,8 +153,10 @@ module Grafana 
     | 
|
| 
       149 
153 
     | 
    
         
             
                    value.gsub(%r{[" |=/\\]}, '\\\\\0')
         
     | 
| 
       150 
154 
     | 
    
         | 
| 
       151 
155 
     | 
    
         
             
                  when /^date(?::(?<format>.*))?$/
         
     | 
| 
       152 
     | 
    
         
            -
                     
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
      
 156 
     | 
    
         
            +
                    if multi? && value.is_a?(Array)
         
     | 
| 
      
 157 
     | 
    
         
            +
                      raise GrafanaError, "Date format cannot be specified for a variable containing an array of values"
         
     | 
| 
      
 158 
     | 
    
         
            +
                    end
         
     | 
| 
      
 159 
     | 
    
         
            +
                    Variable.format_as_date(value, Regexp.last_match(1))
         
     | 
| 
       154 
160 
     | 
    
         | 
| 
       155 
161 
     | 
    
         
             
                  when ''
         
     | 
| 
       156 
162 
     | 
    
         
             
                    # default
         
     | 
| 
         @@ -168,8 +174,9 @@ module Grafana 
     | 
|
| 
       168 
174 
     | 
    
         
             
                  end
         
     | 
| 
       169 
175 
     | 
    
         
             
                end
         
     | 
| 
       170 
176 
     | 
    
         | 
| 
       171 
     | 
    
         
            -
                # @return [Boolean] true, if the value can contain multiple selections, i.e. can contain an Array
         
     | 
| 
      
 177 
     | 
    
         
            +
                # @return [Boolean] true, if the value can contain multiple selections, i.e. can contain an Array or does contain all
         
     | 
| 
       172 
178 
     | 
    
         
             
                def multi?
         
     | 
| 
      
 179 
     | 
    
         
            +
                  return true if @raw_value == '$__all'
         
     | 
| 
       173 
180 
     | 
    
         
             
                  return @config['multi'] unless @config['multi'].nil?
         
     | 
| 
       174 
181 
     | 
    
         | 
| 
       175 
182 
     | 
    
         
             
                  @raw_value.is_a? Array
         
     | 
| 
         @@ -187,12 +194,13 @@ module Grafana 
     | 
|
| 
       187 
194 
     | 
    
         
             
                  @text = new_text
         
     | 
| 
       188 
195 
     | 
    
         
             
                end
         
     | 
| 
       189 
196 
     | 
    
         | 
| 
       190 
     | 
    
         
            -
                 
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                # Realize time formatting according
         
     | 
| 
      
 197 
     | 
    
         
            +
                # Applies the date format according
         
     | 
| 
       193 
198 
     | 
    
         
             
                # {https://grafana.com/docs/grafana/latest/variables/variable-types/global-variables/#__from-and-__to}
         
     | 
| 
       194 
     | 
    
         
            -
                # and {https://momentjs.com/docs/#/displaying/}.
         
     | 
| 
       195 
     | 
    
         
            -
                 
     | 
| 
      
 199 
     | 
    
         
            +
                # and {https://momentjs.com/docs/#/displaying/} to a given value.
         
     | 
| 
      
 200 
     | 
    
         
            +
                # @param value [String] time as milliseconds to be formatted
         
     | 
| 
      
 201 
     | 
    
         
            +
                # @param format [String] format string in which the time value shall be returned
         
     | 
| 
      
 202 
     | 
    
         
            +
                # @return [String] time converted to the specified time format
         
     | 
| 
      
 203 
     | 
    
         
            +
                def self.format_as_date(value, format)
         
     | 
| 
       196 
204 
     | 
    
         
             
                  return (Float(value) / 1000).to_i.to_s if format == 'seconds'
         
     | 
| 
       197 
205 
     | 
    
         
             
                  return Time.at((Float(value) / 1000).to_i).utc.iso8601(3) if !format || (format == 'iso')
         
     | 
| 
       198 
206 
     | 
    
         | 
| 
         @@ -203,13 +211,12 @@ module Grafana 
     | 
|
| 
       203 
211 
     | 
    
         
             
                    tmp = work_string.scan(/^(?:M{1,4}|D{1,4}|d{1,4}|e|E|w{1,2}|W{1,2}|Y{4}|Y{2}|A|a|H{1,2}|
         
     | 
| 
       204 
212 
     | 
    
         
             
                                                h{1,2}|k{1,2}|m{1,2}|s{1,2}|S+|X)/x)
         
     | 
| 
       205 
213 
     | 
    
         | 
| 
       206 
     | 
    
         
            -
                    # TODO: add test for sub! and switch to non-modifying frozen string action
         
     | 
| 
       207 
214 
     | 
    
         
             
                    if tmp.empty?
         
     | 
| 
       208 
215 
     | 
    
         
             
                      matches << work_string[0]
         
     | 
| 
       209 
     | 
    
         
            -
                      work_string.sub 
     | 
| 
      
 216 
     | 
    
         
            +
                      work_string = work_string.sub(/^#{work_string[0]}/, '')
         
     | 
| 
       210 
217 
     | 
    
         
             
                    else
         
     | 
| 
       211 
218 
     | 
    
         
             
                      matches << tmp[0]
         
     | 
| 
       212 
     | 
    
         
            -
                      work_string.sub 
     | 
| 
      
 219 
     | 
    
         
            +
                      work_string = work_string.sub(/^#{tmp[0]}/, '')
         
     | 
| 
       213 
220 
     | 
    
         
             
                    end
         
     | 
| 
       214 
221 
     | 
    
         
             
                  end
         
     | 
| 
       215 
222 
     | 
    
         | 
| 
         @@ -221,5 +228,21 @@ module Grafana 
     | 
|
| 
       221 
228 
     | 
    
         | 
| 
       222 
229 
     | 
    
         
             
                  Time.at((Float(value) / 1000).to_i).strftime(format_string)
         
     | 
| 
       223 
230 
     | 
    
         
             
                end
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
                private
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
                def init_values
         
     | 
| 
      
 235 
     | 
    
         
            +
                  case @config['type']
         
     | 
| 
      
 236 
     | 
    
         
            +
                  when 'constant'
         
     | 
| 
      
 237 
     | 
    
         
            +
                    self.raw_value = @config['query']
         
     | 
| 
      
 238 
     | 
    
         
            +
             
     | 
| 
      
 239 
     | 
    
         
            +
                  else
         
     | 
| 
      
 240 
     | 
    
         
            +
                    if !@config['current'].nil?
         
     | 
| 
      
 241 
     | 
    
         
            +
                      self.raw_value = @config['current']['value']
         
     | 
| 
      
 242 
     | 
    
         
            +
                    else
         
     | 
| 
      
 243 
     | 
    
         
            +
                      raise GrafanaError.new("Grafana variable with type '#{@config['type']}' and name '#{@config['name']}' could not be handled properly. Please raise a ticket.")
         
     | 
| 
      
 244 
     | 
    
         
            +
                    end
         
     | 
| 
      
 245 
     | 
    
         
            +
                  end
         
     | 
| 
      
 246 
     | 
    
         
            +
                end
         
     | 
| 
       224 
247 
     | 
    
         
             
              end
         
     | 
| 
       225 
248 
     | 
    
         
             
            end
         
     | 
    
        data/lib/grafana/webrequest.rb
    CHANGED
    
    | 
         @@ -50,6 +50,7 @@ module Grafana 
     | 
|
| 
       50 
50 
     | 
    
         
             
                  @logger.debug("Requesting #{uri} with '#{@options[:body]}' and timeout '#{timeout}'")
         
     | 
| 
       51 
51 
     | 
    
         
             
                  response = @http.request(request)
         
     | 
| 
       52 
52 
     | 
    
         
             
                  @logger.debug("Received response #{response}")
         
     | 
| 
      
 53 
     | 
    
         
            +
                  @logger.debug("HTTP response body: #{response.body}") unless response.code =~ /^2.*/
         
     | 
| 
       53 
54 
     | 
    
         | 
| 
       54 
55 
     | 
    
         
             
                  response
         
     | 
| 
       55 
56 
     | 
    
         
             
                end
         
     | 
| 
         @@ -44,6 +44,7 @@ module GrafanaReporter 
     | 
|
| 
       44 
44 
     | 
    
         
             
                  else
         
     | 
| 
       45 
45 
     | 
    
         
             
                    raise GrafanaReporterError, "Internal error in AbstractQuery: given object is of type #{grafana_obj.class.name}, which is not supported"
         
     | 
| 
       46 
46 
     | 
    
         
             
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                  @logger = @grafana ? @grafana.logger : ::Logger.new($stderr, level: :info)
         
     | 
| 
       47 
48 
     | 
    
         
             
                  @variables = {}
         
     | 
| 
       48 
49 
     | 
    
         
             
                  @variables['from'] = Grafana::Variable.new(nil)
         
     | 
| 
       49 
50 
     | 
    
         
             
                  @variables['to'] = Grafana::Variable.new(nil)
         
     | 
| 
         @@ -79,7 +80,7 @@ module GrafanaReporter 
     | 
|
| 
       79 
80 
     | 
    
         
             
                  raise DatasourceNotSupportedError.new(@datasource, self) if @datasource.is_a?(Grafana::UnsupportedDatasource)
         
     | 
| 
       80 
81 
     | 
    
         | 
| 
       81 
82 
     | 
    
         
             
                  begin
         
     | 
| 
       82 
     | 
    
         
            -
                    @result = @datasource.request(from: from, to: to, raw_query: raw_query, variables:  
     | 
| 
      
 83 
     | 
    
         
            +
                    @result = @datasource.request(from: from, to: to, raw_query: raw_query, variables: @variables,
         
     | 
| 
       83 
84 
     | 
    
         
             
                                                  prepared_request: @grafana.prepare_request, timeout: timeout)
         
     | 
| 
       84 
85 
     | 
    
         
             
                  rescue ::Grafana::GrafanaError
         
     | 
| 
       85 
86 
     | 
    
         
             
                    # grafana errors will be directly passed through
         
     | 
| 
         @@ -143,6 +144,8 @@ module GrafanaReporter 
     | 
|
| 
       143 
144 
     | 
    
         
             
                #
         
     | 
| 
       144 
145 
     | 
    
         
             
                # Multiple columns may be filtered. Therefore the column titles have to be named in the
         
     | 
| 
       145 
146 
     | 
    
         
             
                # {Grafana::Variable#raw_value} and have to be separated by +,+ (comma).
         
     | 
| 
      
 147 
     | 
    
         
            +
                #
         
     | 
| 
      
 148 
     | 
    
         
            +
                # Commas can be used in a format string, but need to be escaped by using +_,+.
         
     | 
| 
       146 
149 
     | 
    
         
             
                # @param result [Hash] preformatted sql hash, (see {Grafana::AbstractDatasource#request})
         
     | 
| 
       147 
150 
     | 
    
         
             
                # @param filter_columns_variable [Grafana::Variable] column names, which shall be removed in the query result
         
     | 
| 
       148 
151 
     | 
    
         
             
                # @return [Hash] filtered query result
         
     | 
| 
         @@ -150,8 +153,8 @@ module GrafanaReporter 
     | 
|
| 
       150 
153 
     | 
    
         
             
                  return result unless filter_columns_variable
         
     | 
| 
       151 
154 
     | 
    
         | 
| 
       152 
155 
     | 
    
         
             
                  filter_columns = filter_columns_variable.raw_value
         
     | 
| 
       153 
     | 
    
         
            -
                  filter_columns.split( 
     | 
| 
       154 
     | 
    
         
            -
                    pos = result[:header].index(filter_column)
         
     | 
| 
      
 156 
     | 
    
         
            +
                  filter_columns.split(/(?<!_),/).each do |filter_column|
         
     | 
| 
      
 157 
     | 
    
         
            +
                    pos = result[:header].index(filter_column.gsub("_,", ","))
         
     | 
| 
       155 
158 
     | 
    
         | 
| 
       156 
159 
     | 
    
         
             
                    unless pos.nil?
         
     | 
| 
       157 
160 
     | 
    
         
             
                      result[:header].delete_at(pos)
         
     | 
| 
         @@ -167,23 +170,33 @@ module GrafanaReporter 
     | 
|
| 
       167 
170 
     | 
    
         
             
                # The formatting will be applied separately for every column. Therefore the column formats have to be named
         
     | 
| 
       168 
171 
     | 
    
         
             
                # in the {Grafana::Variable#raw_value} and have to be separated by +,+ (comma). If no value is specified for
         
     | 
| 
       169 
172 
     | 
    
         
             
                # a column, no change will happen.
         
     | 
| 
      
 173 
     | 
    
         
            +
                #
         
     | 
| 
      
 174 
     | 
    
         
            +
                # It is also possible to format milliseconds as dates by specifying date formats, e.g. +date:iso+. It is
         
     | 
| 
      
 175 
     | 
    
         
            +
                # possible to use any date format according
         
     | 
| 
      
 176 
     | 
    
         
            +
                # {https://grafana.com/docs/grafana/latest/variables/variable-types/global-variables/#from-and-to}
         
     | 
| 
      
 177 
     | 
    
         
            +
                #
         
     | 
| 
      
 178 
     | 
    
         
            +
                # Commas can be used in a format string, but need to be escaped by using +_,+.
         
     | 
| 
       170 
179 
     | 
    
         
             
                # @param result [Hash] preformatted sql hash, (see {Grafana::AbstractDatasource#request})
         
     | 
| 
       171 
180 
     | 
    
         
             
                # @param formats [Grafana::Variable] formats, which shall be applied to the columns in the query result
         
     | 
| 
       172 
181 
     | 
    
         
             
                # @return [Hash] formatted query result
         
     | 
| 
       173 
182 
     | 
    
         
             
                def format_columns(result, formats)
         
     | 
| 
       174 
183 
     | 
    
         
             
                  return result unless formats
         
     | 
| 
       175 
184 
     | 
    
         | 
| 
       176 
     | 
    
         
            -
                  formats.text.split( 
     | 
| 
       177 
     | 
    
         
            -
                    format = formats.text.split( 
     | 
| 
      
 185 
     | 
    
         
            +
                  formats.text.split(/(?<!_),/).each_index do |i|
         
     | 
| 
      
 186 
     | 
    
         
            +
                    format = formats.text.split(/(?<!_),/)[i].gsub("_,", ",")
         
     | 
| 
       178 
187 
     | 
    
         
             
                    next if format.empty?
         
     | 
| 
       179 
188 
     | 
    
         | 
| 
       180 
189 
     | 
    
         
             
                    result[:content].map do |row|
         
     | 
| 
       181 
190 
     | 
    
         
             
                      next unless row.length > i
         
     | 
| 
       182 
191 
     | 
    
         | 
| 
       183 
192 
     | 
    
         
             
                      begin
         
     | 
| 
       184 
     | 
    
         
            -
                         
     | 
| 
      
 193 
     | 
    
         
            +
                        if format =~ /^date:/
         
     | 
| 
      
 194 
     | 
    
         
            +
                          row[i] = ::Grafana::Variable.format_as_date(row[i], format.sub(/^date:/, '')) if row[i]
         
     | 
| 
      
 195 
     | 
    
         
            +
                        else
         
     | 
| 
      
 196 
     | 
    
         
            +
                          row[i] = format % row[i] if row[i]
         
     | 
| 
      
 197 
     | 
    
         
            +
                        end
         
     | 
| 
       185 
198 
     | 
    
         
             
                      rescue StandardError => e
         
     | 
| 
       186 
     | 
    
         
            -
                        @ 
     | 
| 
      
 199 
     | 
    
         
            +
                        @logger.error(e.message)
         
     | 
| 
       187 
200 
     | 
    
         
             
                        row[i] = e.message
         
     | 
| 
       188 
201 
     | 
    
         
             
                      end
         
     | 
| 
       189 
202 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -248,7 +261,7 @@ module GrafanaReporter 
     | 
|
| 
       248 
261 
     | 
    
         
             
                              begin
         
     | 
| 
       249 
262 
     | 
    
         
             
                                row[i] = row[i].to_s.gsub(/#{k}/, v) if row[i].to_s =~ /#{k}/
         
     | 
| 
       250 
263 
     | 
    
         
             
                              rescue StandardError => e
         
     | 
| 
       251 
     | 
    
         
            -
                                @ 
     | 
| 
      
 264 
     | 
    
         
            +
                                @logger.error(e.message)
         
     | 
| 
       252 
265 
     | 
    
         
             
                                row[i] = e.message
         
     | 
| 
       253 
266 
     | 
    
         
             
                              end
         
     | 
| 
       254 
267 
     | 
    
         | 
| 
         @@ -273,7 +286,7 @@ module GrafanaReporter 
     | 
|
| 
       273 
286 
     | 
    
         
             
                                             end
         
     | 
| 
       274 
287 
     | 
    
         
             
                                  end
         
     | 
| 
       275 
288 
     | 
    
         
             
                                rescue StandardError => e
         
     | 
| 
       276 
     | 
    
         
            -
                                  @ 
     | 
| 
      
 289 
     | 
    
         
            +
                                  @logger.error(e.message)
         
     | 
| 
       277 
290 
     | 
    
         
             
                                  row[i] = e.message
         
     | 
| 
       278 
291 
     | 
    
         
             
                                end
         
     | 
| 
       279 
292 
     | 
    
         
             
                              end
         
     | 
| 
         @@ -298,17 +311,19 @@ module GrafanaReporter 
     | 
|
| 
       298 
311 
     | 
    
         
             
                # @option opts [Grafana::Variable] :column_divider requested row divider for the result table, only to be used with table_formatter `adoc_deprecated`
         
     | 
| 
       299 
312 
     | 
    
         
             
                # @option opts [Grafana::Variable] :include_headline specifies if table should contain headline, defaults to false
         
     | 
| 
       300 
313 
     | 
    
         
             
                # @option opts [Grafana::Variable] :table_formatter specifies which formatter shall be used, defaults to 'csv'
         
     | 
| 
      
 314 
     | 
    
         
            +
                # @option opts [Grafana::Variable] :transposed specifies whether the result table is transposed
         
     | 
| 
       301 
315 
     | 
    
         
             
                # @return [String] table in custom output format
         
     | 
| 
       302 
316 
     | 
    
         
             
                def format_table_output(result, opts)
         
     | 
| 
       303 
317 
     | 
    
         
             
                  opts = { include_headline: Grafana::Variable.new('false'),
         
     | 
| 
       304 
318 
     | 
    
         
             
                           table_formatter: Grafana::Variable.new('csv'),
         
     | 
| 
       305 
319 
     | 
    
         
             
                           row_divider: Grafana::Variable.new('| '),
         
     | 
| 
       306 
     | 
    
         
            -
                           column_divider: Grafana::Variable.new(' | ') 
     | 
| 
      
 320 
     | 
    
         
            +
                           column_divider: Grafana::Variable.new(' | '),
         
     | 
| 
      
 321 
     | 
    
         
            +
                           transpose: Grafana::Variable.new('false') }.merge(opts.delete_if {|_k, v| v.nil? })
         
     | 
| 
       307 
322 
     | 
    
         | 
| 
       308 
323 
     | 
    
         
             
                  if opts[:table_formatter].raw_value == 'adoc_deprecated'
         
     | 
| 
       309 
     | 
    
         
            -
                    @ 
     | 
| 
       310 
     | 
    
         
            -
             
     | 
| 
       311 
     | 
    
         
            -
             
     | 
| 
      
 324 
     | 
    
         
            +
                    @logger.warn("You are using deprecated 'table_formatter' named 'adoc_deprecated', which will be "\
         
     | 
| 
      
 325 
     | 
    
         
            +
                                 "removed in a future version. Start using 'adoc_plain' or register your own "\
         
     | 
| 
      
 326 
     | 
    
         
            +
                                 "implementation of AbstractTableFormatStrategy.")
         
     | 
| 
       312 
327 
     | 
    
         
             
                    return result[:content].map do |row|
         
     | 
| 
       313 
328 
     | 
    
         
             
                      opts[:row_divider].raw_value + row.map do |item|
         
     | 
| 
       314 
329 
     | 
    
         
             
                        item.to_s.gsub('|', '\\|')
         
     | 
| 
         @@ -316,7 +331,7 @@ module GrafanaReporter 
     | 
|
| 
       316 
331 
     | 
    
         
             
                    end.join("\n")
         
     | 
| 
       317 
332 
     | 
    
         
             
                  end
         
     | 
| 
       318 
333 
     | 
    
         | 
| 
       319 
     | 
    
         
            -
                  AbstractTableFormatStrategy.get(opts[:table_formatter].raw_value).format(result, opts[:include_headline].raw_value.downcase == 'true')
         
     | 
| 
      
 334 
     | 
    
         
            +
                  AbstractTableFormatStrategy.get(opts[:table_formatter].raw_value).format(result, opts[:include_headline].raw_value.downcase == 'true', opts[:transpose].raw_value.downcase == 'true')
         
     | 
| 
       320 
335 
     | 
    
         
             
                end
         
     | 
| 
       321 
336 
     | 
    
         | 
| 
       322 
337 
     | 
    
         
             
                # Used to translate the relative date strings used by grafana, e.g. +now-5d/w+ to the
         
     | 
| 
         @@ -334,7 +349,7 @@ module GrafanaReporter 
     | 
|
| 
       334 
349 
     | 
    
         
             
                # @param timezone [Grafana::Variable] timezone to use, if not system timezone
         
     | 
| 
       335 
350 
     | 
    
         
             
                # @return [String] translated date as timestamp string
         
     | 
| 
       336 
351 
     | 
    
         
             
                def translate_date(orig_date, report_time, is_to_time, timezone = nil)
         
     | 
| 
       337 
     | 
    
         
            -
                  @ 
     | 
| 
      
 352 
     | 
    
         
            +
                  @logger.warn("#translate_date has been called without 'report_time' - using current time as fallback.") unless report_time
         
     | 
| 
       338 
353 
     | 
    
         
             
                  report_time ||= ::Grafana::Variable.new(Time.now.to_s)
         
     | 
| 
       339 
354 
     | 
    
         
             
                  orig_date = orig_date.raw_value if orig_date.is_a?(Grafana::Variable)
         
     | 
| 
       340 
355 
     | 
    
         | 
| 
         @@ -405,8 +420,7 @@ module GrafanaReporter 
     | 
|
| 
       405 
420 
     | 
    
         
             
                def datasource_response_valid?
         
     | 
| 
       406 
421 
     | 
    
         
             
                  return false if @result.nil?
         
     | 
| 
       407 
422 
     | 
    
         
             
                  return false unless @result.is_a?(Hash)
         
     | 
| 
       408 
     | 
    
         
            -
                   
     | 
| 
       409 
     | 
    
         
            -
                  return true if @result.empty?
         
     | 
| 
      
 423 
     | 
    
         
            +
                  return false if @result.empty?
         
     | 
| 
       410 
424 
     | 
    
         
             
                  return false unless @result.key?(:header)
         
     | 
| 
       411 
425 
     | 
    
         
             
                  return false unless @result.key?(:content)
         
     | 
| 
       412 
426 
     | 
    
         
             
                  return false unless @result[:header].is_a?(Array)
         
     | 
| 
         @@ -415,12 +429,6 @@ module GrafanaReporter 
     | 
|
| 
       415 
429 
     | 
    
         
             
                  true
         
     | 
| 
       416 
430 
     | 
    
         
             
                end
         
     | 
| 
       417 
431 
     | 
    
         | 
| 
       418 
     | 
    
         
            -
                # @return [Hash<String, Variable>] all grafana variables stored in this query, i.e. the variable name
         
     | 
| 
       419 
     | 
    
         
            -
                #  is prefixed with +var-+
         
     | 
| 
       420 
     | 
    
         
            -
                def grafana_variables
         
     | 
| 
       421 
     | 
    
         
            -
                  @variables.select { |k, _v| k =~ /^var-.+/ }
         
     | 
| 
       422 
     | 
    
         
            -
                end
         
     | 
| 
       423 
     | 
    
         
            -
             
     | 
| 
       424 
432 
     | 
    
         
             
                def delta_date(date, delta_count, time_letter)
         
     | 
| 
       425 
433 
     | 
    
         
             
                  # substract specified time
         
     | 
| 
       426 
434 
     | 
    
         
             
                  case time_letter
         
     | 
| 
         @@ -143,6 +143,8 @@ module GrafanaReporter 
     | 
|
| 
       143 
143 
     | 
    
         
             
                  notify(:on_before_create)
         
     | 
| 
       144 
144 
     | 
    
         
             
                  @start_time = Time.new
         
     | 
| 
       145 
145 
     | 
    
         
             
                  logger.info("Report started at #{@start_time}")
         
     | 
| 
      
 146 
     | 
    
         
            +
                  logger.info("You are running ruby-grafana-reporter version #{GRAFANA_REPORTER_VERSION.join('.')}.")
         
     | 
| 
      
 147 
     | 
    
         
            +
                  logger.info("A newer version is released. Check out https://github.com/divinity666/ruby-grafana-reporter/releases/latest") unless @config.latest_version_check_ok?
         
     | 
| 
       146 
148 
     | 
    
         
             
                  build
         
     | 
| 
       147 
149 
     | 
    
         
             
                rescue MissingTemplateError => e
         
     | 
| 
       148 
150 
     | 
    
         
             
                  @logger.error(e.message)
         
     | 
| 
         @@ -23,12 +23,52 @@ module GrafanaReporter 
     | 
|
| 
       23 
23 
     | 
    
         
             
                  raise NotImplementedError
         
     | 
| 
       24 
24 
     | 
    
         
             
                end
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
                #  
     | 
| 
       27 
     | 
    
         
            -
                #  
     | 
| 
      
 26 
     | 
    
         
            +
                # Used to format a given content array to the desired output format. The default
         
     | 
| 
      
 27 
     | 
    
         
            +
                # implementation applies the {#format_rules} to create a custom string export. If
         
     | 
| 
      
 28 
     | 
    
         
            +
                # this is not sufficient for a desired table format, you may simply overwrite this
         
     | 
| 
      
 29 
     | 
    
         
            +
                # function to have full freedom about the desired output.
         
     | 
| 
      
 30 
     | 
    
         
            +
                # @param content [Hash] datasource table result
         
     | 
| 
       28 
31 
     | 
    
         
             
                # @param include_headline [Boolean] true, if headline should be included in result
         
     | 
| 
      
 32 
     | 
    
         
            +
                # @param transposed [Boolean] true, if result array is in transposed format
         
     | 
| 
       29 
33 
     | 
    
         
             
                # @return [String] formatted in table format
         
     | 
| 
       30 
     | 
    
         
            -
                def format(content, include_headline)
         
     | 
| 
       31 
     | 
    
         
            -
                   
     | 
| 
      
 34 
     | 
    
         
            +
                def format(content, include_headline, transposed)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  result = content[:content]
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  # add the headline at the correct position to the content array
         
     | 
| 
      
 38 
     | 
    
         
            +
                  if include_headline
         
     | 
| 
      
 39 
     | 
    
         
            +
                    if transposed
         
     | 
| 
      
 40 
     | 
    
         
            +
                      result.each_index do |i|
         
     | 
| 
      
 41 
     | 
    
         
            +
                        result[i] = [content[:header][i]] + result[i]
         
     | 
| 
      
 42 
     | 
    
         
            +
                      end
         
     | 
| 
      
 43 
     | 
    
         
            +
                    else
         
     | 
| 
      
 44 
     | 
    
         
            +
                      result = result.unshift(content[:header])
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  # translate the content to a table
         
     | 
| 
      
 49 
     | 
    
         
            +
                  result.map do |row|
         
     | 
| 
      
 50 
     | 
    
         
            +
                    format_rules[:row_start] + row.map do |item|
         
     | 
| 
      
 51 
     | 
    
         
            +
                      value = item.to_s
         
     | 
| 
      
 52 
     | 
    
         
            +
                      if format_rules[:replace_string_or_regex]
         
     | 
| 
      
 53 
     | 
    
         
            +
                        value = value.gsub(format_rules[:replace_string_or_regex], format_rules[:replacement])
         
     | 
| 
      
 54 
     | 
    
         
            +
                      end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                      format_rules[:cell_start] + value + format_rules[:cell_end]
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end.join(format_rules[:between_cells])
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end.join(format_rules[:row_end])
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                # Formatting rules, which are applied to build the table output format.
         
     | 
| 
      
 62 
     | 
    
         
            +
                def format_rules
         
     | 
| 
      
 63 
     | 
    
         
            +
                  {
         
     | 
| 
      
 64 
     | 
    
         
            +
                    row_start: '',
         
     | 
| 
      
 65 
     | 
    
         
            +
                    row_end: '',
         
     | 
| 
      
 66 
     | 
    
         
            +
                    cell_start: '',
         
     | 
| 
      
 67 
     | 
    
         
            +
                    between_cells: '',
         
     | 
| 
      
 68 
     | 
    
         
            +
                    cell_end: '',
         
     | 
| 
      
 69 
     | 
    
         
            +
                    replace_string_or_regex: nil,
         
     | 
| 
      
 70 
     | 
    
         
            +
                    replacement: ''
         
     | 
| 
      
 71 
     | 
    
         
            +
                  }
         
     | 
| 
       32 
72 
     | 
    
         
             
                end
         
     | 
| 
       33 
73 
     | 
    
         
             
              end
         
     | 
| 
       34 
74 
     | 
    
         
             
            end
         
     | 
| 
         @@ -37,7 +37,8 @@ module GrafanaReporter 
     | 
|
| 
       37 
37 
     | 
    
         
             
                                                row_divider: @variables['row_divider'],
         
     | 
| 
       38 
38 
     | 
    
         
             
                                                column_divider: @variables['column_divider'],
         
     | 
| 
       39 
39 
     | 
    
         
             
                                                table_formatter: @variables['table_formatter'],
         
     | 
| 
       40 
     | 
    
         
            -
                                                include_headline: @variables['include_headline'] 
     | 
| 
      
 40 
     | 
    
         
            +
                                                include_headline: @variables['include_headline'],
         
     | 
| 
      
 41 
     | 
    
         
            +
                                                transpose: @variables['transpose'])
         
     | 
| 
       41 
42 
     | 
    
         
             
                end
         
     | 
| 
       42 
43 
     | 
    
         
             
              end
         
     | 
| 
       43 
44 
     | 
    
         
             
            end
         
     | 
| 
         @@ -36,7 +36,8 @@ module GrafanaReporter 
     | 
|
| 
       36 
36 
     | 
    
         
             
                                                row_divider: @variables['row_divider'],
         
     | 
| 
       37 
37 
     | 
    
         
             
                                                column_divider: @variables['column_divider'],
         
     | 
| 
       38 
38 
     | 
    
         
             
                                                table_formatter: @variables['table_formatter'],
         
     | 
| 
       39 
     | 
    
         
            -
                                                include_headline: @variables['include_headline'] 
     | 
| 
      
 39 
     | 
    
         
            +
                                                include_headline: @variables['include_headline'],
         
     | 
| 
      
 40 
     | 
    
         
            +
                                                transpose: @variables['transpose'])
         
     | 
| 
       40 
41 
     | 
    
         
             
                end
         
     | 
| 
       41 
42 
     | 
    
         
             
              end
         
     | 
| 
       42 
43 
     | 
    
         
             
            end
         
     | 
| 
         @@ -26,7 +26,13 @@ module GrafanaReporter 
     | 
|
| 
       26 
26 
     | 
    
         
             
                    @progress_reporter = Thread.new {}
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                    @status = :running
         
     | 
| 
       29 
     | 
    
         
            -
                     
     | 
| 
      
 29 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 30 
     | 
    
         
            +
                      accept_requests_loop
         
     | 
| 
      
 31 
     | 
    
         
            +
                    rescue SystemExit, Interrupt
         
     | 
| 
      
 32 
     | 
    
         
            +
                      @logger.info("Server shutting down.")
         
     | 
| 
      
 33 
     | 
    
         
            +
                      stop!
         
     | 
| 
      
 34 
     | 
    
         
            +
                      retry
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
       30 
36 
     | 
    
         
             
                    @status = :stopped
         
     | 
| 
       31 
37 
     | 
    
         
             
                  end
         
     | 
| 
       32 
38 
     | 
    
         | 
| 
         @@ -57,8 +63,6 @@ module GrafanaReporter 
     | 
|
| 
       57 
63 
     | 
    
         
             
                      # step 1) accept incoming connection
         
     | 
| 
       58 
64 
     | 
    
         
             
                      socket = @server.accept
         
     | 
| 
       59 
65 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                      # TODO: shutdown properly on SIGINT/SIGHUB
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
66 
     | 
    
         
             
                      # stop webservice properly, if shall be shutdown
         
     | 
| 
       63 
67 
     | 
    
         
             
                      if @status == :stopping
         
     | 
| 
       64 
68 
     | 
    
         
             
                        socket.close
         
     | 
| 
         @@ -252,7 +256,7 @@ module GrafanaReporter 
     | 
|
| 
       252 
256 
     | 
    
         
             
                        <% end.join('') %>
         
     | 
| 
       253 
257 
     | 
    
         
             
                        <tbody>
         
     | 
| 
       254 
258 
     | 
    
         
             
                      </table>
         
     | 
| 
       255 
     | 
    
         
            -
                      <p style="font-size: small; color:grey">You are running ruby-grafana-reporter version <%= GRAFANA_REPORTER_VERSION.join('.')  
     | 
| 
      
 259 
     | 
    
         
            +
                      <p style="font-size: small; color:grey">You are running ruby-grafana-reporter version <%= GRAFANA_REPORTER_VERSION.join('.') %>.<%= @config.latest_version_check_ok? ? '' : ' Check out the latest version <a href="https://github.com/divinity666/ruby-grafana-reporter/releases/latest">here</a>.' %></p>
         
     | 
| 
       256 
260 
     | 
    
         
             
                      </body>
         
     | 
| 
       257 
261 
     | 
    
         
             
                      </html>
         
     | 
| 
       258 
262 
     | 
    
         
             
                    HTML_TEMPLATE
         
     | 
| 
         @@ -10,15 +10,17 @@ module GrafanaReporter 
     | 
|
| 
       10 
10 
     | 
    
         
             
                    'adoc_plain'
         
     | 
| 
       11 
11 
     | 
    
         
             
                  end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                  # @see AbstractTableFormatStrategy# 
     | 
| 
       14 
     | 
    
         
            -
                  def  
     | 
| 
       15 
     | 
    
         
            -
                     
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                       
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
      
 13 
     | 
    
         
            +
                  # @see AbstractTableFormatStrategy#format_rules
         
     | 
| 
      
 14 
     | 
    
         
            +
                  def format_rules
         
     | 
| 
      
 15 
     | 
    
         
            +
                    {
         
     | 
| 
      
 16 
     | 
    
         
            +
                      row_start: '| ',
         
     | 
| 
      
 17 
     | 
    
         
            +
                      row_end: "\n",
         
     | 
| 
      
 18 
     | 
    
         
            +
                      cell_start: '',
         
     | 
| 
      
 19 
     | 
    
         
            +
                      between_cells: ' | ',
         
     | 
| 
      
 20 
     | 
    
         
            +
                      cell_end: '',
         
     | 
| 
      
 21 
     | 
    
         
            +
                      replace_string_or_regex: '|',
         
     | 
| 
      
 22 
     | 
    
         
            +
                      replacement: '\\|'
         
     | 
| 
      
 23 
     | 
    
         
            +
                    }
         
     | 
| 
       22 
24 
     | 
    
         
             
                  end
         
     | 
| 
       23 
25 
     | 
    
         
             
                end
         
     | 
| 
       24 
26 
     | 
    
         
             
              end
         
     | 
| 
         @@ -82,7 +82,7 @@ Usage: #{opts[:code_begin]}#{v[:call]}#{opts[:code_end]} 
     | 
|
| 
       82 
82 
     | 
    
         
             
            #{v[:description]}#{"\n\nSee also: #{v[:see]}" if v[:see]}#{unless v[:options].empty?
         
     | 
| 
       83 
83 
     | 
    
         
             
            %(
         
     | 
| 
       84 
84 
     | 
    
         
             
            #{opts[:table_begin]}| Option | Description#{"\n#{opts[:head_postfix_col] * 2}" if opts[:head_postfix_col]}
         
     | 
| 
       85 
     | 
    
         
            -
            #{v[:options].sort.map { |_opt_k, opt_v| "| #{opts[:code_begin]}#{opt_v[:call]}#{opts[:code_end]} | #{opt_v[:description].gsub('|', '\|')}" }.join("\n") }#{opts[:table_end]})
         
     | 
| 
      
 85 
     | 
    
         
            +
            #{v[:options].sort.map { |_opt_k, opt_v| "| #{opts[:code_begin]}#{opt_v[:call]}#{opts[:code_end]} | #{opt_v[:description].gsub('|', '\|')}#{"\nSee also: #{opt_v[:see]}" if opt_v[:see]}" }.join("\n") }#{opts[:table_end]})
         
     | 
| 
       86 
86 
     | 
    
         
             
            end}
         
     | 
| 
       87 
87 
     | 
    
         
             
            )
         
     | 
| 
       88 
88 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -109,12 +109,12 @@ end} 
     | 
|
| 
       109 
109 
     | 
    
         
             
                      res_item[:description] = item['description']
         
     | 
| 
       110 
110 
     | 
    
         
             
                      res_item[:see] = item['see']
         
     | 
| 
       111 
111 
     | 
    
         | 
| 
       112 
     | 
    
         
            -
                      opts = ((item['options'] ? item['options'].keys : [])
         
     | 
| 
      
 112 
     | 
    
         
            +
                      opts = ((item['options'] ? item['options'].keys : []) +
         
     | 
| 
       113 
113 
     | 
    
         
             
                              (item['standard_options'] ? item['standard_options'].keys : [])).sort
         
     | 
| 
       114 
114 
     | 
    
         
             
                      opts.each do |opt_key|
         
     | 
| 
       115 
115 
     | 
    
         
             
                        res_item[:options][opt_key] = {}
         
     | 
| 
       116 
116 
     | 
    
         | 
| 
       117 
     | 
    
         
            -
                        if  
     | 
| 
      
 117 
     | 
    
         
            +
                        if std_opts.key?(opt_key)
         
     | 
| 
       118 
118 
     | 
    
         
             
                          res_item[:options][opt_key][:call] = std_opts[opt_key]['call']
         
     | 
| 
       119 
119 
     | 
    
         
             
                          res_item[:options][opt_key][:description] = "#{std_opts[opt_key]['description']} "\
         
     | 
| 
       120 
120 
     | 
    
         
             
                                                                      "#{item['standard_options'][opt_key]}".chop
         
     | 
| 
         @@ -196,8 +196,12 @@ end} 
     | 
|
| 
       196 
196 
     | 
    
         
             
                        format:
         
     | 
| 
       197 
197 
     | 
    
         
             
                          call: format="<format_col1>,<format_col2>,..."
         
     | 
| 
       198 
198 
     | 
    
         
             
                          description: >-
         
     | 
| 
       199 
     | 
    
         
            -
                            Specify format in which the results shall be returned, e.g. `%.2f` for only 
     | 
| 
       200 
     | 
    
         
            -
                            float. Several  
     | 
| 
      
 199 
     | 
    
         
            +
                            Specify format in which the results in a specific column shall be returned, e.g. `%.2f` for only
         
     | 
| 
      
 200 
     | 
    
         
            +
                            two digit decimals of a float. Several column formats are separated by `,`, i.e. `%.2f,%.3f` would
         
     | 
| 
      
 201 
     | 
    
         
            +
                            apply `%.2f` to the first column and `%.3f` to the second column. All other columns would not be
         
     | 
| 
      
 202 
     | 
    
         
            +
                            formatted. You may also format time in milliseconds to a time format by specifying e.g. `date:iso`.
         
     | 
| 
      
 203 
     | 
    
         
            +
                            Commas in format strings are supported, but have to be escaped by useing `_,`.
         
     | 
| 
      
 204 
     | 
    
         
            +
                            Execution of related functions is applied in the following order `format`,
         
     | 
| 
       201 
205 
     | 
    
         
             
                            `replace_values`, `filter_columns`, `transpose`.
         
     | 
| 
       202 
206 
     | 
    
         
             
                          see: 'https://ruby-doc.org/core/Kernel.html#method-i-sprintf'
         
     | 
| 
       203 
207 
     | 
    
         | 
| 
         @@ -207,21 +211,24 @@ end} 
     | 
|
| 
       207 
211 
     | 
    
         
             
                            Specify result values which shall be replaced, e.g. `2:OK` will replace query values `2` with value `OK`.
         
     | 
| 
       208 
212 
     | 
    
         
             
                            Replacing several values is possible by separating by `,`. Matches with regular expressions are also
         
     | 
| 
       209 
213 
     | 
    
         
             
                            supported, but must be full matches, i.e. have to start with `^` and end with `$`, e.g. `^[012]$:OK`.
         
     | 
| 
       210 
     | 
    
         
            -
                            Number replacements can also be performed, e.g. `<8.2` or `<>3`. Execution  
     | 
| 
      
 214 
     | 
    
         
            +
                            Number replacements can also be performed, e.g. `<8.2` or `<>3`. Execution of related functions is
         
     | 
| 
      
 215 
     | 
    
         
            +
                            applied in the following order `format`,
         
     | 
| 
       211 
216 
     | 
    
         
             
                            `replace_values`, `filter_columns`, `transpose`.
         
     | 
| 
       212 
217 
     | 
    
         
             
                          see: https://ruby-doc.org/core/Regexp.html#class-Regexp-label-Character+Classes
         
     | 
| 
       213 
218 
     | 
    
         | 
| 
       214 
219 
     | 
    
         
             
                        filter_columns:
         
     | 
| 
       215 
220 
     | 
    
         
             
                          call: filter_columns="<column_name_1>,<column_name_2>,..."
         
     | 
| 
       216 
221 
     | 
    
         
             
                          description: >-
         
     | 
| 
       217 
     | 
    
         
            -
                            Removes specified columns from result.  
     | 
| 
       218 
     | 
    
         
            -
                            ` 
     | 
| 
      
 222 
     | 
    
         
            +
                            Removes specified columns from result.  Commas in format strings are supported, but have to be
         
     | 
| 
      
 223 
     | 
    
         
            +
                            escaped by useing `_,`. Execution of related functions is applied in the following order
         
     | 
| 
      
 224 
     | 
    
         
            +
                            `format`, `replace_values`, `filter_columns`, `transpose`.
         
     | 
| 
       219 
225 
     | 
    
         | 
| 
       220 
226 
     | 
    
         
             
                        transpose:
         
     | 
| 
       221 
227 
     | 
    
         
             
                          call: transpose="true"
         
     | 
| 
       222 
228 
     | 
    
         
             
                          description: >-
         
     | 
| 
       223 
     | 
    
         
            -
                            Transposes the query result, i.e. columns become rows and rows become columnns. Execution  
     | 
| 
       224 
     | 
    
         
            -
                            following order `format`, `replace_values`, `filter_columns`, 
     | 
| 
      
 229 
     | 
    
         
            +
                            Transposes the query result, i.e. columns become rows and rows become columnns. Execution of related
         
     | 
| 
      
 230 
     | 
    
         
            +
                            functions is applied in the following order `format`, `replace_values`, `filter_columns`,
         
     | 
| 
      
 231 
     | 
    
         
            +
                            `transpose`.
         
     | 
| 
       225 
232 
     | 
    
         | 
| 
       226 
233 
     | 
    
         
             
                        column_divider:
         
     | 
| 
       227 
234 
     | 
    
         
             
                          call: column_divider="<divider>"
         
     | 
| 
         @@ -234,7 +241,7 @@ end} 
     | 
|
| 
       234 
241 
     | 
    
         
             
                          call: row_divider="<divider>"
         
     | 
| 
       235 
242 
     | 
    
         
             
                          description: >-
         
     | 
| 
       236 
243 
     | 
    
         
             
                            Replace the default row divider with another one, when used in conjunction with `table_formatter` set to
         
     | 
| 
       237 
     | 
    
         
            -
                            `adoc_deprecated`.  
     | 
| 
      
 244 
     | 
    
         
            +
                            `adoc_deprecated`. Defaults to `| ` for being interpreted as a asciidoctor row. DEPRECATED: switch to
         
     | 
| 
       238 
245 
     | 
    
         
             
                            `table_formatter` named `adoc_plain`, or implement a custom table formatter.
         
     | 
| 
       239 
246 
     | 
    
         | 
| 
       240 
247 
     | 
    
         
             
                        table_formatter:
         
     | 
| 
         @@ -258,8 +265,13 @@ end} 
     | 
|
| 
       258 
265 
     | 
    
         
             
                        call: 'include::grafana_help[]'
         
     | 
| 
       259 
266 
     | 
    
         | 
| 
       260 
267 
     | 
    
         
             
                      grafana_environment:
         
     | 
| 
       261 
     | 
    
         
            -
                        description:  
     | 
| 
      
 268 
     | 
    
         
            +
                        description: >-
         
     | 
| 
      
 269 
     | 
    
         
            +
                          Shows all available variables in the rendering context which can be used in the asciidoctor template.
         
     | 
| 
      
 270 
     | 
    
         
            +
                          If optional `instance` is specified, additional information about the configured grafana instance will be provided.
         
     | 
| 
      
 271 
     | 
    
         
            +
                          This is especially helpful for debugging.
         
     | 
| 
       262 
272 
     | 
    
         
             
                        call: 'include::grafana_environment[]'
         
     | 
| 
      
 273 
     | 
    
         
            +
                        standard_options:
         
     | 
| 
      
 274 
     | 
    
         
            +
                          instance:
         
     | 
| 
       263 
275 
     | 
    
         | 
| 
       264 
276 
     | 
    
         
             
                      grafana_alerts:
         
     | 
| 
       265 
277 
     | 
    
         
             
                        description: >-
         
     | 
| 
         @@ -7,8 +7,8 @@ module GrafanaReporter 
     | 
|
| 
       7 
7 
     | 
    
         
             
                # Implements the hook
         
     | 
| 
       8 
8 
     | 
    
         
             
                #   grafana_panel_image::<panel_id>[<options>]
         
     | 
| 
       9 
9 
     | 
    
         
             
                #
         
     | 
| 
       10 
     | 
    
         
            -
                # Stores the queried panel as a temporary image file and returns  
     | 
| 
       11 
     | 
    
         
            -
                # to be included in the report.
         
     | 
| 
      
 10 
     | 
    
         
            +
                # Stores the queried panel as a temporary image file and returns a relative asciidoctor link
         
     | 
| 
      
 11 
     | 
    
         
            +
                # to the storage location, which can then be included in the report.
         
     | 
| 
       12 
12 
     | 
    
         
             
                #
         
     | 
| 
       13 
13 
     | 
    
         
             
                # == Used document parameters
         
     | 
| 
       14 
14 
     | 
    
         
             
                # +grafana_default_instance+ - name of grafana instance, 'default' if not specified
         
     | 
| 
         @@ -20,8 +20,6 @@ module GrafanaReporter 
     | 
|
| 
       20 
20 
     | 
    
         
             
                # +to+ - 'to' time for the sql query
         
     | 
| 
       21 
21 
     | 
    
         
             
                #
         
     | 
| 
       22 
22 
     | 
    
         
             
                # == Supported options
         
     | 
| 
       23 
     | 
    
         
            -
                # +field+ - property to query for, e.g. +description+ or +title+ (*mandatory*)
         
     | 
| 
       24 
     | 
    
         
            -
                #
         
     | 
| 
       25 
23 
     | 
    
         
             
                # +instance+ - name of grafana instance, 'default' if not specified
         
     | 
| 
       26 
24 
     | 
    
         
             
                #
         
     | 
| 
       27 
25 
     | 
    
         
             
                # +dashboard+ - uid of grafana dashboard to use
         
     | 
| 
         @@ -7,8 +7,8 @@ module GrafanaReporter 
     | 
|
| 
       7 
7 
     | 
    
         
             
                # Implements the hook
         
     | 
| 
       8 
8 
     | 
    
         
             
                #   grafana_panel_image:<panel_id>[<options>]
         
     | 
| 
       9 
9 
     | 
    
         
             
                #
         
     | 
| 
       10 
     | 
    
         
            -
                # Stores the queried panel as a temporary image file and returns  
     | 
| 
       11 
     | 
    
         
            -
                # to be included in the report.
         
     | 
| 
      
 10 
     | 
    
         
            +
                # Stores the queried panel as a temporary image file and returns a relative asciidoctor link
         
     | 
| 
      
 11 
     | 
    
         
            +
                # to the storage location, which can then be included in the report.
         
     | 
| 
       12 
12 
     | 
    
         
             
                #
         
     | 
| 
       13 
13 
     | 
    
         
             
                # == Used document parameters
         
     | 
| 
       14 
14 
     | 
    
         
             
                # +grafana_default_instance+ - name of grafana instance, 'default' if not specified
         
     | 
| 
         @@ -20,8 +20,6 @@ module GrafanaReporter 
     | 
|
| 
       20 
20 
     | 
    
         
             
                # +to+ - 'to' time for the sql query
         
     | 
| 
       21 
21 
     | 
    
         
             
                #
         
     | 
| 
       22 
22 
     | 
    
         
             
                # == Supported options
         
     | 
| 
       23 
     | 
    
         
            -
                # +field+ - property to query for, e.g. +description+ or +title+ (*mandatory*)
         
     | 
| 
       24 
     | 
    
         
            -
                #
         
     | 
| 
       25 
23 
     | 
    
         
             
                # +instance+ - name of grafana instance, 'default' if not specified
         
     | 
| 
       26 
24 
     | 
    
         
             
                #
         
     | 
| 
       27 
25 
     | 
    
         
             
                # +dashboard+ - uid of grafana dashboard to use
         
     | 
| 
         @@ -13,6 +13,9 @@ module GrafanaReporter 
     | 
|
| 
       13 
13 
     | 
    
         
             
                #
         
     | 
| 
       14 
14 
     | 
    
         
             
                # == Used document parameters
         
     | 
| 
       15 
15 
     | 
    
         
             
                # All, to be listed as the available environment.
         
     | 
| 
      
 16 
     | 
    
         
            +
                #
         
     | 
| 
      
 17 
     | 
    
         
            +
                # == Supported options
         
     | 
| 
      
 18 
     | 
    
         
            +
                # +instance+ - grafana instance name, if extended information about the grafana instance shall be printed
         
     | 
| 
       16 
19 
     | 
    
         
             
                class ShowEnvironmentIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
         
     | 
| 
       17 
20 
     | 
    
         
             
                  include ProcessorMixin
         
     | 
| 
       18 
21 
     | 
    
         | 
| 
         @@ -22,19 +25,47 @@ module GrafanaReporter 
     | 
|
| 
       22 
25 
     | 
    
         
             
                  end
         
     | 
| 
       23 
26 
     | 
    
         | 
| 
       24 
27 
     | 
    
         
             
                  # :nodoc:
         
     | 
| 
       25 
     | 
    
         
            -
                  def process(doc, reader, _target,  
     | 
| 
      
 28 
     | 
    
         
            +
                  def process(doc, reader, _target, attrs)
         
     | 
| 
       26 
29 
     | 
    
         
             
                    # return if @report.cancel
         
     | 
| 
       27 
30 
     | 
    
         
             
                    @report.next_step
         
     | 
| 
      
 31 
     | 
    
         
            +
                    instance = attrs['instance'] || doc.attr('grafana_default_instance') || 'default'
         
     | 
| 
      
 32 
     | 
    
         
            +
                    attrs['result_type'] = 'sql_table'
         
     | 
| 
       28 
33 
     | 
    
         
             
                    @report.logger.debug('Processing ShowEnvironmentIncludeProcessor')
         
     | 
| 
      
 34 
     | 
    
         
            +
                    grafana = @report.grafana(instance)
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    vars = { 'table_formatter' => 'adoc_plain', 'include_headline' => 'true'}
         
     | 
| 
      
 37 
     | 
    
         
            +
                    vars = vars.merge(build_attribute_hash(doc.attributes, attrs))
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    # query reporter environment
         
     | 
| 
      
 40 
     | 
    
         
            +
                    result = ['== Reporter', '|===']
         
     | 
| 
      
 41 
     | 
    
         
            +
                    query = QueryValueQuery.new(grafana, variables: vars.merge({'transpose' => 'true'}))
         
     | 
| 
      
 42 
     | 
    
         
            +
                    query.datasource = ::GrafanaReporter::ReporterEnvironmentDatasource.new(nil)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    result += query.execute.split("\n")
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                    # query grafana environment
         
     | 
| 
      
 46 
     | 
    
         
            +
                    result += ['|===', '',
         
     | 
| 
      
 47 
     | 
    
         
            +
                               '== Grafana Instance', '|===']
         
     | 
| 
      
 48 
     | 
    
         
            +
                    query = QueryValueQuery.new(grafana, variables: vars.merge({'transpose' => 'true'}))
         
     | 
| 
      
 49 
     | 
    
         
            +
                    query.raw_query = {grafana: grafana, mode: 'general'}
         
     | 
| 
      
 50 
     | 
    
         
            +
                    query.datasource = ::Grafana::GrafanaEnvironmentDatasource.new(nil)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    result += query.execute.split("\n")
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    result += ['|===', '',
         
     | 
| 
      
 54 
     | 
    
         
            +
                               '== Accessible Dashboards', '|===']
         
     | 
| 
      
 55 
     | 
    
         
            +
                    query = QueryValueQuery.new(grafana, variables: vars)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    query.raw_query = {grafana: grafana, mode: 'dashboards'}
         
     | 
| 
      
 57 
     | 
    
         
            +
                    query.datasource = Grafana::GrafanaEnvironmentDatasource.new(nil)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    result += query.execute.split("\n")
         
     | 
| 
       29 
59 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                     
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
      
 60 
     | 
    
         
            +
                    result += ['|===', '',
         
     | 
| 
      
 61 
     | 
    
         
            +
                               '== Accessible Variables',
         
     | 
| 
      
 62 
     | 
    
         
            +
                               '|===']
         
     | 
| 
       32 
63 
     | 
    
         
             
                    doc.attributes.sort.each do |k, v|
         
     | 
| 
       33 
     | 
    
         
            -
                       
     | 
| 
      
 64 
     | 
    
         
            +
                      result << "| `+{#{k}}+` | #{v}"
         
     | 
| 
       34 
65 
     | 
    
         
             
                    end
         
     | 
| 
       35 
     | 
    
         
            -
                     
     | 
| 
      
 66 
     | 
    
         
            +
                    result << '|==='
         
     | 
| 
       36 
67 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                    reader.unshift_lines  
     | 
| 
      
 68 
     | 
    
         
            +
                    reader.unshift_lines result
         
     | 
| 
       38 
69 
     | 
    
         
             
                  end
         
     | 
| 
       39 
70 
     | 
    
         | 
| 
       40 
71 
     | 
    
         
             
                  # @see ProcessorMixin#build_demo_entry
         
     | 
| 
         @@ -58,11 +58,6 @@ module GrafanaReporter 
     | 
|
| 
       58 
58 
     | 
    
         
             
                      return reader
         
     | 
| 
       59 
59 
     | 
    
         
             
                    end
         
     | 
| 
       60 
60 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
                    # TODO: remove dirty hack to allow the document as parameter for other processors
         
     | 
| 
       62 
     | 
    
         
            -
                    def doc.document
         
     | 
| 
       63 
     | 
    
         
            -
                      self
         
     | 
| 
       64 
     | 
    
         
            -
                    end
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
61 
     | 
    
         
             
                    # TODO: properly show error messages also in document
         
     | 
| 
       67 
62 
     | 
    
         
             
                    ext = doc.extensions.find_inline_macro_extension(call) if doc.extensions.inline_macros?
         
     | 
| 
       68 
63 
     | 
    
         
             
                    if !ext
         
     | 
| 
         @@ -152,6 +152,32 @@ module GrafanaReporter 
     | 
|
| 
       152 
152 
     | 
    
         
             
                  get_config('default-document-attributes') || {}
         
     | 
| 
       153 
153 
     | 
    
         
             
                end
         
     | 
| 
       154 
154 
     | 
    
         | 
| 
      
 155 
     | 
    
         
            +
                # Checks if this is the latest ruby-grafana-reporter version. If and how often the check if
         
     | 
| 
      
 156 
     | 
    
         
            +
                # performed, depends on the configuration setting `check-for-updates`. By default this is
         
     | 
| 
      
 157 
     | 
    
         
            +
                # 0 (=disabled). If a number >0 is specified, the checks are performed once every n-days on
         
     | 
| 
      
 158 
     | 
    
         
            +
                # report creation or call of overview webpage.
         
     | 
| 
      
 159 
     | 
    
         
            +
                # @return [Boolean] true, if is ok, false if a newer version exists
         
     | 
| 
      
 160 
     | 
    
         
            +
                def latest_version_check_ok?
         
     | 
| 
      
 161 
     | 
    
         
            +
                  return false if @newer_version_exists
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                  value = get_config('grafana-reporter:check-for-updates') || 0
         
     | 
| 
      
 164 
     | 
    
         
            +
                  return true if value <= 0
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                  # repeat check only every n-th day
         
     | 
| 
      
 167 
     | 
    
         
            +
                  if @last_version_check
         
     | 
| 
      
 168 
     | 
    
         
            +
                    return true if (Time.now - @last_version_check) < (value * 24*60*60)
         
     | 
| 
      
 169 
     | 
    
         
            +
                  end
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
                  # check for newer version
         
     | 
| 
      
 172 
     | 
    
         
            +
                  @last_version_check = Time.now
         
     | 
| 
      
 173 
     | 
    
         
            +
                  url = 'https://github.com/divinity666/ruby-grafana-reporter/releases/latest'
         
     | 
| 
      
 174 
     | 
    
         
            +
                  response = Grafana::WebRequest.new(url).execute
         
     | 
| 
      
 175 
     | 
    
         
            +
                  return true if response['location'] =~ /.*[\/v]#{GRAFANA_REPORTER_VERSION.join('.')}$/
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                  @newer_version_exists = true
         
     | 
| 
      
 178 
     | 
    
         
            +
                  return false
         
     | 
| 
      
 179 
     | 
    
         
            +
                end
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
       155 
181 
     | 
    
         
             
                # This function shall be called, before the configuration object is used in the
         
     | 
| 
       156 
182 
     | 
    
         
             
                # {Application::Application#run}. It ensures, that everything is setup properly
         
     | 
| 
       157 
183 
     | 
    
         
             
                # and all necessary folders exist. Appropriate errors are raised in case of errors.
         
     | 
| 
         @@ -304,6 +330,7 @@ module GrafanaReporter 
     | 
|
| 
       304 
330 
     | 
    
         
             
                    [
         
     | 
| 
       305 
331 
     | 
    
         
             
                      Hash, 1,
         
     | 
| 
       306 
332 
     | 
    
         
             
                      {
         
     | 
| 
      
 333 
     | 
    
         
            +
                        'check-for-updates' => [Integer, 0],
         
     | 
| 
       307 
334 
     | 
    
         
             
                        'debug-level' => [String, 0],
         
     | 
| 
       308 
335 
     | 
    
         
             
                        'run-mode' => [String, 0],
         
     | 
| 
       309 
336 
     | 
    
         
             
                        'test-instance' => [String, 0],
         
     | 
| 
         @@ -6,7 +6,6 @@ module GrafanaReporter 
     | 
|
| 
       6 
6 
     | 
    
         
             
              class ConsoleConfigurationWizard
         
     | 
| 
       7 
7 
     | 
    
         
             
                # Provides a command line configuration wizard for setting up the necessary configuration
         
     | 
| 
       8 
8 
     | 
    
         
             
                # file.
         
     | 
| 
       9 
     | 
    
         
            -
                # TODO: refactor class
         
     | 
| 
       10 
9 
     | 
    
         
             
                def start_wizard(config_file, console_config)
         
     | 
| 
       11 
10 
     | 
    
         
             
                  action = overwrite_or_use_config_file(config_file)
         
     | 
| 
       12 
11 
     | 
    
         
             
                  return if action == 'abort'
         
     | 
| 
         @@ -73,6 +72,9 @@ module GrafanaReporter 
     | 
|
| 
       73 
72 
     | 
    
         
             
            #{grafana}
         
     | 
| 
       74 
73 
     | 
    
         | 
| 
       75 
74 
     | 
    
         
             
            grafana-reporter:
         
     | 
| 
      
 75 
     | 
    
         
            +
            # Specifies how often the reporter shall check for newer versions [number of days].
         
     | 
| 
      
 76 
     | 
    
         
            +
            # You may set check-for-updates to 0 to disable
         
     | 
| 
      
 77 
     | 
    
         
            +
              check-for-updates: 1
         
     | 
| 
       76 
78 
     | 
    
         
             
              report-class: GrafanaReporter::Asciidoctor::Report
         
     | 
| 
       77 
79 
     | 
    
         
             
              templates-folder: #{templates}
         
     | 
| 
       78 
80 
     | 
    
         
             
              reports-folder: #{reports}
         
     | 
| 
         @@ -9,15 +9,17 @@ module GrafanaReporter 
     | 
|
| 
       9 
9 
     | 
    
         
             
                  'csv'
         
     | 
| 
       10 
10 
     | 
    
         
             
                end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                # @see AbstractTableFormatStrategy# 
     | 
| 
       13 
     | 
    
         
            -
                def  
     | 
| 
       14 
     | 
    
         
            -
                   
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                     
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
      
 12 
     | 
    
         
            +
                # @see AbstractTableFormatStrategy#format_rules
         
     | 
| 
      
 13 
     | 
    
         
            +
                def format_rules
         
     | 
| 
      
 14 
     | 
    
         
            +
                  {
         
     | 
| 
      
 15 
     | 
    
         
            +
                    row_start: '',
         
     | 
| 
      
 16 
     | 
    
         
            +
                    row_end: "\n",
         
     | 
| 
      
 17 
     | 
    
         
            +
                    cell_start: '',
         
     | 
| 
      
 18 
     | 
    
         
            +
                    between_cells: ', ',
         
     | 
| 
      
 19 
     | 
    
         
            +
                    cell_end: '',
         
     | 
| 
      
 20 
     | 
    
         
            +
                    replace_string_or_regex: ',',
         
     | 
| 
      
 21 
     | 
    
         
            +
                    replacement: '\\,'
         
     | 
| 
      
 22 
     | 
    
         
            +
                  }
         
     | 
| 
       21 
23 
     | 
    
         
             
                end
         
     | 
| 
       22 
24 
     | 
    
         
             
              end
         
     | 
| 
       23 
25 
     | 
    
         
             
            end
         
     | 
| 
         @@ -55,12 +55,6 @@ module GrafanaReporter 
     | 
|
| 
       55 
55 
     | 
    
         
             
                  results = {}
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         
             
                  dashboard.panels.shuffle.each do |panel|
         
     | 
| 
       58 
     | 
    
         
            -
                    begin
         
     | 
| 
       59 
     | 
    
         
            -
                      next if panel.datasource.is_a?(Grafana::UnsupportedDatasource)
         
     | 
| 
       60 
     | 
    
         
            -
                    rescue Grafana::DatasourceDoesNotExistError
         
     | 
| 
       61 
     | 
    
         
            -
                      next
         
     | 
| 
       62 
     | 
    
         
            -
                    end
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
58 
     | 
    
         
             
                    query_classes.each do |query_class|
         
     | 
| 
       65 
59 
     | 
    
         
             
                      unless query_class.public_instance_methods.include?(:build_demo_entry)
         
     | 
| 
       66 
60 
     | 
    
         
             
                        results[query_class] = "Method 'build_demo_entry' not implemented for #{query_class.name}"
         
     | 
| 
         @@ -77,6 +71,9 @@ module GrafanaReporter 
     | 
|
| 
       77 
71 
     | 
    
         
             
                        # currently not allowed
         
     | 
| 
       78 
72 
     | 
    
         
             
                      rescue StandardError => e
         
     | 
| 
       79 
73 
     | 
    
         
             
                        puts "#{e.message}\n#{e.backtrace.join("\n")}"
         
     | 
| 
      
 74 
     | 
    
         
            +
                      rescue NotImplementedError
         
     | 
| 
      
 75 
     | 
    
         
            +
                        # Ignore these errors, as it only means, that a class does not implement
         
     | 
| 
      
 76 
     | 
    
         
            +
                        # the demo entry
         
     | 
| 
       80 
77 
     | 
    
         
             
                      end
         
     | 
| 
       81 
78 
     | 
    
         
             
                    end
         
     | 
| 
       82 
79 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -15,7 +15,6 @@ module GrafanaReporter 
     | 
|
| 
       15 
15 
     | 
    
         
             
                # Returns the body of the http query, which contains the raw image.
         
     | 
| 
       16 
16 
     | 
    
         
             
                def post_process
         
     | 
| 
       17 
17 
     | 
    
         
             
                  @result = @result[:content].first
         
     | 
| 
       18 
     | 
    
         
            -
                  raise ::Grafana::ImageCouldNotBeRenderedError, @panel if @result.include?('<html')
         
     | 
| 
       19 
18 
     | 
    
         
             
                end
         
     | 
| 
       20 
19 
     | 
    
         | 
| 
       21 
20 
     | 
    
         
             
                # @see AbstractQuery#raw_query
         
     | 
| 
         @@ -19,8 +19,14 @@ module GrafanaReporter 
     | 
|
| 
       19 
19 
     | 
    
         
             
                  modify_results
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                  case @variables['result_type'].raw_value
         
     | 
| 
      
 22 
     | 
    
         
            +
                  when 'object'
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
       22 
24 
     | 
    
         
             
                  when /(?:panel_table|sql_table)/
         
     | 
| 
       23 
     | 
    
         
            -
                    @result = format_table_output(@result, row_divider: @variables['row_divider'], 
     | 
| 
      
 25 
     | 
    
         
            +
                    @result = format_table_output(@result, row_divider: @variables['row_divider'],
         
     | 
| 
      
 26 
     | 
    
         
            +
                                                           column_divider: @variables['column_divider'],
         
     | 
| 
      
 27 
     | 
    
         
            +
                                                           table_formatter: @variables['table_formatter'],
         
     | 
| 
      
 28 
     | 
    
         
            +
                                                           include_headline: @variables['include_headline'],
         
     | 
| 
      
 29 
     | 
    
         
            +
                                                           transpose: @variables['transpose'])
         
     | 
| 
       24 
30 
     | 
    
         | 
| 
       25 
31 
     | 
    
         
             
                  when /(?:panel_value|sql_value)/
         
     | 
| 
       26 
32 
     | 
    
         
             
                    tmp = @result[:content] || []
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module GrafanaReporter
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Implements a datasource to return environment related information about the reporter in a tabular format.
         
     | 
| 
      
 5 
     | 
    
         
            +
              class ReporterEnvironmentDatasource < ::Grafana::AbstractDatasource
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @see AbstractDatasource#request
         
     | 
| 
      
 7 
     | 
    
         
            +
                def request(query_description)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  {
         
     | 
| 
      
 9 
     | 
    
         
            +
                    header: ['Version', 'Release Date'],
         
     | 
| 
      
 10 
     | 
    
         
            +
                    content: [[GRAFANA_REPORTER_VERSION.join('.'), GRAFANA_REPORTER_RELEASE_DATE]]
         
     | 
| 
      
 11 
     | 
    
         
            +
                  }
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                # @see AbstractDatasource#default_variable_format
         
     | 
| 
      
 15 
     | 
    
         
            +
                def default_variable_format
         
     | 
| 
      
 16 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                # @see AbstractDatasource#name
         
     | 
| 
      
 20 
     | 
    
         
            +
                def name
         
     | 
| 
      
 21 
     | 
    
         
            +
                  self.class.to_s
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -18,17 +18,6 @@ require 'asciidoctor-pdf' 
     | 
|
| 
       18 
18 
     | 
    
         
             
            require 'zip'
         
     | 
| 
       19 
19 
     | 
    
         
             
            require_relative 'VERSION'
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
            # TODO: add test to see if datasource default formats are applied
         
     | 
| 
       22 
     | 
    
         
            -
            # TODO: add test for render-height and render-width, as they are not forwarded
         
     | 
| 
       23 
     | 
    
         
            -
            # TODO: show convert-backend, template language and all variables in webservice overview
         
     | 
| 
       24 
     | 
    
         
            -
            # TODO: add automated test against grafana playground before building a new release
         
     | 
| 
       25 
     | 
    
         
            -
            # TODO: allow registration of files to be defined in config file
         
     | 
| 
       26 
     | 
    
         
            -
            # TODO: PRIO: check in cloud - variables fetched from queries are replaced with SQL query instead of the resolved values, which can lead to issues, e.g. when using that in a function as SUBSTRING
         
     | 
| 
       27 
     | 
    
         
            -
            # TODO: PRIO: allow multiple report classes in configuration file including possibility to decide for the individual class for each rendering call
         
     | 
| 
       28 
     | 
    
         
            -
            # TODO: add configuration example to README
         
     | 
| 
       29 
     | 
    
         
            -
            # TODO: find a way, how to automatically update test grafana responses with _real_ grafana responses
         
     | 
| 
       30 
     | 
    
         
            -
            # TODO: append necessary variables on demo report creation for plain SQL queries, as they are lacking the grafana reference
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
21 
     | 
    
         
             
            folders = [
         
     | 
| 
       33 
22 
     | 
    
         
             
              %w[grafana],
         
     | 
| 
       34 
23 
     | 
    
         
             
              %w[grafana_reporter logger],
         
     | 
    
        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. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.5.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Christian Kohlmeyer
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2021- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-11-05 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: asciidoctor
         
     | 
| 
         @@ -118,6 +118,7 @@ files: 
     | 
|
| 
       118 
118 
     | 
    
         
             
            - "./lib/grafana/grafana.rb"
         
     | 
| 
       119 
119 
     | 
    
         
             
            - "./lib/grafana/grafana_alerts_datasource.rb"
         
     | 
| 
       120 
120 
     | 
    
         
             
            - "./lib/grafana/grafana_annotations_datasource.rb"
         
     | 
| 
      
 121 
     | 
    
         
            +
            - "./lib/grafana/grafana_environment_datasource.rb"
         
     | 
| 
       121 
122 
     | 
    
         
             
            - "./lib/grafana/grafana_property_datasource.rb"
         
     | 
| 
       122 
123 
     | 
    
         
             
            - "./lib/grafana/graphite_datasource.rb"
         
     | 
| 
       123 
124 
     | 
    
         
             
            - "./lib/grafana/image_rendering_datasource.rb"
         
     | 
| 
         @@ -165,6 +166,7 @@ files: 
     | 
|
| 
       165 
166 
     | 
    
         
             
            - "./lib/grafana_reporter/panel_property_query.rb"
         
     | 
| 
       166 
167 
     | 
    
         
             
            - "./lib/grafana_reporter/query_value_query.rb"
         
     | 
| 
       167 
168 
     | 
    
         
             
            - "./lib/grafana_reporter/report_webhook.rb"
         
     | 
| 
      
 169 
     | 
    
         
            +
            - "./lib/grafana_reporter/reporter_environment_datasource.rb"
         
     | 
| 
       168 
170 
     | 
    
         
             
            - "./lib/ruby_grafana_extension.rb"
         
     | 
| 
       169 
171 
     | 
    
         
             
            - "./lib/ruby_grafana_reporter.rb"
         
     | 
| 
       170 
172 
     | 
    
         
             
            - LICENSE
         
     |