ruby-grafana-reporter 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de6063d128d57f930e83b17253e34e4e20624ef796e7eb86df2e7d54bee7825c
4
- data.tar.gz: a6a5f8b3bfcdcfc557ede19e7d89a25de8dca277806da0f662c4165d0a05b03c
3
+ metadata.gz: 8b50055253026b61f26a424e6016118db18c4b1998e1a26f8fa6f4c8c37f9d6d
4
+ data.tar.gz: 9ce58b615705b752f13260b4497b297aa1ad193f018a5699e0d4dca53fb1a743
5
5
  SHA512:
6
- metadata.gz: c9338b1dbd16a81af0c28feb9e8f4efd576ffb3f879aae7dd5d31b00468b32cc18ee49e7a73f87e952e2781845cd1d54124512aef6112194379d3840322fbff8
7
- data.tar.gz: 01bed067acfc6442e62ba17dbda3491e6147778a274c65ccacc7f838e57beda53809e8a8b827fad09266b4b506c2e29d7e8d3b0670c506eb0063eddd40d1aa26
6
+ metadata.gz: 3d96e06e01a4f5d861603528f64f57cfdbca4fe32a9790f8bc82982ea8581d6d07243aa5bfccd1fac018f1da1f1ad7a514fc31a9ff1f660aa2abf99ebfd5a2ab
7
+ data.tar.gz: 17b0f9e00461cea9c9fab69572d16b12a69494b06e52500c4f0ba01ced604116c57419726982a87cdd08f462465c4e4e9fe4a891211ff185be2ca52c67c5841d
data/lib/VERSION.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Version information
4
- GRAFANA_REPORTER_VERSION = [0, 5, 2].freeze
4
+ GRAFANA_REPORTER_VERSION = [0, 5, 3].freeze
5
5
  # Release date
6
- GRAFANA_REPORTER_RELEASE_DATE = '2022-03-22'
6
+ GRAFANA_REPORTER_RELEASE_DATE = '2022-03-24'
@@ -113,15 +113,14 @@ module Grafana
113
113
  raise NotImplementedError
114
114
  end
115
115
 
116
- private
117
-
118
116
  # Replaces the grafana variables in the given string with their replacement value.
119
117
  #
120
118
  # @param string [String] string in which the variables shall be replaced
121
119
  # @param variables [Hash<String,Variable>] Hash containing the variables, which shall be replaced in the
122
120
  # given string
121
+ # @param overwrite_default_format [String] {Variable#value_formatted} value, if a custom default format should be used, otherwise {#default_variable_format} is used as default, which may be overwritten
123
122
  # @return [String] string in which all variables are properly replaced
124
- def replace_variables(string, variables = {})
123
+ def replace_variables(string, variables, overwrite_default_format = nil)
125
124
  res = string
126
125
  repeat = true
127
126
  repeat_count = 0
@@ -141,7 +140,8 @@ module Grafana
141
140
  next unless var_name =~ /^\w+$/
142
141
 
