fluent-plugin-google-cloud 0.8.1 → 0.8.6

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: 5a2701d1d315a64fec05aea3f289e2924c5c72aedec4467a76dfe4e29f429dcf
4
- data.tar.gz: 7ab51bcbd2994ace82f0b0c61b318f31ca2ef57827b1ed80dd8e88980bebd420
3
+ metadata.gz: 44d38e36606e310f5ec6dae2931125f139b1e40c8c2b5eafd45c3497e6aeb1c9
4
+ data.tar.gz: b2aecc00518d8787a9d3a2fcd2fad880246cf63cfddc3b4967277eb07baa2e5b
5
5
  SHA512:
6
- metadata.gz: 4d4ea1d83d1f3b23cc1299684802c3d1a15e5f178d6389aad3d49dc351a4efb7ce036027cb07756ce05b381733b46f2ba7924067b4f819e6b8e04556c3600585
7
- data.tar.gz: 60599065092f8b1e19bfde366c2068e735e764b4aff64792f3dedd913f82c023a1895d9ae79edc88bca39d09dadacd26bb771fdf252de44dd9e9ce87d36620d9
6
+ metadata.gz: c4b3ead22e4a4ee3bcb20cbd5102f4847be31bf99606e1072b668a75176b452feb5cf84fd6d19297739ca76fba6c261fa33e562faabc07553587510554e8c867
7
+ data.tar.gz: c5659ca5819695d2799331bb22fe5f05fe39434b7f744e324ad8aa43eeb3b917f5e530868e9c11d2916b896ae2c1f2dee74880a11b0f278da1a0742db3fd6b82
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-google-cloud (0.8.1)
5
- fluentd (= 1.6.3)
4
+ fluent-plugin-google-cloud (0.8.6)
5
+ fluentd (= 1.7.4)
6
6
  google-api-client (= 0.30.8)
7
7
  google-cloud-logging (= 1.6.6)
8
8
  google-protobuf (= 3.9.0)
@@ -35,15 +35,15 @@ GEM
35
35
  docile (1.3.2)
36
36
  faraday (0.17.3)
37
37
  multipart-post (>= 1.2, < 3)
38
- fluentd (1.6.3)
38
+ fluentd (1.7.4)
39
39
  cool.io (>= 1.4.5, < 2.0.0)
40
40
  dig_rb (~> 1.0.0)
41
41
  http_parser.rb (>= 0.5.1, < 0.7.0)
42
- msgpack (>= 0.7.0, < 2.0.0)
42
+ msgpack (>= 1.2.0, < 2.0.0)
43
43
  serverengine (>= 2.0.4, < 3.0.0)
44
44
  sigdump (~> 0.2.2)
45
45
  strptime (>= 0.2.2, < 1.0.0)
46
- tzinfo (~> 1.0)
46
+ tzinfo (~> 2.0)
47
47
  tzinfo-data (~> 1.0)
48
48
  yajl-ruby (~> 1.0)
49
49
  google-api-client (0.30.8)
@@ -57,9 +57,9 @@ GEM
57
57
  google-cloud-core (1.5.0)
58
58
  google-cloud-env (~> 1.0)
59
59
  google-cloud-errors (~> 1.0)
60
- google-cloud-env (1.3.1)
60
+ google-cloud-env (1.3.2)
61
61
  faraday (>= 0.17.3, < 2.0)
62
- google-cloud-errors (1.0.0)
62
+ google-cloud-errors (1.0.1)
63
63
  google-cloud-logging (1.6.6)
64
64
  concurrent-ruby (~> 1.1)
65
65
  google-cloud-core (~> 1.2)
@@ -116,14 +116,14 @@ GEM
116
116
  google-cloud-monitoring (~> 0.32)
117
117
  google-cloud-trace (~> 0.35)
118
118
  opencensus (~> 0.5)
119
- os (1.0.1)
120
- parser (2.7.0.4)
119
+ os (1.1.0)
120
+ parser (2.7.1.3)
121
121
  ast (~> 2.4.0)
122
- power_assert (1.1.6)
122
+ power_assert (1.2.0)
123
123
  powerpack (0.1.2)
124
124
  prometheus-client (0.9.0)
125
125
  quantile (~> 0.2.1)
126
- public_suffix (4.0.3)
126
+ public_suffix (4.0.5)
127
127
  quantile (0.2.1)
128
128
  rainbow (2.2.2)
129
129
  rake
@@ -145,7 +145,7 @@ GEM
145
145
  serverengine (2.2.1)
146
146
  sigdump (~> 0.2.2)
147
147
  sigdump (0.2.4)
148
- signet (0.13.0)
148
+ signet (0.14.0)
149
149
  addressable (~> 2.3)
150
150
  faraday (>= 0.17.3, < 2.0)
151
151
  jwt (>= 1.5, < 3.0)
@@ -157,22 +157,21 @@ GEM
157
157
  simplecov-html (0.10.2)
