fluent-plugin-google-cloud 0.5.1 → 0.5.2

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: bae4e3edae194459b6bffe522aa070d6c96f4c01
4
- data.tar.gz: 290eaab1b92a6cea5c9204f5892fb008c6334d57
3
+ metadata.gz: 8109f72f6f16a0756b3a30c911e9343392051b96
4
+ data.tar.gz: e76c44a9c3e8cb63c6125f1b621e7985e3050918
5
5
  SHA512:
6
- metadata.gz: c8644923f32740b2aee18e0b71047c8dc6d1c881c7f590a88a7a5e136088c9eccd428bfcbe53aadaeedf6b301ecc5f6e29d9a7ec5545635b3f7a1021a2371aba
7
- data.tar.gz: 8d101639abc752dd42a7c0dcf29bdc8834d20bbde8686e4eb3b41b6ca6c09b830e62b2a8ecc4551657eac3ef9baa5d779148358b6326dddd23749ea108a60dda
6
+ metadata.gz: aad0d625ddb42768a112e887bae953d601bd646d9003d7a7308a19a3e9e4afdbd61725bd56b844cefc7626a99dad067ea3ef6d68e44f06bc324ab7abe937bcd2
7
+ data.tar.gz: c880a81905b4ce2535f247a7bd1938e46082461f8c9f48a03716908219e6fe95234397a09ee4975ed21dc5c196b782d1efd1ebf499617c7fb989aa234efbf60e
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-google-cloud (0.5.0)
5
- fluentd (~> 0.10)
4
+ fluent-plugin-google-cloud (0.5.2)
5
+ fluentd (~> 0.10, <= 0.13)
6
6
  google-api-client (> 0.9)
7
7
  googleauth (~> 0.4)
8
8
  json (~> 1.8)
@@ -11,25 +11,25 @@ GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
13
  addressable (2.4.0)
14
- ast (2.2.0)
14
+ ast (2.3.0)
15
15
  astrolabe (1.3.1)
16
16
  parser (~> 2.2)
17
- cool.io (1.4.3)
17
+ cool.io (1.4.4)
18
18
  crack (0.4.3)
19
19
  safe_yaml (~> 1.0.0)
20
20
  faraday (0.9.2)
21
21
  multipart-post (>= 1.2, < 3)
22
- fluentd (0.12.22)
22
+ fluentd (0.12.26)
23
23
  cool.io (>= 1.2.2, < 2.0.0)
24
24
  http_parser.rb (>= 0.5.1, < 0.7.0)
25
25
  json (>= 1.4.3)
26
26
  msgpack (>= 0.5.11, < 0.6.0)
27
27
  sigdump (~> 0.2.2)
28
- string-scrub (>= 0.0.3)
28
+ string-scrub (>= 0.0.3, <= 0.0.5)
29
29
  tzinfo (>= 1.0.0)
30
30
  tzinfo-data (>= 1.0.0)
31
31
  yajl-ruby (~> 1.0)
32
- google-api-client (0.9.5)
32
+ google-api-client (0.9.9)
33
33
  addressable (~> 2.3)
34
34
  googleauth (~> 0.5)
35
35
  httpclient (~> 2.7)
@@ -49,7 +49,7 @@ GEM
49
49
  signet (~> 0.7)
50
50
  hashdiff (0.3.0)
51
51
  http_parser.rb (0.6.0)
52
- httpclient (2.7.1)
52
+ httpclient (2.8.0)
53
53
  hurley (0.2)
54
54
  json (1.8.3)
55
55
  jwt (1.5.4)
@@ -59,18 +59,18 @@ GEM
59
59
  multi_json (~> 1.10)
60
60
  memoist (0.14.0)
61
61
  metaclass (0.0.4)
62
- mime-types (3.0)
62
+ mime-types (3.1)
63
63
  mime-types-data (~> 3.2015)
64
- mime-types-data (3.2016.0221)
64
+ mime-types-data (3.2016.0521)
65
65
  mocha (1.1.0)
66
66
  metaclass (~> 0.0.1)
67
67
  msgpack (0.5.12)
68
- multi_json (1.11.2)
68
+ multi_json (1.12.1)
69
69
  multipart-post (2.0.0)
70
70
  os (0.9.6)
