vmik-fluent-plugin-google-cloud 0.5.5.alpha1
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.
- data/CONTRIBUTING +24 -0
- data/Gemfile +3 -0
- data/LICENSE +201 -0
- data/README.rdoc +46 -0
- data/Rakefile +42 -0
- data/fluent-plugin-google-cloud.gemspec +34 -0
- data/lib/fluent/plugin/out_google_cloud.rb +1184 -0
- data/lib/google/logging/type/http_request_pb.rb +30 -0
- data/lib/google/logging/type/log_severity_pb.rb +26 -0
- data/lib/google/logging/v1/log_entry_pb.rb +52 -0
- data/lib/google/logging/v1/logging_pb.rb +84 -0
- data/lib/google/logging/v1/logging_services_pb.rb +150 -0
- data/test/helper.rb +40 -0
- data/test/plugin/base_test.rb +1534 -0
- data/test/plugin/data/c31e573fd7f62ed495c9ca3821a5a85cb036dee1-privatekey.p12 +0 -0
- data/test/plugin/data/credentials.json +7 -0
- data/test/plugin/data/iam-credentials.json +11 -0
- data/test/plugin/data/invalid_credentials.json +8 -0
- data/test/plugin/test_out_google_cloud.rb +297 -0
- data/test/plugin/test_out_google_cloud_grpc.rb +381 -0
- data/vmik-fluent-plugin-google-cloud-0.5.5.gem +0 -0
- metadata +291 -0
@@ -0,0 +1,381 @@
|
|
1
|
+
# Copyright 2016 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
|
+
require 'grpc'
|
16
|
+
|
17
|
+
require_relative 'base_test'
|
18
|
+
|
19
|
+
# Unit tests for Google Cloud Logging plugin
|
20
|
+
class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
|
21
|
+
include BaseTest
|
22
|
+
|
23
|
+
def test_configure_use_grpc
|
24
|
+
setup_gce_metadata_stubs
|
25
|
+
d = create_driver
|
26
|
+
assert_true d.instance.instance_variable_get(:@use_grpc)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_client_error
|
30
|
+
setup_gce_metadata_stubs
|
31
|
+
{ 8 => 'ResourceExhausted',
|
32
|
+
12 => 'Unimplemented',
|
33
|
+
16 => 'Unauthenticated' }.each_with_index do |(code, message), index|
|
34
|
+
setup_logging_stubs(nil, true, code, message) do
|
35
|
+
d = create_driver(USE_GRPC_CONFIG, 'test',
|
36
|
+
GRPCLoggingMockFailingService.rpc_stub_class)
|
37
|
+
# The API Client should not retry this and the plugin should consume the
|
38
|
+
# exception.
|
39
|
+
d.emit('message' => log_entry(0))
|
40
|
+
d.run
|
41
|
+
end
|
42
|
+
assert_equal 1, @failed_attempts.size, "Index #{index} failed."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_server_error
|
47
|
+
setup_gce_metadata_stubs
|
48
|
+
{ 1 => 'Cancelled',
|
49
|
+
2 => 'Unknown',
|
50
|
+
4 => 'DeadlineExceeded',
|
51
|
+
13 => 'Internal',
|
52
|
+
14 => 'Unavailable' }.each_with_index do |(code, message), index|
|
53
|
+
exception_count = 0
|
54
|
+
setup_logging_stubs(nil, true, code, message) do
|
55
|
+
d = create_driver(USE_GRPC_CONFIG, 'test',
|
56
|
+
GRPCLoggingMockFailingService.rpc_stub_class)
|
57
|
+
# The API client should retry this once, then throw an exception which
|
58
|
+
# gets propagated through the plugin
|
59
|
+
d.emit('message' => log_entry(0))
|
60
|
+
begin
|
61
|
+
d.run
|
62
|
+
rescue GRPC::Cancelled
|
63
|
+
# No need to check the message -- we already know the code.
|
64
|
+
exception_count += 1
|
65
|
+
rescue GRPC::BadStatus => error
|
66
|
+
assert_equal "#{code}:#{message}", error.message
|
67
|
+
exception_count += 1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
assert_equal 1, @failed_attempts.size, "Index #{index} failed."
|
71
|
+
assert_equal 1, exception_count, "Index #{index} failed."
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_http_request_from_record_with_referer_nil
|
76
|
+
setup_gce_metadata_stubs
|
77
|
+
setup_logging_stubs do
|
78
|
+
d = create_driver
|
79
|
+
d.emit('httpRequest' => http_request_message_with_nil_referer)
|
80
|
+
d.run
|
81
|
+
end
|
82
|
+
verify_log_entries(1, COMPUTE_PARAMS, 'httpRequest') do |entry|
|
83
|
+
assert_equal http_request_message_with_absent_referer,
|
84
|
+
entry['httpRequest'], entry
|
85
|
+
assert_nil get_fields(entry['structPayload'])['httpRequest'], entry
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_http_request_from_record_with_referer_absent
|
90
|
+
setup_gce_metadata_stubs
|
91
|
+
setup_logging_stubs do
|
92
|
+
d = create_driver
|
93
|
+
d.emit('httpRequest' => http_request_message_with_absent_referer)
|
94
|
+
d.run
|
95
|
+
end
|
96
|
+
verify_log_entries(1, COMPUTE_PARAMS, 'httpRequest') do |entry|
|
97
|
+
assert_equal http_request_message_with_absent_referer,
|
98
|
+
entry['httpRequest'], entry
|
99
|
+
assert_nil get_fields(entry['structPayload'])['httpRequest'], entry
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# This test looks similar between the grpc and non-grpc paths except that when
|
104
|
+
# parsing "105", the grpc path responds with "DEBUG", while the non-grpc path
|
105
|
+
# responds with "100".
|
106
|
+
#
|
107
|
+
# TODO(lingshi) consolidate the tests between the grpc path and the non-grpc
|
108
|
+
# path, or at least split into two tests, one with string severities and one
|
109
|
+
# with numeric severities.
|
110
|
+
def test_severities
|
111
|
+
setup_gce_metadata_stubs
|
112
|
+
expected_severity = []
|
113
|
+
emit_index = 0
|
114
|
+
setup_logging_stubs do
|
115
|
+
d = create_driver
|
116
|
+
# Array of pairs of [parsed_severity, expected_severity]
|
117
|
+
[%w(INFO INFO), %w(warn WARNING), %w(E ERROR), %w(BLAH DEFAULT),
|
118
|
+
%w(105 DEBUG), ['', 'DEFAULT']].each do |sev|
|
119
|
+
d.emit('message' => log_entry(emit_index), 'severity' => sev[0])
|
120
|
+
expected_severity.push(sev[1])
|
121
|
+
emit_index += 1
|
122
|
+
end
|
123
|
+
d.run
|
124
|
+
end
|
125
|
+
verify_index = 0
|
126
|
+
verify_log_entries(emit_index, COMPUTE_PARAMS) do |entry|
|
127
|
+
assert_equal_with_default(entry['metadata']['severity'],
|
128
|
+
expected_severity[verify_index],
|
129
|
+
'DEFAULT', entry)
|
130
|
+
verify_index += 1
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_struct_payload_non_utf8_log
|
135
|
+
setup_gce_metadata_stubs
|
136
|
+
setup_logging_stubs do
|
137
|
+
d = create_driver
|
138
|
+
d.emit('msg' => log_entry(0),
|
139
|
+
'normal_key' => "test#{non_utf8_character}non utf8",
|
140
|
+
"non_utf8#{non_utf8_character}key" => 5000,
|
141
|
+
'nested_struct' => { "non_utf8#{non_utf8_character}key" => \
|
142
|
+
"test#{non_utf8_character}non utf8" },
|
143
|
+
'null_field' => nil)
|
144
|
+
d.run
|
145
|
+
end
|
146
|
+
verify_log_entries(1, COMPUTE_PARAMS, 'structPayload') do |entry|
|
147
|
+
fields = get_fields(entry['structPayload'])
|
148
|
+
assert_equal 5, fields.size, entry
|
149
|
+
assert_equal 'test log entry 0', get_string(fields['msg']), entry
|
150
|
+
assert_equal 'test non utf8', get_string(fields['normal_key']), entry
|
151
|
+
assert_equal 5000, get_number(fields['non_utf8 key']), entry
|
152
|
+
assert_equal 'test non utf8', get_string(get_fields(get_struct(fields \
|
153
|
+
['nested_struct']))['non_utf8 key']), entry
|
154
|
+
assert_equal null_value, fields['null_field'], entry
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_non_integer_timestamp
|
159
|
+
setup_gce_metadata_stubs
|
160
|
+
time = Time.now
|
161
|
+
{
|
162
|
+
{ 'seconds' => nil, 'nanos' => nil } => nil,
|
163
|
+
{ 'seconds' => nil, 'nanos' => time.tv_nsec } => nil,
|
164
|
+
{ 'seconds' => 'seconds', 'nanos' => time.tv_nsec } => nil,
|
165
|
+
{ 'seconds' => time.tv_sec, 'nanos' => 'nanos' } => \
|
166
|
+
{ 'seconds' => time.tv_sec },
|
167
|
+
{ 'seconds' => time.tv_sec, 'nanos' => nil } => \
|
168
|
+
{ 'seconds' => time.tv_sec }
|
169
|
+
}.each do |input, expected|
|
170
|
+
setup_logging_stubs do
|
171
|
+
d = create_driver
|
172
|
+
@logs_sent = []
|
173
|
+
d.emit('message' => log_entry(0), 'timestamp' => input)
|
174
|
+
d.run
|
175
|
+
end
|
176
|
+
verify_log_entries(1, COMPUTE_PARAMS) do |entry|
|
177
|
+
assert_equal expected, entry['metadata']['timestamp'],
|
178
|
+
"Test with timestamp '#{input}' failed for " \
|
179
|
+
"entry: '#{entry}'."
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
private
|
185
|
+
|
186
|
+
GRPC_MOCK_HOST = 'localhost:56789'
|
187
|
+
|
188
|
+
WriteLogEntriesRequest = Google::Logging::V1::WriteLogEntriesRequest
|
189
|
+
WriteLogEntriesResponse = Google::Logging::V1::WriteLogEntriesResponse
|
190
|
+
|
191
|
+
USE_GRPC_CONFIG = %(
|
192
|
+
use_grpc true
|
193
|
+
)
|
194
|
+
|
195
|
+
# Create a Fluentd output test driver with the Google Cloud Output plugin with
|
196
|
+
# grpc enabled. The signature of this method is different between the grpc
|
197
|
+
# path and the non-grpc path. For grpc, an additional grpc stub class can be
|
198
|
+
# passed in to construct the mock used by the test driver.
|
199
|
+
def create_driver(conf = APPLICATION_DEFAULT_CONFIG, tag = 'test',
|
200
|
+
grpc_stub = GRPCLoggingMockService.rpc_stub_class)
|
201
|
+
conf += USE_GRPC_CONFIG
|
202
|
+
Fluent::Test::BufferedOutputTestDriver.new(
|
203
|
+
GoogleCloudOutputWithGRPCMock.new(grpc_stub), tag).configure(conf, true)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Google Cloud Fluent output stub with grpc mock.
|
207
|
+
class GoogleCloudOutputWithGRPCMock < Fluent::GoogleCloudOutput
|
208
|
+
def initialize(grpc_stub)
|
209
|
+
super()
|
210
|
+
@grpc_stub = grpc_stub
|
211
|
+
end
|
212
|
+
|
213
|
+
def api_client
|
214
|
+
ssl_creds = GRPC::Core::ChannelCredentials.new
|
215
|
+
authentication = Google::Auth.get_application_default
|
216
|
+
creds = GRPC::Core::CallCredentials.new(authentication.updater_proc)
|
217
|
+
ssl_creds.compose(creds)
|
218
|
+
|
219
|
+
# Here we have obtained the creds, but for the mock, we will leave the
|
220
|
+
# channel insecure.
|
221
|
+
@grpc_stub.new(GRPC_MOCK_HOST, :this_channel_is_insecure)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# GRPC logging mock that successfully logs the records.
|
226
|
+
class GRPCLoggingMockService < Google::Logging::V1::LoggingService::Service
|
227
|
+
def initialize(stub_params, requests_received)
|
228
|
+
super()
|
229
|
+
@requests_received = requests_received
|
230
|
+
@expected_log_names = stub_params.map do |param|
|
231
|
+
"projects/#{param[:project_id]}/logs/#{param[:log_name]}"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def write_log_entries(request, _call)
|
236
|
+
fail GRPC::BadStatus.new(99, "Unexpected request: #{request.inspect}") \
|
237
|
+
unless @expected_log_names.include?(request.log_name)
|
238
|
+
@requests_received << request
|
239
|
+
WriteLogEntriesResponse.new
|
240
|
+
end
|
241
|
+
|
242
|
+
# TODO(lingshi) Remove these dummy methods when grpc/9033 is fixed.
|
243
|
+
#
|
244
|
+
# These methods should never be called, so they will just fail the tests
|
245
|
+
# with "unimplemented" errors..
|
246
|
+
def _undefined
|
247
|
+
fail "Method #{__callee__} is unimplemented and needs to be overridden."
|
248
|
+
end
|
249
|
+
|
250
|
+
alias_method :list_logs, :_undefined
|
251
|
+
alias_method :list_log_services, :_undefined
|
252
|
+
alias_method :list_log_service_indexes, :_undefined
|
253
|
+
alias_method :delete_log, :_undefined
|
254
|
+
undef_method :_undefined
|
255
|
+
end
|
256
|
+
|
257
|
+
# GRPC logging mock that fails and returns server side or client side errors.
|
258
|
+
class GRPCLoggingMockFailingService <
|
259
|
+
Google::Logging::V1::LoggingService::Service
|
260
|
+
# 'code_sent' and 'message_sent' are references of external variables. We
|
261
|
+
# will assert the values of them later. 'code_value' and 'message_value'
|
262
|
+
# are actual error code and message we expect this mock to return.
|
263
|
+
def initialize(code, message, failed_attempts)
|
264
|
+
@code = code
|
265
|
+
@message = message
|
266
|
+
@failed_attempts = failed_attempts
|
267
|
+
super()
|
268
|
+
end
|
269
|
+
|
270
|
+
def write_log_entries(_request, _call)
|
271
|
+
@failed_attempts << 1
|
272
|
+
fail GRPC::BadStatus.new(@code, @message)
|
273
|
+
end
|
274
|
+
|
275
|
+
# TODO(lingshi) Remove these dummy methods when grpc/9033 is fixed.
|
276
|
+
#
|
277
|
+
# These methods should never be called, so they will just fail the tests
|
278
|
+
# with "unimplemented" errors..
|
279
|
+
def _undefined
|
280
|
+
fail "Method #{__callee__} is unimplemented and needs to be overridden."
|
281
|
+
end
|
282
|
+
|
283
|
+
alias_method :list_logs, :_undefined
|
284
|
+
alias_method :list_log_services, :_undefined
|
285
|
+
alias_method :list_log_service_indexes, :_undefined
|
286
|
+
alias_method :delete_log, :_undefined
|
287
|
+
undef_method :_undefined
|
288
|
+
end
|
289
|
+
|
290
|
+
# Set up grpc stubs to mock the external calls.
|
291
|
+
def setup_logging_stubs(override_stub_params = nil, should_fail = false,
|
292
|
+
code = 0, message = 'Ok')
|
293
|
+
stub_params = override_stub_params || \
|
294
|
+
[COMPUTE_PARAMS, VMENGINE_PARAMS, CONTAINER_FROM_TAG_PARAMS,
|
295
|
+
CONTAINER_FROM_METADATA_PARAMS, CLOUDFUNCTIONS_PARAMS,
|
296
|
+
CUSTOM_PARAMS, EC2_PARAMS]
|
297
|
+
srv = GRPC::RpcServer.new
|
298
|
+
@failed_attempts = []
|
299
|
+
@requests_sent = []
|
300
|
+
if should_fail
|
301
|
+
grpc = GRPCLoggingMockFailingService.new(code, message, @failed_attempts)
|
302
|
+
else
|
303
|
+
grpc = GRPCLoggingMockService.new(stub_params, @requests_sent)
|
304
|
+
end
|
305
|
+
srv.handle(grpc)
|
306
|
+
srv.add_http2_port(GRPC_MOCK_HOST, :this_port_is_insecure)
|
307
|
+
t = Thread.new { srv.run }
|
308
|
+
srv.wait_till_running
|
309
|
+
begin
|
310
|
+
yield
|
311
|
+
rescue Test::Unit::Failure, StandardError => e
|
312
|
+
srv.stop
|
313
|
+
t.join
|
314
|
+
raise e
|
315
|
+
end
|
316
|
+
srv.stop
|
317
|
+
t.join
|
318
|
+
end
|
319
|
+
|
320
|
+
# Verify the number and the content of the log entries match the expectation.
|
321
|
+
# The caller can optionally provide a block which is called for each entry.
|
322
|
+
def verify_log_entries(n, params, payload_type = 'textPayload', &block)
|
323
|
+
@requests_sent.each do |batch|
|
324
|
+
@logs_sent << JSON.parse(batch.to_json)
|
325
|
+
end
|
326
|
+
verify_json_log_entries(n, params, payload_type, &block)
|
327
|
+
end
|
328
|
+
|
329
|
+
# Use the right single quotation mark as the sample non-utf8 character.
|
330
|
+
def non_utf8_character
|
331
|
+
[0x92].pack('C*')
|
332
|
+
end
|
333
|
+
|
334
|
+
# For an optional field with default values, Protobuf omits the field when it
|
335
|
+
# is deserialized to json. So we need to add an extra check for gRPC which
|
336
|
+
# uses Protobuf.
|
337
|
+
#
|
338
|
+
# An optional block can be passed in if we need to assert something other than
|
339
|
+
# a plain equal. e.g. assert_in_delta.
|
340
|
+
def assert_equal_with_default(field, expected_value, default_value, entry)
|
341
|
+
if expected_value == default_value
|
342
|
+
assert_nil field
|
343
|
+
elsif block_given?
|
344
|
+
yield
|
345
|
+
else
|
346
|
+
assert_equal expected_value, field, entry
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
# Unset the 'referer' field.
|
351
|
+
def http_request_message_with_absent_referer
|
352
|
+
http_request_message.reject do |k, _|
|
353
|
+
k == 'referer'
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
# Get the fields of the struct payload.
|
358
|
+
def get_fields(struct_payload)
|
359
|
+
struct_payload['fields']
|
360
|
+
end
|
361
|
+
|
362
|
+
# Get the value of a struct field.
|
363
|
+
def get_struct(field)
|
364
|
+
field['structValue']
|
365
|
+
end
|
366
|
+
|
367
|
+
# Get the value of a string field.
|
368
|
+
def get_string(field)
|
369
|
+
field['stringValue']
|
370
|
+
end
|
371
|
+
|
372
|
+
# Get the value of a number field.
|
373
|
+
def get_number(field)
|
374
|
+
field['numberValue']
|
375
|
+
end
|
376
|
+
|
377
|
+
# The null value.
|
378
|
+
def null_value
|
379
|
+
{ 'nullValue' => 'NULL_VALUE' }
|
380
|
+
end
|
381
|
+
end
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vmik-fluent-plugin-google-cloud
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.5.alpha1
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Todd Derr
|
9
|
+
- Alex Robinson
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2017-02-15 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: fluentd
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0.12'
|
23
|
+
- - <
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 0.15.0
|
26
|
+
type: :runtime
|
27
|
+
prerelease: false
|
28
|
+
version_requirements: !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.12'
|
34
|
+
- - <
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.15.0
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: googleapis-common-protos
|
39
|
+
requirement: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '1.3'
|
45
|
+
- - <
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.4'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.3'
|
56
|
+
- - <
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '1.4'
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: google-api-client
|
61
|
+
requirement: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 0.9.0
|
67
|
+
- - <
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.10.0
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.9.0
|
78
|
+
- - <
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 0.10.0
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: googleauth
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ~>
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0.5'
|
89
|
+
- - <
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0.6'
|
92
|
+
type: :runtime
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ~>
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0.5'
|
100
|
+
- - <
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0.6'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: grpc
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.1.0
|
111
|
+
- - <
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: 1.2.0
|
114
|
+
type: :runtime
|
115
|
+
prerelease: false
|
116
|
+
version_requirements: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ~>
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: 1.1.0
|
122
|
+
- - <
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.2.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: json
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ~>
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '1.8'
|
133
|
+
- - <
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '1.9'
|
136
|
+
type: :runtime
|
137
|
+
prerelease: false
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ~>
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '1.8'
|
144
|
+
- - <
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '1.9'
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
name: mocha
|
149
|
+
requirement: !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
151
|
+
requirements:
|
152
|
+
- - ~>
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '1.1'
|
155
|
+
type: :development
|
156
|
+
prerelease: false
|
157
|
+
version_requirements: !ruby/object:Gem::Requirement
|
158
|
+
none: false
|
159
|
+
requirements:
|
160
|
+
- - ~>
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '1.1'
|
163
|
+
- !ruby/object:Gem::Dependency
|
164
|
+
name: rake
|
165
|
+
requirement: !ruby/object:Gem::Requirement
|
166
|
+
none: false
|
167
|
+
requirements:
|
168
|
+
- - ~>
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '10.3'
|
171
|
+
type: :development
|
172
|
+
prerelease: false
|
173
|
+
version_requirements: !ruby/object:Gem::Requirement
|
174
|
+
none: false
|
175
|
+
requirements:
|
176
|
+
- - ~>
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '10.3'
|
179
|
+
- !ruby/object:Gem::Dependency
|
180
|
+
name: rubocop
|
181
|
+
requirement: !ruby/object:Gem::Requirement
|
182
|
+
none: false
|
183
|
+
requirements:
|
184
|
+
- - ~>
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: 0.35.0
|
187
|
+
type: :development
|
188
|
+
prerelease: false
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
190
|
+
none: false
|
191
|
+
requirements:
|
192
|
+
- - ~>
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: 0.35.0
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: webmock
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
none: false
|
199
|
+
requirements:
|
200
|
+
- - ~>
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '1.17'
|
203
|
+
type: :development
|
204
|
+
prerelease: false
|
205
|
+
version_requirements: !ruby/object:Gem::Requirement
|
206
|
+
none: false
|
207
|
+
requirements:
|
208
|
+
- - ~>
|
209
|
+
- !ruby/object:Gem::Version
|
210
|
+
version: '1.17'
|
211
|
+
- !ruby/object:Gem::Dependency
|
212
|
+
name: test-unit
|
213
|
+
requirement: !ruby/object:Gem::Requirement
|
214
|
+
none: false
|
215
|
+
requirements:
|
216
|
+
- - ~>
|
217
|
+
- !ruby/object:Gem::Version
|
218
|
+
version: '3.0'
|
219
|
+
type: :development
|
220
|
+
prerelease: false
|
221
|
+
version_requirements: !ruby/object:Gem::Requirement
|
222
|
+
none: false
|
223
|
+
requirements:
|
224
|
+
- - ~>
|
225
|
+
- !ruby/object:Gem::Version
|
226
|
+
version: '3.0'
|
227
|
+
description: ! " Fluentd output plugin for the Stackdriver Logging API, which will
|
228
|
+
make\n logs viewable in the Developer Console's log viewer and can optionally\n
|
229
|
+
\ store them in Google Cloud Storage and/or BigQuery.\n This is an official Google
|
230
|
+
Ruby gem.\n"
|
231
|
+
email:
|
232
|
+
- salty@google.com
|
233
|
+
executables: []
|
234
|
+
extensions: []
|
235
|
+
extra_rdoc_files: []
|
236
|
+
files:
|
237
|
+
- fluent-plugin-google-cloud.gemspec
|
238
|
+
- README.rdoc
|
239
|
+
- Gemfile
|
240
|
+
- vmik-fluent-plugin-google-cloud-0.5.5.gem
|
241
|
+
- LICENSE
|
242
|
+
- CONTRIBUTING
|
243
|
+
- test/helper.rb
|
244
|
+
- test/plugin/base_test.rb
|
245
|
+
- test/plugin/data/iam-credentials.json
|
246
|
+
- test/plugin/data/credentials.json
|
247
|
+
- test/plugin/data/c31e573fd7f62ed495c9ca3821a5a85cb036dee1-privatekey.p12
|
248
|
+
- test/plugin/data/invalid_credentials.json
|
249
|
+
- test/plugin/test_out_google_cloud.rb
|
250
|
+
- test/plugin/test_out_google_cloud_grpc.rb
|
251
|
+
- Rakefile
|
252
|
+
- lib/fluent/plugin/out_google_cloud.rb
|
253
|
+
- lib/google/logging/v1/log_entry_pb.rb
|
254
|
+
- lib/google/logging/v1/logging_pb.rb
|
255
|
+
- lib/google/logging/v1/logging_services_pb.rb
|
256
|
+
- lib/google/logging/type/http_request_pb.rb
|
257
|
+
- lib/google/logging/type/log_severity_pb.rb
|
258
|
+
homepage: https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud
|
259
|
+
licenses:
|
260
|
+
- Apache-2.0
|
261
|
+
post_install_message:
|
262
|
+
rdoc_options: []
|
263
|
+
require_paths:
|
264
|
+
- lib
|
265
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
266
|
+
none: false
|
267
|
+
requirements:
|
268
|
+
- - ! '>='
|
269
|
+
- !ruby/object:Gem::Version
|
270
|
+
version: '2.0'
|
271
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
272
|
+
none: false
|
273
|
+
requirements:
|
274
|
+
- - ! '>'
|
275
|
+
- !ruby/object:Gem::Version
|
276
|
+
version: 1.3.1
|
277
|
+
requirements: []
|
278
|
+
rubyforge_project:
|
279
|
+
rubygems_version: 1.8.23
|
280
|
+
signing_key:
|
281
|
+
specification_version: 3
|
282
|
+
summary: fluentd output plugin for the Stackdriver Logging API
|
283
|
+
test_files:
|
284
|
+
- test/helper.rb
|
285
|
+
- test/plugin/base_test.rb
|
286
|
+
- test/plugin/data/iam-credentials.json
|
287
|
+
- test/plugin/data/credentials.json
|
288
|
+
- test/plugin/data/c31e573fd7f62ed495c9ca3821a5a85cb036dee1-privatekey.p12
|
289
|
+
- test/plugin/data/invalid_credentials.json
|
290
|
+
- test/plugin/test_out_google_cloud.rb
|
291
|
+
- test/plugin/test_out_google_cloud_grpc.rb
|