158
158
  stackdriver-core (1.4.0)
159
159
  google-cloud-core (~> 1.2)
160
- strptime (0.2.3)
160
+ strptime (0.2.4)
161
161
  sync (0.5.0)
162
162
  term-ansicolor (1.7.1)
163
163
  tins (~> 1.0)
164
164
  test-unit (3.3.3)
165
165
  power_assert
166
166
  thor (1.0.1)
167
- thread_safe (0.3.6)
168
- tins (1.24.1)
167
+ tins (1.25.0)
169
168
  sync
170
- tzinfo (1.2.6)
171
- thread_safe (~> 0.1)
172
- tzinfo-data (1.2019.3)
169
+ tzinfo (2.0.2)
170
+ concurrent-ruby (~> 1.0)
171
+ tzinfo-data (1.2020.1)
173
172
  tzinfo (>= 1.0.0)
174
173
  uber (0.1.0)
175
- unicode-display_width (1.6.1)
174
+ unicode-display_width (1.7.0)
176
175
  webmock (3.6.2)
177
176
  addressable (>= 2.3.6)
178
177
  crack (>= 0.3.2)
@@ -193,4 +192,4 @@ DEPENDENCIES
193
192
  webmock (= 3.6.2)
194
193
 
195
194
  BUNDLED WITH
196
- 2.1.1
195
+ 2.1.4
@@ -10,7 +10,7 @@ eos
10
10
  gem.homepage =
11
11
  'https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud'
12
12
  gem.license = 'Apache-2.0'
13
- gem.version = '0.8.1'
13
+ gem.version = '0.8.6'
14
14
  gem.authors = ['Stackdriver Agents Team']
15
15
  gem.email = ['stackdriver-agents@google.com']
16
16
  gem.required_ruby_version = Gem::Requirement.new('>= 2.2')
@@ -19,7 +19,7 @@ eos
19
19
  gem.test_files = gem.files.grep(/^(test)/)
20
20
  gem.require_paths = ['lib']
21
21
 
22
- gem.add_runtime_dependency 'fluentd', '1.6.3'
22
+ gem.add_runtime_dependency 'fluentd', '1.7.4'
23
23
  gem.add_runtime_dependency 'googleapis-common-protos', '1.3.9'
24
24
  gem.add_runtime_dependency 'googleauth', '0.9.0'
25
25
  gem.add_runtime_dependency 'google-api-client', '0.30.8'