71
- parser (2.3.0.7)
71
+ parser (2.3.1.2)
72
72
  ast (~> 2.2)
73
- power_assert (0.2.7)
73
+ power_assert (0.3.0)
74
74
  powerpack (0.1.1)
75
75
  rainbow (2.1.0)
76
76
  rake (10.5.0)
@@ -83,25 +83,25 @@ GEM
83
83
  powerpack (~> 0.1)
84
84
  rainbow (>= 1.99.1, < 3.0)
85
85
  ruby-progressbar (~> 1.7)
86
- ruby-progressbar (1.7.5)
86
+ ruby-progressbar (1.8.1)
87
87
  safe_yaml (1.0.4)
88
88
  sigdump (0.2.4)
89
- signet (0.7.2)
89
+ signet (0.7.3)
90
90
  addressable (~> 2.3)
91
91
  faraday (~> 0.9)
92
92
  jwt (~> 1.5)
93
93
  multi_json (~> 1.10)
94
94
  string-scrub (0.0.5)
95
- test-unit (3.1.8)
95
+ test-unit (3.2.0)
96
96
  power_assert
97
97
  thor (0.19.1)
98
98
  thread_safe (0.3.5)
99
99
  tzinfo (1.2.2)
100
100
  thread_safe (~> 0.1)
101
- tzinfo-data (1.2016.4)
101
+ tzinfo-data (1.2016.5)
102
102
  tzinfo (>= 1.0.0)
103
103
  uber (0.0.15)
104
- webmock (1.24.3)
104
+ webmock (1.24.6)
105
105
  addressable (>= 2.3.6)
106
106
  crack (>= 0.3.2)
107
107
  hashdiff
@@ -119,4 +119,4 @@ DEPENDENCIES
119
119
  webmock (~> 1.17)
120
120
 
121
121
  BUNDLED WITH
122
- 1.11.2
122
+ 1.12.5
@@ -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.5.1'
13
+ gem.version = '0.5.2'
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')
@@ -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', '~> 0.10'
22
+ gem.add_runtime_dependency 'fluentd', '~> 0.10', '<= 0.13'
23
23
  gem.add_runtime_dependency 'google-api-client', '> 0.9'
24
24
  gem.add_runtime_dependency 'googleauth', '~> 0.4'
25
25
  gem.add_runtime_dependency 'json', '~> 1.8'
@@ -14,6 +14,7 @@
14
14
  require 'json'
15
15
  require 'open-uri'
16
16
  require 'socket'
17
+ require 'time'
17
18
  require 'yaml'
18
19
  require 'google/apis'
19
20
  require 'google/apis/logging_v1beta3'
@@ -25,7 +26,7 @@ module Fluent
25
26
  Fluent::Plugin.register_output('google_cloud', self)
26
27
 
27
28
  PLUGIN_NAME = 'Fluentd Google Cloud Logging plugin'
28
- PLUGIN_VERSION = '0.5.1'
29
+ PLUGIN_VERSION = '0.5.2'
29
30
 
30
31
  # Constants for service names.
31
32
  APPENGINE_SERVICE = 'appengine.googleapis.com'
@@ -347,7 +348,6 @@ module Fluent
347
348
  end
348
349
  end
349
350
  end
350
- is_container_json = nil
351
351
  arr.each do |time, record|
352
352
  next unless record.is_a?(Hash)
353
353
 
@@ -373,24 +373,27 @@ module Fluent
373
373
  if record.key?('kubernetes')
374
374
  handle_container_metadata(record, entry)
375
375
  end
376
- # If the log from the user container is json, we want to export it
377
- # as a structured log. Now that we've pulled out all the
378
- # container-specific metadata from the record, we can replace the
379
- # record with the json that the user logged.
380
- # To save CPU in the common case of unstructured logs, only check if
381
- # the contents are parsable as json for the first entry of each
382
- # batch.
383
- if is_container_json.nil? && record.key?('log')
384
- record_json = parse_json_or_nil(record['log'])
385
- if record_json.nil?
386
- is_container_json = false
387
- else
388
- record = record_json
389
- is_container_json = true
390
- end
391
- elsif is_container_json && record.key?('log')
376
+
377
+ # Save the timestamp if available, then clear it out to allow for
378
+ # determining whether we should parse the log or message field.
379
+ timestamp = record.key?('time') ? record['time'] : nil
380
+ record.delete('time')
381
+ # If the log is json, we want to export it as a structured log
382
+ # unless there is additional metadata that would be lost.
383
+ is_json = false
384
+ if record.length == 1 && record.key?('log')
392
385
  record_json = parse_json_or_nil(record['log'])
