fluent-plugin-google-cloud 0.8.6 → 0.8.7
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 +4 -4
- data/Gemfile.lock +2 -2
- data/fluent-plugin-google-cloud.gemspec +1 -1
- data/lib/fluent/plugin/common.rb +381 -0
- data/lib/fluent/plugin/out_google_cloud.rb +24 -357
- data/test/plugin/base_test.rb +1 -1
- data/test/plugin/constants.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 851c496e93becdfb6a735f9c71aceecfdeccfff14519ce8311bb3dd42c7ed382
|
4
|
+
data.tar.gz: d893b865df5a2b10bac43c65381abe1b95e27333ff77ac45c6cb988c2f446036
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f840e9c06e995be5dd4abd0dcd9d04042c6d78507896fc842ab2b1fb8cb82eac4535fdb6259656cc703e99955e074e64c1ec0292c31d77647cbc95d54e7b919
|
7
|
+
data.tar.gz: c1573f562d3691a83b8b3dd2b8e8a0ed1585edac5f67df6179bc8c62af4a3728ce97b90be8827008718921069806eb6e0d2e81fd5c7f6de4c6603a1c2738774e
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fluent-plugin-google-cloud (0.8.
|
4
|
+
fluent-plugin-google-cloud (0.8.7)
|
5
5
|
fluentd (= 1.7.4)
|
6
6
|
google-api-client (= 0.30.8)
|
7
7
|
google-cloud-logging (= 1.6.6)
|
@@ -18,7 +18,7 @@ GEM
|
|
18
18
|
specs:
|
19
19
|
addressable (2.7.0)
|
20
20
|
public_suffix (>= 2.0.2, < 5.0)
|
21
|
-
ast (2.4.
|
21
|
+
ast (2.4.1)
|
22
22
|
concurrent-ruby (1.1.6)
|
23
23
|
cool.io (1.6.0)
|
24
24
|
coveralls (0.8.23)
|
@@ -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.8.
|
13
|
+
gem.version = '0.8.7'
|
14
14
|
gem.authors = ['Stackdriver Agents Team']
|
15
15
|
gem.email = ['stackdriver-agents@google.com']
|
16
16
|
gem.required_ruby_version = Gem::Requirement.new('>= 2.2')
|
@@ -0,0 +1,381 @@
|
|
1
|
+
# Copyright 2020 Google Inc. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Common
|
16
|
+
# Constants for service names, resource types and etc.
|
17
|
+
module ServiceConstants
|
18
|
+
APPENGINE_CONSTANTS = {
|
19
|
+
service: 'appengine.googleapis.com',
|
20
|
+
resource_type: 'gae_app',
|
21
|
+
metadata_attributes: %w(gae_backend_name gae_backend_version)
|
22
|
+
}.freeze
|
23
|
+
COMPUTE_CONSTANTS = {
|
24
|
+
service: 'compute.googleapis.com',
|
25
|
+
resource_type: 'gce_instance'
|
26
|
+
}.freeze
|
27
|
+
GKE_CONSTANTS = {
|
28
|
+
service: 'container.googleapis.com',
|
29
|
+
resource_type: 'gke_container',
|
30
|
+
extra_resource_labels: %w(namespace_id pod_id container_name),
|
31
|
+
extra_common_labels: %w(namespace_name pod_name),
|
32
|
+
metadata_attributes: %w(cluster-name cluster-location),
|
33
|
+
stream_severity_map: {
|
34
|
+
'stdout' => 'INFO',
|
35
|
+
'stderr' => 'ERROR'
|
36
|
+
}
|
37
|
+
}.freeze
|
38
|
+
K8S_CONTAINER_CONSTANTS = {
|
39
|
+
resource_type: 'k8s_container'
|
40
|
+
}.freeze
|
41
|
+
K8S_POD_CONSTANTS = {
|
42
|
+
resource_type: 'k8s_pod'
|
43
|
+
}.freeze
|
44
|
+
K8S_NODE_CONSTANTS = {
|
45
|
+
resource_type: 'k8s_node'
|
46
|
+
}.freeze
|
47
|
+
DATAFLOW_CONSTANTS = {
|
48
|
+
service: 'dataflow.googleapis.com',
|
49
|
+
resource_type: 'dataflow_step',
|
50
|
+
extra_resource_labels: %w(region job_name job_id step_id)
|
51
|
+
}.freeze
|
52
|
+
DATAPROC_CONSTANTS = {
|
53
|
+
service: 'cluster.dataproc.googleapis.com',
|
54
|
+
resource_type: 'cloud_dataproc_cluster',
|
55
|
+
metadata_attributes: %w(dataproc-cluster-uuid dataproc-cluster-name)
|
56
|
+
}.freeze
|
57
|
+
EC2_CONSTANTS = {
|
58
|
+
service: 'ec2.amazonaws.com',
|
59
|
+
resource_type: 'aws_ec2_instance'
|
60
|
+
}.freeze
|
61
|
+
ML_CONSTANTS = {
|
62
|
+
service: 'ml.googleapis.com',
|
63
|
+
resource_type: 'ml_job',
|
64
|
+
extra_resource_labels: %w(job_id task_name)
|
65
|
+
}.freeze
|
66
|
+
|
67
|
+
# The map between a subservice name and a resource type.
|
68
|
+
SUBSERVICE_MAP =
|
69
|
+
[APPENGINE_CONSTANTS, GKE_CONSTANTS, DATAFLOW_CONSTANTS,
|
70
|
+
DATAPROC_CONSTANTS, ML_CONSTANTS]
|
71
|
+
.map { |consts| [consts[:service], consts[:resource_type]] }.to_h
|
72
|
+
# Default back to GCE if invalid value is detected.
|
73
|
+
SUBSERVICE_MAP.default = COMPUTE_CONSTANTS[:resource_type]
|
74
|
+
SUBSERVICE_MAP.freeze
|
75
|
+
|
76
|
+
# The map between a resource type and expected subservice attributes.
|
77
|
+
SUBSERVICE_METADATA_ATTRIBUTES =
|
78
|
+
[APPENGINE_CONSTANTS, GKE_CONSTANTS, DATAPROC_CONSTANTS].map do |consts|
|
79
|
+
[consts[:resource_type], consts[:metadata_attributes].to_set]
|
80
|
+
end.to_h.freeze
|
81
|
+
end
|
82
|
+
|
83
|
+
# Name of the the Google cloud logging write scope.
|
84
|
+
LOGGING_SCOPE = 'https://www.googleapis.com/auth/logging.write'.freeze
|
85
|
+
|
86
|
+
# Address of the metadata service.
|
87
|
+
METADATA_SERVICE_ADDR = '169.254.169.254'.freeze
|
88
|
+
|
89
|
+
# "enum" of Platform values
|
90
|
+
module Platform
|
91
|
+
OTHER = 0 # Other/unkown platform
|
92
|
+
GCE = 1 # Google Compute Engine
|
93
|
+
EC2 = 2 # Amazon EC2
|
94
|
+
end
|
95
|
+
|
96
|
+
# Utilities for managing the resource used when writing to the
|
97
|
+
# Google API.
|
98
|
+
class Utils
|
99
|
+
include Common::ServiceConstants
|
100
|
+
|
101
|
+
def initialize(log)
|
102
|
+
@log = log
|
103
|
+
end
|
104
|
+
|
105
|
+
# Determine what platform we are running on by consulting the metadata
|
106
|
+
# service (unless the user has explicitly disabled using that).
|
107
|
+
def detect_platform(use_metadata_service)
|
108
|
+
unless use_metadata_service
|
109
|
+
@log.info 'use_metadata_service is false; not detecting platform'
|
110
|
+
return Platform::OTHER
|
111
|
+
end
|
112
|
+
|
113
|
+
begin
|
114
|
+
open('http://' + METADATA_SERVICE_ADDR, proxy: false) do |f|
|
115
|
+
if f.meta['metadata-flavor'] == 'Google'
|
116
|
+
@log.info 'Detected GCE platform'
|
117
|
+
return Platform::GCE
|
118
|
+
end
|
119
|
+
if f.meta['server'] == 'EC2ws'
|
120
|
+
@log.info 'Detected EC2 platform'
|
121
|
+
return Platform::EC2
|
122
|
+
end
|
123
|
+
end
|
124
|
+
rescue StandardError => e
|
125
|
+
@log.error 'Failed to access metadata service: ', error: e
|
126
|
+
end
|
127
|
+
|
128
|
+
@log.info 'Unable to determine platform'
|
129
|
+
Platform::OTHER
|
130
|
+
end
|
131
|
+
|
132
|
+
def fetch_gce_metadata(platform, metadata_path)
|
133
|
+
raise "Called fetch_gce_metadata with platform=#{platform}" unless
|
134
|
+
platform == Platform::GCE
|
135
|
+
# See https://cloud.google.com/compute/docs/metadata
|
136
|
+
open('http://' + METADATA_SERVICE_ADDR + '/computeMetadata/v1/' +
|
137
|
+
metadata_path, 'Metadata-Flavor' => 'Google', :proxy => false,
|
138
|
+
&:read)
|
139
|
+
end
|
140
|
+
|
141
|
+
# EC2 Metadata server returns everything in one call. Store it after the
|
142
|
+
# first fetch to avoid making multiple calls.
|
143
|
+
def ec2_metadata(platform)
|
144
|
+
raise "Called ec2_metadata with platform=#{platform}" unless
|
145
|
+
platform == Platform::EC2
|
146
|
+
unless @ec2_metadata
|
147
|
+
# See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
|
148
|
+
open('http://' + METADATA_SERVICE_ADDR +
|
149
|
+
'/latest/dynamic/instance-identity/document', proxy: false) do |f|
|
150
|
+
contents = f.read
|
151
|
+
@ec2_metadata = JSON.parse(contents)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
@ec2_metadata
|
156
|
+
end
|
157
|
+
|
158
|
+
# Check required variables like @project_id, @vm_id, @vm_name and @zone.
|
159
|
+
def check_required_metadata_variables(platform, project_id, zone, vm_id)
|
160
|
+
missing = []
|
161
|
+
missing << 'project_id' unless project_id
|
162
|
+
if platform != Platform::OTHER
|
163
|
+
missing << 'zone' unless zone
|
164
|
+
missing << 'vm_id' unless vm_id
|
165
|
+
end
|
166
|
+
return if missing.empty?
|
167
|
+
raise Fluent::ConfigError,
|
168
|
+
"Unable to obtain metadata parameters: #{missing.join(' ')}"
|
169
|
+
end
|
170
|
+
|
171
|
+
# 1. Return the value if it is explicitly set in the config already.
|
172
|
+
# 2. If not, try to retrieve it by calling metadata server directly.
|
173
|
+
# 3. If still not set, try to obtain it from the credentials.
|
174
|
+
def get_project_id(platform, project_id)
|
175
|
+
project_id ||= CredentialsInfo.project_id
|
176
|
+
project_id ||= fetch_gce_metadata(platform, 'project/project-id') if
|
177
|
+
platform == Platform::GCE
|
178
|
+
project_id
|
179
|
+
end
|
180
|
+
|
181
|
+
# 1. Return the value if it is explicitly set in the config already.
|
182
|
+
# 2. If not, try to retrieve it by calling metadata servers directly.
|
183
|
+
def get_vm_id(platform, vm_id)
|
184
|
+
vm_id ||= fetch_gce_metadata(platform, 'instance/id') if
|
185
|
+
platform == Platform::GCE
|
186
|
+
vm_id ||= ec2_metadata(platform)['instanceId'] if
|
187
|
+
platform == Platform::EC2
|
188
|
+
vm_id
|
189
|
+
rescue StandardError => e
|
190
|
+
@log.error 'Failed to obtain vm_id: ', error: e
|
191
|
+
end
|
192
|
+
|
193
|
+
# 1. Return the value if it is explicitly set in the config already.
|
194
|
+
# 2. If not, try to retrieve it locally.
|
195
|
+
def get_vm_name(vm_name)
|
196
|
+
vm_name ||= Socket.gethostname
|
197
|
+
vm_name
|
198
|
+
rescue StandardError => e
|
199
|
+
@log.error 'Failed to obtain vm name: ', error: e
|
200
|
+
end
|
201
|
+
|
202
|
+
# 1. Return the value if it is explicitly set in the config already.
|
203
|
+
# 2. If not, try to retrieve it locally.
|
204
|
+
def get_location(platform, zone, use_aws_availability_zone)
|
205
|
+
# Response format: "projects/<number>/zones/<zone>"
|
206
|
+
zone ||= fetch_gce_metadata(platform,
|
207
|
+
'instance/zone').rpartition('/')[2] if
|
208
|
+
platform == Platform::GCE
|
209
|
+
aws_location_key = if use_aws_availability_zone
|
210
|
+
'availabilityZone'
|
211
|
+
else
|
212
|
+
'region'
|
213
|
+
end
|
214
|
+
zone ||= 'aws:' + ec2_metadata(platform)[aws_location_key] if
|
215
|
+
platform == Platform::EC2 &&
|
216
|
+
ec2_metadata(platform).key?(aws_location_key)
|
217
|
+
zone
|
218
|
+
rescue StandardError => e
|
219
|
+
@log.error 'Failed to obtain location: ', error: e
|
220
|
+
end
|
221
|
+
|
222
|
+
# Retrieve monitored resource via the legacy way.
|
223
|
+
#
|
224
|
+
# Note: This is just a failover plan if we fail to get metadata from
|
225
|
+
# Metadata Agent. Thus it should be equivalent to what Metadata Agent
|
226
|
+
# returns.
|
227
|
+
def determine_agent_level_monitored_resource_via_legacy(
|
228
|
+
platform, subservice_name, detect_subservice, vm_id, zone)
|
229
|
+
resource = Google::Apis::LoggingV2::MonitoredResource.new(
|
230
|
+
labels: {})
|
231
|
+
resource.type = determine_agent_level_monitored_resource_type(
|
232
|
+
platform, subservice_name, detect_subservice)
|
233
|
+
resource.labels = determine_agent_level_monitored_resource_labels(
|
234
|
+
platform, resource.type, vm_id, zone)
|
235
|
+
resource
|
236
|
+
end
|
237
|
+
|
238
|
+
# Determine agent level monitored resource type.
|
239
|
+
def determine_agent_level_monitored_resource_type(
|
240
|
+
platform, subservice_name, detect_subservice)
|
241
|
+
case platform
|
242
|
+
when Platform::OTHER
|
243
|
+
# Unknown platform will be defaulted to GCE instance.
|
244
|
+
return COMPUTE_CONSTANTS[:resource_type]
|
245
|
+
|
246
|
+
when Platform::EC2
|
247
|
+
return EC2_CONSTANTS[:resource_type]
|
248
|
+
|
249
|
+
when Platform::GCE
|
250
|
+
# Resource types determined by subservice_name config.
|
251
|
+
return SUBSERVICE_MAP[subservice_name] if subservice_name
|
252
|
+
|
253
|
+
# Resource types determined by detect_subservice config.
|
254
|
+
if detect_subservice
|
255
|
+
begin
|
256
|
+
attributes = fetch_gce_metadata(platform,
|
257
|
+
'instance/attributes/').split.to_set
|
258
|
+
SUBSERVICE_METADATA_ATTRIBUTES.each do |resource_type, expected|
|
259
|
+
return resource_type if attributes.superset?(expected)
|
260
|
+
end
|
261
|
+
rescue StandardError => e
|
262
|
+
@log.error 'Failed to detect subservice: ', error: e
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
# GCE instance.
|
267
|
+
return COMPUTE_CONSTANTS[:resource_type]
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# Determine agent level monitored resource labels based on the resource
|
272
|
+
# type. Each resource type has its own labels that need to be filled in.
|
273
|
+
def determine_agent_level_monitored_resource_labels(
|
274
|
+
platform, type, vm_id, zone)
|
275
|
+
case type
|
276
|
+
# GAE app.
|
277
|
+
when APPENGINE_CONSTANTS[:resource_type]
|
278
|
+
return {
|
279
|
+
'module_id' =>
|
280
|
+
fetch_gce_metadata(platform,
|
281
|
+
'instance/attributes/gae_backend_name'),
|
282
|
+
'version_id' =>
|
283
|
+
fetch_gce_metadata(platform,
|
284
|
+
'instance/attributes/gae_backend_version')
|
285
|
+
}
|
286
|
+
|
287
|
+
# GCE.
|
288
|
+
when COMPUTE_CONSTANTS[:resource_type]
|
289
|
+
raise "Cannot construct a #{type} resource without vm_id and zone" \
|
290
|
+
unless vm_id && zone
|
291
|
+
return {
|
292
|
+
'instance_id' => vm_id,
|
293
|
+
'zone' => zone
|
294
|
+
}
|
295
|
+
|
296
|
+
# GKE container.
|
297
|
+
when GKE_CONSTANTS[:resource_type]
|
298
|
+
raise "Cannot construct a #{type} resource without vm_id and zone" \
|
299
|
+
unless vm_id && zone
|
300
|
+
return {
|
301
|
+
'instance_id' => vm_id,
|
302
|
+
'zone' => zone,
|
303
|
+
'cluster_name' =>
|
304
|
+
fetch_gce_metadata(platform, 'instance/attributes/cluster-name')
|
305
|
+
}
|
306
|
+
|
307
|
+
# Cloud Dataproc.
|
308
|
+
when DATAPROC_CONSTANTS[:resource_type]
|
309
|
+
return {
|
310
|
+
'cluster_uuid' =>
|
311
|
+
fetch_gce_metadata(platform,
|
312
|
+
'instance/attributes/dataproc-cluster-uuid'),
|
313
|
+
'cluster_name' =>
|
314
|
+
fetch_gce_metadata(platform,
|
315
|
+
'instance/attributes/dataproc-cluster-name'),
|
316
|
+
'region' =>
|
317
|
+
fetch_gce_metadata(platform,
|
318
|
+
'instance/attributes/dataproc-region')
|
319
|
+
}
|
320
|
+
|
321
|
+
# EC2.
|
322
|
+
when EC2_CONSTANTS[:resource_type]
|
323
|
+
raise "Cannot construct a #{type} resource without vm_id and zone" \
|
324
|
+
unless vm_id && zone
|
325
|
+
labels = {
|
326
|
+
'instance_id' => vm_id,
|
327
|
+
'region' => zone
|
328
|
+
}
|
329
|
+
labels['aws_account'] = ec2_metadata(platform)['accountId'] if
|
330
|
+
ec2_metadata(platform).key?('accountId')
|
331
|
+
return labels
|
332
|
+
end
|
333
|
+
|
334
|
+
{}
|
335
|
+
rescue StandardError => e
|
336
|
+
if [Platform::GCE, Platform::EC2].include?(platform)
|
337
|
+
@log.error "Failed to set monitored resource labels for #{type}: ",
|
338
|
+
error: e
|
339
|
+
end
|
340
|
+
{}
|
341
|
+
end
|
342
|
+
|
343
|
+
# TODO: This functionality should eventually be available in another
|
344
|
+
# library, but implement it ourselves for now.
|
345
|
+
module CredentialsInfo
|
346
|
+
# Determine the project ID from the credentials, if possible.
|
347
|
+
# Returns the project ID (as a string) on success, or nil on failure.
|
348
|
+
def self.project_id
|
349
|
+
creds = Google::Auth.get_application_default(LOGGING_SCOPE)
|
350
|
+
if creds.respond_to?(:project_id)
|
351
|
+
return creds.project_id if creds.project_id
|
352
|
+
end
|
353
|
+
if creds.issuer
|
354
|
+
id = extract_project_id(creds.issuer)
|
355
|
+
return id unless id.nil?
|
356
|
+
end
|
357
|
+
if creds.client_id
|
358
|
+
id = extract_project_id(creds.client_id)
|
359
|
+
return id unless id.nil?
|
360
|
+
end
|
361
|
+
nil
|
362
|
+
end
|
363
|
+
|
364
|
+
# Extracts the project id (either name or number) from str and returns
|
365
|
+
# it (as a string) on success, or nil on failure.
|
366
|
+
#
|
367
|
+
# Recognizes IAM format (account@project-name.iam.gserviceaccount.com)
|
368
|
+
# as well as the legacy format with a project number at the front of the
|
369
|
+
# string, terminated by a dash (-) which is not part of the ID, i.e.:
|
370
|
+
# <PROJECT_ID>-<OTHER_PARTS>.apps.googleusercontent.com
|
371
|
+
def self.extract_project_id(str)
|
372
|
+
[/^.*@(?<project_id>.+)\.iam\.gserviceaccount\.com/,
|
373
|
+
/^(?<project_id>\d+)-/].each do |exp|
|
374
|
+
match_data = exp.match(str)
|
375
|
+
return match_data['project_id'] unless match_data.nil?
|
376
|
+
end
|
377
|
+
nil
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
@@ -28,6 +28,7 @@ require 'google/logging/v2/logging_services_pb'
|
|
28
28
|
require 'google/logging/v2/log_entry_pb'
|
29
29
|
require 'googleauth'
|
30
30
|
|
31
|
+
require_relative 'common'
|
31
32
|
require_relative 'monitoring'
|
32
33
|
require_relative 'statusz'
|
33
34
|
|
@@ -90,73 +91,6 @@ end
|
|
90
91
|
module Fluent
|
91
92
|
# fluentd output plugin for the Stackdriver Logging API
|
92
93
|
class GoogleCloudOutput < BufferedOutput
|
93
|
-
# Constants for service names, resource types and etc.
|
94
|
-
module ServiceConstants
|
95
|
-
APPENGINE_CONSTANTS = {
|
96
|
-
service: 'appengine.googleapis.com',
|
97
|
-
resource_type: 'gae_app',
|
98
|
-
metadata_attributes: %w(gae_backend_name gae_backend_version)
|
99
|
-
}.freeze
|
100
|
-
COMPUTE_CONSTANTS = {
|
101
|
-
service: 'compute.googleapis.com',
|
102
|
-
resource_type: 'gce_instance'
|
103
|
-
}.freeze
|
104
|
-
GKE_CONSTANTS = {
|
105
|
-
service: 'container.googleapis.com',
|
106
|
-
resource_type: 'gke_container',
|
107
|
-
extra_resource_labels: %w(namespace_id pod_id container_name),
|
108
|
-
extra_common_labels: %w(namespace_name pod_name),
|
109
|
-
metadata_attributes: %w(cluster-name cluster-location),
|
110
|
-
stream_severity_map: {
|
111
|
-
'stdout' => 'INFO',
|
112
|
-
'stderr' => 'ERROR'
|
113
|
-
}
|
114
|
-
}.freeze
|
115
|
-
K8S_CONTAINER_CONSTANTS = {
|
116
|
-
resource_type: 'k8s_container'
|
117
|
-
}.freeze
|
118
|
-
K8S_POD_CONSTANTS = {
|
119
|
-
resource_type: 'k8s_pod'
|
120
|
-
}.freeze
|
121
|
-
K8S_NODE_CONSTANTS = {
|
122
|
-
resource_type: 'k8s_node'
|
123
|
-
}.freeze
|
124
|
-
DATAFLOW_CONSTANTS = {
|
125
|
-
service: 'dataflow.googleapis.com',
|
126
|
-
resource_type: 'dataflow_step',
|
127
|
-
extra_resource_labels: %w(region job_name job_id step_id)
|
128
|
-
}.freeze
|
129
|
-
DATAPROC_CONSTANTS = {
|
130
|
-
service: 'cluster.dataproc.googleapis.com',
|
131
|
-
resource_type: 'cloud_dataproc_cluster',
|
132
|
-
metadata_attributes: %w(dataproc-cluster-uuid dataproc-cluster-name)
|
133
|
-
}.freeze
|
134
|
-
EC2_CONSTANTS = {
|
135
|
-
service: 'ec2.amazonaws.com',
|
136
|
-
resource_type: 'aws_ec2_instance'
|
137
|
-
}.freeze
|
138
|
-
ML_CONSTANTS = {
|
139
|
-
service: 'ml.googleapis.com',
|
140
|
-
resource_type: 'ml_job',
|
141
|
-
extra_resource_labels: %w(job_id task_name)
|
142
|
-
}.freeze
|
143
|
-
|
144
|
-
# The map between a subservice name and a resource type.
|
145
|
-
SUBSERVICE_MAP =
|
146
|
-
[APPENGINE_CONSTANTS, GKE_CONSTANTS, DATAFLOW_CONSTANTS,
|
147
|
-
DATAPROC_CONSTANTS, ML_CONSTANTS]
|
148
|
-
.map { |consts| [consts[:service], consts[:resource_type]] }.to_h
|
149
|
-
# Default back to GCE if invalid value is detected.
|
150
|
-
SUBSERVICE_MAP.default = COMPUTE_CONSTANTS[:resource_type]
|
151
|
-
SUBSERVICE_MAP.freeze
|
152
|
-
|
153
|
-
# The map between a resource type and expected subservice attributes.
|
154
|
-
SUBSERVICE_METADATA_ATTRIBUTES =
|
155
|
-
[APPENGINE_CONSTANTS, GKE_CONSTANTS, DATAPROC_CONSTANTS].map do |consts|
|
156
|
-
[consts[:resource_type], consts[:metadata_attributes].to_set]
|
157
|
-
end.to_h.freeze
|
158
|
-
end
|
159
|
-
|
160
94
|
# Constants for configuration.
|
161
95
|
module ConfigConstants
|
162
96
|
# Default values for JSON payload keys to set the "httpRequest",
|
@@ -247,7 +181,7 @@ module Fluent
|
|
247
181
|
.freeze
|
248
182
|
end
|
249
183
|
|
250
|
-
include
|
184
|
+
include Common::ServiceConstants
|
251
185
|
include self::ConfigConstants
|
252
186
|
include self::InternalConstants
|
253
187
|
|
@@ -278,12 +212,6 @@ module Fluent
|
|
278
212
|
end
|
279
213
|
end.freeze
|
280
214
|
|
281
|
-
# Name of the the Google cloud logging write scope.
|
282
|
-
LOGGING_SCOPE = 'https://www.googleapis.com/auth/logging.write'.freeze
|
283
|
-
|
284
|
-
# Address of the metadata service.
|
285
|
-
METADATA_SERVICE_ADDR = '169.254.169.254'.freeze
|
286
|
-
|
287
215
|
# Disable this warning to conform to fluentd config_param conventions.
|
288
216
|
# rubocop:disable Style/HashSyntax
|
289
217
|
|
@@ -539,7 +467,9 @@ module Fluent
|
|
539
467
|
|
540
468
|
set_regexp_patterns
|
541
469
|
|
542
|
-
@
|
470
|
+
@utils = Common::Utils.new(@log)
|
471
|
+
|
472
|
+
@platform = @utils.detect_platform(@use_metadata_service)
|
543
473
|
|
544
474
|
# Treat an empty setting of the credentials file path environment variable
|
545
475
|
# as unset. This way the googleauth lib could fetch the credentials
|
@@ -548,12 +478,20 @@ module Fluent
|
|
548
478
|
ENV[CREDENTIALS_PATH_ENV_VAR] == ''
|
549
479
|
|
550
480
|
# Set required variables: @project_id, @vm_id, @vm_name and @zone.
|
551
|
-
|
481
|
+
@project_id = @utils.get_project_id(@platform, @project_id)
|
482
|
+
@vm_id = @utils.get_vm_id(@platform, @vm_id)
|
483
|
+
@vm_name = @utils.get_vm_name(@vm_name)
|
484
|
+
@zone = @utils.get_location(@platform, @zone, @use_aws_availability_zone)
|
485
|
+
|
486
|
+
# All metadata parameters must now be set.
|
487
|
+
@utils.check_required_metadata_variables(
|
488
|
+
@platform, @project_id, @zone, @vm_id)
|
552
489
|
|
553
490
|
# Retrieve monitored resource.
|
554
491
|
# Fail over to retrieve monitored resource via the legacy path if we fail
|
555
492
|
# to get it from Metadata Agent.
|
556
|
-
@resource ||= determine_agent_level_monitored_resource_via_legacy
|
493
|
+
@resource ||= @utils.determine_agent_level_monitored_resource_via_legacy(
|
494
|
+
@platform, @subservice_name, @detect_subservice, @vm_id, @zone)
|
557
495
|
|
558
496
|
# If monitoring is enabled, register metrics in the default registry
|
559
497
|
# and store metric objects for future use.
|
@@ -611,7 +549,7 @@ module Fluent
|
|
611
549
|
|
612
550
|
# Determine the common labels that should be added to all log entries
|
613
551
|
# processed by this logging agent.
|
614
|
-
@common_labels = determine_agent_level_common_labels
|
552
|
+
@common_labels = determine_agent_level_common_labels(@resource)
|
615
553
|
|
616
554
|
# The resource and labels are now set up; ensure they can't be modified
|
617
555
|
# without first duping them.
|
@@ -627,7 +565,7 @@ module Fluent
|
|
627
565
|
@write_request = method(:write_request_via_rest)
|
628
566
|
end
|
629
567
|
|
630
|
-
if [Platform::GCE, Platform::EC2].include?(@platform)
|
568
|
+
if [Common::Platform::GCE, Common::Platform::EC2].include?(@platform)
|
631
569
|
# Log an informational message containing the Logs viewer URL
|
632
570
|
@log.info 'Logs viewer address: https://console.cloud.google.com/logs/',
|
633
571
|
"viewer?project=#{@project_id}&resource=#{@resource.type}/",
|
@@ -1094,66 +1032,6 @@ module Fluent
|
|
1094
1032
|
nil
|
1095
1033
|
end
|
1096
1034
|
|
1097
|
-
# "enum" of Platform values
|
1098
|
-
module Platform
|
1099
|
-
OTHER = 0 # Other/unkown platform
|
1100
|
-
GCE = 1 # Google Compute Engine
|
1101
|
-
EC2 = 2 # Amazon EC2
|
1102
|
-
end
|
1103
|
-
|
1104
|
-
# Determine what platform we are running on by consulting the metadata
|
1105
|
-
# service (unless the user has explicitly disabled using that).
|
1106
|
-
def detect_platform
|
1107
|
-
unless @use_metadata_service
|
1108
|
-
@log.info 'use_metadata_service is false; not detecting platform'
|
1109
|
-
return Platform::OTHER
|
1110
|
-
end
|
1111
|
-
|
1112
|
-
begin
|
1113
|
-
open('http://' + METADATA_SERVICE_ADDR, proxy: false) do |f|
|
1114
|
-
if f.meta['metadata-flavor'] == 'Google'
|
1115
|
-
@log.info 'Detected GCE platform'
|
1116
|
-
return Platform::GCE
|
1117
|
-
end
|
1118
|
-
if f.meta['server'] == 'EC2ws'
|
1119
|
-
@log.info 'Detected EC2 platform'
|
1120
|
-
return Platform::EC2
|
1121
|
-
end
|
1122
|
-
end
|
1123
|
-
rescue StandardError => e
|
1124
|
-
@log.error 'Failed to access metadata service: ', error: e
|
1125
|
-
end
|
1126
|
-
|
1127
|
-
@log.info 'Unable to determine platform'
|
1128
|
-
Platform::OTHER
|
1129
|
-
end
|
1130
|
-
|
1131
|
-
def fetch_gce_metadata(metadata_path)
|
1132
|
-
raise "Called fetch_gce_metadata with platform=#{@platform}" unless
|
1133
|
-
@platform == Platform::GCE
|
1134
|
-
# See https://cloud.google.com/compute/docs/metadata
|
1135
|
-
open('http://' + METADATA_SERVICE_ADDR + '/computeMetadata/v1/' +
|
1136
|
-
metadata_path, 'Metadata-Flavor' => 'Google', :proxy => false,
|
1137
|
-
&:read)
|
1138
|
-
end
|
1139
|
-
|
1140
|
-
# EC2 Metadata server returns everything in one call. Store it after the
|
1141
|
-
# first fetch to avoid making multiple calls.
|
1142
|
-
def ec2_metadata
|
1143
|
-
raise "Called ec2_metadata with platform=#{@platform}" unless
|
1144
|
-
@platform == Platform::EC2
|
1145
|
-
unless @ec2_metadata
|
1146
|
-
# See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
|
1147
|
-
open('http://' + METADATA_SERVICE_ADDR +
|
1148
|
-
'/latest/dynamic/instance-identity/document', proxy: false) do |f|
|
1149
|
-
contents = f.read
|
1150
|
-
@ec2_metadata = JSON.parse(contents)
|
1151
|
-
end
|
1152
|
-
end
|
1153
|
-
|
1154
|
-
@ec2_metadata
|
1155
|
-
end
|
1156
|
-
|
1157
1035
|
# Set regexp patterns to parse tags and logs.
|
1158
1036
|
def set_regexp_patterns
|
1159
1037
|
@compiled_kubernetes_tag_regexp = Regexp.new(@kubernetes_tag_regexp) if
|
@@ -1163,187 +1041,14 @@ module Fluent
|
|
1163
1041
|
/^\s*(?<seconds>\d+)(?<decimal>\.\d+)?\s*s\s*$/
|
1164
1042
|
end
|
1165
1043
|
|
1166
|
-
# Set required variables like @project_id, @vm_id, @vm_name and @zone.
|
1167
|
-
def set_required_metadata_variables
|
1168
|
-
set_project_id
|
1169
|
-
set_vm_id
|
1170
|
-
set_vm_name
|
1171
|
-
set_location
|
1172
|
-
|
1173
|
-
# All metadata parameters must now be set.
|
1174
|
-
missing = []
|
1175
|
-
missing << 'project_id' unless @project_id
|
1176
|
-
if @platform != Platform::OTHER
|
1177
|
-
missing << 'zone' unless @zone
|
1178
|
-
missing << 'vm_id' unless @vm_id
|
1179
|
-
end
|
1180
|
-
return if missing.empty?
|
1181
|
-
raise Fluent::ConfigError,
|
1182
|
-
"Unable to obtain metadata parameters: #{missing.join(' ')}"
|
1183
|
-
end
|
1184
|
-
|
1185
|
-
# 1. Return the value if it is explicitly set in the config already.
|
1186
|
-
# 2. If not, try to retrieve it by calling metadata server directly.
|
1187
|
-
# 3. If still not set, try to obtain it from the credentials.
|
1188
|
-
def set_project_id
|
1189
|
-
@project_id ||= CredentialsInfo.project_id
|
1190
|
-
@project_id ||= fetch_gce_metadata('project/project-id') if
|
1191
|
-
@platform == Platform::GCE
|
1192
|
-
end
|
1193
|
-
|
1194
|
-
# 1. Return the value if it is explicitly set in the config already.
|
1195
|
-
# 2. If not, try to retrieve it by calling metadata servers directly.
|
1196
|
-
def set_vm_id
|
1197
|
-
@vm_id ||= fetch_gce_metadata('instance/id') if @platform == Platform::GCE
|
1198
|
-
@vm_id ||= ec2_metadata['instanceId'] if @platform == Platform::EC2
|
1199
|
-
rescue StandardError => e
|
1200
|
-
@log.error 'Failed to obtain vm_id: ', error: e
|
1201
|
-
end
|
1202
|
-
|
1203
|
-
# 1. Return the value if it is explicitly set in the config already.
|
1204
|
-
# 2. If not, try to retrieve it locally.
|
1205
|
-
def set_vm_name
|
1206
|
-
@vm_name ||= Socket.gethostname
|
1207
|
-
rescue StandardError => e
|
1208
|
-
@log.error 'Failed to obtain vm name: ', error: e
|
1209
|
-
end
|
1210
|
-
|
1211
|
-
# 1. Return the value if it is explicitly set in the config already.
|
1212
|
-
# 2. If not, try to retrieve it locally.
|
1213
|
-
def set_location
|
1214
|
-
# Response format: "projects/<number>/zones/<zone>"
|
1215
|
-
@zone ||= fetch_gce_metadata('instance/zone').rpartition('/')[2] if
|
1216
|
-
@platform == Platform::GCE
|
1217
|
-
aws_location_key = if @use_aws_availability_zone
|
1218
|
-
'availabilityZone'
|
1219
|
-
else
|
1220
|
-
'region'
|
1221
|
-
end
|
1222
|
-
@zone ||= 'aws:' + ec2_metadata[aws_location_key] if
|
1223
|
-
@platform == Platform::EC2 && ec2_metadata.key?(aws_location_key)
|
1224
|
-
rescue StandardError => e
|
1225
|
-
@log.error 'Failed to obtain location: ', error: e
|
1226
|
-
end
|
1227
|
-
|
1228
|
-
# Retrieve monitored resource via the legacy way.
|
1229
|
-
#
|
1230
|
-
# Note: This is just a failover plan if we fail to get metadata from
|
1231
|
-
# Metadata Agent. Thus it should be equivalent to what Metadata Agent
|
1232
|
-
# returns.
|
1233
|
-
def determine_agent_level_monitored_resource_via_legacy
|
1234
|
-
resource = Google::Apis::LoggingV2::MonitoredResource.new(
|
1235
|
-
labels: {})
|
1236
|
-
resource.type = determine_agent_level_monitored_resource_type
|
1237
|
-
resource.labels = determine_agent_level_monitored_resource_labels(
|
1238
|
-
resource.type)
|
1239
|
-
resource
|
1240
|
-
end
|
1241
|
-
|
1242
|
-
# Determine agent level monitored resource type.
|
1243
|
-
def determine_agent_level_monitored_resource_type
|
1244
|
-
case @platform
|
1245
|
-
when Platform::OTHER
|
1246
|
-
# Unknown platform will be defaulted to GCE instance.
|
1247
|
-
return COMPUTE_CONSTANTS[:resource_type]
|
1248
|
-
|
1249
|
-
when Platform::EC2
|
1250
|
-
return EC2_CONSTANTS[:resource_type]
|
1251
|
-
|
1252
|
-
when Platform::GCE
|
1253
|
-
# Resource types determined by @subservice_name config.
|
1254
|
-
return SUBSERVICE_MAP[@subservice_name] if @subservice_name
|
1255
|
-
|
1256
|
-
# Resource types determined by @detect_subservice config.
|
1257
|
-
if @detect_subservice
|
1258
|
-
begin
|
1259
|
-
attributes = fetch_gce_metadata('instance/attributes/').split.to_set
|
1260
|
-
SUBSERVICE_METADATA_ATTRIBUTES.each do |resource_type, expected|
|
1261
|
-
return resource_type if attributes.superset?(expected)
|
1262
|
-
end
|
1263
|
-
rescue StandardError => e
|
1264
|
-
@log.error 'Failed to detect subservice: ', error: e
|
1265
|
-
end
|
1266
|
-
end
|
1267
|
-
|
1268
|
-
# GCE instance.
|
1269
|
-
return COMPUTE_CONSTANTS[:resource_type]
|
1270
|
-
end
|
1271
|
-
end
|
1272
|
-
|
1273
|
-
# Determine agent level monitored resource labels based on the resource
|
1274
|
-
# type. Each resource type has its own labels that need to be filled in.
|
1275
|
-
def determine_agent_level_monitored_resource_labels(type)
|
1276
|
-
case type
|
1277
|
-
# GAE app.
|
1278
|
-
when APPENGINE_CONSTANTS[:resource_type]
|
1279
|
-
return {
|
1280
|
-
'module_id' =>
|
1281
|
-
fetch_gce_metadata('instance/attributes/gae_backend_name'),
|
1282
|
-
'version_id' =>
|
1283
|
-
fetch_gce_metadata('instance/attributes/gae_backend_version')
|
1284
|
-
}
|
1285
|
-
|
1286
|
-
# GCE.
|
1287
|
-
when COMPUTE_CONSTANTS[:resource_type]
|
1288
|
-
raise "Cannot construct a #{type} resource without vm_id and zone" \
|
1289
|
-
unless @vm_id && @zone
|
1290
|
-
return {
|
1291
|
-
'instance_id' => @vm_id,
|
1292
|
-
'zone' => @zone
|
1293
|
-
}
|
1294
|
-
|
1295
|
-
# GKE container.
|
1296
|
-
when GKE_CONSTANTS[:resource_type]
|
1297
|
-
raise "Cannot construct a #{type} resource without vm_id and zone" \
|
1298
|
-
unless @vm_id && @zone
|
1299
|
-
return {
|
1300
|
-
'instance_id' => @vm_id,
|
1301
|
-
'zone' => @zone,
|
1302
|
-
'cluster_name' =>
|
1303
|
-
fetch_gce_metadata('instance/attributes/cluster-name')
|
1304
|
-
}
|
1305
|
-
|
1306
|
-
# Cloud Dataproc.
|
1307
|
-
when DATAPROC_CONSTANTS[:resource_type]
|
1308
|
-
return {
|
1309
|
-
'cluster_uuid' =>
|
1310
|
-
fetch_gce_metadata('instance/attributes/dataproc-cluster-uuid'),
|
1311
|
-
'cluster_name' =>
|
1312
|
-
fetch_gce_metadata('instance/attributes/dataproc-cluster-name'),
|
1313
|
-
'region' =>
|
1314
|
-
fetch_gce_metadata('instance/attributes/dataproc-region')
|
1315
|
-
}
|
1316
|
-
|
1317
|
-
# EC2.
|
1318
|
-
when EC2_CONSTANTS[:resource_type]
|
1319
|
-
raise "Cannot construct a #{type} resource without vm_id and zone" \
|
1320
|
-
unless @vm_id && @zone
|
1321
|
-
labels = {
|
1322
|
-
'instance_id' => @vm_id,
|
1323
|
-
'region' => @zone
|
1324
|
-
}
|
1325
|
-
labels['aws_account'] = ec2_metadata['accountId'] if
|
1326
|
-
ec2_metadata.key?('accountId')
|
1327
|
-
return labels
|
1328
|
-
end
|
1329
|
-
|
1330
|
-
{}
|
1331
|
-
rescue StandardError => e
|
1332
|
-
if [Platform::GCE, Platform::EC2].include?(@platform)
|
1333
|
-
@log.error "Failed to set monitored resource labels for #{type}: ",
|
1334
|
-
error: e
|
1335
|
-
end
|
1336
|
-
{}
|
1337
|
-
end
|
1338
|
-
|
1339
1044
|
# Determine the common labels that should be added to all log entries
|
1340
1045
|
# processed by this logging agent.
|
1341
|
-
def determine_agent_level_common_labels
|
1046
|
+
def determine_agent_level_common_labels(resource)
|
1342
1047
|
labels = {}
|
1343
1048
|
# User can specify labels via config. We want to capture those as well.
|
1344
1049
|
labels.merge!(@labels) if @labels
|
1345
1050
|
|
1346
|
-
case
|
1051
|
+
case resource.type
|
1347
1052
|
# GAE, Cloud Dataflow, Cloud Dataproc and Cloud ML.
|
1348
1053
|
when APPENGINE_CONSTANTS[:resource_type],
|
1349
1054
|
DATAFLOW_CONSTANTS[:resource_type],
|
@@ -1548,44 +1253,6 @@ module Fluent
|
|
1548
1253
|
[resource, common_labels]
|
1549
1254
|
end
|
1550
1255
|
|
1551
|
-
# TODO: This functionality should eventually be available in another
|
1552
|
-
# library, but implement it ourselves for now.
|
1553
|
-
module CredentialsInfo
|
1554
|
-
# Determine the project ID from the credentials, if possible.
|
1555
|
-
# Returns the project ID (as a string) on success, or nil on failure.
|
1556
|
-
def self.project_id
|
1557
|
-
creds = Google::Auth.get_application_default(LOGGING_SCOPE)
|
1558
|
-
if creds.respond_to?(:project_id)
|
1559
|
-
return creds.project_id if creds.project_id
|
1560
|
-
end
|
1561
|
-
if creds.issuer
|
1562
|
-
id = extract_project_id(creds.issuer)
|
1563
|
-
return id unless id.nil?
|
1564
|
-
end
|
1565
|
-
if creds.client_id
|
1566
|
-
id = extract_project_id(creds.client_id)
|
1567
|
-
return id unless id.nil?
|
1568
|
-
end
|
1569
|
-
nil
|
1570
|
-
end
|
1571
|
-
|
1572
|
-
# Extracts the project id (either name or number) from str and returns
|
1573
|
-
# it (as a string) on success, or nil on failure.
|
1574
|
-
#
|
1575
|
-
# Recognizes IAM format (account@project-name.iam.gserviceaccount.com)
|
1576
|
-
# as well as the legacy format with a project number at the front of the
|
1577
|
-
# string, terminated by a dash (-) which is not part of the ID, i.e.:
|
1578
|
-
# <PROJECT_ID>-<OTHER_PARTS>.apps.googleusercontent.com
|
1579
|
-
def self.extract_project_id(str)
|
1580
|
-
[/^.*@(?<project_id>.+)\.iam\.gserviceaccount\.com/,
|
1581
|
-
/^(?<project_id>\d+)-/].each do |exp|
|
1582
|
-
match_data = exp.match(str)
|
1583
|
-
return match_data['project_id'] unless match_data.nil?
|
1584
|
-
end
|
1585
|
-
nil
|
1586
|
-
end
|
1587
|
-
end
|
1588
|
-
|
1589
1256
|
def time_or_nil(ts_secs, ts_nanos)
|
1590
1257
|
Time.at((Integer ts_secs), (Integer ts_nanos) / 1_000.0)
|
1591
1258
|
rescue ArgumentError, TypeError
|
@@ -2081,7 +1748,7 @@ module Fluent
|
|
2081
1748
|
Google::Apis::ClientOptions.default.application_version = PLUGIN_VERSION
|
2082
1749
|
@client = Google::Apis::LoggingV2::LoggingService.new
|
2083
1750
|
@client.authorization = Google::Auth.get_application_default(
|
2084
|
-
LOGGING_SCOPE)
|
1751
|
+
Common::LOGGING_SCOPE)
|
2085
1752
|
end
|
2086
1753
|
end
|
2087
1754
|
|
@@ -2310,10 +1977,10 @@ module Fluent
|
|
2310
1977
|
@k8s_cluster_location = nil if @k8s_cluster_location == ''
|
2311
1978
|
|
2312
1979
|
begin
|
2313
|
-
@k8s_cluster_name ||= fetch_gce_metadata(
|
2314
|
-
'instance/attributes/cluster-name')
|
2315
|
-
@k8s_cluster_location ||= fetch_gce_metadata(
|
2316
|
-
'instance/attributes/cluster-location')
|
1980
|
+
@k8s_cluster_name ||= @utils.fetch_gce_metadata(
|
1981
|
+
@platform, 'instance/attributes/cluster-name')
|
1982
|
+
@k8s_cluster_location ||= @utils.fetch_gce_metadata(
|
1983
|
+
@platform, 'instance/attributes/cluster-location')
|
2317
1984
|
rescue StandardError => e
|
2318
1985
|
@log.error 'Failed to retrieve k8s cluster name and location.', \
|
2319
1986
|
error: e
|
data/test/plugin/base_test.rb
CHANGED
@@ -107,7 +107,7 @@ module BaseTest
|
|
107
107
|
|
108
108
|
def test_configure_metadata_missing_parts_on_other_platforms
|
109
109
|
setup_no_metadata_service_stubs
|
110
|
-
|
110
|
+
Common::Utils::CredentialsInfo.stubs(:project_id).returns(nil)
|
111
111
|
[[CONFIG_MISSING_METADATA_PROJECT_ID, ['project_id'], false],
|
112
112
|
[CONFIG_MISSING_METADATA_ZONE, [], true],
|
113
113
|
[CONFIG_MISSING_METADATA_VM_ID, [], true],
|
data/test/plugin/constants.rb
CHANGED
@@ -45,7 +45,7 @@ end
|
|
45
45
|
|
46
46
|
# Constants used by unit tests for Google Cloud Logging plugin.
|
47
47
|
module Constants
|
48
|
-
include
|
48
|
+
include Common::ServiceConstants
|
49
49
|
include Fluent::GoogleCloudOutput::ConfigConstants
|
50
50
|
include Fluent::GoogleCloudOutput::InternalConstants
|
51
51
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-google-cloud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stackdriver Agents Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-06-
|
11
|
+
date: 2020-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -266,6 +266,7 @@ files:
|
|
266
266
|
- README.rdoc
|
267
267
|
- Rakefile
|
268
268
|
- fluent-plugin-google-cloud.gemspec
|
269
|
+
- lib/fluent/plugin/common.rb
|
269
270
|
- lib/fluent/plugin/filter_add_insert_ids.rb
|
270
271
|
- lib/fluent/plugin/filter_analyze_config.rb
|
271
272
|
- lib/fluent/plugin/in_object_space_dump.rb
|