@@ -0,0 +1,306 @@
1
+ # Copyright 2020 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'fileutils'
16
+ require 'fluent/config'
17
+ require 'fluent/config/v1_parser'
18
+ require 'set'
19
+
20
+ require_relative 'monitoring'
21
+
22
+ module Fluent
23
+ # Fluentd filter plugin to analyze configuration usage.
24
+ #
25
+ # For documentation on inspecting parsed configuration elements, see
26
+ # https://www.rubydoc.info/github/fluent/fluentd/Fluent/Config/Element
27
+ class AnalyzeConfigFilter < Filter
28
+ include Fluent::Config
29
+ Fluent::Plugin.register_filter('analyze_config', self)
30
+
31
+ module Constants
32
+ # Built-in plugins that are ok to reference in metrics.
33
+ KNOWN_PLUGINS = {
34
+ 'filter' => Set[
35
+ 'geoip',
36
+ 'grep',
37
+ 'parser',
38
+ 'record_transformer',
39
+ 'stdout',
40
+ ],
41
+ 'match' => Set[
42
+ 'copy',
43
+ 'elasticsearch',
44
+ 'exec',
45
+ 'exec_filter',
46
+ 'file',
47
+ 'forward',
48
+ 'http',
49
+ 'kafka',
50
+ 'mongo',
51
+ 'mongo_replset',
52
+ 'null',
53
+ 'relabel',
54
+ 'rewrite_tag_filter',
55
+ 'roundrobin',
56
+ 's3',
57
+ 'secondary_file',
58
+ 'stdout',
59
+ 'webhdfs',
60
+ ],
61
+ 'source' => Set[
62
+ 'dummy',
63
+ 'exec',
64
+ 'forward',
65
+ 'http',
66
+ 'monitor_agent',
67
+ 'syslog',
68
+ 'tail',
69
+ 'tcp',
70
+ 'udp',
71
+ 'unix',
72
+ 'windows_eventlog',
73
+ ]
74
+ }.freeze
75
+
76
+ # For Google plugins, we collect metrics on the params listed here.
77
+ GOOGLE_PLUGIN_PARAMS = {
78
+ 'google_cloud' => %w(
79
+ adjust_invalid_timestamps
80
+ auth_method
81
+ autoformat_stackdriver_trace
82
+ coerce_to_utf8
83
+ detect_json
84
+ enable_monitoring
85
+ gcm_service_address
86
+ grpc_compression_algorithm
87
+ http_request_key
88
+ insert_id_key
89
+ label_map
90
+ labels
91
+ labels_key
92
+ logging_api_url
93
+ monitoring_type
94
+ non_utf8_replacement_string
95
+ operation_key
96
+ private_key_email
97
+ private_key_passphrase
98
+ private_key_path
99
+ project_id
100
+ source_location_key
101
+ span_id_key
102
+ statusz_port
103
+ trace_key
104
+ trace_sampled_key
105
+ use_grpc
106
+ use_metadata_service
107
+ vm_id
108
+ vm_name
109
+ zone
110
+ ),
111
+ 'detect_exceptions' => %w(
112
+ languages
113
+ max_bytes
114
+ max_lines
115
+ message
116
+ multiline_flush_interval
117
+ remove_tag_prefix
118
+ stream
119
+ )
120
+ }.freeze
121
+ end
122
+
123
+ include self::Constants
124
+
125
+ # The root configuration file of google-fluentd package.
126
+ # This only applies to Linux.
127
+ config_param :google_fluentd_config_path,
128
+ :string,
129
+ default: '/etc/google-fluentd/google-fluentd.conf'
130
+ # Baseline configuration for comparing with local
131
+ # customizations.
132
+ config_param :google_fluentd_baseline_config_path,
133
+ :string,
134
+ default: '/etc/google-fluentd/baseline/google-fluentd.conf'
135
+
136
+ def start
137
+ super
138
+ @log = $log # rubocop:disable Style/GlobalVars
139
+
140
+ # Initialize the insertID.
141
+ @log.info 'Started the analyze_config plugin to analyze configuration.'
142
+ end
143
+
144
+ def parse_config(path)
145
+ data = File.open(path, 'r', &:read)
146
+ fname = File.basename(path)
147
+ basepath = File.dirname(path)
148
+ eval_context = Kernel.binding
149
+ # Override instance_eval so that LiteralParser does not actually
150
+ # evaluate the embedded Ruby, but instead just returns the
151
+ # source string. See
152
+ # https://github.com/fluent/fluentd/blob/master/lib/fluent/config/literal_parser.rb
153
+ def eval_context.instance_eval(code)
154
+ code
155
+ end
156
+ Fluent::Config::V1Parser.parse(data, fname, basepath, eval_context)
157
+ end
158
+
159
+ # Returns a name for identifying plugins we ship by default.
160
+ def default_plugin_name(e)
161
+ case e['@type']
162
+ when 'syslog'
163
+ "#{e.name}/syslog/#{e['protocol_type']}"
164
+ when 'tail'
165
+ "#{e.name}/tail/#{File.basename(e['pos_file'], '.pos')}"
166
+ else
167
+ "#{e.name}/#{e['@type']}"
168
+ end
169
+ end
170
+
171
+ # Returns a name for identifying plugins not in our default
172
+ # config. This should not contain arbitrary user-supplied data.
173
+ def custom_plugin_name(e)
174
+ if KNOWN_PLUGINS.key?(e.name) &&
175
+ KNOWN_PLUGINS[e.name].include?(e['@type'])
176
+ "#{e.name}/#{e['@type']}"
177
+ else
178
+ e.name.to_s
179
+ end
180
+ end
181
+
182
+ def embedded_ruby?(e)
183
+ (e.arg.include?('#{') ||
184
+ e.any? { |_, v| v.include?('#{') } ||
185
+ e.elements.any? { |ee| embedded_ruby?(ee) })
186
+ end
187
+
188
+ def configure(conf)
189
+ super
190
+ if File.file?(@google_fluentd_config_path) &&
191
+ File.file?(@google_fluentd_baseline_config_path)
192
+ @log.info(
193
+ 'google-fluentd configuration file found at' \
194
+ " #{@google_fluentd_config_path}. " \
195
+ 'google-fluentd baseline configuration file found at' \
196
+ " #{@google_fluentd_baseline_config_path}. " \
197
+ 'google-fluentd Analyzing configuration.')
198
+
199
+ # TODO: Add OpenCensus support.
200
+ registry = Monitoring::MonitoringRegistryFactory.create(
201
+ Monitoring::PrometheusMonitoringRegistry.name, nil, nil, nil)
202
+
203
+ plugin_usage = registry.counter(
204
+ :stackdriver_enabled_plugins,
205
+ [:plugin_name, :is_default_plugin, :has_default_value],
206
+ 'Enabled plugins')
207
+ config_usage = registry.counter(
208
+ :stackdriver_config_usage,
209
+ [:plugin_name, :param, :is_present, :has_default_value],
210
+ 'Parameter usage for Google Cloud plugins')
211
+ config_bool_values = registry.counter(
212
+ :stackdriver_config_bool_values,
213
+ [:plugin_name, :param, :value],
214
+ 'Values for bool parameters in Google Cloud plugins')
215
+
216
+ config = parse_config(@google_fluentd_config_path)
217
+ baseline_config = parse_config(@google_fluentd_baseline_config_path)
218
+
219
+ # Create hash of all baseline elements by their plugin names.
220
+ baseline_elements = Hash[baseline_config.elements.collect do |e|
221
+ [default_plugin_name(e), e]
222
+ end]
223
+ baseline_google_element = baseline_config.elements.find do |e|
224
+ e['@type'] == 'google_cloud'
225
+ end
226
+
227
+ # Look at each top-level config element and see whether it
228
+ # matches the baseline value.
229
+ #
230
+ # Note on custom configurations: If the plugin has a custom
231
+ # value (e.g. if a tail plugin has pos_file
232
+ # /var/lib/google-fluentd/pos/my-custom-value.pos), then the
233
+ # default_plugin_name (e.g. source/tail/my-custom-value) won't
234
+ # be a key in baseline_elements below, so it won't be
235
+ # used. Instead it will use the custom_plugin_name
236
+ # (e.g. source/tail).
237
+ config.elements.each do |e|
238
+ plugin_name = default_plugin_name(e)
239
+ if baseline_elements.key?(plugin_name)
240
+ is_default_plugin = true
241
+ has_default_value = (baseline_elements[plugin_name] == e)
242
+ else
243
+ plugin_name = custom_plugin_name(e)
244
+ is_default_plugin = false
245
+ has_default_value = false
246
+ end
247
+ plugin_usage.increment(
248
+ labels: {
249
+ plugin_name: plugin_name,
250
+ is_default_plugin: is_default_plugin,
251
+ has_default_value: has_default_value,
252
+ has_ruby_snippet: embedded_ruby?(e)
253
+ },
254
+ by: 1)
255
+
256
+ # Additional metric for Google plugins (google_cloud and
257
+ # detect_exceptions).
258
+ next unless GOOGLE_PLUGIN_PARAMS.key?(e['@type'])
259
+ GOOGLE_PLUGIN_PARAMS[e['@type']].each do |p|
260
+ config_usage.increment(
261
+ labels: {
262
+ plugin_name: e['@type'],
263
+ param: p,
264
+ is_present: e.key?(p),
265
+ has_default_value: (e.key?(p) &&
266
+ baseline_google_element.key?(p) &&
267
+ e[p] == baseline_google_element[p])
268
+ },
269
+ by: 1)
270
+ next unless e.key?(p) && %w(true false).include?(e[p])
271
+ config_bool_values.increment(
272
+ labels: {
273
+ plugin_name: e['@type'],
274
+ param: p,
275
+ value: e[p] == 'true'
276
+ },
277
+ by: 1)
278
+ end
279
+ end
280
+ else
281
+ @log.info(
282
+ 'google-fluentd configuration file does not exist at' \
283
+ " #{@google_fluentd_config_path} or " \
284
+ 'google-fluentd baseline configuration file does not exist at' \
285
+ " #{@google_fluentd_baseline_config_path} or " \
286
+ '. Skipping configuration analysis.')
287
+ end
288
+ rescue => e
289
+ # Do not crash the agent due to configuration analysis failures.
290
+ @log.warn(
291
+ 'Failed to optionally analyze the google-fluentd configuration' \
292
+ " file. Proceeding anyway. Error: #{e}")
293
+ end
294
+
295
+ def shutdown
296
+ super
297
+ end
298
+
299
+ # rubocop:disable Lint/UnusedMethodArgument
300
+ def filter(tag, time, record)
301
+ # Skip the actual filtering process.
302
+ record
303
+ end
304
+ # rubocop:enable Lint/UnusedMethodArgument
305
+ end
306
+ end
@@ -103,7 +103,7 @@ module Fluent
103
103
  }.freeze