393
- record = record_json unless record_json.nil?
386
+ end
387
+ if record.length == 1 && record.key?('message')
388
+ record_json = parse_json_or_nil(record['message'])
389
+ end
390
+ unless record_json.nil?
391
+ record = record_json
392
+ is_json = true
393
+ end
394
+ # Restore timestamp if necessary.
395
+ unless record.key?('time') || timestamp.nil?
396
+ record['time'] = timestamp
394
397
  end
395
398
  end
396
399
 
@@ -414,7 +417,7 @@ module Fluent
414
417
  @cloudfunctions_log_match['execution_id']
415
418
  end
416
419
 
417
- set_payload(record, entry, is_container_json)
420
+ set_payload(record, entry, is_json)
418
421
  entry.metadata.labels = nil if entry.metadata.labels.empty?
419
422
 
420
423
  entries.push(entry)
@@ -476,11 +479,23 @@ module Fluent
476
479
  # Only here to please rubocop...
477
480
  return nil if input.nil?
478
481
 
479
- begin
480
- return JSON.parse(input)
481
- rescue JSON::ParserError
482
- return nil
483
- end
482
+ input.each_codepoint do |c|
483
+ if c == 123
484
+ # left curly bracket (U+007B)
485
+ begin
486
+ return JSON.parse(input)
487
+ rescue JSON::ParserError
488
+ return nil
489
+ end
490
+ else
491
+ # Break (and return nil) unless the current character is whitespace,
492
+ # in which case we continue to look for a left curly bracket.
493
+ # Whitespace as per the JSON spec are: tabulation (U+0009),
494
+ # line feed (U+000A), carriage return (U+000D), and space (U+0020).
495
+ break unless c == 9 || c == 10 || c == 13 || c == 32
496
+ end # case
497
+ end # do
498
+ nil
484
499
  end
485
500
 
486
501
  # "enum" of Platform values
@@ -616,6 +631,15 @@ module Fluent
616
631
  timestamp = DateTime.parse(@cloudfunctions_log_match['timestamp'])
617
632
  ts_secs = timestamp.strftime('%s')
618
633
  ts_nanos = timestamp.strftime('%N')
634
+ elsif record.key?('time')
635
+ # k8s ISO8601 timestamp
636
+ begin
637
+ timestamp = Time.iso8601(record.delete('time'))
638
+ rescue
639
+ timestamp = Time.at(time)
640
+ end
641
+ ts_secs = timestamp.tv_sec
642
+ ts_nanos = timestamp.tv_nsec
619
643
  else
620
644
  timestamp = Time.at(time)
621
645
  ts_secs = timestamp.tv_sec
@@ -644,6 +668,16 @@ module Fluent
644
668
  elsif record.key?('severity')
645
669
  entry.metadata.severity = parse_severity(record['severity'])
646
670
  record.delete('severity')
671
+ elsif @service_name == CONTAINER_SERVICE && \
672
+ entry.metadata.labels.key?("#{CONTAINER_SERVICE}/stream")
673
+ stream = entry.metadata.labels["#{CONTAINER_SERVICE}/stream"]
674
+ if stream == 'stdout'
675
+ entry.metadata.severity = 'INFO'
676
+ elsif stream == 'stderr'
677
+ entry.metadata.severity = 'ERROR'
678
+ else
679
+ entry.metadata.severity = 'DEFAULT'
680
+ end
647
681
  else
648
682
  entry.metadata.severity = 'DEFAULT'
649
683
  end
@@ -759,18 +793,20 @@ module Fluent
759
793
  record.delete(field)
760
794
  end
761
795
 
