fluent-plugin-google-cloud 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +19 -19
- data/fluent-plugin-google-cloud.gemspec +2 -2
- data/lib/fluent/plugin/out_google_cloud.rb +69 -33
- data/test/plugin/test_out_google_cloud.rb +112 -9
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8109f72f6f16a0756b3a30c911e9343392051b96
|
4
|
+
data.tar.gz: e76c44a9c3e8cb63c6125f1b621e7985e3050918
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aad0d625ddb42768a112e887bae953d601bd646d9003d7a7308a19a3e9e4afdbd61725bd56b844cefc7626a99dad067ea3ef6d68e44f06bc324ab7abe937bcd2
|
7
|
+
data.tar.gz: c880a81905b4ce2535f247a7bd1938e46082461f8c9f48a03716908219e6fe95234397a09ee4975ed21dc5c196b782d1efd1ebf499617c7fb989aa234efbf60e
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fluent-plugin-google-cloud (0.5.
|
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.
|
14
|
+
ast (2.3.0)
|
15
15
|
astrolabe (1.3.1)
|
16
16
|
parser (~> 2.2)
|
17
|
-
cool.io (1.4.
|
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
|
+
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.
|
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.
|
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.
|
62
|
+
mime-types (3.1)
|
63
63
|
mime-types-data (~> 3.2015)
|
64
|
-
mime-types-data (3.2016.
|
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.
|
68
|
+
multi_json (1.12.1)
|
69
69
|
multipart-post (2.0.0)
|
70
70
|
os (0.9.6)
|
71
|
-
parser (2.3.
|
71
|
+
parser (2.3.1.2)
|
72
72
|
ast (~> 2.2)
|
73
|
-
power_assert (0.
|
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.
|
86
|
+
ruby-progressbar (1.8.1)
|
87
87
|
safe_yaml (1.0.4)
|
88
88
|
sigdump (0.2.4)
|
89
|
-
signet (0.7.
|
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.
|
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.
|
101
|
+
tzinfo-data (1.2016.5)
|
102
102
|
tzinfo (>= 1.0.0)
|
103
103
|
uber (0.0.15)
|
104
|
-
webmock (1.24.
|
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.
|
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.
|
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.
|
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
|
-
|
377
|
-
#
|
378
|
-
#
|
379
|
-
|
380
|
-
|
381
|
-
# the
|
382
|
-
#
|
383
|
-
|
384
|
-
|
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
|
-
|
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,
|
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
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
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,
|
763
|
-
#
|
764
|
-
#
|
765
|
-
#
|
766
|
-
#
|
767
|
-
#
|
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
|
773
|
-
|
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:
|
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:
|
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.
|
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-
|
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
|