104
104
  GKE_CONSTANTS = {
105
105
  service: 'container.googleapis.com',
106
- resource_type: 'container',
106
+ resource_type: 'gke_container',
107
107
  extra_resource_labels: %w(namespace_id pod_id container_name),
108
108
  extra_common_labels: %w(namespace_name pod_name),
109
109
  metadata_attributes: %w(cluster-name cluster-location),
@@ -1575,7 +1575,7 @@ module Fluent
1575
1575
  # Recognizes IAM format (account@project-name.iam.gserviceaccount.com)
1576
1576
  # as well as the legacy format with a project number at the front of the
1577
1577
  # string, terminated by a dash (-) which is not part of the ID, i.e.:
1578
- # 270694816269-1l1r2hb813leuppurdeik0apglbs80sv.apps.googleusercontent.com
1578
+ # <PROJECT_ID>-<OTHER_PARTS>.apps.googleusercontent.com
1579
1579
  def self.extract_project_id(str)
1580
1580
  [/^.*@(?<project_id>.+)\.iam\.gserviceaccount\.com/,
1581
1581
  /^(?<project_id>\d+)-/].each do |exp|
@@ -1909,7 +1909,11 @@ module Fluent
1909
1909
  end
1910
1910
 
1911
1911
  def format(tag, time, record)
1912
- Fluent::Engine.msgpack_factory.packer.write([tag, time, record]).to_s
1912
+ Fluent::MessagePackFactory
1913
+ .engine_factory
1914
+ .packer
1915
+ .write([tag, time, record])
1916
+ .to_s
1913
1917
  end
1914
1918
 
1915
1919
  # Given a tag, returns the corresponding valid tag if possible, or nil if
@@ -0,0 +1,75 @@
1
+ # Copyright 2020 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Additional assert functions.
16
+ module Asserts
17
+ # For an optional field with default values, Protobuf omits the field when it
18
+ # is deserialized to json. So we need to add an extra check for gRPC which
19
+ # uses Protobuf.
20
+ #
21
+ # An optional block can be passed in if we need to assert something other than
22
+ # a plain equal. e.g. assert_in_delta.
23
+ def assert_equal_with_default(_field, _expected_value, _default_value, _entry)
24
+ _undefined
25
+ end
26
+
27
+ # Compare the timestamp seconds and nanoseconds with the expected timestamp.
28
+ def assert_timestamp_matches(expected_ts, ts_secs, ts_nanos, entry)
29
+ assert_equal expected_ts.tv_sec, ts_secs, entry
30
+ # Fluentd v0.14 onwards supports nanosecond timestamp values.
31
+ # Added in 600 ns delta to avoid flaky tests introduced
32
+ # due to rounding error in double-precision floating-point numbers
33
+ # (to account for the missing 9 bits of precision ~ 512 ns).
34
+ # See http://wikipedia.org/wiki/Double-precision_floating-point_format.
35
+ assert_in_delta expected_ts.tv_nsec, ts_nanos, 600, entry
36
+ end
37
+
38
+ def assert_prometheus_metric_value(metric_name, expected_value, labels = {})
39
+ metric = Prometheus::Client.registry.get(metric_name)
40
+ assert_not_nil(metric)
41
+ metric_value = if labels == :aggregate
42
+ # Sum up all metric values regardless of the labels.
43
+ metric.values.values.reduce(0.0, :+)
44
+ else
45
+ metric.get(labels)
46
+ end
47
+ assert_equal(expected_value, metric_value)
48
+ end
49
+
50
+ def assert_opencensus_metric_value(metric_name, expected_value, labels = {})
51
+ translator = Monitoring::MetricTranslator.new(metric_name, labels)
52
+ metric_name = translator.name
53
+ labels = translator.translate_labels(labels)
54
+ # The next line collapses the labels to assert against the aggregated data,
55
+ # which can have some labels removed. Without this, it would test against
56
+ # the raw data. The view is more representative of the user experience, even
57
+ # though both tests should work because currently we only aggregate away one
58
+ # label that never changes during runtime.
59
+ labels.select! { |k, _| translator.view_labels.include? k }
60
+ labels = labels.map { |k, v| [k.to_s, v.to_s] }.to_h
61
+ stats_recorder = OpenCensus::Stats.ensure_recorder
62
+ view_data = stats_recorder.view_data metric_name
63
+ assert_not_nil(view_data)
64
+ # For now assume all metrics are counters.
65
+ assert_kind_of(OpenCensus::Stats::Aggregation::Sum,
66
+ view_data.view.aggregation)
67
+ assert_true(view_data.view.measure.int64?)
68
+ tag_values = view_data.view.columns.map { |column| labels[column] }
69
+ metric_value = 0
70
+ if view_data.data.key? tag_values
71
+ metric_value = view_data.data[tag_values].value
72
+ end
73
+ assert_equal(expected_value, metric_value)
74
+ end
75
+ end
@@ -22,6 +22,7 @@ require 'mocha/test_unit'
22
22
  require 'webmock/test_unit'
23
23
  require 'prometheus/client'
24
24
 
25
+ require_relative 'asserts'
25
26
  require_relative 'constants'
26
27
 
27
28
  module Monitoring
@@ -35,6 +36,7 @@ end
35
36
 
36
37
  # Unit tests for Google Cloud Logging plugin
37
38
  module BaseTest
39
+ include Asserts
38
40
  include Constants
39
41
 
40
42
  def setup
@@ -2534,65 +2536,6 @@ module BaseTest
2534
2536
  _undefined
2535
2537
  end
2536
2538
 
2537
- # For an optional field with default values, Protobuf omits the field when it
2538
- # is deserialized to json. So we need to add an extra check for gRPC which
2539
- # uses Protobuf.
2540
- #
2541
- # An optional block can be passed in if we need to assert something other than
2542
- # a plain equal. e.g. assert_in_delta.
2543
- def assert_equal_with_default(_field, _expected_value, _default_value, _entry)
2544
- _undefined
2545
- end
2546
-
2547
- # Compare the timestamp seconds and nanoseconds with the expected timestamp.
2548
- def assert_timestamp_matches(expected_ts, ts_secs, ts_nanos, entry)
2549
- assert_equal expected_ts.tv_sec, ts_secs, entry
2550
- # Fluentd v0.14 onwards supports nanosecond timestamp values.
2551
- # Added in 600 ns delta to avoid flaky tests introduced
2552
- # due to rounding error in double-precision floating-point numbers
2553
- # (to account for the missing 9 bits of precision ~ 512 ns).
2554
- # See http://wikipedia.org/wiki/Double-precision_floating-point_format.
2555
- assert_in_delta expected_ts.tv_nsec, ts_nanos, 600, entry
2556
- end
2557
-
2558
- def assert_prometheus_metric_value(metric_name, expected_value, labels = {})
2559
- metric = Prometheus::Client.registry.get(metric_name)
2560
- assert_not_nil(metric)
2561
- metric_value = if labels == :aggregate
2562
- # Sum up all metric values regardless of the labels.
2563
- metric.values.values.reduce(0.0, :+)
2564
- else
2565
- metric.get(labels)
2566
- end
2567
- assert_equal(expected_value, metric_value)
2568
- end
2569
-
2570
- def assert_opencensus_metric_value(metric_name, expected_value, labels = {})
2571
- translator = Monitoring::MetricTranslator.new(metric_name, labels)
2572
- metric_name = translator.name
2573
- labels = translator.translate_labels(labels)
2574
- # The next line collapses the labels to assert against the aggregated data,
2575
- # which can have some labels removed. Without this, it would test against
2576
- # the raw data. The view is more representative of the user experience, even
2577
- # though both tests should work because currently we only aggregate away one
2578
- # label that never changes during runtime.
2579
- labels.select! { |k, _| translator.view_labels.include? k }
2580
- labels = labels.map { |k, v| [k.to_s, v.to_s] }.to_h
2581
- stats_recorder = OpenCensus::Stats.ensure_recorder
2582
- view_data = stats_recorder.view_data metric_name
2583
- assert_not_nil(view_data)
2584
- # For now assume all metrics are counters.
2585
- assert_kind_of(OpenCensus::Stats::Aggregation::Sum,
2586
- view_data.view.aggregation)
2587
- assert_true(view_data.view.measure.int64?)
2588
- tag_values = view_data.view.columns.map { |column| labels[column] }
2589
- metric_value = 0
2590
- if view_data.data.key? tag_values
2591
- metric_value = view_data.data[tag_values].value
2592
- end
2593
- assert_equal(expected_value, metric_value)
2594
- end
2595
-
2596
2539
  # Defined in specific gRPC or REST files.
2597
2540
  def expected_operation_message2
2598
2541
  _undefined
@@ -471,6 +471,14 @@ module Constants
471
471
  zone asia-east2
472
472
  ).freeze