762
- def set_payload(record, entry, is_container_json)
763
- # Use textPayload if
764
- # 1. This is a Cloud Functions log that matched the expected regexp
765
- # 2. This is a Cloud Functions log and the 'log' key is available
766
- # 3. This is an unstructured Container log and the 'log' key is available
767
- # 4. The only remaining key is 'message'
796
+ def set_payload(record, entry, is_json)
797
+ # If this is a Cloud Functions log that matched the expected regexp,
798
+ # use text payload. Otherwise, use JSON if we found valid JSON, or text
799
+ # payload in the following cases:
800
+ # 1. This is a Cloud Functions log and the 'log' key is available
801
+ # 2. This is an unstructured Container log and the 'log' key is available
802
+ # 3. The only remaining key is 'message'
768
803
  if @service_name == CLOUDFUNCTIONS_SERVICE && @cloudfunctions_log_match
769
804
  entry.text_payload = @cloudfunctions_log_match['text']
770
805
  elsif @service_name == CLOUDFUNCTIONS_SERVICE && record.key?('log')
771
806
  entry.text_payload = record['log']
772
- elsif @service_name == CONTAINER_SERVICE && record.key?('log') &&
773
- !is_container_json
807
+ elsif is_json
808
+ entry.struct_payload = record
809
+ elsif @service_name == CONTAINER_SERVICE && record.key?('log')
774
810
  entry.text_payload = record['log']
775
811
  elsif record.size == 1 && record.key?('message')
776
812
  entry.text_payload = record['message']
@@ -14,6 +14,7 @@
14
14
 
15
15
  require 'helper'
16
16
  require 'json'
17
+ require 'time'
17
18
  require 'mocha/test_unit'
18
19
  require 'webmock/test_unit'
19
20
  require 'google/apis'
@@ -82,6 +83,11 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
82
83
  CONTAINER_LABEL_KEY = 'component'
83
84
  CONTAINER_LABEL_VALUE = 'redis-component'
84
85
  CONTAINER_STREAM = 'stdout'
86
+ CONTAINER_SEVERITY = 'INFO'
87
+ # Timestamp for 1234567890 seconds and 987654321 nanoseconds since epoch
88
+ CONTAINER_TIMESTAMP = '2009-02-13T23:31:30.987654321Z'
89
+ CONTAINER_SECONDS_EPOCH = 1_234_567_890
90
+ CONTAINER_NANOS = 987_654_321
85
91
 
86
92
  # Cloud Functions specific labels
87
93
  CLOUDFUNCTIONS_FUNCTION_NAME = '$My_Function.Name-@1'
@@ -583,6 +589,46 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
583
589
  end
584
590
  end
585
591
 
592
+ def test_struct_payload_json_log
593
+ setup_gce_metadata_stubs
594
+ setup_logging_stubs
595
+ d = create_driver
596
+ json_string = '{"msg": "test log entry 0", "tag2": "test", "data": 5000}'
597
+ d.emit('message' => 'notJSON ' + json_string)
598
+ d.emit('message' => json_string)
599
+ d.emit('message' => "\t" + json_string)
600
+ d.emit('message' => ' ' + json_string)
601
+ d.run
602
+ verify_log_entries(4, COMPUTE_PARAMS, '') do |entry|
603
+ assert entry.key?('textPayload'), 'Entry did not have textPayload'
604
+ end
605
+ end
606
+
607
+ def test_struct_payload_json_container_log
608
+ setup_gce_metadata_stubs
609
+ setup_container_metadata_stubs
610
+ setup_logging_stubs
611
+ d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
612
+ json_string = '{"msg": "test log entry 0", "tag2": "test", "data": 5000}'
613
+ d.emit(container_log_entry_with_metadata('notJSON' + json_string))
614
+ d.emit(container_log_entry_with_metadata(json_string))
615
+ d.emit(container_log_entry_with_metadata(" \r\n \t" + json_string))
616
+ d.run
617
+ log_index = 0
618
+ verify_log_entries(3, CONTAINER_FROM_METADATA_PARAMS, '') do |entry|
619
+ log_index += 1
620
+ if log_index == 1
621
+ assert entry.key?('textPayload'), 'Entry did not have textPayload'
622
+ else
623
+ assert entry.key?('structPayload'), 'Entry did not have structPayload'
624
+ assert_equal 3, entry['structPayload'].size, entry
625
+ assert_equal 'test log entry 0', entry['structPayload']['msg'], entry
626
+ assert_equal 'test', entry['structPayload']['tag2'], entry
627
+ assert_equal 5000, entry['structPayload']['data'], entry
628
+ end
629
+ end
630
+ end
631
+
586
632
  def test_timestamps
