fluent-plugin-azurestorage 0.0.1

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: 173125873d3f72fb76b104b180df63b23472c02d
4
+ data.tar.gz: 4895ded3228acfb7c5e3e6458f9cc081c0ce69da
5
+ SHA512:
6
+ metadata.gz: 87d07b8903865caccf0e90833cbbc5edf9fb4ac81bcf453e526d9b3555a0c92af0aff6abee645abdab4789ecdd98ede4cfcaddc0c53e1b0eadb6c905f71585e8
7
+ data.tar.gz: 12b97072aa1633a683b7061212f6ac7a7c3c30c5374f9068edac973ab4972cbb086f4397c58e35a95d2dbf26ff20febd883f8ec0d91d8e181505c1a296fb17c7
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-azurestorage.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Hidemasa Togashi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # Azure Storage output plugin for Fluentd
2
+
3
+ ## Overview
4
+
5
+ Azure Storate output plugin buffers logs in local file and upload them to Azure Storage periodically.
6
+ This plugin is porting from [fluent-plugin-s3](https://github.com/fluent/fluent-plugin-s3) for AzureStorage.
7
+
8
+ ## Installation
9
+
10
+ Install from RubyGems:
11
+ ```
12
+ $ gem install fluent-plugin-azurestorage
13
+ ```
14
+
15
+ ## Configuration
16
+
17
+ ```
18
+ <match pattern>
19
+ type azurestorage
20
+
21
+ azure_storage_account <your azure storage account>
22
+ azure_storage_access_key <your azure storage access key>
23
+ azure_container <your azure storage container>
24
+ azure_storage_type blob
25
+ store_as gzip
26
+ auto_create_container true
27
+ path logs/
28
+ azure_object_key_format %{path}%{time_slice}_%{index}.%{file_extension}
29
+ buffer_path /var/log/fluent/azurestorage
30
+
31
+ time_slice_format %Y%m%d-%H
32
+ time_slice_wait 10m
33
+ utc
34
+ </match>
35
+ ```
36
+
37
+ ### azure_storage_account
38
+
39
+ Your Azure Storage Account Name. This can be got from Azure Management potal.
40
+ This parameter is required when environment variable 'AZURE_STORAGE_ACCOUNT' is not set.
41
+
42
+ ### azure_storage_access_key
43
+
44
+ Your Azure Storage Access Key(Primary or Secondary). This also can be got from Azure Management potal.
45
+ This parameter is required when environment variable 'AZURE_STORAGE_ACCESS_KEY' is not set.
46
+
47
+ ### azure_container (Required)
48
+
49
+ Azure Storage Container name
50
+
51
+ ### auto_create_container
52
+
53
+ This plugin create container if not exist when you set 'auto_create_container' to true.
54
+
55
+ ### azure_storage_type
56
+
57
+ Azure Storage type. Now supports only 'blob'(default). 'tables' and 'queues' are not implemented.
58
+
59
+ ### azure_object_key_format
60
+
61
+ The format of Azure Storage object keys. You can use several built-in variables:
62
+
63
+ - %{path}
64
+ - %{time_slice}
65
+ - %{index}
66
+ - %{file_extension}
67
+
68
+ to decide keys dynamically.
69
+
70
+ %{path} is exactly the value of *path* configured in the configuration file. E.g., "logs/" in the example configuration above.
71
+ %{time_slice} is the time-slice in text that are formatted with *time_slice_format*.
72
+ %{index} is the sequential number starts from 0, increments when multiple files are uploaded to Azure Storage in the same time slice.
73
+ %{file_extention} is always "gz" for now.
74
+
75
+ The default format is "%{path}%{time_slice}_%{index}.%{file_extension}".
76
+
77
+ For instance, using the example configuration above, actual object keys on Azure Storage will be something like:
78
+
79
+ ```
80
+ "logs/20130111-22_0.gz"
81
+ "logs/20130111-23_0.gz"
82
+ "logs/20130111-23_1.gz"
83
+ "logs/20130112-00_0.gz"
84
+ ```
85
+
86
+ With the configuration:
87
+
88
+ ```
89
+ azure_object_key_format %{path}/events/ts=%{time_slice}/events_%{index}.%{file_extension}
90
+ path log
91
+ time_slice_format %Y%m%d-%H
92
+ ```
93
+
94
+ You get:
95
+
96
+ ```
97
+ "log/events/ts=20130111-22/events_0.gz"
98
+ "log/events/ts=20130111-23/events_0.gz"
99
+ "log/events/ts=20130111-23/events_1.gz"
100
+ "log/events/ts=20130112-00/events_0.gz"
101
+ ```
102
+
103
+ The [fluent-mixin-config-placeholders](https://github.com/tagomoris/fluent-mixin-config-placeholders) mixin is also incorporated, so additional variables such as %{hostname}, %{uuid}, etc. can be used in the azure_object_key_format. This could prove useful in preventing filename conflicts when writing from multiple servers.
104
+
105
+ ```
106
+ azure_object_key_format %{path}/events/ts=%{time_slice}/events_%{index}-%{hostname}.%{file_extension}
107
+ ```
108
+
109
+ ### store_as
110
+
111
+ Archive format on Azure Storage. You can use following types:
112
+
113
+ - gzip (default)
114
+ - json
115
+ - text
116
+ - lzo (Need lzop command)
117
+ - lzma2 (Need xz command)
118
+
119
+ ### format
120
+
121
+ Change one line format in the Azure Storage object. Supported formats are 'out_file', 'json', 'ltsv' and 'single_value'.
122
+
123
+ - out_file (default)
124
+
125
+ ```
126
+ time\ttag\t{..json1..}
127
+ time\ttag\t{..json2..}
128
+ ...
129
+ ```
130
+
131
+ - json
132
+
133
+ ```
134
+ {..json1..}
135
+ {..json2..}
136
+ ...
137
+ ```
138
+
139
+ At this format, "time" and "tag" are omitted.
140
+ But you can set these information to the record by setting "include_tag_key" / "tag_key" and "include_time_key" / "time_key" option.
141
+ If you set following configuration in AzureStorage output:
142
+
143
+ ```
144
+ format json
145
+ include_time_key true
146
+ time_key log_time # default is time
147
+ ```
148
+
149
+ then the record has log_time field.
150
+
151
+ ```
152
+ {"log_time":"time string",...}
153
+ ```
154
+
155
+ - ltsv
156
+
157
+ ```
158
+ key1:value1\tkey2:value2
159
+ key1:value1\tkey2:value2
160
+ ...
161
+ ```
162
+
163
+ "ltsv" format also accepts "include_xxx" related options. See "json" section.
164
+
165
+ - single_value
166
+
167
+ Use specified value instead of entire recode. If you get '{"message":"my log"}', then contents are
168
+
169
+ ```
170
+ my log1
171
+ my log2
172
+ ...
173
+ ```
174
+
175
+ You can change key name by "message_key" option.
176
+
177
+ ### path
178
+
179
+ path prefix of the files on Azure Storage. Default is "" (no prefix).
180
+
181
+ ### buffer_path (required)
182
+
183
+ path prefix of the files to buffer logs.
184
+
185
+ ### time_slice_format
186
+
187
+ Format of the time used as the file name. Default is '%Y%m%d'. Use '%Y%m%d%H' to split files hourly.
188
+
189
+ ### time_slice_wait
190
+
191
+ The time to wait old logs. Default is 10 minutes. Specify larger value if old logs may reache.
192
+
193
+ ### utc
194
+
195
+ Use UTC instead of local time.
196
+
197
+ ## License
198
+ Azure Storage output plugin is licensed according to the terms of the Apache License, Version 2.0.
199
+
200
+ The full version of this lisence can be found at http://www.apache.org/licenses/LICENSE-2.0 [TXT](http://www.apache.org/licenses/LICENSE-2.0.txt) or [HTML](http://www.apache.org/licenses/LICENSE-2.0.html)
201
+
202
+ ## Contributing
203
+
204
+ 1. Fork it
205
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
206
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
207
+ 4. Push to the branch (`git push origin my-new-feature`)
208
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ #lib = File.expand_path('../lib', __FILE__)
3
+ #$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-azurestorage"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Hidemasa Togashi"]
9
+ spec.email = ["togachiro@gmail.com"]
10
+ spec.description = %q{Fluent plugin for store to Azure Storage}
11
+ spec.summary = %q{Fluent plugin for store to Azure Storage}
12
+ spec.homepage = ""
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "rake"
22
+
23
+ spec.add_runtime_dependency "fluentd"
24
+ spec.add_runtime_dependency "azure"
25
+ end
@@ -0,0 +1,162 @@
1
+ module Fluent
2
+ require 'fluent/mixin/config_placeholders'
3
+
4
+ class AzureStorageOutput < Fluent::TimeSlicedOutput
5
+ Fluent::Plugin.register_output('azurestorage', self)
6
+
7
+ def initialize
8
+ super
9
+ require 'azure'
10
+ require 'zlib'
11
+ require 'time'
12
+ require 'tempfile'
13
+ require 'open3'
14
+ end
15
+
16
+ config_param :path, :string, :default => ''
17
+ config_param :azure_storage_account, :string, :default => nil
18
+ config_param :azure_storage_access_key, :string, :default => nil
19
+ config_param :azure_container, :string, :default => nil
20
+ config_param :azure_storage_type, :string, :default => 'blob'
21
+ config_param :azure_object_key_format, :string, :default => "%{path}%{time_slice}_%{index}.%{file_extension}"
22
+ config_param :store_as, :string, :default => 'gzip'
23
+ config_param :auto_create_container, :bool, :default => true
24
+ config_param :format, :string, :default => 'out_file'
25
+ config_param :command_parameter, :string, :default => nil
26
+
27
+ include Fluent::Mixin::ConfigPlaceholders
28
+
29
+ def configure(conf)
30
+ super
31
+
32
+ @ext = case @store_as
33
+ when 'gzip'
34
+ 'gz'
35
+ when 'lzo'
36
+ check_command('lzop', 'LZO')
37
+ @command_parameter = '-qf1' if @command_parameter.nil?
38
+ 'lzo'
39
+ when 'lzma2'
40
+ check_command('xz', 'LZMA2')
41
+ @command_paramter = '-qf0' if @command_parameter.nil?
42
+ 'xz'
43
+ when 'json'
44
+ 'json'
45
+ else
46
+ 'txt'
47
+ end
48
+
49
+ @storage_type = case @azure_storage_type
50
+ when 'tables'
51
+ raise NotImplementedError
52
+ when 'queues'
53
+ raise NotImplementedError
54
+ else
55
+ 'blob'
56
+ end
57
+
58
+ conf['format'] = @format
59
+ @formatter = TextFormatter.create(conf)
60
+
61
+ if @localtime
62
+ @path_slicer = Proc.new {|path|
63
+ Time.now.strftime(path)
64
+ }
65
+ else
66
+ @path_slicer = Proc.new {|path|
67
+ Time.now.utc.strftime(path)
68
+ }
69
+ end
70
+
71
+ if @azure_container.nil?
72
+ raise ConfigError, 'azure_container is needed'
73
+ end
74
+ end
75
+
76
+ def start
77
+ super
78
+
79
+ if (!@azure_storage_account.nil? && !@azure_storage_access_key)
80
+ Azure.configure do |config|
81
+ config.storage_account_name = @azure_storage_account
82
+ config.storage_access_key = @azure_storage_access_key
83
+ end
84
+ end
85
+ @bs = Azure::BlobService.new
86
+
87
+ ensure_container
88
+ end
89
+
90
+ def format(tag, time, record)
91
+ @formatter.format(tag, time, record)
92
+ end
93
+
94
+ def write(chunk)
95
+ blob_list = @bs.list_blobs(@azure_container)
96
+ i = 0
97
+ begin
98
+ path = @path_slicer.call(@path)
99
+ values_for_object_key = {
100
+ 'path' => path,
101
+ 'time_slice' => chunk.key,
102
+ 'file_extension' => @ext,
103
+ 'index' => i
104
+ }
105
+ storage_path = @azure_object_key_format.gsub(%r(%{[^}]+})) { |expr|
106
+ values_for_object_key[expr[2...expr.size-1]]
107
+ }
108
+ i += 1
109
+ end while blob_list.find { |elem| elem.name == storage_path }
110
+
111
+ tmp = Tempfile.new("azure-")
112
+ begin
113
+ case @store_as
114
+ when 'gzip'
115
+ w = Zlib::GzipWriter.new(tmp)
116
+ chunk.write_to(w)
117
+ w.close
118
+ when 'lzo'
119
+ w = Tempfile.new('chunk-tmp')
120
+ chunk.write_to(w)
121
+ w.close
122
+ tmp.close
123
+ system "lzop #{@command_parameter} -o #{tmp.path} #{w.path}"
124
+ when 'lzma2'
125
+ w = Tempfile.new('chunk-xz-tmp')
126
+ chunk.write_to(w)
127
+ w.close
128
+ tmp.close
129
+ system "xz #{@command_parameter} -c #{w.path} > #{tmp.path}"
130
+ else
131
+ chunk.write_to(tmp)
132
+ tmp.close
133
+ end
134
+ content = File.open(tmp.path, 'rb') { |file| file.read }
135
+ @bs.create_block_blob(@azure_container, storage_path, content)
136
+ ensure
137
+ tmp.close(true) rescue nil
138
+ w.close rescue nil
139
+ w.unlink rescue nil
140
+ end
141
+ end
142
+
143
+ private
144
+ def ensure_container
145
+ if ! @bs.list_containers.find { |c| c.name == @azure_container }
146
+ if @auto_create_container
147
+ @bs.create_container(@azure_container)
148
+ else
149
+ raise "The specified container does not exist: container = #{@azure_container}"
150
+ end
151
+ end
152
+ end
153
+
154
+ def check_command(command, algo)
155
+ begin
156
+ Open3.capture3("#{command} -V")
157
+ rescue Errno::ENOENT
158
+ raise ConfigError, "'#{command}' utility must be in PATH for #{algo} compression"
159
+ end
160
+ end
161
+ end
162
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-azurestorage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Hidemasa Togashi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fluentd
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: azure
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Fluent plugin for store to Azure Storage
70
+ email:
71
+ - togachiro@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - fluent-plugin-azurestorage.gemspec
82
+ - lib/fluent/plugin/out_azurestorage.rb
83
+ homepage: ''
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.0.14
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Fluent plugin for store to Azure Storage
107
+ test_files: []