143
142
  res = res.gsub(/(?:\$\{#{var_name}(?::(?<format>\w+))?\}|\$#{var_name}(?!\w))/) do
144
- format = default_variable_format
143
+ format = overwrite_default_format
144
+ format = default_variable_format if overwrite_default_format.nil?
145
145
  if $LAST_MATCH_INFO
146
146
  format = $LAST_MATCH_INFO[:format] if $LAST_MATCH_INFO[:format]
147
147
  end
@@ -153,5 +153,31 @@ module Grafana
153
153
 
154
154
  res
155
155
  end
156
+
157
+ private
158
+
159
+ # Provides a general method to handle the given query response as general Grafana Dataframe format.
160
+ #
161
+ # This method throws {UnsupportedQueryResponseReceivedError} if the given query response is not a
162
+ # properly formattes dataframe
163
+ #
164
+ # @param response_body [String] raw response body
165
+ def preformat_dataframe_response(response_body)
166
+ json = JSON.parse(response_body)
167
+ data = json['results'].values.first
168
+
169
+ # TODO: check how multiple frames have to be handled
170
+ data = data['frames']
171
+ headers = []
172
+ data.first['schema']['fields'].each do |headline|
173
+ header = headline['config']['displayNameFromDS'].nil? ? headline['name'] : headline['config']['displayNameFromDS']
174
+ headers << header
175
+ end
176
+ content = data.first['data']['values'][0].zip(data.first['data']['values'][1])
177
+ return { header: headers, content: content }
178
+
179
+ rescue
180
+ raise UnsupportedQueryResponseReceivedError, response_body
181
+ end
156
182
  end
157
183
  end
File without changes
@@ -43,13 +43,14 @@ module Grafana
43
43
 
44
44
  private
45
45
 
46
- # @see AbstractDatasource#preformat_response
47
46
  def preformat_response(response_body)
48
- json = JSON.parse(response_body)
49
-
50
- raise UnsupportedQueryResponseReceivedError, response_body if json.first['target'].nil?
51
- raise UnsupportedQueryResponseReceivedError, response_body if json.first['datapoints'].nil?
47
+ begin
48
+ return preformat_dataframe_response(response_body)
49
+ rescue
50
+ # TODO: show an info, that the response if not a dataframe
51
+ end
52
52
 
53
+ json = JSON.parse(response_body)
53
54
  header = ['time']
54
55
  content = {}
55
56
 
@@ -69,7 +70,10 @@ module Grafana
69
70
  end
70
71
  end
71
72
 
72
- { header: header, content: content.to_a.map(&:flatten).sort { |a, b| a[0] <=> b[0] } }
73
+ return { header: header, content: content.to_a.map(&:flatten).sort { |a, b| a[0] <=> b[0] } }
74
+
75
+ rescue
76
+ raise UnsupportedQueryResponseReceivedError, response_body
73
77
  end
74
78
  end
75
79
  end
@@ -127,14 +127,15 @@ module Grafana
127
127
  "#{res} #{parts.join(', ')}"
128
128
  end
129
129
 
130
- # @see AbstractDatasource#preformat_response
131
130
  def preformat_response(response_body)
131
+ begin
132
+ return preformat_dataframe_response(response_body)
133
+ rescue
134
+ # TODO: show an info, that the response if not a dataframe
135
+ end
136
+
132
137
  # TODO: how to handle multiple query results?
133
138
  json = JSON.parse(response_body)
134
- raise UnsupportedQueryResponseReceivedError, response_body if json['results'].nil?
135
- raise UnsupportedQueryResponseReceivedError, response_body if json['results'].first.nil?
136
- raise UnsupportedQueryResponseReceivedError, response_body if json['results'].first['series'].nil?
137
-
138
139
  json = json['results'].first['series']
139
140
  return {} if json.nil?
140
141
 
@@ -157,7 +158,10 @@ module Grafana
157
158
  end
158
159
  end
159
160
 
160
- { header: header, content: content.to_a.map(&:flatten).sort { |a, b| a[0] <=> b[0] } }
161
+ return { header: header, content: content.to_a.map(&:flatten).sort { |a, b| a[0] <=> b[0] } }
162
+
163
+ rescue
164
+ raise UnsupportedQueryResponseReceivedError, response_body
161
165
  end
162
166
  end
163
167
  end
data/lib/grafana/panel.rb CHANGED
@@ -12,6 +12,11 @@ module Grafana
12
12
  def initialize(model, dashboard)
13
13
  @model = model
14
14
  @dashboard = dashboard
15
+
16
+ @datasource_uid_or_name = @model['datasource']
17
+ if @model['datasource'].is_a?(Hash)
18
+ @datasource_uid_or_name = @model['datasource']['uid']
19
+ end
15
20
  end
16
21
 
17
22
  # @return [String] content of the requested field or +''+ if not found
@@ -26,12 +31,21 @@ module Grafana
26
31
  @model['id']
27
32
  end
28
33
 
34
+ # This method should always be called before the +datasource+ method of a
35
+ # panel is invoked, to ensure that the variable names in the datasource
36
+ # field are resolved.
37
+ #
38
+ # @param variables [Hash] variables hash, which should be use to resolve variable datasource
39
+ def resolve_variable_datasource(variables)
40
+ @datasource_uid_or_name = AbstractDatasource.new(nil).replace_variables(@datasource_uid_or_name, variables, 'raw')
41
+ end
42
+
29
43
  # @return [Datasource] datasource object specified for the current panel
30
44
  def datasource
31
- if @model['datasource'].is_a?(Hash)
32
- dashboard.grafana.datasource_by_uid(@model['datasource']['uid'])
45
+ if datasource_kind_is_uid?
46
+ dashboard.grafana.datasource_by_uid(@datasource_uid_or_name)
33
47
  else
34
- dashboard.grafana.datasource_by_name(@model['datasource'])
48
+ dashboard.grafana.datasource_by_name(@datasource_uid_or_name)
35
49
  end
36
50
  end
37
51
 
@@ -47,5 +61,14 @@ module Grafana
47
61
  def render_url
48
62
  "/render/d-solo/#{@dashboard.id}?panelId=#{@model['id']}"
49
63
  end
64
+
65
+ private
66
+
67
+ def datasource_kind_is_uid?
68
+ if @model['datasource'].is_a?(Hash)
69
+ return true
70
+ end
71
+ false
72
+ end
50
73
  end
51
74
  end
@@ -55,47 +55,25 @@ module Grafana
55
55
 
56
56
  private
57
57
 
58
- # @see AbstractDatasource#preformat_response
59
58
  def preformat_response(response_body)
60
- json = {}
59
+ # TODO: show raw response body to debug case https://github.com/divinity666/ruby-grafana-reporter/issues/24
61
60
  begin
62
- json = JSON.parse(response_body)
61
+ return preformat_dataframe_response(response_body)
63
62
  rescue
64
- raise UnsupportedQueryResponseReceivedError, response_body
63
+ # TODO: show an info, that the response if not a dataframe
65
64
  end
66
65
 
66
+ json = JSON.parse(response_body)
67
+
67
68
  # handle response with error result
68
69
  unless json['error'].nil?
69
70
  return { header: ['error'], content: [[ json['error'] ]] }
70
71
  end
71
72
 
72
- # handle dataframes
73
- if json['results']
74
- data = json['results'].values.first
75
- raise UnsupportedQueryResponseReceivedError, response_body if data.nil?
76
- raise UnsupportedQueryResponseReceivedError, response_body if data['frames'].nil?
77
- # TODO: check how multiple frames have to be handled
78
-
79
- data = data['frames']
80
- headers = []
81
- data.first['schema']['fields'].each do |headline|
82
- header = headline['config']['displayNameFromDS'].nil? ? headline['name'] : headline['config']['displayNameFromDS']
83
- headers << header
84
- end
85
- content = data.first['data']['values'][0].zip(data.first['data']['values'][1])
86
- return { header: headers, content: content }
87
- end
88
-
89
73
  # handle former result formats
90
- raise UnsupportedQueryResponseReceivedError, response_body if json['data'].nil?
91
- raise UnsupportedQueryResponseReceivedError, response_body if json['data']['resultType'].nil?
92
- raise UnsupportedQueryResponseReceivedError, response_body if json['data']['result'].nil?
93
-
94
74
  result_type = json['data']['resultType']
95
75
  json = json['data']['result']
96
76
 
97
- raise UnsupportedQueryResponseReceivedError, response_body if not result_type =~ /^(?:scalar|string|vector|matrix)$/
98
-
99
77
  headers = ['time']
100
78
  content = {}
101
79
 
@@ -130,7 +108,10 @@ module Grafana
130
108
  end
131
109
  end
132
110
 
133
- { header: headers, content: content.to_a.map(&:flatten).sort { |a, b| a[0] <=> b[0] } }
111
+ return { header: headers, content: content.to_a.map(&:flatten).sort { |a, b| a[0] <=> b[0] } }
112
+
113
+ rescue
114
+ raise UnsupportedQueryResponseReceivedError, response_body
134
115
  end
135
116
  end
136
117
  end
@@ -47,6 +47,12 @@ module Grafana
47
47
  private
48
48
 
49
49
  def preformat_response(response_body)
50
+ begin
51
+ return preformat_dataframe_response(response_body)
52
+ rescue
53
+ # TODO: show an info, that the response if not a dataframe
54
+ end
55
+
50
56
  results = {}
51
57
  results.default = []
52
58
  results[:header] = []
@@ -64,13 +70,13 @@ module Grafana
64
70
  results[:content] = table['rows']
65
71
  end
66
72
  end
67
-
68
- else
69
- raise UnsupportedQueryResponseReceivedError, response_body
70
73
  end
71
74
  end
72
75
 
73
- results
76
+ return results
77
+
78
+ rescue
79
+ raise UnsupportedQueryResponseReceivedError, response_body
74
80
  end
75
81
  end
76
82
  end
@@ -13,6 +13,7 @@ module GrafanaReporter
13
13
  attr_reader :variables, :result, :panel, :dashboard
14
14
 
15
15
  def timeout
16
+ # TODO: PRIO check where value priorities should be evaluated
16
17
  return @variables['timeout'].raw_value if @variables['timeout']
17
18
  return @variables['grafana_default_timeout'].raw_value if @variables['grafana_default_timeout']
18
19
 
@@ -88,7 +89,7 @@ module GrafanaReporter
88
89
  # grafana errors will be directly passed through
89
90
  raise
90
91
  rescue StandardError => e
91
- raise DatasourceRequestInternalError.new(@datasource, e.message)
92
+ raise DatasourceRequestInternalError.new(@datasource, "#{e.message}\n#{e.backtrace.join("\n")}")
92
93
  end
93
94
 
94
95
  raise DatasourceRequestInvalidReturnValueError.new(@datasource, @result) unless datasource_response_valid?
@@ -5,7 +5,10 @@ module GrafanaReporter
5
5
  class QueryValueQuery < AbstractQuery
6
6
  # @see Grafana::AbstractQuery#pre_process
7
7
  def pre_process
8
- @datasource = @panel.datasource if @panel
8
+ if @panel
9
+ @panel.resolve_variable_datasource(@variables)
10
+ @datasource = @panel.datasource
11
+ end
9
12
 
10
13
  @variables['result_type'] ||= Variable.new('')
11
14
  end
@@ -18,17 +18,6 @@ require 'asciidoctor-pdf'
18
18
  require 'zip'
19
19
  require_relative 'VERSION'
20
20
 
21
- # TODO: add test for variable replacement for sql
22
- # TODO: check why value is All instead of $__all
23
- # TODO: check why single sql values are replaced including ticks, whereas grafana does not do so
24
-
25
- # TODO: add FAQ for fixing most common issues with the reporter
26
- # TODO: implement an easy function to document a whole dashboard at once with different presentations
27
- # TODO: add automated test against grafana playground before building a new release
28
- # TODO: allow registration of files to be defined in config file
29
- # TODO: append necessary variables on demo report creation for plain SQL queries, as they are lacking the grafana reference
30
- # TODO: make demo report more readable
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.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Kohlmeyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-22 00:00:00.000000000 Z
11
+ date: 2022-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor