fluent-plugin-google-cloud 0.6.13.pre.memory.2 → 0.6.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 26e55203b2c40d92dfa4087065c41b547291cdf0
4
- data.tar.gz: dc3d1822611b4dfc35e00980449e525ab54e75e1
3
+ metadata.gz: 9d51deb1fd15ce338a6165a33e853704f7244051
4
+ data.tar.gz: 111bc6001f81947c1fd46e50a1d138487d864bc6
5
5
  SHA512:
6
- metadata.gz: 670621b542a34fe36eac6b2ca0dda0a59043116476a61068060c7622c4def2def173e7d11342483e4f1b4bcf192cab2e0f736745558160e700c6ee7575189c2a
7
- data.tar.gz: 1b37a3134df21f2fa17685f93f1ba2f2b1bb6a260add960a26b6dc6cd764f1cc42fff2581ac2bcfb739bddc01bd168bf6d23cecce8a422b022a8e9b306f7436e
6
+ metadata.gz: 7490512b67ea3bcdd2dcf60c12e29f8a2aa2f7232532a5d7f5a3e878c15913122bb7ee03b8c82b352d64b3224a90d900af3e2db94415ab694d5dce08eddd0193
7
+ data.tar.gz: 63e06d74b7148efc7c2ec31272ac15a999b921556ac08ef8f46807b110c22de0609f9a17573bb850a8ab2d6da7f88f90db2a1f6d9adb0cb64afd9ad70f07930b
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-google-cloud (0.6.13.pre.memory.2)
4
+ fluent-plugin-google-cloud (0.6.13)
5
5
  fluentd (~> 0.10)
6
6
  google-api-client (~> 0.14)
7
7
  google-cloud-logging (~> 1.2.3)
8
8
  googleapis-common-protos (~> 1.3)
9
9
  googleauth (~> 0.5)
10
- grpc (~> 1.8.3)
10
+ grpc (~> 1.2.5)
11
11
  json (~> 1.8)
12
12
 
13
13
  GEM
@@ -70,10 +70,9 @@ GEM
70
70
  multi_json (~> 1.11)
71
71
  os (~> 0.9)
72
72
  signet (~> 0.7)
73
- grpc (1.8.3)
73
+ grpc (1.2.5)
74
74
  google-protobuf (~> 3.1)
75
- googleapis-common-protos-types (~> 1.0.0)
76
- googleauth (>= 0.5.1, < 0.7)
75
+ googleauth (~> 0.5.1)
77
76
  hashdiff (0.3.7)
78
77
  http_parser.rb (0.6.0)
79
78
  httpclient (2.8.3)
@@ -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.6.13.pre.memory.2'
13
+ gem.version = '0.6.13'
14
14
  gem.authors = ['Todd Derr', 'Alex Robinson']
15
15
  gem.email = ['salty@google.com']
16
16
  gem.required_ruby_version = Gem::Requirement.new('>= 2.0')
@@ -24,7 +24,7 @@ eos
24
24
  gem.add_runtime_dependency 'google-api-client', '~> 0.14'
25
25
  gem.add_runtime_dependency 'google-cloud-logging', '~> 1.2.3'
26
26
  gem.add_runtime_dependency 'googleauth', '~> 0.5'
27
- gem.add_runtime_dependency 'grpc', '~> 1.8.3'
27
+ gem.add_runtime_dependency 'grpc', '~> 1.2.5'
28
28
  gem.add_runtime_dependency 'json', '~> 1.8'
29
29
 
30
30
  gem.add_development_dependency 'mocha', '~> 1.1'
@@ -195,7 +195,7 @@ module Fluent
195
195
  Fluent::Plugin.register_output('google_cloud', self)
196
196
 
197
197
  PLUGIN_NAME = 'Fluentd Google Cloud Logging plugin'.freeze
198
- PLUGIN_VERSION = '0.6.13.pre.memory.2'.freeze
198
+ PLUGIN_VERSION = '0.6.13'.freeze
199
199
 
200
200
  # Name of the the Google cloud logging write scope.
201
201
  LOGGING_SCOPE = 'https://www.googleapis.com/auth/logging.write'.freeze
@@ -341,6 +341,10 @@ module Fluent
341
341
  config_param :metadata_agent_url, :string,
342
342
  :default => DEFAULT_METADATA_AGENT_URL
343
343
 
344
+ # Whether to split log entries with different log tags into different
345
+ # requests when talking to Stackdriver Logging API.
346
+ config_param :split_logs_by_tag, :bool, :default => true
347
+
344
348
  # rubocop:enable Style/HashSyntax
345
349
 
346
350
  # TODO: Add a log_name config option rather than just using the tag?
@@ -555,8 +559,24 @@ module Fluent
555
559
  }
556
560
  end
557
561
 
558
- requests_to_send.each do |request|
559
- @write_request.call(request)
562
+ if @split_logs_by_tag
563
+ requests_to_send.each do |request|
564
+ @write_request.call(request)
565
+ end
566
+ else
567
+ # Combine all requests into one. The request level "log_name" will be
568
+ # ported to the entry level. The request level "resource" and "labels"
569
+ # are ignored as they should have been folded into the entry level
570
+ # "resource" and "labels" already anyway.
571
+ combined_entries = []
572
+ requests_to_send.each do |request|
573
+ request[:entries].each do |entry|
574
+ # Modify entries in-place as they are not needed later on.
575
+ entry.log_name = request[:log_name]
576
+ end
577
+ combined_entries.concat(request[:entries])
578
+ end
579
+ @write_request.call(entries: combined_entries)
560
580
  end
561
581
  end
562
582
 
@@ -607,17 +627,23 @@ module Fluent
607
627
  )
608
628
  end
609
629
 
610
- def write_request_via_grpc(entries:, log_name:, resource:, labels:)
630
+ def write_request_via_grpc(entries:,
631
+ log_name: '',
632
+ resource: nil,
633
+ labels: {})
611
634
  client = api_client
612
635
  entries_count = entries.length
613
636
  client.write_log_entries(
614
637
  # Ignore partial_success for gRPC path.
615
638
  entries,
616
639
  log_name: log_name,
617
- resource: Google::Api::MonitoredResource.new(
618
- type: resource.type,
619
- labels: resource.labels.to_h
620
- ),
640
+ # Leave resource nil if it's nil.
641
+ resource: if resource
642
+ Google::Api::MonitoredResource.new(
643
+ type: resource.type,
644
+ labels: resource.labels.to_h
645
+ )
646
+ end,
621
647
  labels: labels.map do |k, v|
622
648
  [k.encode('utf-8'), convert_to_utf8(v)]
623
649
  end.to_h
@@ -705,7 +731,10 @@ module Fluent
705
731
  error: error.to_s
706
732
  end
707
733
 
708
- def write_request_via_rest(entries:, log_name:, resource:, labels:)
734
+ def write_request_via_rest(entries:,
735
+ log_name: '',
736
+ resource: nil,
737
+ labels: {})
709
738
  client = api_client
710
739
  entries_count = entries.length
711
740
  client.write_entry_log_entries(
@@ -605,6 +605,56 @@ module BaseTest
605
605
  end
606
606
  end
607
607
 
608
+ def test_configure_split_logs_by_tag
609
+ setup_gce_metadata_stubs
610
+ {
611
+ APPLICATION_DEFAULT_CONFIG => true,
612
+ DISABLE_SPLIT_LOGS_BY_TAG_CONFIG => false
613
+ }.each do |(config, split_logs_by_tag)|
614
+ d = create_driver(config)
615
+ assert_equal split_logs_by_tag,
616
+ d.instance.instance_variable_get(:@split_logs_by_tag)
617
+ end
618
+ end
619
+
620
+ def test_split_logs_by_tag
621
+ setup_gce_metadata_stubs
622
+ log_entry_count = 5
623
+ dynamic_log_names = (0..log_entry_count - 1).map do |index|
624
+ "projects/test-project-id/logs/tag#{index}"
625
+ end
626
+ [
627
+ # [] returns nil for any index.
628
+ [APPLICATION_DEFAULT_CONFIG, log_entry_count, dynamic_log_names, []],
629
+ [DISABLE_SPLIT_LOGS_BY_TAG_CONFIG, 1, [''], dynamic_log_names]
630
+ ].each do |(config, request_count, request_log_names, entry_log_names)|
631
+ setup_prometheus
632
+ setup_logging_stubs do
633
+ @logs_sent = []
634
+ d = create_driver(config + PROMETHEUS_ENABLE_CONFIG, 'test', true)
635
+ log_entry_count.times do |i|
636
+ d.emit("tag#{i}", 'message' => log_entry(i))
637
+ end
638
+ d.run
639
+ end
640
+ @logs_sent.zip(request_log_names).each do |request, log_name|
641
+ assert_equal log_name, request['logName']
642
+ end
643
+ verify_log_entries(log_entry_count, COMPUTE_PARAMS_NO_LOG_NAME,
644
+ 'textPayload') do |entry, entry_index|
645
+ verify_default_log_entry_text(entry['textPayload'], entry_index,
646
+ entry)
647
+ assert_equal entry_log_names[entry_index], entry['logName']
648
+ end
649
+ # Verify the number of requests is different based on whether the
650
+ # 'split_logs_by_tag' flag is enabled.
651
+ assert_prometheus_metric_value(:stackdriver_successful_requests_count,
652
+ request_count, :aggregate)
653
+ assert_prometheus_metric_value(:stackdriver_ingested_entries_count,
654
+ log_entry_count, :aggregate)
655
+ end
656
+ end
657
+
608
658
  def test_timestamps
609
659
  setup_gce_metadata_stubs
610
660
  current_time = Time.now
@@ -1591,12 +1641,13 @@ module BaseTest
1591
1641
 
1592
1642
  # The caller can optionally provide a block which is called for each entry.
1593
1643
  def verify_json_log_entries(n, params, payload_type = 'textPayload')
1594
- i = 0
1644
+ entry_count = 0
1595
1645
  @logs_sent.each do |request|
1596
1646
  request['entries'].each do |entry|
1597
1647
  unless payload_type.empty?
1598
- assert entry.key?(payload_type), "Entry ##{i} did not contain " \
1599
- "expected #{payload_type} key: #{entry}"
1648
+ assert entry.key?(payload_type),
1649
+ "Entry ##{entry_count} did not contain expected" \
1650
+ " #{payload_type} key: #{entry}."
1600
1651
  end
1601
1652
 
1602
1653
  # per-entry resource or log_name overrides the corresponding field
@@ -1608,22 +1659,27 @@ module BaseTest
1608
1659
  labels ||= request['labels']
1609
1660
  labels.merge!(entry['labels'] || {})
1610
1661
 
1611
- assert_equal \
1612
- "projects/#{params[:project_id]}/logs/#{params[:log_name]}", log_name
1662
+ if params[:log_name]
1663
+ assert_equal \
1664
+ "projects/#{params[:project_id]}/logs/#{params[:log_name]}",
1665
+ log_name
1666
+ end
1613
1667
  assert_equal params[:resource][:type], resource['type']
1614
1668
  check_labels resource['labels'], params[:resource][:labels]
1615
1669
  check_labels labels, params[:labels]
1616
1670
  if block_given?
1617
- yield(entry, i)
1671
+ yield(entry, entry_count)
1618
1672
  elsif payload_type == 'textPayload'
1619
1673
  # Check the payload for textPayload, otherwise it's up to the caller.
1620
- verify_default_log_entry_text(entry['textPayload'], i, entry)
1674
+ verify_default_log_entry_text(entry['textPayload'], entry_count,
1675
+ entry)
1621
1676
  end
1622
- i += 1
1623
- assert i <= n, "Number of entries #{i} exceeds expected number #{n}"
1677
+ entry_count += 1
1678
+ assert entry_count <= n,
1679
+ "Number of entries #{entry_count} exceeds expected number #{n}."
1624
1680
  end
1625
1681
  end
1626
- assert i == n, "Number of entries #{i} does not match expected number #{n}"
1682
+ assert_equal n, entry_count
1627
1683
  end
1628
1684
 
1629
1685
  def verify_container_logs(log_entry_factory, expected_params)
@@ -1781,7 +1837,13 @@ module BaseTest
1781
1837
  def assert_prometheus_metric_value(metric_name, expected_value, labels = {})
1782
1838
  metric = Prometheus::Client.registry.get(metric_name)
1783
1839
  assert_not_nil(metric)
1784
- assert_equal(expected_value, metric.get(labels))
1840
+ metric_value = if labels == :aggregate
1841
+ # Sum up all metric values regardless of the labels.
1842
+ metric.values.values.reduce(0.0, :+)
1843
+ else
1844
+ metric.get(labels)
1845
+ end
1846
+ assert_equal(expected_value, metric_value)
1785
1847
  end
1786
1848
 
1787
1849
  # Get the fields of the payload.
@@ -166,6 +166,10 @@ module Constants
166
166
  detect_subservice false
167
167
  ).freeze
168
168
 
169
+ DISABLE_SPLIT_LOGS_BY_TAG_CONFIG = %(
170
+ split_logs_by_tag false
171
+ ).freeze
172
+
169
173
  PROMETHEUS_ENABLE_CONFIG = %(
170
174
  enable_monitoring true
171
175
  monitoring_type prometheus
@@ -243,7 +247,7 @@ module Constants
243
247
  # Service configurations for various services.
244
248
 
245
249
  # GCE.
246
- COMPUTE_PARAMS = {
250
+ COMPUTE_PARAMS_NO_LOG_NAME = {
247
251
  resource: {
248
252
  type: COMPUTE_CONSTANTS[:resource_type],
249
253
  labels: {
@@ -251,12 +255,14 @@ module Constants
251
255
  'zone' => ZONE
252
256
  }
253
257
  },
254
- log_name: 'test',
255
258
  project_id: PROJECT_ID,
256
259
  labels: {
257
260
  "#{COMPUTE_CONSTANTS[:service]}/resource_name" => HOSTNAME
258
261
  }
259
262
  }.freeze
263
+ COMPUTE_PARAMS = COMPUTE_PARAMS_NO_LOG_NAME.merge(
264
+ log_name: 'test'
265
+ ).freeze
260
266
  COMPUTE_PARAMS_WITH_METADATA_VM_ID_AND_ZONE = COMPUTE_PARAMS.merge(
261
267
  resource: COMPUTE_PARAMS[:resource].merge(
262
268
  labels: {
@@ -0,0 +1,55 @@
1
+ # Copyright 2018 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 'fluent/engine'
16
+ require 'fluent/event'
17
+ require 'fluent/test/input_test'
18
+
19
+ module Fluent
20
+ module Test
21
+ # Similar to the standard BufferedOutputTestDriver, but allows multiple tags
22
+ # to exist in one chunk.
23
+ class MultiTagBufferedOutputTestDriver < InputTestDriver
24
+ def initialize(klass, &block)
25
+ super(klass, &block)
26
+ @entries = []
27
+ end
28
+
29
+ def emit(tag, record, time = Engine.now)
30
+ es = ArrayEventStream.new([[time, record]])
31
+ data = @instance.format_stream(tag, es)
32
+ @entries << data
33
+ self
34
+ end
35
+
36
+ def run(num_waits = 10)
37
+ result = nil
38
+ super(num_waits) do
39
+ chunk = @instance.buffer.generate_chunk(
40
+ @instance.metadata(nil, nil, nil)).staged!
41
+ @entries.each do |entry|
42
+ chunk.concat(entry, 1)
43
+ end
44
+
45
+ begin
46
+ result = @instance.write(chunk)
47
+ ensure
48
+ chunk.purge
49
+ end
50
+ end
51
+ result
52
+ end
53
+ end
54
+ end
55
+ end
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require_relative 'base_test'
16
+ require_relative 'test_driver'
16
17
 
17
18
  # Unit tests for Google Cloud Logging plugin
18
19
  class GoogleCloudOutputTest < Test::Unit::TestCase
@@ -308,9 +309,17 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
308
309
  end
309
310
 
310
311
  # Create a Fluentd output test driver with the Google Cloud Output plugin.
311
- def create_driver(conf = APPLICATION_DEFAULT_CONFIG, tag = 'test')
312
- Fluent::Test::BufferedOutputTestDriver.new(
313
- Fluent::GoogleCloudOutput, tag).configure(conf, true)
312
+ def create_driver(conf = APPLICATION_DEFAULT_CONFIG,
313
+ tag = 'test',
314
+ multi_tags = false)
315
+ driver = if multi_tags
316
+ Fluent::Test::MultiTagBufferedOutputTestDriver.new(
317
+ Fluent::GoogleCloudOutput)
318
+ else
319
+ Fluent::Test::BufferedOutputTestDriver.new(
320
+ Fluent::GoogleCloudOutput, tag)
321
+ end
322
+ driver.configure(conf, true)
314
323
  end
315
324
 
316
325
  # Verify the number and the content of the log entries match the expectation.
@@ -15,6 +15,7 @@
15
15
  require 'grpc'
16
16
 
17
17
  require_relative 'base_test'
18
+ require_relative 'test_driver'
18
19
 
19
20
  # Unit tests for Google Cloud Logging plugin
20
21
  class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
@@ -223,10 +224,18 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
223
224
  # grpc enabled. The signature of this method is different between the grpc
224
225
  # path and the non-grpc path. For grpc, an additional grpc stub class can be
225
226
  # passed in to construct the mock used by the test driver.
226
- def create_driver(conf = APPLICATION_DEFAULT_CONFIG, tag = 'test')
227
+ def create_driver(conf = APPLICATION_DEFAULT_CONFIG,
228
+ tag = 'test',
229
+ multi_tags = false)
227
230
  conf += USE_GRPC_CONFIG
228
- Fluent::Test::BufferedOutputTestDriver.new(
229
- GoogleCloudOutputWithGRPCMock.new(@grpc_stub), tag).configure(conf, true)
231
+ driver = if multi_tags
232
+ Fluent::Test::MultiTagBufferedOutputTestDriver.new(
233
+ GoogleCloudOutputWithGRPCMock.new(@grpc_stub))
234
+ else
235
+ Fluent::Test::BufferedOutputTestDriver.new(
236
+ GoogleCloudOutputWithGRPCMock.new(@grpc_stub), tag)
237
+ end
238
+ driver.configure(conf, true)
230
239
  end
231
240
 
232
241
  # Google Cloud Fluent output stub with grpc mock.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-google-cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.13.pre.memory.2
4
+ version: 0.6.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd Derr
@@ -87,14 +87,14 @@ dependencies:
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: 1.8.3
90
+ version: 1.2.5
91
91
  type: :runtime
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: 1.8.3
97
+ version: 1.2.5
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: json
100
100
  requirement: !ruby/object:Gem::Requirement
@@ -220,6 +220,7 @@ files:
220
220
  - test/plugin/data/credentials.json
221
221
  - test/plugin/data/iam-credentials.json
222
222
  - test/plugin/data/invalid_credentials.json
223
+ - test/plugin/test_driver.rb
223
224
  - test/plugin/test_out_google_cloud.rb
224
225
  - test/plugin/test_out_google_cloud_grpc.rb
225
226
  homepage: https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud
@@ -237,9 +238,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
237
238
  version: '2.0'
238
239
  required_rubygems_version: !ruby/object:Gem::Requirement
239
240
  requirements:
240
- - - ">"
241
+ - - ">="
241
242
  - !ruby/object:Gem::Version
242
- version: 1.3.1
243
+ version: '0'
243
244
  requirements: []
244
245
  rubyforge_project:
245
246
  rubygems_version: 2.4.8
@@ -254,5 +255,6 @@ test_files:
254
255
  - test/plugin/data/credentials.json
255
256
  - test/plugin/data/iam-credentials.json
256
257
  - test/plugin/data/invalid_credentials.json
258
+ - test/plugin/test_driver.rb
257
259
  - test/plugin/test_out_google_cloud.rb
258
260
  - test/plugin/test_out_google_cloud_grpc.rb