587
633
  setup_gce_metadata_stubs
588
634
  setup_logging_stubs
@@ -843,7 +889,13 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
843
889
  d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
844
890
  d.emit(container_log_entry_with_metadata(log_entry(0)))
845
891
  d.run
846
- verify_log_entries(1, CONTAINER_FROM_METADATA_PARAMS)
892
+ verify_log_entries(1, CONTAINER_FROM_METADATA_PARAMS) do |entry|
893
+ assert_equal CONTAINER_SECONDS_EPOCH, \
894
+ entry['metadata']['timestamp']['seconds'], entry
895
+ assert_equal CONTAINER_NANOS, \
896
+ entry['metadata']['timestamp']['nanos'], entry
897
+ assert_equal CONTAINER_SEVERITY, entry['metadata']['severity'], entry
898
+ end
847
899
  end
848
900
 
849
901
  def test_multiple_container_logs_metadata_from_plugin
@@ -858,7 +910,13 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
858
910
  @logs_sent = []
859
911
  n.times { |i| d.emit(container_log_entry_with_metadata(log_entry(i))) }
860
912
  d.run
861
- verify_log_entries(n, CONTAINER_FROM_METADATA_PARAMS)
913
+ verify_log_entries(n, CONTAINER_FROM_METADATA_PARAMS) do |entry|
914
+ assert_equal CONTAINER_SECONDS_EPOCH, \
915
+ entry['metadata']['timestamp']['seconds'], entry
916
+ assert_equal CONTAINER_NANOS, \
917
+ entry['metadata']['timestamp']['nanos'], entry
918
+ assert_equal CONTAINER_SEVERITY, entry['metadata']['severity'], entry
919
+ end
862
920
  end
863
921
  end
864
922
 
@@ -869,7 +927,13 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
869
927
  d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
870
928
  d.emit(container_log_entry(log_entry(0)))
871
929
  d.run
872
- verify_log_entries(1, CONTAINER_FROM_TAG_PARAMS)
930
+ verify_log_entries(1, CONTAINER_FROM_TAG_PARAMS) do |entry|
931
+ assert_equal CONTAINER_SECONDS_EPOCH, \
932
+ entry['metadata']['timestamp']['seconds'], entry
933
+ assert_equal CONTAINER_NANOS, \
934
+ entry['metadata']['timestamp']['nanos'], entry
935
+ assert_equal CONTAINER_SEVERITY, entry['metadata']['severity'], entry
936
+ end
873
937
  end
874
938
 
875
939
  def test_multiple_container_logs_metadata_from_tag
@@ -884,7 +948,32 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
884
948
  @logs_sent = []
885
949
  n.times { |i| d.emit(container_log_entry(log_entry(i))) }
886
950
  d.run
887
- verify_log_entries(n, CONTAINER_FROM_TAG_PARAMS)
951
+ verify_log_entries(n, CONTAINER_FROM_TAG_PARAMS) do |entry|
952
+ assert_equal CONTAINER_SECONDS_EPOCH, \
953
+ entry['metadata']['timestamp']['seconds'], entry
954
+ assert_equal CONTAINER_NANOS, \
955
+ entry['metadata']['timestamp']['nanos'], entry
956
+ assert_equal CONTAINER_SEVERITY, entry['metadata']['severity'], entry
957
+ end
958
+ end
959
+ end
960
+
961
+ def test_one_container_log_from_tag_stderr
962
+ setup_gce_metadata_stubs
963
+ setup_container_metadata_stubs
964
+ setup_logging_stubs
965
+ d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
966
+ d.emit(container_log_entry(log_entry(0), 'stderr'))
967
+ d.run
968
+ expected_params = CONTAINER_FROM_TAG_PARAMS.merge(
969
+ labels: { "#{CONTAINER_SERVICE_NAME}/stream" => 'stderr' }
970
+ ) { |_, oldval, newval| oldval.merge(newval) }
971
+ verify_log_entries(1, expected_params) do |entry|
972
+ assert_equal CONTAINER_SECONDS_EPOCH, \
973
+ entry['metadata']['timestamp']['seconds'], entry
974
+ assert_equal CONTAINER_NANOS, \
975
+ entry['metadata']['timestamp']['nanos'], entry
976
+ assert_equal 'ERROR', entry['metadata']['severity'], entry
888
977
  end
