fluent-plugin-google-cloud 0.6.13 → 0.6.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +22 -21
- data/fluent-plugin-google-cloud.gemspec +5 -5
- data/lib/fluent/plugin/out_google_cloud.rb +147 -33
- data/test/plugin/base_test.rb +84 -50
- data/test/plugin/constants.rb +69 -2
- data/test/plugin/test_out_google_cloud_grpc.rb +53 -12
- metadata +16 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f370253a680adefd979f61cee26d87eedb36e3f8
|
4
|
+
data.tar.gz: bfd12ef42e11ce1cd51bee4bf356f9014ad07a67
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 671183d082caca469f7ded93eb737d07658beed0cce472806efeac2f303e810bd86049461a5ec5daef1d6d68436355bc4af81056ca0ee0c30a10f2a0047d86b9
|
7
|
+
data.tar.gz: d99f68afa553f93a280d0c648a24565c16bc1449af6d045cb31efc666e98c6c2d3406c1cf6879d77957a0513906fb87eb53a67c6133d37df523b81652aba87d9
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fluent-plugin-google-cloud (0.6.
|
4
|
+
fluent-plugin-google-cloud (0.6.14)
|
5
5
|
fluentd (~> 0.10)
|
6
|
-
google-api-client (~> 0.
|
7
|
-
google-cloud-logging (~> 1.
|
6
|
+
google-api-client (~> 0.17)
|
7
|
+
google-cloud-logging (~> 1.3, >= 1.3.2)
|
8
8
|
googleapis-common-protos (~> 1.3)
|
9
|
-
googleauth (~> 0.
|
10
|
-
grpc (~> 1.
|
9
|
+
googleauth (~> 0.6)
|
10
|
+
grpc (~> 1.0)
|
11
11
|
json (~> 1.8)
|
12
12
|
|
13
13
|
GEM
|
@@ -15,13 +15,13 @@ GEM
|
|
15
15
|
specs:
|
16
16
|
addressable (2.5.2)
|
17
17
|
public_suffix (>= 2.0.2, < 4.0)
|
18
|
-
ast (2.
|
18
|
+
ast (2.4.0)
|
19
19
|
cool.io (1.5.3)
|
20
20
|
crack (0.4.3)
|
21
21
|
safe_yaml (~> 1.0.0)
|
22
22
|
declarative (0.0.10)
|
23
23
|
declarative-option (0.1.0)
|
24
|
-
faraday (0.
|
24
|
+
faraday (0.14.0)
|
25
25
|
multipart-post (>= 1.2, < 3)
|
26
26
|
fluentd (0.14.25)
|
27
27
|
cool.io (>= 1.4.5, < 2.0.0)
|
@@ -34,7 +34,7 @@ GEM
|
|
34
34
|
tzinfo (~> 1.0)
|
35
35
|
tzinfo-data (~> 1.0)
|
36
36
|
yajl-ruby (~> 1.0)
|
37
|
-
google-api-client (0.19.
|
37
|
+
google-api-client (0.19.4)
|
38
38
|
addressable (~> 2.5, >= 2.5.1)
|
39
39
|
googleauth (>= 0.5, < 0.7.0)
|
40
40
|
httpclient (>= 2.8.1, < 3.0)
|
@@ -45,15 +45,15 @@ GEM
|
|
45
45
|
google-cloud-env (~> 1.0)
|
46
46
|
google-cloud-env (1.0.1)
|
47
47
|
faraday (~> 0.11)
|
48
|
-
google-cloud-logging (1.
|
49
|
-
google-cloud-core (~> 1.
|
50
|
-
google-gax (~>
|
48
|
+
google-cloud-logging (1.4.0)
|
49
|
+
google-cloud-core (~> 1.1)
|
50
|
+
google-gax (~> 1.0)
|
51
51
|
stackdriver-core (~> 1.2)
|
52
|
-
google-gax (0.
|
52
|
+
google-gax (1.0.1)
|
53
53
|
google-protobuf (~> 3.2)
|
54
|
-
googleapis-common-protos (
|
55
|
-
googleauth (~> 0.
|
56
|
-
grpc (
|
54
|
+
googleapis-common-protos (>= 1.3.5, < 2.0)
|
55
|
+
googleauth (~> 0.6.2)
|
56
|
+
grpc (>= 1.7.2, < 2.0)
|
57
57
|
rly (~> 0.2.3)
|
58
58
|
google-protobuf (3.5.1.1)
|
59
59
|
googleapis-common-protos (1.3.7)
|
@@ -62,22 +62,23 @@ GEM
|
|
62
62
|
grpc (~> 1.0)
|
63
63
|
googleapis-common-protos-types (1.0.1)
|
64
64
|
google-protobuf (~> 3.0)
|
65
|
-
googleauth (0.
|
65
|
+
googleauth (0.6.2)
|
66
66
|
faraday (~> 0.12)
|
67
|
-
jwt (
|
67
|
+
jwt (>= 1.4, < 3.0)
|
68
68
|
logging (~> 2.0)
|
69
69
|
memoist (~> 0.12)
|
70
70
|
multi_json (~> 1.11)
|
71
71
|
os (~> 0.9)
|
72
72
|
signet (~> 0.7)
|
73
|
-
grpc (1.
|
73
|
+
grpc (1.8.3)
|
74
74
|
google-protobuf (~> 3.1)
|
75
|
-
|
75
|
+
googleapis-common-protos-types (~> 1.0.0)
|
76
|
+
googleauth (>= 0.5.1, < 0.7)
|
76
77
|
hashdiff (0.3.7)
|
77
78
|
http_parser.rb (0.6.0)
|
78
79
|
httpclient (2.8.3)
|
79
80
|
json (1.8.6)
|
80
|
-
jwt (1.
|
81
|
+
jwt (2.1.0)
|
81
82
|
little-plugger (1.1.4)
|
82
83
|
logging (2.2.2)
|
83
84
|
little-plugger (~> 1.1)
|
@@ -134,7 +135,7 @@ GEM
|
|
134
135
|
thread_safe (0.3.6)
|
135
136
|
tzinfo (1.2.4)
|
136
137
|
thread_safe (~> 0.1)
|
137
|
-
tzinfo-data (1.
|
138
|
+
tzinfo-data (1.2018.3)
|
138
139
|
tzinfo (>= 1.0.0)
|
139
140
|
uber (0.1.0)
|
140
141
|
unicode-display_width (1.3.0)
|
@@ -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
|
+
gem.version = '0.6.14'
|
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')
|
@@ -21,10 +21,10 @@ eos
|
|
21
21
|
|
22
22
|
gem.add_runtime_dependency 'fluentd', '~> 0.10'
|
23
23
|
gem.add_runtime_dependency 'googleapis-common-protos', '~> 1.3'
|
24
|
-
gem.add_runtime_dependency 'google-api-client', '~> 0.
|
25
|
-
gem.add_runtime_dependency 'google-cloud-logging', '~> 1.
|
26
|
-
gem.add_runtime_dependency 'googleauth', '~> 0.
|
27
|
-
gem.add_runtime_dependency 'grpc', '~> 1.
|
24
|
+
gem.add_runtime_dependency 'google-api-client', '~> 0.17'
|
25
|
+
gem.add_runtime_dependency 'google-cloud-logging', '~> 1.3', '>= 1.3.2'
|
26
|
+
gem.add_runtime_dependency 'googleauth', '~> 0.6'
|
27
|
+
gem.add_runtime_dependency 'grpc', '~> 1.0'
|
28
28
|
gem.add_runtime_dependency 'json', '~> 1.8'
|
29
29
|
|
30
30
|
gem.add_development_dependency 'mocha', '~> 1.1'
|
@@ -120,6 +120,7 @@ module Fluent
|
|
120
120
|
DEFAULT_SOURCE_LOCATION_KEY =
|
121
121
|
'logging.googleapis.com/sourceLocation'.freeze
|
122
122
|
DEFAULT_TRACE_KEY = 'logging.googleapis.com/trace'.freeze
|
123
|
+
DEFAULT_SPAN_ID_KEY = 'logging.googleapis.com/spanId'.freeze
|
123
124
|
|
124
125
|
DEFAULT_METADATA_AGENT_URL =
|
125
126
|
'http://local-metadata-agent.stackdriver.com:8000'.freeze
|
@@ -127,6 +128,8 @@ module Fluent
|
|
127
128
|
|
128
129
|
# Internal constants.
|
129
130
|
module InternalConstants
|
131
|
+
DEFAULT_LOGGING_API_URL = 'https://logging.googleapis.com'.freeze
|
132
|
+
|
130
133
|
# The label name of local_resource_id in the json payload. When a record
|
131
134
|
# has this field in the payload, we will use the value to retrieve
|
132
135
|
# monitored resource from Stackdriver Metadata agent.
|
@@ -195,7 +198,7 @@ module Fluent
|
|
195
198
|
Fluent::Plugin.register_output('google_cloud', self)
|
196
199
|
|
197
200
|
PLUGIN_NAME = 'Fluentd Google Cloud Logging plugin'.freeze
|
198
|
-
PLUGIN_VERSION = '0.6.
|
201
|
+
PLUGIN_VERSION = '0.6.14'.freeze
|
199
202
|
|
200
203
|
# Name of the the Google cloud logging write scope.
|
201
204
|
LOGGING_SCOPE = 'https://www.googleapis.com/auth/logging.write'.freeze
|
@@ -219,6 +222,9 @@ module Fluent
|
|
219
222
|
# Whether to attempt to obtain metadata from the local metadata service.
|
220
223
|
# It is safe to specify 'true' even on platforms with no metadata service.
|
221
224
|
config_param :use_metadata_service, :bool, :default => true
|
225
|
+
# A compatibility option to enable the legacy behavior of setting the AWS
|
226
|
+
# location to the availability zone rather than the region.
|
227
|
+
config_param :use_aws_availability_zone, :bool, :default => true
|
222
228
|
# These parameters override any values obtained from the metadata service.
|
223
229
|
config_param :project_id, :string, :default => nil
|
224
230
|
config_param :zone, :string, :default => nil
|
@@ -232,6 +238,7 @@ module Fluent
|
|
232
238
|
config_param :source_location_key, :string, :default =>
|
233
239
|
DEFAULT_SOURCE_LOCATION_KEY
|
234
240
|
config_param :trace_key, :string, :default => DEFAULT_TRACE_KEY
|
241
|
+
config_param :span_id_key, :string, :default => DEFAULT_SPAN_ID_KEY
|
235
242
|
|
236
243
|
# Whether to try to detect if the record is a text log entry with JSON
|
237
244
|
# content that needs to be parsed.
|
@@ -323,6 +330,12 @@ module Fluent
|
|
323
330
|
:default => nil,
|
324
331
|
:secret => true
|
325
332
|
|
333
|
+
# The URL of Stackdriver Logging API. Right now this only works with the
|
334
|
+
# gRPC path (use_grpc = true). An unsecured channel is used if the URL
|
335
|
+
# scheme is 'http' instead of 'https'. One common use case of this config is
|
336
|
+
# to provide a mocked / stubbed Logging API, e.g., http://localhost:52000.
|
337
|
+
config_param :logging_api_url, :string, :default => DEFAULT_LOGGING_API_URL
|
338
|
+
|
326
339
|
# Whether to collect metrics about the plugin usage. The mechanism for
|
327
340
|
# collecting and exposing metrics is controlled by the monitoring_type
|
328
341
|
# parameter.
|
@@ -368,11 +381,11 @@ module Fluent
|
|
368
381
|
|
369
382
|
# TODO(qingling128): Remove this warning after the support is added. Also
|
370
383
|
# remove the comment in the description of this configuration.
|
371
|
-
|
372
|
-
@log.warn 'Detected
|
373
|
-
' enabled.
|
374
|
-
' is
|
375
|
-
'
|
384
|
+
unless @logging_api_url == DEFAULT_LOGGING_API_URL || @use_grpc
|
385
|
+
@log.warn 'Detected customized logging_api_url while use_grpc is not' \
|
386
|
+
' enabled. Customized logging_api_url for the non-gRPC path' \
|
387
|
+
' is not supported. The logging_api_url option will be' \
|
388
|
+
' ignored.'
|
376
389
|
end
|
377
390
|
|
378
391
|
# If monitoring is enabled, register metrics in the default registry
|
@@ -397,7 +410,7 @@ module Fluent
|
|
397
410
|
'The number of log entries that failed to be ingested by the'\
|
398
411
|
' Stackdriver output plugin due to a transient error and were'\
|
399
412
|
' retried')
|
400
|
-
@ok_code = @use_grpc ?
|
413
|
+
@ok_code = @use_grpc ? GRPC::Core::StatusCodes::OK : 200
|
401
414
|
end
|
402
415
|
|
403
416
|
# Alert on old authentication configuration.
|
@@ -540,6 +553,9 @@ module Fluent
|
|
540
553
|
fq_trace_id = record.delete(@trace_key)
|
541
554
|
entry.trace = fq_trace_id if fq_trace_id
|
542
555
|
|
556
|
+
span_id = record.delete(@span_id_key)
|
557
|
+
entry.span_id = span_id if span_id
|
558
|
+
|
543
559
|
set_log_entry_fields(record, entry)
|
544
560
|
set_payload(entry_level_resource.type, record, entry, is_json)
|
545
561
|
|
@@ -634,7 +650,6 @@ module Fluent
|
|
634
650
|
client = api_client
|
635
651
|
entries_count = entries.length
|
636
652
|
client.write_log_entries(
|
637
|
-
# Ignore partial_success for gRPC path.
|
638
653
|
entries,
|
639
654
|
log_name: log_name,
|
640
655
|
# Leave resource nil if it's nil.
|
@@ -646,7 +661,8 @@ module Fluent
|
|
646
661
|
end,
|
647
662
|
labels: labels.map do |k, v|
|
648
663
|
[k.encode('utf-8'), convert_to_utf8(v)]
|
649
|
-
end.to_h
|
664
|
+
end.to_h,
|
665
|
+
partial_success: @partial_success
|
650
666
|
)
|
651
667
|
increment_successful_requests_count
|
652
668
|
increment_ingested_entries_count(entries_count)
|
@@ -683,14 +699,10 @@ module Fluent
|
|
683
699
|
# Most client errors indicate a problem with the request itself and
|
684
700
|
# should not be retried.
|
685
701
|
when \
|
686
|
-
# HTTP status 400 (Bad Request).
|
687
|
-
GRPC::InvalidArgument,
|
688
702
|
# HTTP status 401 (Unauthorized).
|
689
|
-
# These are usually solved via a `gcloud auth` call, or by
|
690
|
-
#
|
703
|
+
# These are usually solved via a `gcloud auth` call, or by modifying
|
704
|
+
# the permissions on the Google Cloud project.
|
691
705
|
GRPC::Unauthenticated,
|
692
|
-
# HTTP status 403 (Forbidden).
|
693
|
-
GRPC::PermissionDenied,
|
694
706
|
# HTTP status 404 (Not Found).
|
695
707
|
GRPC::NotFound,
|
696
708
|
# HTTP status 409 (Conflict).
|
@@ -711,6 +723,33 @@ module Fluent
|
|
711
723
|
@log.warn "Dropping #{entries_count} log message(s)",
|
712
724
|
error: error.to_s, error_code: error.code.to_s
|
713
725
|
|
726
|
+
# If partial_success is enabled, valid entries should have be
|
727
|
+
# written even if some other entries fail due to InvalidArgument or
|
728
|
+
# PermissionDenied errors. Only invalid entries will be dropped.
|
729
|
+
when \
|
730
|
+
# HTTP status 400 (Bad Request).
|
731
|
+
GRPC::InvalidArgument,
|
732
|
+
# HTTP status 403 (Forbidden).
|
733
|
+
GRPC::PermissionDenied
|
734
|
+
error_details_map = construct_error_details_map_grpc(gax_error)
|
735
|
+
if error_details_map.empty?
|
736
|
+
increment_dropped_entries_count(entries_count, error.code)
|
737
|
+
@log.warn "Dropping #{entries_count} log message(s)",
|
738
|
+
error: error.to_s, error_code: error.code.to_s
|
739
|
+
else
|
740
|
+
error_details_map.each do |(error_code, error_message), indexes|
|
741
|
+
partial_errors_count = indexes.length
|
742
|
+
increment_dropped_entries_count(partial_errors_count,
|
743
|
+
error_code)
|
744
|
+
entries_count -= partial_errors_count
|
745
|
+
@log.warn "Dropping #{partial_errors_count} log message(s)",
|
746
|
+
error: error_message, error_code: error_code.to_s
|
747
|
+
end
|
748
|
+
# Consider partially successful requests successful.
|
749
|
+
increment_successful_requests_count
|
750
|
+
increment_ingested_entries_count(entries_count)
|
751
|
+
end
|
752
|
+
|
714
753
|
else
|
715
754
|
# Assume it's a problem with the request itself and don't retry.
|
716
755
|
increment_failed_requests_count(error.code)
|
@@ -771,7 +810,7 @@ module Fluent
|
|
771
810
|
increment_failed_requests_count(error.status_code)
|
772
811
|
increment_dropped_entries_count(entries_count, error.status_code)
|
773
812
|
@log.warn "Dropping #{entries_count} log message(s)",
|
774
|
-
|
813
|
+
error: error.to_s, error_code: error.status_code.to_s
|
775
814
|
|
776
815
|
rescue Google::Apis::ClientError => error
|
777
816
|
# 4xx client errors. Most client errors indicate a problem with the
|
@@ -781,15 +820,15 @@ module Fluent
|
|
781
820
|
increment_failed_requests_count(error.status_code)
|
782
821
|
increment_dropped_entries_count(entries_count, error.status_code)
|
783
822
|
@log.warn "Dropping #{entries_count} log message(s)",
|
784
|
-
|
823
|
+
error: error.to_s, error_code: error.status_code.to_s
|
785
824
|
else
|
786
825
|
error_details_map.each do |(error_code, error_message), indexes|
|
787
|
-
|
788
|
-
increment_dropped_entries_count(
|
789
|
-
entries_count -=
|
790
|
-
@log.warn "Dropping #{
|
791
|
-
|
792
|
-
|
826
|
+
partial_errors_count = indexes.length
|
827
|
+
increment_dropped_entries_count(partial_errors_count, error_code)
|
828
|
+
entries_count -= partial_errors_count
|
829
|
+
@log.warn "Dropping #{partial_errors_count} log message(s)",
|
830
|
+
error: error_message,
|
831
|
+
error_code: "google.rpc.Code[#{error_code}]"
|
793
832
|
end
|
794
833
|
# Consider partially successful requests successful.
|
795
834
|
increment_successful_requests_count
|
@@ -945,8 +984,13 @@ module Fluent
|
|
945
984
|
# Response format: "projects/<number>/zones/<zone>"
|
946
985
|
@zone ||= fetch_gce_metadata('instance/zone').rpartition('/')[2] if
|
947
986
|
@platform == Platform::GCE
|
948
|
-
|
949
|
-
|
987
|
+
aws_location_key = if @use_aws_availability_zone
|
988
|
+
'availabilityZone'
|
989
|
+
else
|
990
|
+
'region'
|
991
|
+
end
|
992
|
+
@zone ||= 'aws:' + ec2_metadata[aws_location_key] if
|
993
|
+
@platform == Platform::EC2 && ec2_metadata.key?(aws_location_key)
|
950
994
|
rescue StandardError => e
|
951
995
|
@log.error 'Failed to obtain location: ', error: e
|
952
996
|
end
|
@@ -1828,13 +1872,24 @@ module Fluent
|
|
1828
1872
|
|
1829
1873
|
def init_api_client
|
1830
1874
|
if @use_grpc
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1875
|
+
uri = URI.parse(@logging_api_url)
|
1876
|
+
host = uri.host
|
1877
|
+
unless host
|
1878
|
+
raise Fluent::ConfigError,
|
1879
|
+
'The logging_api_url option specifies an invalid URL:' \
|
1880
|
+
" #{@logging_api_url}."
|
1881
|
+
end
|
1882
|
+
if uri.scheme == 'https'
|
1883
|
+
ssl_creds = GRPC::Core::ChannelCredentials.new
|
1884
|
+
authentication = Google::Auth.get_application_default
|
1885
|
+
creds = GRPC::Core::CallCredentials.new(authentication.updater_proc)
|
1886
|
+
creds = ssl_creds.compose(creds)
|
1887
|
+
else
|
1888
|
+
creds = :this_channel_is_insecure
|
1889
|
+
end
|
1890
|
+
port = ":#{uri.port}" if uri.port
|
1835
1891
|
@client = Google::Cloud::Logging::V2::LoggingServiceV2Client.new(
|
1836
|
-
|
1837
|
-
'logging.googleapis.com', nil, creds))
|
1892
|
+
credentials: GRPC::Core::Channel.new("#{host}#{port}", nil, creds))
|
1838
1893
|
else
|
1839
1894
|
# TODO: Use a non-default ClientOptions object.
|
1840
1895
|
Google::Apis::ClientOptions.default.application_name = PLUGIN_NAME
|
@@ -1885,8 +1940,8 @@ module Fluent
|
|
1885
1940
|
end
|
1886
1941
|
end
|
1887
1942
|
|
1888
|
-
# Extract a map of error details from
|
1889
|
-
# request. Return an empty map if @partial_success is not enabled.
|
1943
|
+
# Extract a map of error details from a potentially partially successful
|
1944
|
+
# REST request. Return an empty map if @partial_success is not enabled.
|
1890
1945
|
#
|
1891
1946
|
# The keys in this map are [error_code, error_message] pairs, and the values
|
1892
1947
|
# are a list of stringified indexes of log entries that failed due to this
|
@@ -1989,6 +2044,65 @@ module Fluent
|
|
1989
2044
|
{}
|
1990
2045
|
end
|
1991
2046
|
|
2047
|
+
# Extract a map of error details from a potentially partially successful
|
2048
|
+
# gRPC request. Return an empty map if @partial_success is not enabled.
|
2049
|
+
#
|
2050
|
+
# The keys in this map are [error_code, error_message] pairs, and the values
|
2051
|
+
# are a list of indexes of log entries that failed due to this error.
|
2052
|
+
#
|
2053
|
+
# A sample error looks like:
|
2054
|
+
# <Google::Gax::RetryError:
|
2055
|
+
# message: 'GaxError Exception occurred in retry method that was not class
|
2056
|
+
# ified as transient, caused by 7:User not authorized.',
|
2057
|
+
# details: [
|
2058
|
+
# <Google::Logging::V2::WriteLogEntriesPartialErrors:
|
2059
|
+
# log_entry_errors: {
|
2060
|
+
# 0 => <Google::Rpc::Status:
|
2061
|
+
# code: 7,
|
2062
|
+
# message: "User not authorized.",
|
2063
|
+
# details: []>,
|
2064
|
+
# 1 => <Google::Rpc::Status:
|
2065
|
+
# code: 3,
|
2066
|
+
# message: "Log name contains illegal character :",
|
2067
|
+
# details: []>,
|
2068
|
+
# 3 => <Google::Rpc::Status:
|
2069
|
+
# code: 3,
|
2070
|
+
# message: "Log name contains illegal character :",
|
2071
|
+
# details: []>
|
2072
|
+
# }
|
2073
|
+
# >,
|
2074
|
+
# <Google::Rpc::DebugInfo:
|
2075
|
+
# stack_entries: [],
|
2076
|
+
# detail: "..."
|
2077
|
+
# >
|
2078
|
+
# ]
|
2079
|
+
# cause: <GRPC::PermissionDenied: 7:User not authorized.>
|
2080
|
+
# }
|
2081
|
+
#
|
2082
|
+
# The ultimate map that is constructed is:
|
2083
|
+
# {
|
2084
|
+
# [7, 'User not authorized.']: [0],
|
2085
|
+
# [3, 'Log name contains illegal character :']: [1, 3]
|
2086
|
+
# }
|
2087
|
+
def construct_error_details_map_grpc(gax_error)
|
2088
|
+
return {} unless @partial_success
|
2089
|
+
error_details_map = Hash.new { |h, k| h[k] = [] }
|
2090
|
+
|
2091
|
+
error_details = ensure_array(gax_error.status_details)
|
2092
|
+
raise JSON::ParserError, 'The error details are empty.' if
|
2093
|
+
error_details.empty?
|
2094
|
+
log_entry_errors = ensure_hash(error_details[0].log_entry_errors)
|
2095
|
+
log_entry_errors.each do |index, log_entry_error|
|
2096
|
+
error_key = [log_entry_error[:code], log_entry_error[:message]].freeze
|
2097
|
+
error_details_map[error_key] << index
|
2098
|
+
end
|
2099
|
+
error_details_map
|
2100
|
+
rescue JSON::ParserError => e
|
2101
|
+
@log.warn 'Failed to extract log entry errors from the error details:' \
|
2102
|
+
" #{gax_error.details.inspect}.", error: e
|
2103
|
+
{}
|
2104
|
+
end
|
2105
|
+
|
1992
2106
|
def ensure_array(value)
|
1993
2107
|
Array.try_convert(value) || (raise JSON::ParserError, value.class.to_s)
|
1994
2108
|
end
|
data/test/plugin/base_test.rb
CHANGED
@@ -62,6 +62,17 @@ module BaseTest
|
|
62
62
|
assert_equal 1, exception_count
|
63
63
|
end
|
64
64
|
|
65
|
+
def test_configure_logging_api_url
|
66
|
+
setup_gce_metadata_stubs
|
67
|
+
{
|
68
|
+
APPLICATION_DEFAULT_CONFIG => DEFAULT_LOGGING_API_URL,
|
69
|
+
CUSTOM_LOGGING_API_URL_CONFIG => CUSTOM_LOGGING_API_URL
|
70
|
+
}.each do |(config, url)|
|
71
|
+
d = create_driver(config)
|
72
|
+
assert_equal url, d.instance.instance_variable_get(:@logging_api_url)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
65
76
|
def test_configure_custom_metadata
|
66
77
|
setup_no_metadata_service_stubs
|
67
78
|
d = create_driver(CUSTOM_METADATA_CONFIG)
|
@@ -163,7 +174,9 @@ module BaseTest
|
|
163
174
|
CONFIG_EC2_PROJECT_ID =>
|
164
175
|
['ec2', EC2_PROJECT_ID, EC2_PREFIXED_ZONE, EC2_VM_ID],
|
165
176
|
CONFIG_EC2_PROJECT_ID_AND_CUSTOM_VM_ID =>
|
166
|
-
['ec2', EC2_PROJECT_ID, EC2_PREFIXED_ZONE, CUSTOM_VM_ID]
|
177
|
+
['ec2', EC2_PROJECT_ID, EC2_PREFIXED_ZONE, CUSTOM_VM_ID],
|
178
|
+
CONFIG_EC2_PROJECT_ID_USE_REGION =>
|
179
|
+
['ec2', EC2_PROJECT_ID, EC2_PREFIXED_REGION, EC2_VM_ID]
|
167
180
|
}.each_with_index do |(config, parts), index|
|
168
181
|
send("setup_#{parts[0]}_metadata_stubs")
|
169
182
|
d = create_driver(config)
|
@@ -257,7 +270,18 @@ module BaseTest
|
|
257
270
|
d.emit('message' => log_entry(0))
|
258
271
|
d.run
|
259
272
|
end
|
260
|
-
verify_log_entries(1,
|
273
|
+
verify_log_entries(1, EC2_ZONE_PARAMS)
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_one_log_ec2_region
|
277
|
+
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = IAM_CREDENTIALS[:path]
|
278
|
+
setup_ec2_metadata_stubs
|
279
|
+
setup_logging_stubs do
|
280
|
+
d = create_driver(CONFIG_EC2_PROJECT_ID_USE_REGION)
|
281
|
+
d.emit('message' => log_entry(0))
|
282
|
+
d.run
|
283
|
+
end
|
284
|
+
verify_log_entries(1, EC2_REGION_PARAMS)
|
261
285
|
end
|
262
286
|
|
263
287
|
def test_structured_payload_log
|
@@ -1154,55 +1178,14 @@ module BaseTest
|
|
1154
1178
|
end
|
1155
1179
|
|
1156
1180
|
def test_log_entry_trace_field
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
{
|
1162
|
-
# It leaves trace entry field nil if no trace value sent.
|
1163
|
-
driver_config: APPLICATION_DEFAULT_CONFIG,
|
1164
|
-
emitted_log: { 'msg' => message },
|
1165
|
-
expected_fields: { 'msg' => message },
|
1166
|
-
expected_trace_value: nil
|
1167
|
-
},
|
1168
|
-
{
|
1169
|
-
# By default, it sets trace via Google-specific key.
|
1170
|
-
driver_config: APPLICATION_DEFAULT_CONFIG,
|
1171
|
-
emitted_log: { 'msg' => message, DEFAULT_TRACE_KEY => trace },
|
1172
|
-
expected_fields: { 'msg' => message },
|
1173
|
-
expected_trace_value: trace
|
1174
|
-
},
|
1175
|
-
{
|
1176
|
-
# It allows setting the trace via a custom configured key.
|
1177
|
-
driver_config: CONFIG_CUSTOM_TRACE_KEY_SPECIFIED,
|
1178
|
-
emitted_log: { 'msg' => message, 'custom_trace_key' => trace },
|
1179
|
-
expected_fields: { 'msg' => message },
|
1180
|
-
expected_trace_value: trace
|
1181
|
-
},
|
1182
|
-
{
|
1183
|
-
# It no longer sets trace by the default key if custom key specified.
|
1184
|
-
driver_config: CONFIG_CUSTOM_TRACE_KEY_SPECIFIED,
|
1185
|
-
emitted_log: { 'msg' => message, DEFAULT_TRACE_KEY => trace },
|
1186
|
-
expected_fields: { 'msg' => message, DEFAULT_TRACE_KEY => trace },
|
1187
|
-
expected_trace_value: nil
|
1188
|
-
}
|
1189
|
-
].each do |input|
|
1190
|
-
setup_logging_stubs do
|
1191
|
-
@logs_sent = []
|
1192
|
-
d = create_driver(input[:driver_config])
|
1193
|
-
d.emit(input[:emitted_log])
|
1194
|
-
d.run
|
1195
|
-
end
|
1196
|
-
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry|
|
1197
|
-
assert_equal input[:expected_trace_value], entry['trace'], input
|
1181
|
+
verify_field_key('trace', DEFAULT_TRACE_KEY, 'custom_trace_key',
|
1182
|
+
CONFIG_CUSTOM_TRACE_KEY_SPECIFIED,
|
1183
|
+
'projects/proj1/traces/1234567890abcdef1234567890abcdef')
|
1184
|
+
end
|
1198
1185
|
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
assert_equal input[:expected_fields][key], get_string(value), input
|
1203
|
-
end
|
1204
|
-
end
|
1205
|
-
end
|
1186
|
+
def test_log_entry_span_id_field
|
1187
|
+
verify_field_key('spanId', DEFAULT_SPAN_ID_KEY, 'custom_span_id_key',
|
1188
|
+
CONFIG_CUSTOM_SPAN_ID_KEY_SPECIFIED, '000000000000004a')
|
1206
1189
|
end
|
1207
1190
|
|
1208
1191
|
# Metadata Agent related tests.
|
@@ -1765,6 +1748,57 @@ module BaseTest
|
|
1765
1748
|
end
|
1766
1749
|
end
|
1767
1750
|
|
1751
|
+
def verify_field_key(log_entry_field, default_key, custom_key,
|
1752
|
+
custom_key_config, sample_value)
|
1753
|
+
setup_gce_metadata_stubs
|
1754
|
+
message = log_entry(0)
|
1755
|
+
[
|
1756
|
+
{
|
1757
|
+
# It leaves log entry field nil if no keyed value sent.
|
1758
|
+
driver_config: APPLICATION_DEFAULT_CONFIG,
|
1759
|
+
emitted_log: { 'msg' => message },
|
1760
|
+
expected_payload: { 'msg' => message },
|
1761
|
+
expected_field_value: nil
|
1762
|
+
},
|
1763
|
+
{
|
1764
|
+
# By default, it sets log entry field via a default key.
|
1765
|
+
driver_config: APPLICATION_DEFAULT_CONFIG,
|
1766
|
+
emitted_log: { 'msg' => message, default_key => sample_value },
|
1767
|
+
expected_payload: { 'msg' => message },
|
1768
|
+
expected_field_value: sample_value
|
1769
|
+
},
|
1770
|
+
{
|
1771
|
+
# It allows setting the log entry field via a custom configured key.
|
1772
|
+
driver_config: custom_key_config,
|
1773
|
+
emitted_log: { 'msg' => message, custom_key => sample_value },
|
1774
|
+
expected_payload: { 'msg' => message },
|
1775
|
+
expected_field_value: sample_value
|
1776
|
+
},
|
1777
|
+
{
|
1778
|
+
# It doesn't set log entry field by default key if custom key specified.
|
1779
|
+
driver_config: custom_key_config,
|
1780
|
+
emitted_log: { 'msg' => message, default_key => sample_value },
|
1781
|
+
expected_payload: { 'msg' => message, default_key => sample_value },
|
1782
|
+
expected_field_value: nil
|
1783
|
+
}
|
1784
|
+
].each do |input|
|
1785
|
+
setup_logging_stubs do
|
1786
|
+
@logs_sent = []
|
1787
|
+
d = create_driver(input[:driver_config])
|
1788
|
+
d.emit(input[:emitted_log])
|
1789
|
+
d.run
|
1790
|
+
end
|
1791
|
+
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry|
|
1792
|
+
assert_equal input[:expected_field_value], entry[log_entry_field], input
|
1793
|
+
payload_fields = get_fields(entry['jsonPayload'])
|
1794
|
+
assert_equal input[:expected_payload].size, payload_fields.size, input
|
1795
|
+
payload_fields.each do |key, value|
|
1796
|
+
assert_equal input[:expected_payload][key], get_string(value), input
|
1797
|
+
end
|
1798
|
+
end
|
1799
|
+
end
|
1800
|
+
end
|
1801
|
+
|
1768
1802
|
def http_request_message
|
1769
1803
|
HTTP_REQUEST_MESSAGE
|
1770
1804
|
end
|
data/test/plugin/constants.rb
CHANGED
@@ -20,6 +20,7 @@ module Constants
|
|
20
20
|
|
21
21
|
# Generic attributes.
|
22
22
|
HOSTNAME = Socket.gethostname
|
23
|
+
CUSTOM_LOGGING_API_URL = 'http://localhost:52000'.freeze
|
23
24
|
|
24
25
|
# TODO(qingling128) Separate constants into different submodules.
|
25
26
|
# Attributes used for the GCE metadata service.
|
@@ -43,6 +44,8 @@ module Constants
|
|
43
44
|
EC2_PROJECT_ID = 'test-ec2-project-id'.freeze
|
44
45
|
EC2_ZONE = 'us-west-2b'.freeze
|
45
46
|
EC2_PREFIXED_ZONE = "aws:#{EC2_ZONE}".freeze
|
47
|
+
EC2_REGION = 'us-west-2'.freeze
|
48
|
+
EC2_PREFIXED_REGION = "aws:#{EC2_REGION}".freeze
|
46
49
|
EC2_VM_ID = 'i-81c16767'.freeze
|
47
50
|
EC2_ACCOUNT_ID = '123456789012'.freeze
|
48
51
|
|
@@ -50,6 +53,7 @@ module Constants
|
|
50
53
|
EC2_IDENTITY_DOCUMENT = %({
|
51
54
|
"accountId" : "#{EC2_ACCOUNT_ID}",
|
52
55
|
"availabilityZone" : "#{EC2_ZONE}",
|
56
|
+
"region" : "#{EC2_REGION}",
|
53
57
|
"instanceId" : "#{EC2_VM_ID}"
|
54
58
|
}).freeze
|
55
59
|
|
@@ -138,6 +142,10 @@ module Constants
|
|
138
142
|
APPLICATION_DEFAULT_CONFIG = %(
|
139
143
|
).freeze
|
140
144
|
|
145
|
+
CUSTOM_LOGGING_API_URL_CONFIG = %(
|
146
|
+
logging_api_url #{CUSTOM_LOGGING_API_URL}
|
147
|
+
).freeze
|
148
|
+
|
141
149
|
DETECT_JSON_CONFIG = %(
|
142
150
|
detect_json true
|
143
151
|
).freeze
|
@@ -220,6 +228,11 @@ module Constants
|
|
220
228
|
vm_id #{CUSTOM_VM_ID}
|
221
229
|
).freeze
|
222
230
|
|
231
|
+
CONFIG_EC2_PROJECT_ID_USE_REGION = %(
|
232
|
+
project_id #{EC2_PROJECT_ID}
|
233
|
+
use_aws_availability_zone false
|
234
|
+
).freeze
|
235
|
+
|
223
236
|
CONFIG_DATAFLOW = %(
|
224
237
|
subservice_name "#{DATAFLOW_CONSTANTS[:service]}"
|
225
238
|
labels {
|
@@ -244,6 +257,10 @@ module Constants
|
|
244
257
|
trace_key custom_trace_key
|
245
258
|
).freeze
|
246
259
|
|
260
|
+
CONFIG_CUSTOM_SPAN_ID_KEY_SPECIFIED = %(
|
261
|
+
span_id_key custom_span_id_key
|
262
|
+
).freeze
|
263
|
+
|
247
264
|
# Service configurations for various services.
|
248
265
|
|
249
266
|
# GCE.
|
@@ -506,12 +523,12 @@ module Constants
|
|
506
523
|
}
|
507
524
|
}.freeze
|
508
525
|
|
509
|
-
|
526
|
+
EC2_REGION_PARAMS = {
|
510
527
|
resource: {
|
511
528
|
type: EC2_CONSTANTS[:resource_type],
|
512
529
|
labels: {
|
513
530
|
'instance_id' => EC2_VM_ID,
|
514
|
-
'region' =>
|
531
|
+
'region' => EC2_PREFIXED_REGION,
|
515
532
|
'aws_account' => EC2_ACCOUNT_ID
|
516
533
|
}
|
517
534
|
},
|
@@ -522,6 +539,14 @@ module Constants
|
|
522
539
|
}
|
523
540
|
}.freeze
|
524
541
|
|
542
|
+
EC2_ZONE_PARAMS = EC2_REGION_PARAMS.merge(
|
543
|
+
resource: EC2_REGION_PARAMS[:resource].merge(
|
544
|
+
labels: EC2_REGION_PARAMS[:resource][:labels].merge(
|
545
|
+
'region' => EC2_PREFIXED_ZONE
|
546
|
+
)
|
547
|
+
)
|
548
|
+
).freeze
|
549
|
+
|
525
550
|
HTTP_REQUEST_MESSAGE = {
|
526
551
|
'requestMethod' => 'POST',
|
527
552
|
'requestUrl' => 'http://example/',
|
@@ -651,4 +676,46 @@ module Constants
|
|
651
676
|
]
|
652
677
|
}
|
653
678
|
}.freeze
|
679
|
+
|
680
|
+
# rubocop:disable Style/StringLiterals
|
681
|
+
PARTIAL_SUCCESS_GRPC_METADATA = {
|
682
|
+
'google.logging.v2.writelogentriespartialerrors-bin' =>
|
683
|
+
Google::Logging::V2::WriteLogEntriesPartialErrors.encode(
|
684
|
+
Google::Logging::V2::WriteLogEntriesPartialErrors.new(
|
685
|
+
log_entry_errors: {
|
686
|
+
0 => Google::Rpc::Status.new(
|
687
|
+
code: GRPC::Core::StatusCodes::PERMISSION_DENIED,
|
688
|
+
message: "User not authorized.",
|
689
|
+
details: []),
|
690
|
+
1 => Google::Rpc::Status.new(
|
691
|
+
code: GRPC::Core::StatusCodes::INVALID_ARGUMENT,
|
692
|
+
message: "Log name contains illegal character :",
|
693
|
+
details: []),
|
694
|
+
3 => Google::Rpc::Status.new(
|
695
|
+
code: GRPC::Core::StatusCodes::INVALID_ARGUMENT,
|
696
|
+
message: "Log name contains illegal character :",
|
697
|
+
details: []) })),
|
698
|
+
'google.rpc.debuginfo-bin' =>
|
699
|
+
"\x12\xA7\x03[ORIGINAL ERROR] generic::permission_denied: User not auth" \
|
700
|
+
"orized. [google.rpc.error_details_ext] { message: \"User not authorize" \
|
701
|
+
"d.\" details { type_url: \"type.googleapis.com/google.logging.v2.Write" \
|
702
|
+
"LogEntriesPartialErrors\" value: \"\\n\\034\\010\\000\\022\\030\\010\\" \
|
703
|
+
"007\\022\\024User not authorized.\\n-\\010\\001\\022)\\010\\003\\022%L" \
|
704
|
+
"og name contains illegal character :\\n-\\010\\002\\022)\\010\\003\\02" \
|
705
|
+
"2%Log name contains illegal character :\" } }",
|
706
|
+
'grpc-status-details-bin' =>
|
707
|
+
"\b\a\x12\x14User not authorized.\x1A\xC2\x01\nBtype.googleapis.com/goo" \
|
708
|
+
"gle.logging.v2.WriteLogEntriesPartialErrors\x12|\n\x1C\b\x00\x12\x18\b" \
|
709
|
+
"\a\x12\x14User not authorized.\n-\b\x01\x12)\b\x03\x12%Log name contai" \
|
710
|
+
"ns illegal character :\n-\b\x02\x12)\b\x03\x12%Log name contains illeg" \
|
711
|
+
"al character :\x1A\xD7\x03\n(type.googleapis.com/google.rpc.DebugInfo" \
|
712
|
+
"\x12\xAA\x03\x12\xA7\x03[ORIGINAL ERROR] generic::permission_denied: U" \
|
713
|
+
"ser not authorized. [google.rpc.error_details_ext] { message: \"User n" \
|
714
|
+
"ot authorized.\" details { type_url: \"type.googleapis.com/google.logg" \
|
715
|
+
"ing.v2.WriteLogEntriesPartialErrors\" value: \"\\n\\034\\010\\000\\022" \
|
716
|
+
"\\030\\010\\007\\022\\024User not authorized.\\n-\\010\\001\\022)\\010" \
|
717
|
+
"\\003\\022%Log name contains illegal character :\\n-\\010\\002\\022)" \
|
718
|
+
"\\010\\003\\022%Log name contains illegal character :\" } }"
|
719
|
+
}.freeze
|
720
|
+
# rubocop:enable Style/StringLiterals
|
654
721
|
end
|
@@ -51,6 +51,39 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
def test_partial_success
|
55
|
+
setup_gce_metadata_stubs
|
56
|
+
setup_prometheus
|
57
|
+
setup_logging_stubs(
|
58
|
+
true, GRPC::Core::StatusCodes::PERMISSION_DENIED,
|
59
|
+
'User not authorized.', PARTIAL_SUCCESS_GRPC_METADATA) do
|
60
|
+
# The API Client should not retry this and the plugin should consume
|
61
|
+
# the exception.
|
62
|
+
d = create_driver(PROMETHEUS_ENABLE_CONFIG + PARTIAL_SUCCESS_CONFIG)
|
63
|
+
4.times do |i|
|
64
|
+
d.emit('message' => log_entry(i.to_s))
|
65
|
+
end
|
66
|
+
d.run
|
67
|
+
assert_prometheus_metric_value(
|
68
|
+
:stackdriver_successful_requests_count, 1,
|
69
|
+
grpc: true, code: GRPC::Core::StatusCodes::OK)
|
70
|
+
assert_prometheus_metric_value(
|
71
|
+
:stackdriver_failed_requests_count, 0,
|
72
|
+
grpc: true, code: GRPC::Core::StatusCodes::PERMISSION_DENIED)
|
73
|
+
assert_prometheus_metric_value(
|
74
|
+
:stackdriver_ingested_entries_count, 1,
|
75
|
+
grpc: true, code: GRPC::Core::StatusCodes::OK)
|
76
|
+
assert_prometheus_metric_value(
|
77
|
+
:stackdriver_dropped_entries_count, 2,
|
78
|
+
grpc: true, code: GRPC::Core::StatusCodes::INVALID_ARGUMENT)
|
79
|
+
assert_prometheus_metric_value(
|
80
|
+
:stackdriver_dropped_entries_count, 1,
|
81
|
+
grpc: true, code: GRPC::Core::StatusCodes::PERMISSION_DENIED)
|
82
|
+
assert_prometheus_metric_value(
|
83
|
+
:stackdriver_retried_entries_count, 0, grpc: true)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
54
87
|
def test_server_error
|
55
88
|
setup_gce_metadata_stubs
|
56
89
|
{
|
@@ -246,11 +279,6 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
|
|
246
279
|
end
|
247
280
|
|
248
281
|
def api_client
|
249
|
-
ssl_creds = GRPC::Core::ChannelCredentials.new
|
250
|
-
authentication = Google::Auth.get_application_default
|
251
|
-
creds = GRPC::Core::CallCredentials.new(authentication.updater_proc)
|
252
|
-
ssl_creds.compose(creds)
|
253
|
-
|
254
282
|
@grpc_stub
|
255
283
|
end
|
256
284
|
end
|
@@ -263,12 +291,17 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
|
|
263
291
|
@requests_received = requests_received
|
264
292
|
end
|
265
293
|
|
266
|
-
def write_log_entries(entries,
|
294
|
+
def write_log_entries(entries,
|
295
|
+
log_name: nil,
|
296
|
+
resource: nil,
|
297
|
+
labels: nil,
|
298
|
+
partial_success: nil)
|
267
299
|
request = Google::Apis::LoggingV2::WriteLogEntriesRequest.new(
|
268
300
|
log_name: log_name,
|
269
301
|
resource: resource,
|
270
302
|
labels: labels,
|
271
|
-
entries: entries
|
303
|
+
entries: entries,
|
304
|
+
partial_success: partial_success
|
272
305
|
)
|
273
306
|
@requests_received << request
|
274
307
|
WriteLogEntriesResponse.new
|
@@ -278,18 +311,23 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
|
|
278
311
|
# GRPC logging mock that fails and returns server side or client side errors.
|
279
312
|
class GRPCLoggingMockFailingService <
|
280
313
|
Google::Cloud::Logging::V2::LoggingServiceV2Client
|
281
|
-
def initialize(code, message, failed_attempts)
|
314
|
+
def initialize(code, message, metadata, failed_attempts)
|
282
315
|
@code = code
|
283
316
|
@message = message
|
317
|
+
@metadata = metadata
|
284
318
|
@failed_attempts = failed_attempts
|
285
319
|
super()
|
286
320
|
end
|
287
321
|
|
288
322
|
# rubocop:disable Lint/UnusedMethodArgument
|
289
|
-
def write_log_entries(entries,
|
323
|
+
def write_log_entries(entries,
|
324
|
+
log_name: nil,
|
325
|
+
resource: nil,
|
326
|
+
labels: nil,
|
327
|
+
partial_success: nil)
|
290
328
|
@failed_attempts << 1
|
291
329
|
begin
|
292
|
-
raise GRPC::BadStatus.new_status_exception(@code, @message)
|
330
|
+
raise GRPC::BadStatus.new_status_exception(@code, @message, @metadata)
|
293
331
|
rescue
|
294
332
|
# Google::Gax::GaxError will wrap the latest thrown exception as @cause.
|
295
333
|
raise Google::Gax::GaxError, @message
|
@@ -299,11 +337,14 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
|
|
299
337
|
end
|
300
338
|
|
301
339
|
# Set up grpc stubs to mock the external calls.
|
302
|
-
def setup_logging_stubs(should_fail = false,
|
340
|
+
def setup_logging_stubs(should_fail = false,
|
341
|
+
code = nil,
|
342
|
+
message = nil,
|
343
|
+
metadata = {})
|
303
344
|
if should_fail
|
304
345
|
@failed_attempts = []
|
305
346
|
@grpc_stub = GRPCLoggingMockFailingService.new(
|
306
|
-
code, message, @failed_attempts)
|
347
|
+
code, message, metadata, @failed_attempts)
|
307
348
|
else
|
308
349
|
@requests_sent = []
|
309
350
|
@grpc_stub = GRPCLoggingMockService.new(@requests_sent)
|
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.
|
4
|
+
version: 0.6.14
|
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: 2018-01-
|
12
|
+
date: 2018-01-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|
@@ -45,56 +45,62 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '0.
|
48
|
+
version: '0.17'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '0.
|
55
|
+
version: '0.17'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: google-cloud-logging
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
60
|
- - "~>"
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: 1.
|
62
|
+
version: '1.3'
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.3.2
|
63
66
|
type: :runtime
|
64
67
|
prerelease: false
|
65
68
|
version_requirements: !ruby/object:Gem::Requirement
|
66
69
|
requirements:
|
67
70
|
- - "~>"
|
68
71
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.
|
72
|
+
version: '1.3'
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.3.2
|
70
76
|
- !ruby/object:Gem::Dependency
|
71
77
|
name: googleauth
|
72
78
|
requirement: !ruby/object:Gem::Requirement
|
73
79
|
requirements:
|
74
80
|
- - "~>"
|
75
81
|
- !ruby/object:Gem::Version
|
76
|
-
version: '0.
|
82
|
+
version: '0.6'
|
77
83
|
type: :runtime
|
78
84
|
prerelease: false
|
79
85
|
version_requirements: !ruby/object:Gem::Requirement
|
80
86
|
requirements:
|
81
87
|
- - "~>"
|
82
88
|
- !ruby/object:Gem::Version
|
83
|
-
version: '0.
|
89
|
+
version: '0.6'
|
84
90
|
- !ruby/object:Gem::Dependency
|
85
91
|
name: grpc
|
86
92
|
requirement: !ruby/object:Gem::Requirement
|
87
93
|
requirements:
|
88
94
|
- - "~>"
|
89
95
|
- !ruby/object:Gem::Version
|
90
|
-
version: 1.
|
96
|
+
version: '1.0'
|
91
97
|
type: :runtime
|
92
98
|
prerelease: false
|
93
99
|
version_requirements: !ruby/object:Gem::Requirement
|
94
100
|
requirements:
|
95
101
|
- - "~>"
|
96
102
|
- !ruby/object:Gem::Version
|
97
|
-
version: 1.
|
103
|
+
version: '1.0'
|
98
104
|
- !ruby/object:Gem::Dependency
|
99
105
|
name: json
|
100
106
|
requirement: !ruby/object:Gem::Requirement
|