fluent-plugin-google-cloud 0.6.17 → 0.6.18.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +162 -0
- data/fluent-plugin-google-cloud.gemspec +1 -1
- data/lib/fluent/plugin/out_google_cloud.rb +115 -2
- data/test/plugin/base_test.rb +185 -0
- data/test/plugin/constants.rb +95 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96a5943e560b95ee0e8427efb2eef06d17218f75
|
4
|
+
data.tar.gz: 944c1f9d6391f286a00024ad69a433725b82bdd5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75e217bea7703bddf67cba284afb6cab2c16b70e18ae1f7e87e6e8e0e7a8fdfd434c1a6dd8be91f299f5e6dac9643ebb9d2c240ca6369f744b9837bd13d9ec59
|
7
|
+
data.tar.gz: b3f7a0aa1b2df536bff44bdcb1272a4d8a70b7ce4c8737ad79f28b1615945b698a9683b7d291c22566a22f9ffa98d382a82a518c3238a28cdce5c7b6bd605f8f
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fluent-plugin-google-cloud (0.6.17)
|
5
|
+
fluentd (~> 0.10)
|
6
|
+
google-api-client (~> 0.17)
|
7
|
+
google-cloud-logging (~> 1.3, >= 1.3.2)
|
8
|
+
googleapis-common-protos (~> 1.3)
|
9
|
+
googleauth (~> 0.6)
|
10
|
+
grpc (~> 1.0)
|
11
|
+
json (~> 1.8)
|
12
|
+
|
13
|
+
GEM
|
14
|
+
remote: https://rubygems.org/
|
15
|
+
specs:
|
16
|
+
addressable (2.5.2)
|
17
|
+
public_suffix (>= 2.0.2, < 4.0)
|
18
|
+
ast (2.4.0)
|
19
|
+
cool.io (1.5.3)
|
20
|
+
crack (0.4.3)
|
21
|
+
safe_yaml (~> 1.0.0)
|
22
|
+
declarative (0.0.10)
|
23
|
+
declarative-option (0.1.0)
|
24
|
+
faraday (0.14.0)
|
25
|
+
multipart-post (>= 1.2, < 3)
|
26
|
+
fluentd (0.14.25)
|
27
|
+
cool.io (>= 1.4.5, < 2.0.0)
|
28
|
+
http_parser.rb (>= 0.5.1, < 0.7.0)
|
29
|
+
msgpack (>= 0.7.0, < 2.0.0)
|
30
|
+
ruby_dig (~> 0.0.2)
|
31
|
+
serverengine (>= 2.0.4, < 3.0.0)
|
32
|
+
sigdump (~> 0.2.2)
|
33
|
+
strptime (~> 0.1.7)
|
34
|
+
tzinfo (~> 1.0)
|
35
|
+
tzinfo-data (~> 1.0)
|
36
|
+
yajl-ruby (~> 1.0)
|
37
|
+
google-api-client (0.19.8)
|
38
|
+
addressable (~> 2.5, >= 2.5.1)
|
39
|
+
googleauth (>= 0.5, < 0.7.0)
|
40
|
+
httpclient (>= 2.8.1, < 3.0)
|
41
|
+
mime-types (~> 3.0)
|
42
|
+
representable (~> 3.0)
|
43
|
+
retriable (>= 2.0, < 4.0)
|
44
|
+
google-cloud-core (1.2.0)
|
45
|
+
google-cloud-env (~> 1.0)
|
46
|
+
google-cloud-env (1.0.1)
|
47
|
+
faraday (~> 0.11)
|
48
|
+
google-cloud-logging (1.5.0)
|
49
|
+
google-cloud-core (~> 1.2)
|
50
|
+
google-gax (~> 1.0)
|
51
|
+
stackdriver-core (~> 1.3)
|
52
|
+
google-gax (1.0.1)
|
53
|
+
google-protobuf (~> 3.2)
|
54
|
+
googleapis-common-protos (>= 1.3.5, < 2.0)
|
55
|
+
googleauth (~> 0.6.2)
|
56
|
+
grpc (>= 1.7.2, < 2.0)
|
57
|
+
rly (~> 0.2.3)
|
58
|
+
google-protobuf (3.5.1.2-x86_64-linux)
|
59
|
+
googleapis-common-protos (1.3.7)
|
60
|
+
google-protobuf (~> 3.0)
|
61
|
+
googleapis-common-protos-types (~> 1.0)
|
62
|
+
grpc (~> 1.0)
|
63
|
+
googleapis-common-protos-types (1.0.1)
|
64
|
+
google-protobuf (~> 3.0)
|
65
|
+
googleauth (0.6.2)
|
66
|
+
faraday (~> 0.12)
|
67
|
+
jwt (>= 1.4, < 3.0)
|
68
|
+
logging (~> 2.0)
|
69
|
+
memoist (~> 0.12)
|
70
|
+
multi_json (~> 1.11)
|
71
|
+
os (~> 0.9)
|
72
|
+
signet (~> 0.7)
|
73
|
+
grpc (1.10.0-x86_64-linux)
|
74
|
+
google-protobuf (~> 3.1)
|
75
|
+
googleapis-common-protos-types (~> 1.0.0)
|
76
|
+
googleauth (>= 0.5.1, < 0.7)
|
77
|
+
hashdiff (0.3.7)
|
78
|
+
http_parser.rb (0.6.0)
|
79
|
+
httpclient (2.8.3)
|
80
|
+
json (1.8.6)
|
81
|
+
jwt (2.1.0)
|
82
|
+
little-plugger (1.1.4)
|
83
|
+
logging (2.2.2)
|
84
|
+
little-plugger (~> 1.1)
|
85
|
+
multi_json (~> 1.10)
|
86
|
+
memoist (0.16.0)
|
87
|
+
metaclass (0.0.4)
|
88
|
+
mime-types (3.1)
|
89
|
+
mime-types-data (~> 3.2015)
|
90
|
+
mime-types-data (3.2016.0521)
|
91
|
+
mocha (1.3.0)
|
92
|
+
metaclass (~> 0.0.1)
|
93
|
+
msgpack (1.2.4)
|
94
|
+
multi_json (1.13.1)
|
95
|
+
multipart-post (2.0.0)
|
96
|
+
os (0.9.6)
|
97
|
+
parser (2.5.0.3)
|
98
|
+
ast (~> 2.4.0)
|
99
|
+
power_assert (1.1.1)
|
100
|
+
powerpack (0.1.1)
|
101
|
+
prometheus-client (0.7.1)
|
102
|
+
quantile (~> 0.2.0)
|
103
|
+
public_suffix (3.0.2)
|
104
|
+
quantile (0.2.0)
|
105
|
+
rainbow (2.2.2)
|
106
|
+
rake
|
107
|
+
rake (10.5.0)
|
108
|
+
representable (3.0.4)
|
109
|
+
declarative (< 0.1.0)
|
110
|
+
declarative-option (< 0.2.0)
|
111
|
+
uber (< 0.2.0)
|
112
|
+
retriable (3.1.1)
|
113
|
+
rly (0.2.3)
|
114
|
+
rubocop (0.39.0)
|
115
|
+
parser (>= 2.3.0.7, < 3.0)
|
116
|
+
powerpack (~> 0.1)
|
117
|
+
rainbow (>= 1.99.1, < 3.0)
|
118
|
+
ruby-progressbar (~> 1.7)
|
119
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
120
|
+
ruby-progressbar (1.9.0)
|
121
|
+
ruby_dig (0.0.2)
|
122
|
+
safe_yaml (1.0.4)
|
123
|
+
serverengine (2.0.6)
|
124
|
+
sigdump (~> 0.2.2)
|
125
|
+
sigdump (0.2.4)
|
126
|
+
signet (0.8.1)
|
127
|
+
addressable (~> 2.3)
|
128
|
+
faraday (~> 0.9)
|
129
|
+
jwt (>= 1.5, < 3.0)
|
130
|
+
multi_json (~> 1.10)
|
131
|
+
stackdriver-core (1.3.0)
|
132
|
+
google-cloud-core (~> 1.2)
|
133
|
+
strptime (0.1.9)
|
134
|
+
test-unit (3.2.7)
|
135
|
+
power_assert
|
136
|
+
thread_safe (0.3.6)
|
137
|
+
tzinfo (1.2.5)
|
138
|
+
thread_safe (~> 0.1)
|
139
|
+
tzinfo-data (1.2018.3)
|
140
|
+
tzinfo (>= 1.0.0)
|
141
|
+
uber (0.1.0)
|
142
|
+
unicode-display_width (1.3.0)
|
143
|
+
webmock (2.3.2)
|
144
|
+
addressable (>= 2.3.6)
|
145
|
+
crack (>= 0.3.2)
|
146
|
+
hashdiff
|
147
|
+
yajl-ruby (1.3.1)
|
148
|
+
|
149
|
+
PLATFORMS
|
150
|
+
ruby
|
151
|
+
|
152
|
+
DEPENDENCIES
|
153
|
+
fluent-plugin-google-cloud!
|
154
|
+
mocha (~> 1.1)
|
155
|
+
prometheus-client (~> 0.7.1)
|
156
|
+
rake (~> 10.3)
|
157
|
+
rubocop (~> 0.39.0)
|
158
|
+
test-unit (~> 3.0)
|
159
|
+
webmock (~> 2.3.1)
|
160
|
+
|
161
|
+
BUNDLED WITH
|
162
|
+
1.16.1
|
@@ -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.18.pre.1'
|
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')
|
@@ -92,6 +92,12 @@ module Fluent
|
|
92
92
|
'stderr' => 'ERROR'
|
93
93
|
}
|
94
94
|
}.freeze
|
95
|
+
K8S_CONTAINER_CONSTANTS = {
|
96
|
+
resource_type: 'k8s_container'
|
97
|
+
}.freeze
|
98
|
+
K8S_NODE_CONSTANTS = {
|
99
|
+
resource_type: 'k8s_node'
|
100
|
+
}.freeze
|
95
101
|
DOCKER_CONSTANTS = {
|
96
102
|
service: 'docker.googleapis.com',
|
97
103
|
resource_type: 'docker_container'
|
@@ -220,7 +226,7 @@ module Fluent
|
|
220
226
|
Fluent::Plugin.register_output('google_cloud', self)
|
221
227
|
|
222
228
|
PLUGIN_NAME = 'Fluentd Google Cloud Logging plugin'.freeze
|
223
|
-
PLUGIN_VERSION = '0.6.
|
229
|
+
PLUGIN_VERSION = '0.6.18.pre.1'.freeze
|
224
230
|
|
225
231
|
# Name of the the Google cloud logging write scope.
|
226
232
|
LOGGING_SCOPE = 'https://www.googleapis.com/auth/logging.write'.freeze
|
@@ -974,6 +980,16 @@ module Fluent
|
|
974
980
|
|
975
981
|
@compiled_http_latency_regexp =
|
976
982
|
/^\s*(?<seconds>\d+)(?<decimal>\.\d+)?\s*s\s*$/
|
983
|
+
|
984
|
+
# TODO(qingling128): Temporary fallback for metadata agent restarts.
|
985
|
+
@compiled_k8s_container_local_resource_id_regexp = /^
|
986
|
+
(?<resource_type>k8s_container)
|
987
|
+
\.(?<namespace_name>[0-9a-z-]+)
|
988
|
+
\.(?<pod_name>[0-9a-z-.]+)
|
989
|
+
\.(?<container_name>[0-9a-z-]+)$/x
|
990
|
+
@compiled_k8s_node_local_resource_id_regexp = /^
|
991
|
+
(?<resource_type>k8s_node)
|
992
|
+
\.(?<node_name>[0-9a-z-]+)$/x
|
977
993
|
end
|
978
994
|
|
979
995
|
# Set required variables like @project_id, @vm_id, @vm_name and @zone.
|
@@ -1238,6 +1254,16 @@ module Fluent
|
|
1238
1254
|
# TODO(qingling128): Fix this temporary renaming from 'gke_container'
|
1239
1255
|
# to 'container'.
|
1240
1256
|
resource.type = 'container' if resource.type == 'gke_container'
|
1257
|
+
else
|
1258
|
+
# TODO(qingling128): This entire else clause is temporary before we
|
1259
|
+
# implement buffering and caching.
|
1260
|
+
@log.warn('Failing to retrieve monitored resource from Metadata' \
|
1261
|
+
" Agent with local_resource_id #{local_resource_id}." \
|
1262
|
+
' Trying to construct resource locally if it is a k8s' \
|
1263
|
+
' resource.')
|
1264
|
+
constructed_k8s_resource = construct_k8s_resource_locally(
|
1265
|
+
local_resource_id)
|
1266
|
+
resource = constructed_k8s_resource if constructed_k8s_resource
|
1241
1267
|
end
|
1242
1268
|
end
|
1243
1269
|
|
@@ -1288,7 +1314,11 @@ module Fluent
|
|
1288
1314
|
# Docker container.
|
1289
1315
|
# TODO(qingling128): Remove this logic once the resource is retrieved at a
|
1290
1316
|
# proper time (b/65175256).
|
1291
|
-
when DOCKER_CONSTANTS[:resource_type]
|
1317
|
+
when DOCKER_CONSTANTS[:resource_type],
|
1318
|
+
# TODO(qingling128): Temporary fallback for metadata agent restarts.
|
1319
|
+
K8S_CONTAINER_CONSTANTS[:resource_type],
|
1320
|
+
K8S_NODE_CONSTANTS[:resource_type]
|
1321
|
+
|
1292
1322
|
common_labels.delete("#{COMPUTE_CONSTANTS[:service]}/resource_name")
|
1293
1323
|
end
|
1294
1324
|
|
@@ -2145,6 +2175,89 @@ module Fluent
|
|
2145
2175
|
{}
|
2146
2176
|
end
|
2147
2177
|
|
2178
|
+
# Construct monitored resource locally for k8s resources.
|
2179
|
+
def construct_k8s_resource_locally(local_resource_id)
|
2180
|
+
matched_regexp_group = nil
|
2181
|
+
# Regex match the local_resource_id to make sure we only do
|
2182
|
+
# this for 'k8s_container' and 'k8s_node'.
|
2183
|
+
[@compiled_k8s_node_local_resource_id_regexp,
|
2184
|
+
@compiled_k8s_container_local_resource_id_regexp].each do |id_regexp|
|
2185
|
+
matched_regexp_group ||= id_regexp.match(local_resource_id)
|
2186
|
+
end
|
2187
|
+
return unless matched_regexp_group
|
2188
|
+
case matched_regexp_group['resource_type']
|
2189
|
+
when 'k8s_container'
|
2190
|
+
@log.debug('Detected local_resource_id in k8s_container format.' \
|
2191
|
+
"Constructing resource locally with #{local_resource_id}.")
|
2192
|
+
return construct_k8s_container_resource(matched_regexp_group)
|
2193
|
+
when 'k8s_node'
|
2194
|
+
@log.debug('Detected local_resource_id in k8s_node format.' \
|
2195
|
+
"Constructing resource locally with #{local_resource_id}.")
|
2196
|
+
return construct_k8s_node_resource(matched_regexp_group)
|
2197
|
+
end
|
2198
|
+
end
|
2199
|
+
|
2200
|
+
# Construct the k8s_container monitored resource locally. In case of any
|
2201
|
+
# exception, return nil.
|
2202
|
+
def construct_k8s_container_resource(matched_regexp_group)
|
2203
|
+
constructed_resource = Google::Apis::LoggingV2::MonitoredResource.new(
|
2204
|
+
type: 'k8s_container',
|
2205
|
+
labels: {
|
2206
|
+
'namespace_name' => matched_regexp_group['namespace_name'],
|
2207
|
+
'pod_name' => matched_regexp_group['pod_name'],
|
2208
|
+
'container_name' => matched_regexp_group['container_name'],
|
2209
|
+
'cluster_name' => retrieve_k8s_cluster_name,
|
2210
|
+
'location' => retrieve_k8s_location
|
2211
|
+
}
|
2212
|
+
)
|
2213
|
+
@log.debug('Constructed k8s_container resource locally:\n' \
|
2214
|
+
"#{constructed_resource.inspect}")
|
2215
|
+
constructed_resource
|
2216
|
+
rescue StandardError => e
|
2217
|
+
@log.error 'Failed to construct "k8s_container" resource locally.' \
|
2218
|
+
' Falling back to writing logs against instance resource.',
|
2219
|
+
error: e
|
2220
|
+
# Fall back to legacy gke resource or default instance resource.
|
2221
|
+
return
|
2222
|
+
end
|
2223
|
+
|
2224
|
+
# Construct the k8s_node monitored resource locally. In case of any
|
2225
|
+
# exception, return nil.
|
2226
|
+
def construct_k8s_node_resource(matched_regexp_group)
|
2227
|
+
constructed_resource = Google::Apis::LoggingV2::MonitoredResource.new(
|
2228
|
+
type: 'k8s_node',
|
2229
|
+
labels: {
|
2230
|
+
'node_name' => matched_regexp_group['node_name'],
|
2231
|
+
'cluster_name' => retrieve_k8s_cluster_name,
|
2232
|
+
'location' => retrieve_k8s_location
|
2233
|
+
}
|
2234
|
+
)
|
2235
|
+
@log.debug('Constructed k8s_node resource locally:\n' \
|
2236
|
+
"#{constructed_resource.inspect}")
|
2237
|
+
constructed_resource
|
2238
|
+
rescue StandardError => e
|
2239
|
+
@log.error 'Failed to construct "k8s_node" resource locally. Falling' \
|
2240
|
+
' back to writing logs against instance resource.', error: e
|
2241
|
+
# Fall back to default instance resource.
|
2242
|
+
return
|
2243
|
+
end
|
2244
|
+
|
2245
|
+
# Only retrieve cluster name once since it's not changing for this
|
2246
|
+
# agent instance's life time.
|
2247
|
+
# Throw an error if failed to retrieve the cluster name.
|
2248
|
+
def retrieve_k8s_cluster_name
|
2249
|
+
@k8s_cluster_name ||= fetch_gce_metadata(
|
2250
|
+
'instance/attributes/cluster-name')
|
2251
|
+
end
|
2252
|
+
|
2253
|
+
# Only retrieve location once since it is the location of K8s Master which
|
2254
|
+
# is not changing for this agent instance's life time.
|
2255
|
+
# Throw an error if neither endpoint is available.
|
2256
|
+
def retrieve_k8s_location
|
2257
|
+
@k8s_location ||= fetch_gce_metadata(
|
2258
|
+
'instance/attributes/cluster-location')
|
2259
|
+
end
|
2260
|
+
|
2148
2261
|
def ensure_array(value)
|
2149
2262
|
Array.try_convert(value) || (raise JSON::ParserError, value.class.to_s)
|
2150
2263
|
end
|
data/test/plugin/base_test.rb
CHANGED
@@ -1303,6 +1303,143 @@ module BaseTest
|
|
1303
1303
|
end
|
1304
1304
|
end
|
1305
1305
|
|
1306
|
+
# Test k8s monitored resource including the fallback when Metadata Agent
|
1307
|
+
# restarts.
|
1308
|
+
def test_k8s_monitored_resource_fallback
|
1309
|
+
[
|
1310
|
+
# k8s_container.
|
1311
|
+
# When enable_metadata_agent is false.
|
1312
|
+
{
|
1313
|
+
enable_metadata_agent: false,
|
1314
|
+
set_up_metadata_agent_stub: false,
|
1315
|
+
set_up_k8s_stub: false,
|
1316
|
+
log_entry: k8s_container_log_entry(log_entry(0)),
|
1317
|
+
expected_params: COMPUTE_PARAMS
|
1318
|
+
},
|
1319
|
+
{
|
1320
|
+
enable_metadata_agent: false,
|
1321
|
+
set_up_metadata_agent_stub: true,
|
1322
|
+
set_up_k8s_stub: false,
|
1323
|
+
log_entry: k8s_container_log_entry(log_entry(0)),
|
1324
|
+
expected_params: COMPUTE_PARAMS
|
1325
|
+
},
|
1326
|
+
{
|
1327
|
+
enable_metadata_agent: false,
|
1328
|
+
set_up_metadata_agent_stub: true,
|
1329
|
+
set_up_k8s_stub: true,
|
1330
|
+
log_entry: k8s_container_log_entry(log_entry(0)),
|
1331
|
+
expected_params: COMPUTE_PARAMS
|
1332
|
+
},
|
1333
|
+
{
|
1334
|
+
enable_metadata_agent: false,
|
1335
|
+
set_up_metadata_agent_stub: false,
|
1336
|
+
set_up_k8s_stub: true,
|
1337
|
+
log_entry: k8s_container_log_entry(log_entry(0)),
|
1338
|
+
expected_params: COMPUTE_PARAMS
|
1339
|
+
},
|
1340
|
+
# When enable_metadata_agent is true.
|
1341
|
+
{
|
1342
|
+
enable_metadata_agent: true,
|
1343
|
+
set_up_metadata_agent_stub: false,
|
1344
|
+
set_up_k8s_stub: false,
|
1345
|
+
log_entry: k8s_container_log_entry(log_entry(0)),
|
1346
|
+
expected_params: COMPUTE_PARAMS
|
1347
|
+
},
|
1348
|
+
{
|
1349
|
+
enable_metadata_agent: true,
|
1350
|
+
set_up_metadata_agent_stub: false,
|
1351
|
+
set_up_k8s_stub: true,
|
1352
|
+
log_entry: k8s_container_log_entry(log_entry(0)),
|
1353
|
+
expected_params: K8S_CONTAINER_PARAMS_FROM_LOCAL
|
1354
|
+
},
|
1355
|
+
{
|
1356
|
+
enable_metadata_agent: true,
|
1357
|
+
set_up_metadata_agent_stub: true,
|
1358
|
+
set_up_k8s_stub: false,
|
1359
|
+
log_entry: k8s_container_log_entry(log_entry(0)),
|
1360
|
+
expected_params: K8S_CONTAINER_PARAMS
|
1361
|
+
},
|
1362
|
+
{
|
1363
|
+
enable_metadata_agent: true,
|
1364
|
+
set_up_metadata_agent_stub: true,
|
1365
|
+
set_up_k8s_stub: true,
|
1366
|
+
log_entry: k8s_container_log_entry(log_entry(0)),
|
1367
|
+
expected_params: K8S_CONTAINER_PARAMS
|
1368
|
+
},
|
1369
|
+
# When local_resource_id is not present or does not match k8s regexes.
|
1370
|
+
{
|
1371
|
+
enable_metadata_agent: true,
|
1372
|
+
set_up_metadata_agent_stub: true,
|
1373
|
+
set_up_k8s_stub: true,
|
1374
|
+
log_entry: k8s_container_log_entry(
|
1375
|
+
log_entry(0)).reject { |k, _| k == LOCAL_RESOURCE_ID_KEY },
|
1376
|
+
expected_params: COMPUTE_PARAMS
|
1377
|
+
},
|
1378
|
+
{
|
1379
|
+
enable_metadata_agent: true,
|
1380
|
+
set_up_metadata_agent_stub: true,
|
1381
|
+
set_up_k8s_stub: true,
|
1382
|
+
log_entry: k8s_container_log_entry(
|
1383
|
+
log_entry(0),
|
1384
|
+
local_resource_id: RANDOM_LOCAL_RESOURCE_ID),
|
1385
|
+
expected_params: COMPUTE_PARAMS
|
1386
|
+
},
|
1387
|
+
# Specific cases for k8s_node.
|
1388
|
+
{
|
1389
|
+
enable_metadata_agent: false,
|
1390
|
+
set_up_metadata_agent_stub: true,
|
1391
|
+
set_up_k8s_stub: true,
|
1392
|
+
log_entry: k8s_node_log_entry(log_entry(0)),
|
1393
|
+
expected_params: COMPUTE_PARAMS
|
1394
|
+
},
|
1395
|
+
{
|
1396
|
+
enable_metadata_agent: true,
|
1397
|
+
set_up_metadata_agent_stub: true,
|
1398
|
+
set_up_k8s_stub: true,
|
1399
|
+
log_entry: k8s_node_log_entry(log_entry(0)),
|
1400
|
+
expected_params: K8S_NODE_PARAMS
|
1401
|
+
},
|
1402
|
+
{
|
1403
|
+
enable_metadata_agent: true,
|
1404
|
+
set_up_metadata_agent_stub: true,
|
1405
|
+
set_up_k8s_stub: true,
|
1406
|
+
log_entry: k8s_node_log_entry(log_entry(0)),
|
1407
|
+
expected_params: K8S_NODE_PARAMS
|
1408
|
+
}
|
1409
|
+
].each do |test_params|
|
1410
|
+
new_stub_context do
|
1411
|
+
setup_gce_metadata_stubs
|
1412
|
+
if test_params[:set_up_metadata_agent_stub]
|
1413
|
+
setup_metadata_agent_stubs
|
1414
|
+
else
|
1415
|
+
setup_no_metadata_agent_stubs
|
1416
|
+
end
|
1417
|
+
if test_params[:set_up_k8s_stub]
|
1418
|
+
set_up_k8s_metadata_stubs
|
1419
|
+
else
|
1420
|
+
set_up_no_k8s_metadata_stubs
|
1421
|
+
end
|
1422
|
+
setup_logging_stubs do
|
1423
|
+
config = if test_params[:enable_metadata_agent]
|
1424
|
+
ENABLE_METADATA_AGENT_CONFIG
|
1425
|
+
else
|
1426
|
+
APPLICATION_DEFAULT_CONFIG
|
1427
|
+
end
|
1428
|
+
d = create_driver(config)
|
1429
|
+
d.emit(test_params[:log_entry])
|
1430
|
+
d.run
|
1431
|
+
end
|
1432
|
+
verify_log_entries(1, test_params[:expected_params],
|
1433
|
+
'jsonPayload') do |entry|
|
1434
|
+
fields = get_fields(entry['jsonPayload'])
|
1435
|
+
assert_equal 2, fields.size, entry
|
1436
|
+
assert_equal 'test log entry 0', get_string(fields['log']), entry
|
1437
|
+
assert_equal K8S_STREAM, get_string(fields['stream']), entry
|
1438
|
+
end
|
1439
|
+
end
|
1440
|
+
end
|
1441
|
+
end
|
1442
|
+
|
1306
1443
|
# Test that the 'time' field from the json record is extracted and set to
|
1307
1444
|
# entry.timestamp for Docker container logs.
|
1308
1445
|
def test_time_field_extraction_for_docker_container_logs
|
@@ -1466,6 +1603,22 @@ module BaseTest
|
|
1466
1603
|
'KUBE_BEARER_TOKEN: AoQiMuwkNP2BMT0S')
|
1467
1604
|
end
|
1468
1605
|
|
1606
|
+
def set_up_k8s_metadata_stubs
|
1607
|
+
stub_metadata_request(
|
1608
|
+
'instance/attributes/',
|
1609
|
+
"attribute1\ncluster-name\ncluster-location\nlast_attribute")
|
1610
|
+
stub_metadata_request('instance/attributes/cluster-location', K8S_LOCATION2)
|
1611
|
+
stub_metadata_request('instance/attributes/cluster-name', K8S_CLUSTER_NAME)
|
1612
|
+
end
|
1613
|
+
|
1614
|
+
def set_up_no_k8s_metadata_stubs
|
1615
|
+
# Simulate an environment with no new k8s endpoints present.
|
1616
|
+
stub_request(:get, %r{.*instance/attributes/cluster-location.*})
|
1617
|
+
.to_raise(Errno::EHOSTUNREACH)
|
1618
|
+
stub_request(:get, %r{.*instance/attributes/cluster-name.*})
|
1619
|
+
.to_raise(Errno::EHOSTUNREACH)
|
1620
|
+
end
|
1621
|
+
|
1469
1622
|
def setup_cloudfunctions_metadata_stubs
|
1470
1623
|
stub_metadata_request(
|
1471
1624
|
'instance/attributes/',
|
@@ -1514,6 +1667,14 @@ module BaseTest
|
|
1514
1667
|
stub_request(:get, metadata_request_url(local_resource_id))
|
1515
1668
|
.to_return(status: 200, body: resource)
|
1516
1669
|
end
|
1670
|
+
stub_request(:get, metadata_request_url(RANDOM_LOCAL_RESOURCE_ID))
|
1671
|
+
.to_return(status: 404, body: '')
|
1672
|
+
end
|
1673
|
+
|
1674
|
+
def setup_no_metadata_agent_stubs
|
1675
|
+
# Simulate an environment with no metadata agent endpoint present.
|
1676
|
+
stub_request(:get, %r{#{DEFAULT_METADATA_AGENT_URL}\/monitoredResource/.*})
|
1677
|
+
.to_raise(Errno::EHOSTUNREACH)
|
1517
1678
|
end
|
1518
1679
|
|
1519
1680
|
def assert_requested_metadata_agent_stub(local_resource_id)
|
@@ -1589,6 +1750,29 @@ module BaseTest
|
|
1589
1750
|
}
|
1590
1751
|
end
|
1591
1752
|
|
1753
|
+
# k8s resources.
|
1754
|
+
|
1755
|
+
def k8s_container_log_entry(log,
|
1756
|
+
local_resource_id: K8S_LOCAL_RESOURCE_ID)
|
1757
|
+
{
|
1758
|
+
log: log,
|
1759
|
+
stream: K8S_STREAM,
|
1760
|
+
time: K8S_TIMESTAMP,
|
1761
|
+
LOCAL_RESOURCE_ID_KEY => local_resource_id
|
1762
|
+
}
|
1763
|
+
end
|
1764
|
+
|
1765
|
+
def k8s_node_log_entry(log)
|
1766
|
+
{
|
1767
|
+
log: log,
|
1768
|
+
stream: K8S_STREAM,
|
1769
|
+
time: K8S_TIMESTAMP,
|
1770
|
+
LOCAL_RESOURCE_ID_KEY =>
|
1771
|
+
"#{K8S_NODE_LOCAL_RESOURCE_ID_PREFIX}" \
|
1772
|
+
".#{K8S_NODE_NAME}"
|
1773
|
+
}
|
1774
|
+
end
|
1775
|
+
|
1592
1776
|
def cloudfunctions_log_entry(i)
|
1593
1777
|
{
|
1594
1778
|
stream: 'stdout',
|
@@ -1631,6 +1815,7 @@ module BaseTest
|
|
1631
1815
|
end
|
1632
1816
|
|
1633
1817
|
def check_labels(labels, expected_labels)
|
1818
|
+
return if labels.empty? && expected_labels.empty?
|
1634
1819
|
labels.each do |key, value|
|
1635
1820
|
assert value.is_a?(String), "Value #{value} for label #{key} " \
|
1636
1821
|
'is not a string: ' + value.class.name
|
data/test/plugin/constants.rb
CHANGED
@@ -31,6 +31,8 @@ module Constants
|
|
31
31
|
FULLY_QUALIFIED_ZONE = "projects/#{PROJECT_ID}/zones/#{ZONE}".freeze
|
32
32
|
VM_ID = '9876543210'.freeze
|
33
33
|
|
34
|
+
RANDOM_LOCAL_RESOURCE_ID = 'ehb.jjk.poq.ll'.freeze
|
35
|
+
|
34
36
|
# Attributes used for the Metadata Agent resources.
|
35
37
|
METADATA_ZONE = 'us-central1-c'.freeze
|
36
38
|
METADATA_VM_ID = '0123456789'.freeze
|
@@ -75,6 +77,30 @@ module Constants
|
|
75
77
|
DOCKER_CONTAINER_NANOS = 987_654_321
|
76
78
|
DOCKER_CONTAINER_LOCAL_RESOURCE_ID_PREFIX = 'container'.freeze
|
77
79
|
|
80
|
+
# New K8s resource constants.
|
81
|
+
K8S_LOCATION = 'us-central1-b'.freeze
|
82
|
+
K8S_LOCATION2 = 'us-central1-c'.freeze
|
83
|
+
K8S_CLUSTER_NAME = 'cluster-1'.freeze
|
84
|
+
K8S_NAMESPACE_NAME = 'kube-system'.freeze
|
85
|
+
K8S_NODE_NAME = 'performance--default-pool-cabf1342-08jc'.freeze
|
86
|
+
K8S_POD_NAME = 'redis-master-c0l82.foo.bar'.freeze
|
87
|
+
K8S_CONTAINER_NAME = 'redis'.freeze
|
88
|
+
K8S_STREAM = 'stdout'.freeze
|
89
|
+
# Timestamp for 1234567890 seconds and 987654321 nanoseconds since epoch.
|
90
|
+
K8S_TIMESTAMP = '2009-02-13T23:31:30.987654321Z'.freeze
|
91
|
+
K8S_SECONDS_EPOCH = 1_234_567_890
|
92
|
+
K8S_NANOS = 987_654_321
|
93
|
+
K8S_CONTAINER_LOCAL_RESOURCE_ID_PREFIX = 'k8s_container'.freeze
|
94
|
+
K8S_NODE_LOCAL_RESOURCE_ID_PREFIX = 'k8s_node'.freeze
|
95
|
+
K8S_TAG =
|
96
|
+
"var.log.containers.#{K8S_NAMESPACE_NAME}_#{K8S_POD_NAME}_" \
|
97
|
+
"#{K8S_CONTAINER_NAME}.log".freeze
|
98
|
+
K8S_LOCAL_RESOURCE_ID =
|
99
|
+
"#{K8S_CONTAINER_LOCAL_RESOURCE_ID_PREFIX}" \
|
100
|
+
".#{K8S_NAMESPACE_NAME}" \
|
101
|
+
".#{K8S_POD_NAME}" \
|
102
|
+
".#{K8S_CONTAINER_NAME}".freeze
|
103
|
+
|
78
104
|
# Container Engine / Kubernetes specific labels.
|
79
105
|
CONTAINER_CLUSTER_NAME = 'cluster-1'.freeze
|
80
106
|
CONTAINER_NAMESPACE_ID = '898268c8-4a36-11e5-9d81-42010af0194c'.freeze
|
@@ -392,6 +418,52 @@ module Constants
|
|
392
418
|
}
|
393
419
|
}.freeze
|
394
420
|
|
421
|
+
# K8s Container.
|
422
|
+
K8S_CONTAINER_PARAMS = {
|
423
|
+
resource: {
|
424
|
+
type: K8S_CONTAINER_CONSTANTS[:resource_type],
|
425
|
+
labels: {
|
426
|
+
'namespace_name' => K8S_NAMESPACE_NAME,
|
427
|
+
'pod_name' => K8S_POD_NAME,
|
428
|
+
'container_name' => K8S_CONTAINER_NAME,
|
429
|
+
'cluster_name' => K8S_CLUSTER_NAME,
|
430
|
+
'location' => K8S_LOCATION
|
431
|
+
}
|
432
|
+
},
|
433
|
+
log_name: 'test',
|
434
|
+
project_id: PROJECT_ID,
|
435
|
+
labels: {}
|
436
|
+
}.freeze
|
437
|
+
K8S_CONTAINER_PARAMS_FROM_LOCAL = K8S_CONTAINER_PARAMS.merge(
|
438
|
+
resource: K8S_CONTAINER_PARAMS[:resource].merge(
|
439
|
+
labels: K8S_CONTAINER_PARAMS[:resource][:labels].merge(
|
440
|
+
'location' => K8S_LOCATION2
|
441
|
+
)
|
442
|
+
)
|
443
|
+
).freeze
|
444
|
+
|
445
|
+
# K8s Node.
|
446
|
+
K8S_NODE_PARAMS = {
|
447
|
+
resource: {
|
448
|
+
type: K8S_NODE_CONSTANTS[:resource_type],
|
449
|
+
labels: {
|
450
|
+
'node_name' => K8S_NODE_NAME,
|
451
|
+
'cluster_name' => K8S_CLUSTER_NAME,
|
452
|
+
'location' => K8S_LOCATION
|
453
|
+
}
|
454
|
+
},
|
455
|
+
log_name: 'test',
|
456
|
+
project_id: PROJECT_ID,
|
457
|
+
labels: {}
|
458
|
+
}.freeze
|
459
|
+
K8S_NODE_PARAMS_FROM_LOCAL = K8S_NODE_PARAMS.merge(
|
460
|
+
resource: K8S_NODE_PARAMS[:resource].merge(
|
461
|
+
labels: K8S_NODE_PARAMS[:resource][:labels].merge(
|
462
|
+
'location' => K8S_LOCATION2
|
463
|
+
)
|
464
|
+
)
|
465
|
+
).freeze
|
466
|
+
|
395
467
|
# Docker Container.
|
396
468
|
DOCKER_CONTAINER_PARAMS = {
|
397
469
|
resource: {
|
@@ -647,6 +719,29 @@ module Constants
|
|
647
719
|
'pod_id' => CONTAINER_POD_ID,
|
648
720
|
'zone' => ZONE
|
649
721
|
}
|
722
|
+
}.to_json,
|
723
|
+
# K8s container logs.
|
724
|
+
"#{K8S_CONTAINER_LOCAL_RESOURCE_ID_PREFIX}.#{K8S_NAMESPACE_NAME}" \
|
725
|
+
".#{K8S_POD_NAME}.#{K8S_CONTAINER_NAME}" =>
|
726
|
+
{
|
727
|
+
'type' => K8S_CONTAINER_CONSTANTS[:resource_type],
|
728
|
+
'labels' => {
|
729
|
+
'namespace_name' => K8S_NAMESPACE_NAME,
|
730
|
+
'pod_name' => K8S_POD_NAME,
|
731
|
+
'container_name' => K8S_CONTAINER_NAME,
|
732
|
+
'cluster_name' => K8S_CLUSTER_NAME,
|
733
|
+
'location' => K8S_LOCATION
|
734
|
+
}
|
735
|
+
}.to_json,
|
736
|
+
# K8s node logs.
|
737
|
+
"#{K8S_NODE_LOCAL_RESOURCE_ID_PREFIX}.#{K8S_NODE_NAME}" =>
|
738
|
+
{
|
739
|
+
'type' => K8S_NODE_CONSTANTS[:resource_type],
|
740
|
+
'labels' => {
|
741
|
+
'node_name' => K8S_NODE_NAME,
|
742
|
+
'cluster_name' => K8S_CLUSTER_NAME,
|
743
|
+
'location' => K8S_LOCATION
|
744
|
+
}
|
650
745
|
}.to_json
|
651
746
|
}.freeze
|
652
747
|
|
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.18.pre.1
|
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-03-
|
12
|
+
date: 2018-03-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|
@@ -212,6 +212,7 @@ extra_rdoc_files: []
|
|
212
212
|
files:
|
213
213
|
- CONTRIBUTING
|
214
214
|
- Gemfile
|
215
|
+
- Gemfile.lock
|
215
216
|
- LICENSE
|
216
217
|
- README.rdoc
|
217
218
|
- Rakefile
|
@@ -244,9 +245,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
244
245
|
version: '2.0'
|
245
246
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
246
247
|
requirements:
|
247
|
-
- - "
|
248
|
+
- - ">"
|
248
249
|
- !ruby/object:Gem::Version
|
249
|
-
version:
|
250
|
+
version: 1.3.1
|
250
251
|
requirements: []
|
251
252
|
rubyforge_project:
|
252
253
|
rubygems_version: 2.6.14
|