889
978
  end
890
979
 
@@ -894,7 +983,8 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
894
983
  setup_logging_stubs
895
984
  d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
896
985
  d.emit(container_log_entry_with_metadata('{"msg": "test log entry 0", ' \
897
- '"tag2": "test", "data": 5000}'))
986
+ '"tag2": "test", "data": 5000, ' \
987
+ '"severity": "WARNING"}'))
898
988
  d.run
899
989
  verify_log_entries(1, CONTAINER_FROM_METADATA_PARAMS,
900
990
  'structPayload') do |entry|
@@ -902,6 +992,11 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
902
992
  assert_equal 'test log entry 0', entry['structPayload']['msg'], entry
903
993
  assert_equal 'test', entry['structPayload']['tag2'], entry
904
994
  assert_equal 5000, entry['structPayload']['data'], entry
995
+ assert_equal CONTAINER_SECONDS_EPOCH, \
996
+ entry['metadata']['timestamp']['seconds'], entry
997
+ assert_equal CONTAINER_NANOS, \
998
+ entry['metadata']['timestamp']['nanos'], entry
999
+ assert_equal 'WARNING', entry['metadata']['severity'], entry
905
1000
  end
906
1001
  end
907
1002
 
@@ -911,7 +1006,8 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
911
1006
  setup_logging_stubs
912
1007
  d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
913
1008
  d.emit(container_log_entry('{"msg": "test log entry 0", ' \
914
- '"tag2": "test", "data": 5000}'))
1009
+ '"tag2": "test", "data": 5000, ' \
1010
+ '"severity": "W"}'))
915
1011
  d.run
916
1012
  verify_log_entries(1, CONTAINER_FROM_TAG_PARAMS,
917
1013
  'structPayload') do |entry|
@@ -919,6 +1015,11 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
919
1015
  assert_equal 'test log entry 0', entry['structPayload']['msg'], entry
920
1016
  assert_equal 'test', entry['structPayload']['tag2'], entry
921
1017
  assert_equal 5000, entry['structPayload']['data'], entry
1018
+ assert_equal CONTAINER_SECONDS_EPOCH, \
1019
+ entry['metadata']['timestamp']['seconds'], entry
1020
+ assert_equal CONTAINER_NANOS, \
1021
+ entry['metadata']['timestamp']['nanos'], entry
1022
+ assert_equal 'WARNING', entry['metadata']['severity'], entry
922
1023
  end
923
1024
  end
924
1025
 
@@ -1250,7 +1351,8 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
1250
1351
  def container_log_entry_with_metadata(log)
1251
1352
  {
1252
1353
  log: log,
1253
- stream: 'stdout',
1354
+ stream: CONTAINER_STREAM,
1355
+ time: CONTAINER_TIMESTAMP,
1254
1356
  kubernetes: {
1255
1357
  namespace_id: CONTAINER_NAMESPACE_ID,
1256
1358
  namespace_name: CONTAINER_NAMESPACE_NAME,
@@ -1264,10 +1366,11 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
1264
1366
  }
1265
1367
  end
1266
1368
 
1267
- def container_log_entry(log)
1369
+ def container_log_entry(log, stream = CONTAINER_STREAM)
1268
1370
  {
1269
1371
  log: log,
1270
- stream: 'stdout'
1372
+ stream: stream,
1373
+ time: CONTAINER_TIMESTAMP
1271
1374
  }
1272
1375
  end
1273
1376
 
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.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd Derr
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-11 00:00:00.000000000 Z
12
+ date: 2016-06-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fluentd
@@ -18,6 +18,9 @@ dependencies:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
20
  version: '0.10'
21
+ - - "<="
22
+ - !ruby/object:Gem::Version
23
+ version: '0.13'
21
24
  type: :runtime
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -25,6 +28,9 @@ dependencies:
25
28
  - - "~>"
26
29
  - !ruby/object:Gem::Version
27
30
  version: '0.10'
31
+ - - "<="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.13'
28
34
  - !ruby/object:Gem::Dependency
29
35
  name: google-api-client
30
36
  requirement: !ruby/object:Gem::Requirement