fluent-plugin-gcs-dustinblackman 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b09761a8c8b6e1bc2a128e091de242b2b50b5b9e
4
+ data.tar.gz: d970e3a6c4854c3fcb3501b57f3df3cc7f5de9c8
5
+ SHA512:
6
+ metadata.gz: e6804b62ea895dbe59deb47d541a0d5fe4cdf5336b47da835fb6c33d46ebb4147589bf3e630a2f42ef904d13a9c2fa6dd7f8f10a447741a5336984cd04e0c6ac
7
+ data.tar.gz: e3d24d69c58bff260a85ee5c0515fb56c918fc6c90c865caf841a376da2d6d9746da71443bcd432340dd75766e6fe882db82ecc1421e71bd32c246c91e351024
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.1
5
+ - 2.2
6
+ - 2.3.0
7
+
8
+ before_install:
9
+ - gem update bundler
10
+
11
+ script: bundle exec rake test
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ ## ChangeLog
2
+
3
+ ### Release 0.3.0 - 2017/02/28
4
+
5
+ - Add support for setting a File's storage_class on file creation
6
+ - see also https://cloud.google.com/storage/docs/storage-classes
7
+
8
+ ### Release 0.2.0 - 2017/01/16
9
+
10
+ - Remove encryption_key_sha256 parameter.
11
+ - see also. https://github.com/GoogleCloudPlatform/google-cloud-ruby/blob/master/google-cloud-storage/CHANGELOG.md#0230--2016-12-8
12
+
13
+ ### Release 0.1.1 - 2016/11/28
14
+
15
+ - Add support for `%{hostname}` of object_key_format
16
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-gcs-dustinblackman.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2016 - Daichi HIRATA
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.
data/README.md ADDED
@@ -0,0 +1,211 @@
1
+ # fluent-plugin-gcs
2
+ [![Gem Version](https://badge.fury.io/rb/fluent-plugin-gcs.svg)](https://badge.fury.io/rb/fluent-plugin-gcs) [![Build Status](https://travis-ci.org/daichirata/fluent-plugin-gcs.svg?branch=master)](https://travis-ci.org/daichirata/fluent-plugin-gcs) [![Code Climate](https://codeclimate.com/github/daichirata/fluent-plugin-gcs/badges/gpa.svg)](https://codeclimate.com/github/daichirata/fluent-plugin-gcs)
3
+
4
+ Google Cloud Storage output plugin for [Fluentd](https://github.com/fluent/fluentd).
5
+
6
+ ## Installation
7
+
8
+ ``` shell
9
+ gem install fluent-plugin-gcs
10
+ ```
11
+
12
+ ## Examples
13
+
14
+ ```
15
+ <match pattern>
16
+ @type gcs
17
+
18
+ project YOUR_PROJECT
19
+ keyfile YOUR_KEYFILE_PATH
20
+ bucket YOUR_GCS_BUCKET_NAME
21
+ object_key_format %{path}%{time_slice}_%{index}.%{file_extension}
22
+ path logs/
23
+ buffer_path /var/log/fluent/gcs
24
+
25
+ time_slice_format %Y%m%d-%H
26
+ time_slice_wait 10m
27
+ utc
28
+ </match>
29
+ ```
30
+
31
+ ## Configuration
32
+
33
+ ### Authentication
34
+
35
+ You can provide the project and credential information to connect to the Storage
36
+ service, or if you are running on Google Compute Engine this configuration is taken care of for you.
37
+
38
+ **project**
39
+
40
+ Project identifier for GCS. Project are discovered in the following order:
41
+ * Specify project in `project`
42
+ * Discover project in environment variables `STORAGE_PROJECT`, `GOOGLE_CLOUD_PROJECT`, `GCLOUD_PROJECT`
43
+ * Discover GCE credentials
44
+
45
+ **keyfile**
46
+
47
+ Path of GCS service account credentials JSON file. Credentials are discovered in the following order:
48
+ * Specify credentials path in `keyfile`
49
+ * Discover credentials path in environment variables `GOOGLE_CLOUD_KEYFILE`, `GCLOUD_KEYFILE`
50
+ * Discover credentials JSON in environment variables `GOOGLE_CLOUD_KEYFILE_JSON`, `GCLOUD_KEYFILE_JSON`
51
+ * Discover credentials file in the Cloud SDK's path
52
+ * Discover GCE credentials
53
+
54
+ **client_retries**
55
+
56
+ Number of times to retry requests on server error.
57
+
58
+ **client_timeout**
59
+
60
+ Default timeout to use in requests.
61
+
62
+ **bucket (*required)**
63
+
64
+ GCS bucket name.
65
+
66
+ **store_as**
67
+
68
+ Archive format on GCS. You can use serveral format:
69
+
70
+ * gzip (default)
71
+ * json
72
+ * text
73
+
74
+ **path**
75
+
76
+ path prefix of the files on GCS. Default is "" (no prefix).
77
+
78
+ **object_key_format**
79
+
80
+ The format of GCS object keys. You can use several built-in variables:
81
+
82
+ * %{path}
83
+ * %{time_slice}
84
+ * %{index}
85
+ * %{file_extension}
86
+ * %{uuid_flush}
87
+ * %{hex_random}
88
+ * %{hostname}
89
+
90
+ to decide keys dynamically.
91
+
92
+ * `%{path}` is exactly the value of `path` configured in the configuration file. E.g., "logs/" in the example configuration above.
93
+ * `%{time_slice}` is the time-slice in text that are formatted with `time_slice_format`.
94
+ * `%{index}` is the sequential number starts from 0, increments when multiple files are uploaded to GCS in the same time slice.
95
+ * `%{file_extention}` is changed by the value of `store_as`.
96
+ * gzip - gz
97
+ * json - json
98
+ * text - txt
99
+ * `%{uuid_flush}` a uuid that is replaced everytime the buffer will be flushed
100
+ * `%{hex_random}` a random hex string that is replaced for each buffer chunk, not assured to be unique. You can configure the length of string with a `hex_random_length` parameter (Default: 4).
101
+ * `%{hostname}` is set to the standard host name of the system of the running server.
102
+
103
+ The default format is `%{path}%{time_slice}_%{index}.%{file_extension}`.
104
+
105
+ **hex_random_length**
106
+
107
+ The length of `%{hex_random}` placeholder.
108
+
109
+ **transcoding**
110
+
111
+ Enable the decompressive form of transcoding.
112
+
113
+ See also [Transcoding of gzip-compressed files](https://cloud.google.com/storage/docs/transcoding).
114
+
115
+ **format**
116
+
117
+ Change one line format in the GCS object. You can use serveral format:
118
+
119
+ * out_file (default)
120
+ * json
121
+ * ltsv
122
+ * single_value
123
+
124
+ See also [official Formatter article](http://docs.fluentd.org/articles/formatter-plugin-overview).
125
+
126
+ **auto_create_bucket**
127
+
128
+ Create GCS bucket if it does not exists. Default is true.
129
+
130
+ **acl**
131
+
132
+ Permission for the object in GCS. Acceptable values are:
133
+
134
+ * `auth_read` - File owner gets OWNER access, and allAuthenticatedUsers get READER access.
135
+ * `owner_full` - File owner gets OWNER access, and project team owners get OWNER access.
136
+ * `owner_read` - File owner gets OWNER access, and project team owners get READER access.
137
+ * `private` - File owner gets OWNER access.
138
+ * `project_private` - File owner gets OWNER access, and project team members get access according to their roles.
139
+ * `public_read` - File owner gets OWNER access, and allUsers get READER access.
140
+
141
+ Default is nil (bucket default object ACL). See also [official document](https://cloud.google.com/storage/docs/access-control/lists).
142
+
143
+ **storage_class**
144
+
145
+ Storage class of the file. Acceptable values are:
146
+
147
+ * `dra` - Durable Reduced Availability
148
+ * `nearline` - Nearline Storage
149
+ * `coldline` - Coldline Storage
150
+ * `multi_regional` - Multi-Regional Storage
151
+ * `regional` - Regional Storage
152
+ * `standard` - Standard Storage
153
+
154
+ Default is nil. See also [official document](https://cloud.google.com/storage/docs/storage-classes).
155
+
156
+ **encryption_key**
157
+
158
+ You can also choose to provide your own AES-256 key for server-side encryption. See also [Customer-supplied encryption keys](https://cloud.google.com/storage/docs/encryption#customer-supplied).
159
+
160
+ `encryption_key_sha256` will be calculated using encryption_key.
161
+
162
+ **overwrite**
163
+
164
+ Overwrite already existing path. Default is false, which raises an error
165
+ if a GCS object of the same path already exists, or increment the
166
+ `%{index}` placeholder until finding an absent path.
167
+
168
+ **buffer_path (*required)**
169
+
170
+ path prefix of the files to buffer logs.
171
+
172
+ **time_slice_format**
173
+
174
+ Format of the time used as the file name. Default is '%Y%m%d'. Use
175
+ '%Y%m%d%H' to split files hourly.
176
+
177
+ **time_slice_wait**
178
+
179
+ The time to wait old logs. Default is 10 minutes. Specify larger value if
180
+ old logs may reache.
181
+
182
+ **localtime**
183
+
184
+ Use Local time instead of UTC.
185
+
186
+ **utc**
187
+
188
+ Use UTC instead of local time.
189
+
190
+
191
+ And see [official Time Sliced Output article](http://docs.fluentd.org/articles/output-plugin-overview#time-sliced-output-parameters)
192
+
193
+ ### ObjectMetadata
194
+
195
+ User provided web-safe keys and arbitrary string values that will returned with requests for the file as "x-goog-meta-" response headers.
196
+
197
+ ```
198
+ <match *>
199
+ @type gcs
200
+
201
+ <object_metadata>
202
+ key KEY_DATA_1
203
+ value VALUE_DATA_1
204
+ </object_metadata>
205
+
206
+ <object_metadata>
207
+ key KEY_DATA_2
208
+ value VALUE_DATA_2
209
+ </object_metadata>
210
+ </match>
211
+ ```
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rake/testtask"
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << "lib" << "test"
7
+ test.test_files = FileList["test/plugin/test_*.rb"]
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => [:test]
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "fluent/plugin/gcs"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fluent/plugin/gcs/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fluent-plugin-gcs-dustinblackman"
8
+ spec.version = Fluent::GCSPlugin::VERSION
9
+ spec.authors = ["Daichi HIRATA"]
10
+ spec.email = ["hirata.daichi@gmail.com"]
11
+ spec.summary = "Google Cloud Storage output plugin for Fluentd"
12
+ spec.description = "Google Cloud Storage output plugin for Fluentd"
13
+ spec.homepage = "https://github.com/dustinblackman/fluent-plugin-gcs"
14
+ spec.license = "Apache-2.0"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_runtime_dependency "fluentd", "~> 0.14.0"
24
+ spec.add_runtime_dependency "google-cloud-storage", "~> 0.23.2"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.13"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rr", "= 1.1.2"
29
+ spec.add_development_dependency "test-unit", ">= 3.0.8"
30
+ spec.add_development_dependency "test-unit-rr", ">= 1.0.3"
31
+ spec.add_development_dependency "timecop"
32
+ end
@@ -0,0 +1,92 @@
1
+ require "tempfile"
2
+ require "zlib"
3
+
4
+ module Fluent
5
+ module GCS
6
+ def self.discovered_object_creator(store_as, transcoding: nil)
7
+ case store_as
8
+ when :gzip
9
+ Fluent::GCS::GZipObjectCreator.new(transcoding)
10
+ when :json
11
+ Fluent::GCS::JSONObjectCreator.new
12
+ when :text
13
+ Fluent::GCS::TextObjectCreator.new
14
+ end
15
+ end
16
+
17
+ class ObjectCreator
18
+ def content_type
19
+ raise NotImplementedError
20
+ end
21
+
22
+ def content_encoding
23
+ nil
24
+ end
25
+
26
+ def file_extension
27
+ raise NotImplementedError
28
+ end
29
+
30
+ def write(chunk, io)
31
+ raise NotImplementedError
32
+ end
33
+
34
+ def create(chunk, &block)
35
+ Tempfile.create("fluent-plugin-gcs") do |f|
36
+ f.binmode
37
+ f.sync = true
38
+ write(chunk, f)
39
+ block.call(f)
40
+ end
41
+ end
42
+ end
43
+
44
+ class GZipObjectCreator < ObjectCreator
45
+ def initialize(transcoding)
46
+ @transcoding = transcoding
47
+ end
48
+
49
+ def content_type
50
+ @transcoding ? "text/plain" : "application/gzip"
51
+ end
52
+
53
+ def content_encoding
54
+ @transcoding ? "gzip" : nil
55
+ end
56
+
57
+ def file_extension
58
+ "gz"
59
+ end
60
+
61
+ def write(chunk, io)
62
+ writer = Zlib::GzipWriter.new(io)
63
+ chunk.write_to(writer)
64
+ writer.finish
65
+ end
66
+ end
67
+
68
+ class TextObjectCreator < ObjectCreator
69
+ def content_type
70
+ "text/plain"
71
+ end
72
+
73
+ def file_extension
74
+ "txt"
75
+ end
76
+
77
+ def write(chunk, io)
78
+ chunk.write_to(io)
79
+ end
80
+ end
81
+
82
+ class JSONObjectCreator < TextObjectCreator
83
+ def content_type
84
+ "application/json"
85
+ end
86
+
87
+ def file_extension
88
+ "json"
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,5 @@
1
+ module Fluent
2
+ module GCSPlugin
3
+ VERSION = "0.3.0"
4
+ end
5
+ end
@@ -0,0 +1,157 @@
1
+ require "digest/md5"
2
+ require "securerandom"
3
+ require "socket"
4
+
5
+ require "fluent/plugin/gcs/object_creator"
6
+ require "fluent/plugin/gcs/version"
7
+
8
+ module Fluent
9
+ class GCSOutput < TimeSlicedOutput
10
+ Fluent::Plugin.register_output("gcs", self)
11
+
12
+ def initialize
13
+ super
14
+ require "google/cloud/storage"
15
+ end
16
+
17
+ config_param :project, :string, default: nil,
18
+ desc: "Project identifier for GCS"
19
+ config_param :keyfile, :string, default: nil,
20
+ desc: "Path of GCS service account credentials JSON file"
21
+ config_param :client_retries, :integer, default: nil,
22
+ desc: "Number of times to retry requests on server error"
23
+ config_param :client_timeout, :integer, default: nil,
24
+ desc: "Default timeout to use in requests"
25
+ config_param :bucket, :string,
26
+ desc: "Name of a GCS bucket"
27
+ config_param :object_key_format, :string, default: "%{path}%{time_slice}_%{index}.%{file_extension}",
28
+ desc: "Format of GCS object keys"
29
+ config_param :path, :string, default: "",
30
+ desc: "Path prefix of the files on GCS"
31
+ config_param :store_as, :enum, list: %i(gzip json text), default: :gzip,
32
+ desc: "Archive format on GCS"
33
+ config_param :transcoding, :bool, default: false,
34
+ desc: "Enable the decompressive form of transcoding"
35
+ config_param :auto_create_bucket, :bool, default: true,
36
+ desc: "Create GCS bucket if it does not exists"
37
+ config_param :hex_random_length, :integer, default: 4,
38
+ desc: "Max length of `%{hex_random}` placeholder(4-16)"
39
+ config_param :overwrite, :bool, default: false,
40
+ desc: "Overwrite already existing path"
41
+ config_param :format, :string, default: "out_file",
42
+ desc: "Change one line format in the GCS object"
43
+ config_param :acl, :enum, list: %i(auth_read owner_full owner_read private project_private public_read), default: nil,
44
+ desc: "Permission for the object in GCS"
45
+ config_param :storage_class, :enum, list: %i(dra nearline coldline multi_regional regional standard), default: nil,
46
+ desc: "Storage class of the file"
47
+ config_param :encryption_key, :string, default: nil, secret: true,
48
+ desc: "Customer-supplied, AES-256 encryption key"
49
+ config_section :object_metadata, required: false do
50
+ config_param :key, :string, default: ""
51
+ config_param :value, :string, default: ""
52
+ end
53
+
54
+ MAX_HEX_RANDOM_LENGTH = 32
55
+
56
+ def configure(conf)
57
+ super
58
+
59
+ if @hex_random_length > MAX_HEX_RANDOM_LENGTH
60
+ raise Fluent::ConfigError, "hex_random_length parameter should be set to #{MAX_HEX_RANDOM_LENGTH} characters or less."
61
+ end
62
+
63
+ # The customer-supplied, AES-256 encryption key that will be used to encrypt the file.
64
+ @encryption_opts = {
65
+ encryption_key: @encryption_key,
66
+ }
67
+
68
+ if @object_metadata
69
+ @object_metadata_hash = @object_metadata.map {|m| [m.key, m.value] }.to_h
70
+ end
71
+
72
+ @formatter = Fluent::Plugin.new_formatter(@format)
73
+ @formatter.configure(conf)
74
+
75
+ @object_creator = Fluent::GCS.discovered_object_creator(@store_as, transcoding: @transcoding)
76
+ end
77
+
78
+ def start
79
+ @gcs = Google::Cloud::Storage.new(
80
+ project: @project,
81
+ keyfile: @keyfile,
82
+ retries: @client_retries,
83
+ timeout: @client_timeout
84
+ )
85
+ @gcs_bucket = @gcs.bucket(@bucket)
86
+
87
+ ensure_bucket
88
+ super
89
+ end
90
+
91
+ def format(tag, time, record)
92
+ @formatter.format(tag, time, record)
93
+ end
94
+
95
+ def write(chunk)
96
+ path = generate_path(chunk)
97
+
98
+ @object_creator.create(chunk) do |obj|
99
+ opts = {
100
+ metadata: @object_metadata_hash,
101
+ acl: @acl,
102
+ storage_class: @storage_class,
103
+ content_type: @object_creator.content_type,
104
+ content_encoding: @object_creator.content_encoding,
105
+ }
106
+ opts.merge!(@encryption_opts)
107
+
108
+ log.debug { "out_gcs: upload chunk:#{chunk.key} to gcs://#{@bucket}/#{path} options: #{opts}" }
109
+ @gcs_bucket.upload_file(obj.path, path, opts)
110
+ end
111
+ end
112
+
113
+ private
114
+
115
+ def ensure_bucket
116
+ return unless @gcs_bucket.nil?
117
+
118
+ if !@auto_create_bucket
119
+ raise "bucket `#{@bucket}` does not exist"
120
+ end
121
+ log.info "creating bucket `#{@bucket}`"
122
+ @gcs_bucket = @gcs.create_bucket(@bucket)
123
+ end
124
+
125
+ def hex_random(chunk)
126
+ Digest::MD5.hexdigest(chunk.unique_id)[0...@hex_random_length]
127
+ end
128
+
129
+ def format_path(chunk)
130
+ now = Time.strptime(chunk.key, @time_slice_format)
131
+ (@localtime ? now : now.utc).strftime(@path)
132
+ end
133
+
134
+ def generate_path(chunk, i = 0, prev = nil)
135
+ tags = {
136
+ "%{file_extension}" => @object_creator.file_extension,
137
+ "%{hex_random}" => hex_random(chunk),
138
+ "%{hostname}" => Socket.gethostname,
139
+ "%{index}" => i,
140
+ "%{path}" => format_path(chunk),
141
+ "%{time_slice}" => chunk.key,
142
+ "%{uuid_flush}" => SecureRandom.uuid,
143
+ }
144
+ path = @object_key_format.gsub(Regexp.union(tags.keys), tags)
145
+ return path unless @gcs_bucket.find_file(path, @encryption_opts)
146
+
147
+ if path == prev
148
+ if @overwrite
149
+ log.warn "object `#{path}` already exists but overwrites it"
150
+ return path
151
+ end
152
+ raise "object `#{path}` already exists"
153
+ end
154
+ generate_path(chunk, i + 1, path)
155
+ end
156
+ end
157
+ end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-gcs-dustinblackman
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Daichi HIRATA
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.14.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.14.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: google-cloud-storage
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.23.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.23.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.13'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.13'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rr
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 1.1.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 1.1.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: test-unit
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 3.0.8
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 3.0.8
97
+ - !ruby/object:Gem::Dependency
98
+ name: test-unit-rr
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 1.0.3
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 1.0.3
111
+ - !ruby/object:Gem::Dependency
112
+ name: timecop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: Google Cloud Storage output plugin for Fluentd
126
+ email:
127
+ - hirata.daichi@gmail.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".travis.yml"
134
+ - CHANGELOG.md
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - bin/console
140
+ - bin/setup
141
+ - fluent-plugin-gcs.gemspec
142
+ - lib/fluent/plugin/gcs/object_creator.rb
143
+ - lib/fluent/plugin/gcs/version.rb
144
+ - lib/fluent/plugin/out_gcs.rb
145
+ homepage: https://github.com/dustinblackman/fluent-plugin-gcs
146
+ licenses:
147
+ - Apache-2.0
148
+ metadata: {}
149
+ post_install_message:
150
+ rdoc_options: []
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ requirements: []
164
+ rubyforge_project:
165
+ rubygems_version: 2.4.5.1
166
+ signing_key:
167
+ specification_version: 4
168
+ summary: Google Cloud Storage output plugin for Fluentd
169
+ test_files: []