473
473
 
474
+ # For analyze_config.
475
+ CONFIG_ANALYZE_CONFIG = %(
476
+ google_fluentd_config_path \
477
+ test/plugin/data/google-fluentd-custom.conf
478
+ google_fluentd_baseline_config_path \
479
+ test/plugin/data/google-fluentd-baseline.conf
480
+ ).freeze
481
+
474
482
  # Service configurations for various services.
475
483
 
476
484
  # GCE.
@@ -0,0 +1,24 @@
1
+ <source>
2
+ @type syslog
3
+ port 514
4
+ protocol_type tcp
5
+ bind 127.0.0.1
6
+ tag syslog
7
+ </source>
8
+
9
+ <source>
10
+ @type tail
11
+ path /var/log/apache*/access.log,/var/log/apache*/access_log,/var/log/httpd/access.log,/var/log/httpd/access_log
12
+ pos_file /var/lib/google-fluentd/pos/apache-access.pos
13
+ tag apache-access
14
+ </source>
15
+
16
+ <filter **>
17
+ @type add_insert_ids
18
+ </filter>
19
+
20
+ <match **>
21
+ @type google_cloud
22
+ adjust_invalid_timestamps true
23
+ autoformat_stackdriver_trace true
24
+ </match>
@@ -0,0 +1,40 @@
1
+ <source>
2
+ @type syslog
3
+ port 514
4
+ protocol_type tcp
5
+ bind 127.0.0.1
6
+ tag syslog
7
+ </source>
8
+
9
+ <source>
10
+ @type tail
11
+ path /var/log/apache*/access.log,/var/log/apache*/access_log,/var/log/httpd/access.log,/var/log/httpd/access_log
12
+ pos_file /var/lib/google-fluentd/pos/apache-access.pos
13
+ tag apache-access
14
+ </source>
15
+
16
+ <filter **>
17
+ @type add_insert_ids
18
+ </filter>
19
+
20
+ <match **>
21
+ @type google_cloud
22
+ adjust_invalid_timestamps true
23
+ autoformat_stackdriver_trace false
24
+ coerce_to_utf8 true
25
+ </match>
26
+
27
+ <filter **>
28
+ @type some_custom_filter
29
+ </filter>
30
+
31
+ <filter **>
32
+ @type record_transformer
33
+ <record>
34
+ host_param "#{Socket.gethostname}"
35
+ </record>
36
+ </filter>
37
+
38
+ <match "app.#{ENV['FLUENTD_TAG']}">
39
+ @type stdout
40
+ </match>
@@ -0,0 +1,187 @@
1
+ # Copyright 2020 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../helper'
16
+ require_relative 'asserts'
17
+ require_relative 'constants'
18
+
19
+ require 'fluent/test/driver/filter'
20
+ require 'fluent/plugin/filter_analyze_config'
21
+
22
+ # Unit tests for filter_analyze_config plugin.
23
+ class FilterAnalyzeConfigTest < Test::Unit::TestCase
24
+ include Asserts
25
+ include Constants
26
+ include Fluent::AnalyzeConfigFilter::Constants
27
+
28
+ APPLICATION_DEFAULT_CONFIG = ''.freeze
29
+
30
+ def setup
31
+ Fluent::Test.setup
32
+ end
33
+
34
+ def test_config_file_does_not_exist
35
+ # By default, the FilterTestDriver.new does not set up a config file at:
36
+ # /etc/google-fluentd/google-fluentd.conf. The plugin should still proceed.
37
+ create_driver
38
+ # No exceptions were thrown.
39
+ end
40
+
41
+ def test_analyze_config
42
+ create_driver(CONFIG_ANALYZE_CONFIG)
43
+
44
+ # Default plugins, with default config.
45
+ assert_prometheus_metric_value(
46
+ :stackdriver_enabled_plugins,
47
+ 1,
48
+ plugin_name: 'source/syslog/tcp',
49
+ is_default_plugin: true,
50
+ has_default_value: true,
51
+ has_ruby_snippet: false)
52
+ assert_prometheus_metric_value(
53
+ :stackdriver_enabled_plugins,
54
+ 1,
55
+ plugin_name: 'source/tail/apache-access',
56
+ is_default_plugin: true,
57
+ has_default_value: true,
58
+ has_ruby_snippet: false)
59
+ assert_prometheus_metric_value(
60
+ :stackdriver_enabled_plugins,
61
+ 1,
62
+ plugin_name: 'filter/add_insert_ids',
63
+ is_default_plugin: true,
64
+ has_default_value: true,
65
+ has_ruby_snippet: false)
66
+
67
+ # Default plugins, with custom config.
68
+ assert_prometheus_metric_value(
69
+ :stackdriver_enabled_plugins,
70
+ 1,
71
+ plugin_name: 'match/google_cloud',
72
+ is_default_plugin: true,
73
+ has_default_value: false,
74
+ has_ruby_snippet: false)
75
+
76
+ # Custom plugins, some with embedded Ruby.
77
+ assert_prometheus_metric_value(
78
+ :stackdriver_enabled_plugins,
79
+ 1,
80
+ plugin_name: 'filter',
81
+ is_default_plugin: false,
82
+ has_default_value: false,
83
+ has_ruby_snippet: false)
84
+ assert_prometheus_metric_value(
85
+ :stackdriver_enabled_plugins,
86
+ 1,
87
+ plugin_name: 'filter/record_transformer',
88
+ is_default_plugin: false,
89
+ has_default_value: false,
90
+ has_ruby_snippet: true)
91
+ assert_prometheus_metric_value(
92
+ :stackdriver_enabled_plugins,
93
+ 1,
94
+ plugin_name: 'match/stdout',
95
+ is_default_plugin: false,
96
+ has_default_value: false,
97
+ has_ruby_snippet: true)
98
+
99
+ # For out_google_cloud, 3 params are present.
100
+ assert_prometheus_metric_value(
101
+ :stackdriver_config_usage,
102
+ 1,
103
+ plugin_name: 'google_cloud',
104
+ param: 'adjust_invalid_timestamps',
105
+ is_present: true,
106
+ has_default_value: true)
107
+ assert_prometheus_metric_value(
108
+ :stackdriver_config_usage,
109
+ 1,
110
+ plugin_name: 'google_cloud',
111
+ param: 'autoformat_stackdriver_trace',
112
+ is_present: true,
113
+ has_default_value: false)
114
+ assert_prometheus_metric_value(
115
+ :stackdriver_config_usage,
116
+ 1,
117
+ plugin_name: 'google_cloud',
118
+ param: 'coerce_to_utf8',
119
+ is_present: true,
120
+ has_default_value: false)
121
+ # The remaining "google_cloud" params are not present.
122
+ # The are no params for "detect_exceptions".
123
+ %w(
124
+ auth_method
125
+ detect_json
126
+ enable_monitoring
127
+ gcm_service_address
128
+ grpc_compression_algorithm
129
+ http_request_key
130
+ insert_id_key
131
+ label_map
132
+ labels
133
+ labels_key
134
+ logging_api_url
135
+ monitoring_type
136
+ non_utf8_replacement_string
137
+ operation_key
138
+ private_key_email
139
+ private_key_passphrase
140
+ private_key_path
141
+ project_id
142
+ source_location_key
143
+ span_id_key
144
+ statusz_port
145
+ trace_key
146
+ trace_sampled_key
147
+ use_grpc
148
+ use_metadata_service
149
+ vm_id
150
+ vm_name
151
+ zone
152
+ ).each do |p|
153
+ assert_prometheus_metric_value(
154
+ :stackdriver_config_usage,
155
+ 1,
156
+ plugin_name: 'google_cloud',
157
+ param: p,
158
+ is_present: false,
159
+ has_default_value: false)
160
+ end
161
+
162
+ # We also export values for the bools.
163
+ assert_prometheus_metric_value(
164
+ :stackdriver_config_bool_values,
165
+ 1,
166
+ plugin_name: 'google_cloud',
167
+ param: 'adjust_invalid_timestamps',
168
+ value: true)
169
+ assert_prometheus_metric_value(
170
+ :stackdriver_config_bool_values,
171
+ 1,
172
+ plugin_name: 'google_cloud',
173
+ param: 'autoformat_stackdriver_trace',
174
+ value: false)
175
+ assert_prometheus_metric_value(
176
+ :stackdriver_config_bool_values,
177
+ 1,
178
+ plugin_name: 'google_cloud',
179
+ param: 'coerce_to_utf8',
180
+ value: true)
181
+ end
182
+
183
+ def create_driver(conf = APPLICATION_DEFAULT_CONFIG)
184
+ Fluent::Test::FilterTestDriver.new(
185
+ Fluent::AnalyzeConfigFilter).configure(conf, true)
186
+ end
187
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-google-cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stackdriver Agents Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-06 00:00:00.000000000 Z
11
+ date: 2020-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 1.6.3
19
+ version: 1.7.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 1.6.3
26
+ version: 1.7.4
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: googleapis-common-protos
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -267,20 +267,25 @@ files:
267
267
  - Rakefile
268
268
  - fluent-plugin-google-cloud.gemspec
269
269
  - lib/fluent/plugin/filter_add_insert_ids.rb
270
+ - lib/fluent/plugin/filter_analyze_config.rb
270
271
  - lib/fluent/plugin/in_object_space_dump.rb
271
272
  - lib/fluent/plugin/monitoring.rb
272
273
  - lib/fluent/plugin/out_google_cloud.rb
273
274
  - lib/fluent/plugin/statusz.rb
274
275
  - test/helper.rb
276
+ - test/plugin/asserts.rb
275
277
  - test/plugin/base_test.rb
276
278
  - test/plugin/constants.rb
277
279
  - test/plugin/data/c31e573fd7f62ed495c9ca3821a5a85cb036dee1-privatekey.p12
278
280
  - test/plugin/data/credentials.json
281
+ - test/plugin/data/google-fluentd-baseline.conf
282
+ - test/plugin/data/google-fluentd-custom.conf
279
283
  - test/plugin/data/iam-credentials.json
280
284
  - test/plugin/data/invalid_credentials.json
281
285
  - test/plugin/data/new-style-credentials.json
282
286
  - test/plugin/test_driver.rb
283
287
  - test/plugin/test_filter_add_insert_ids.rb
288
+ - test/plugin/test_filter_analyze_config.rb
284
289
  - test/plugin/test_out_google_cloud.rb
285
290
  - test/plugin/test_out_google_cloud_grpc.rb
286
291
  homepage: https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud
@@ -302,20 +307,24 @@ required_rubygems_version: !ruby/object:Gem::Requirement
302
307
  - !ruby/object:Gem::Version
303
308
  version: '0'
304
309
  requirements: []
305
- rubygems_version: 3.0.6
310
+ rubygems_version: 3.0.8
306
311
  signing_key:
307
312
  specification_version: 4
308
313
  summary: fluentd plugins for the Stackdriver Logging API
309
314
  test_files:
310
315
  - test/helper.rb
316
+ - test/plugin/asserts.rb
311
317
  - test/plugin/base_test.rb
312
318
  - test/plugin/constants.rb
313
319
  - test/plugin/data/c31e573fd7f62ed495c9ca3821a5a85cb036dee1-privatekey.p12
314
320
  - test/plugin/data/credentials.json
321
+ - test/plugin/data/google-fluentd-baseline.conf
322
+ - test/plugin/data/google-fluentd-custom.conf
315
323
  - test/plugin/data/iam-credentials.json
316
324
  - test/plugin/data/invalid_credentials.json
317
325
  - test/plugin/data/new-style-credentials.json
318
326
  - test/plugin/test_driver.rb
319
327
  - test/plugin/test_filter_add_insert_ids.rb
328
+ - test/plugin/test_filter_analyze_config.rb
320
329
  - test/plugin/test_out_google_cloud.rb
321
330
  - test/plugin/test_out_google_cloud_grpc.rb