fluent-plugin-azurestorage-gen2 0.2.7 → 0.3.1
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/README.md +26 -0
- data/VERSION +1 -1
- data/fluent-plugin-azurestorage-gen2.gemspec +1 -0
- data/lib/fluent/plugin/out_azurestorage_gen2.rb +141 -47
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cabf8cf518b936b57ea4674553cfeb10126f0740
|
4
|
+
data.tar.gz: baba4ab34b169b1316a02d9b8a70e7bde1c373bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7821f9a44d3520ebe7f596f7770d1fc236c5e5e40c7bb077eefefee29bca471954701e64b8b1a6b20c3aba7db2bd1013eda38c5b71a8b3ea259dd9e6b10987f
|
7
|
+
data.tar.gz: d3f03f3bae956b1ccd4566e54a563e4e5d43cea1478bc9833aec44917947fe7f5a12a6f0e918b50459b8593a4e2663d8772241be66b3845bffd13f3473eca361
|
data/README.md
CHANGED
@@ -140,6 +140,10 @@ If that setting is disabled, the worker won't fail on initialization (getting fi
|
|
140
140
|
|
141
141
|
The defaultt `url_domain_suffix` is `.dfs.core.windows.net`, you can override this in case of private endpoints.
|
142
142
|
|
143
|
+
### url_storage_resource
|
144
|
+
|
145
|
+
The url that is used during accessing a resource. Default value: `https://storage.azure.com/`
|
146
|
+
|
143
147
|
### azure_object_key_format
|
144
148
|
|
145
149
|
The format of Azure Storage object keys. You can use several built-in variables:
|
@@ -148,6 +152,7 @@ The format of Azure Storage object keys. You can use several built-in variables:
|
|
148
152
|
- %{time_slice}
|
149
153
|
- %{index}
|
150
154
|
- %{file_extension}
|
155
|
+
- %{upload_timestamp}
|
151
156
|
|
152
157
|
to decide keys dynamically.
|
153
158
|
|
@@ -155,6 +160,7 @@ to decide keys dynamically.
|
|
155
160
|
%{time_slice} is the time-slice in text that are formatted with *time_slice_format*.
|
156
161
|
%{index} is the sequential number starts from 0, increments when multiple files are uploaded to Azure Storage in the same time slice.
|
157
162
|
%{file_extention} is always "gz" for now.
|
163
|
+
%{upload_timestamp} is an upload timestamp in text that are formatted with *upload_timestamp_format*. Difference between time_slice and upload_timestamp is that the second one is the actual system timestamp (other one is from the metadata)
|
158
164
|
|
159
165
|
The default format is "%{path}%{time_slice}_%{index}.%{file_extension}".
|
160
166
|
|
@@ -279,10 +285,30 @@ Format of the time used as the file name. Default is '%Y%m%d'. Use '%Y%m%d%H' to
|
|
279
285
|
|
280
286
|
The time to wait old logs. Default is 10 minutes.
|
281
287
|
|
288
|
+
### upload_timestamp_format
|
289
|
+
|
290
|
+
Format of the upload timestamp used as the file name. Can be used instead of index in case of `write_only` option is enabled. Default value is '%H%M%S%L'.
|
291
|
+
|
282
292
|
### utc
|
283
293
|
|
284
294
|
Use UTC instead of local time.
|
285
295
|
|
296
|
+
### write_only
|
297
|
+
|
298
|
+
If that option is enabled, HEAD calls are skipped during blob operations. (so make sure to set the chunk limit to 4MB in order to avoid HEAD operation because of the append operation needs the last position of the uploaded blobs).
|
299
|
+
|
300
|
+
### proxy_url
|
301
|
+
|
302
|
+
Proxy URL for Azure endpoint.
|
303
|
+
|
304
|
+
### proxy_username
|
305
|
+
|
306
|
+
Proxy username for Azure proxy endpoint (used only if `proxy_url` is filled)
|
307
|
+
|
308
|
+
### proxy_password
|
309
|
+
|
310
|
+
Proxy password for Azure `proxy_username` (used only if `proxy_url` is filled)
|
311
|
+
|
286
312
|
## TODOs
|
287
313
|
|
288
314
|
- add storage key support
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.1
|
@@ -21,6 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.1'
|
22
22
|
gem.add_runtime_dependency 'json', '~> 2.1', '>= 2.1.0'
|
23
23
|
gem.add_runtime_dependency "yajl-ruby", '~> 1.4'
|
24
|
+
gem.add_runtime_dependency 'concurrent-ruby', '~> 1.1', '>= 1.1.5'
|
24
25
|
gem.add_development_dependency 'rake', '~> 12.3', '>= 12.3.1'
|
25
26
|
gem.add_development_dependency 'test-unit', '~> 3.3', '>= 3.3.3'
|
26
27
|
gem.add_development_dependency 'test-unit-rr', '~> 1.0', '>= 1.0.5'
|
@@ -6,6 +6,7 @@ require 'tempfile'
|
|
6
6
|
require 'time'
|
7
7
|
require 'typhoeus'
|
8
8
|
require 'fluent/plugin/output'
|
9
|
+
require 'concurrent'
|
9
10
|
require 'zlib'
|
10
11
|
|
11
12
|
module Fluent::Plugin
|
@@ -38,9 +39,16 @@ module Fluent::Plugin
|
|
38
39
|
config_param :enable_retry, :bool, :default => false
|
39
40
|
config_param :startup_fail_on_error, :bool, :default => true
|
40
41
|
config_param :url_domain_suffix, :string, :default => '.dfs.core.windows.net'
|
42
|
+
config_param :url_storage_resource, :string, :default => 'https://storage.azure.com/'
|
41
43
|
config_param :format, :string, :default => "out_file"
|
42
44
|
config_param :time_slice_format, :string, :default => '%Y%m%d'
|
45
|
+
config_param :hex_random_length, :integer, default: 4
|
43
46
|
config_param :command_parameter, :string, :default => nil
|
47
|
+
config_param :proxy_url, :string, :default => nil
|
48
|
+
config_param :proxy_username, :string, :default => nil
|
49
|
+
config_param :proxy_password, :string, :default => nil, :secret => true
|
50
|
+
config_param :write_only, :bool, :default => false
|
51
|
+
config_param :upload_timestamp_format, :string, :default => '%H%M%S%L'
|
44
52
|
|
45
53
|
DEFAULT_FORMAT_TYPE = "out_file"
|
46
54
|
ACCESS_TOKEN_API_VERSION = "2018-02-01"
|
@@ -74,16 +82,6 @@ module Fluent::Plugin
|
|
74
82
|
|
75
83
|
@formatter = formatter_create
|
76
84
|
|
77
|
-
if @localtime
|
78
|
-
@path_slicer = Proc.new {|path|
|
79
|
-
Time.now.strftime(path)
|
80
|
-
}
|
81
|
-
else
|
82
|
-
@path_slicer = Proc.new {|path|
|
83
|
-
Time.now.utc.strftime(path)
|
84
|
-
}
|
85
|
-
end
|
86
|
-
|
87
85
|
if @azure_container.nil?
|
88
86
|
raise Fluent::ConfigError, "azure_container is needed"
|
89
87
|
end
|
@@ -97,7 +95,7 @@ module Fluent::Plugin
|
|
97
95
|
else
|
98
96
|
@final_file_extension = @compressor.ext
|
99
97
|
end
|
100
|
-
|
98
|
+
@values_for_object_chunk = {}
|
101
99
|
end
|
102
100
|
|
103
101
|
def multi_workers_ready?
|
@@ -109,12 +107,20 @@ module Fluent::Plugin
|
|
109
107
|
if !@skip_container_check
|
110
108
|
if @failsafe_container_check
|
111
109
|
begin
|
112
|
-
|
110
|
+
if @write_only && @auto_create_container
|
111
|
+
create_container
|
112
|
+
else
|
113
|
+
ensure_container
|
114
|
+
end
|
113
115
|
rescue Exception => e
|
114
116
|
log.warn("#{e.message}, container list/create failsafe is enabled. Continue without those operations.")
|
115
117
|
end
|
116
118
|
else
|
117
|
-
|
119
|
+
if @write_only && @auto_create_container
|
120
|
+
create_container
|
121
|
+
else
|
122
|
+
ensure_container
|
123
|
+
end
|
118
124
|
end
|
119
125
|
end
|
120
126
|
super
|
@@ -126,17 +132,16 @@ module Fluent::Plugin
|
|
126
132
|
end
|
127
133
|
|
128
134
|
def write(chunk)
|
129
|
-
metadata = chunk.metadata
|
130
135
|
if @store_as.nil? || @store_as == "none"
|
131
|
-
generate_log_name(
|
136
|
+
generate_log_name(chunk, @current_index)
|
132
137
|
if @last_azure_storage_path != @azure_storage_path
|
133
138
|
@current_index = 0
|
134
|
-
generate_log_name(
|
139
|
+
generate_log_name(chunk, @current_index)
|
135
140
|
end
|
136
141
|
raw_data = chunk.read
|
137
142
|
unless raw_data.empty?
|
138
143
|
log.debug "azurestorage_gen2: processing raw data", chunk_id: dump_unique_id_hex(chunk.unique_id)
|
139
|
-
upload_blob(raw_data,
|
144
|
+
upload_blob(raw_data, chunk)
|
140
145
|
end
|
141
146
|
chunk.close rescue nil
|
142
147
|
@last_azure_storage_path = @azure_storage_path
|
@@ -146,51 +151,76 @@ module Fluent::Plugin
|
|
146
151
|
begin
|
147
152
|
@compressor.compress(chunk, tmp)
|
148
153
|
tmp.rewind
|
149
|
-
generate_log_name(
|
154
|
+
generate_log_name(chunk, @current_index)
|
150
155
|
if @last_azure_storage_path != @azure_storage_path
|
151
156
|
@current_index = 0
|
152
|
-
generate_log_name(
|
157
|
+
generate_log_name(chunk, @current_index)
|
153
158
|
end
|
154
159
|
log.debug "azurestorage_gen2: Start uploading temp file: #{tmp.path}"
|
155
160
|
content = File.open(tmp.path, 'rb') { |file| file.read }
|
156
|
-
upload_blob(content,
|
161
|
+
upload_blob(content, chunk)
|
157
162
|
@last_azure_storage_path = @azure_storage_path
|
158
163
|
ensure
|
159
164
|
tmp.close(true) rescue nil
|
160
165
|
end
|
166
|
+
@values_for_object_chunk.delete(chunk.unique_id)
|
161
167
|
end
|
162
168
|
|
163
169
|
end
|
164
170
|
|
165
171
|
private
|
166
|
-
def upload_blob(content,
|
172
|
+
def upload_blob(content, chunk)
|
167
173
|
log.debug "azurestorage_gen2: Uploading blob: #{@azure_storage_path}"
|
168
|
-
|
169
|
-
if existing_content_length == 0
|
174
|
+
if @write_only
|
170
175
|
create_blob(@azure_storage_path)
|
176
|
+
append_blob(content, chunk, 0)
|
177
|
+
else
|
178
|
+
existing_content_length = get_blob_properties(@azure_storage_path)
|
179
|
+
if existing_content_length == 0
|
180
|
+
create_blob(@azure_storage_path)
|
181
|
+
end
|
182
|
+
append_blob(content, chunk, existing_content_length)
|
171
183
|
end
|
172
|
-
append_blob(content, metadata, existing_content_length)
|
173
184
|
end
|
174
185
|
|
175
186
|
private
|
176
|
-
def generate_log_name(
|
187
|
+
def generate_log_name(chunk, index)
|
188
|
+
metadata = chunk.metadata
|
177
189
|
time_slice = if metadata.timekey.nil?
|
178
190
|
''.freeze
|
179
191
|
else
|
180
192
|
Time.at(metadata.timekey).utc.strftime(@time_slice_format)
|
181
193
|
end
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
194
|
+
if @localtime
|
195
|
+
hms_slicer = Time.now.strftime("%H%M%S")
|
196
|
+
upload_timestamp = Time.now.strftime(@upload_timestamp_format)
|
197
|
+
else
|
198
|
+
hms_slicer = Time.now.utc.strftime("%H%M%S")
|
199
|
+
upload_timestamp = Time.now.utc.strftime(@upload_timestamp_format)
|
200
|
+
end
|
201
|
+
|
202
|
+
@values_for_object_chunk[chunk.unique_id] ||= {
|
203
|
+
"%{hex_random}" => hex_random(chunk),
|
204
|
+
}
|
205
|
+
values_for_object_key_pre = {
|
206
|
+
"%{path}" => @path,
|
186
207
|
"%{index}" => index,
|
187
208
|
"%{uuid_flush}" => uuid_random,
|
188
|
-
"%{file_extension}" => @final_file_extension
|
209
|
+
"%{file_extension}" => @final_file_extension,
|
210
|
+
"%{upload_timestamp}" => upload_timestamp,
|
189
211
|
}
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
212
|
+
values_for_object_key_post = {
|
213
|
+
"%{date_slice}" => time_slice,
|
214
|
+
"%{time_slice}" => time_slice,
|
215
|
+
"%{hms_slice}" => hms_slicer,
|
216
|
+
}.merge!(@values_for_object_chunk[chunk.unique_id])
|
217
|
+
storage_path = @azure_object_key_format.gsub(%r(%{[^}]+})) do |matched_key|
|
218
|
+
values_for_object_key_pre.fetch(matched_key, matched_key)
|
219
|
+
end
|
220
|
+
storage_path = extract_placeholders(storage_path, chunk)
|
221
|
+
storage_path = storage_path.gsub(%r(%{[^}]+}), values_for_object_key_post)
|
222
|
+
storage_path = "/" + storage_path unless storage_path.start_with?("/")
|
223
|
+
@azure_storage_path = storage_path
|
194
224
|
end
|
195
225
|
|
196
226
|
def setup_access_token
|
@@ -242,11 +272,16 @@ module Fluent::Plugin
|
|
242
272
|
# https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/tutorial-linux-vm-access-storage#get-an-access-token-and-use-it-to-call-azure-storage
|
243
273
|
private
|
244
274
|
def acquire_access_token_msi
|
245
|
-
params = { :"api-version" => ACCESS_TOKEN_API_VERSION, :resource => "
|
275
|
+
params = { :"api-version" => ACCESS_TOKEN_API_VERSION, :resource => "#{@url_storage_resource}" }
|
246
276
|
unless @azure_instance_msi.nil?
|
247
277
|
params[:msi_res_id] = @azure_instance_msi
|
248
278
|
end
|
249
|
-
|
279
|
+
req_opts = {
|
280
|
+
:params => params,
|
281
|
+
:headers => { Metadata: "true" }
|
282
|
+
}
|
283
|
+
add_proxy_options(req_opts)
|
284
|
+
request = Typhoeus::Request.new("http://169.254.169.254/metadata/identity/oauth2/token", req_opts)
|
250
285
|
request.on_complete do |response|
|
251
286
|
if response.success?
|
252
287
|
data = JSON.parse(response.body)
|
@@ -261,10 +296,16 @@ module Fluent::Plugin
|
|
261
296
|
|
262
297
|
private
|
263
298
|
def acquire_access_token_oauth_app
|
264
|
-
params = { :"api-version" => ACCESS_TOKEN_API_VERSION, :resource => "
|
299
|
+
params = { :"api-version" => ACCESS_TOKEN_API_VERSION, :resource => "#{@url_storage_resource}"}
|
265
300
|
headers = {:"Content-Type" => "application/x-www-form-urlencoded"}
|
266
|
-
content = "grant_type=client_credentials&client_id=#{@azure_oauth_app_id}&client_secret=#{@azure_oauth_secret}&resource
|
267
|
-
|
301
|
+
content = "grant_type=client_credentials&client_id=#{@azure_oauth_app_id}&client_secret=#{@azure_oauth_secret}&resource=#{@url_storage_resource}"
|
302
|
+
req_opts = {
|
303
|
+
:params => params,
|
304
|
+
:body => content,
|
305
|
+
:headers => headers
|
306
|
+
}
|
307
|
+
add_proxy_options(req_opts)
|
308
|
+
request = Typhoeus::Request.new("https://login.microsoftonline.com/#{@azure_oauth_tenant_id}/oauth2/token", req_opts)
|
268
309
|
request.on_complete do |response|
|
269
310
|
if response.success?
|
270
311
|
data = JSON.parse(response.body)
|
@@ -279,7 +320,7 @@ module Fluent::Plugin
|
|
279
320
|
|
280
321
|
private
|
281
322
|
def acquire_access_token_by_az
|
282
|
-
access_token=`az account get-access-token --resource
|
323
|
+
access_token=`az account get-access-token --resource #{@url_storage_resource} --query accessToken -o tsv`
|
283
324
|
log.debug "azurestorage_gen2: Token response: #{access_token}"
|
284
325
|
@azure_access_token = access_token.chomp
|
285
326
|
end
|
@@ -291,7 +332,13 @@ module Fluent::Plugin
|
|
291
332
|
params = {:resource => "filesystem" }
|
292
333
|
auth_header = create_auth_header("head", datestamp, "#{@azure_container}", headers, params)
|
293
334
|
headers[:Authorization] = auth_header
|
294
|
-
|
335
|
+
req_opts = {
|
336
|
+
:method => :head,
|
337
|
+
:params => params,
|
338
|
+
:headers => headers
|
339
|
+
}
|
340
|
+
add_proxy_options(req_opts)
|
341
|
+
request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}", req_opts)
|
295
342
|
request.on_complete do |response|
|
296
343
|
if response.success?
|
297
344
|
log.info "azurestorage_gen2: Container '#{@azure_container}' exists."
|
@@ -318,7 +365,13 @@ module Fluent::Plugin
|
|
318
365
|
params = {:resource => "filesystem" }
|
319
366
|
auth_header = create_auth_header("put", datestamp, "#{@azure_container}", headers, params)
|
320
367
|
headers[:Authorization] = auth_header
|
321
|
-
|
368
|
+
req_opts = {
|
369
|
+
:method => :put,
|
370
|
+
:params => params,
|
371
|
+
:headers => headers
|
372
|
+
}
|
373
|
+
add_proxy_options(req_opts)
|
374
|
+
request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}", req_opts)
|
322
375
|
request.on_complete do |response|
|
323
376
|
if response.success?
|
324
377
|
log.debug "azurestorage_gen2: Container '#{@azure_container}' created, response code: #{response.code}"
|
@@ -338,7 +391,13 @@ module Fluent::Plugin
|
|
338
391
|
params = {:resource => "file", :recursive => "false"}
|
339
392
|
auth_header = create_auth_header("put", datestamp, "#{@azure_container}#{blob_path}", headers, params)
|
340
393
|
headers[:Authorization] = auth_header
|
341
|
-
|
394
|
+
req_opts = {
|
395
|
+
:method => :put,
|
396
|
+
:params => params,
|
397
|
+
:headers => headers
|
398
|
+
}
|
399
|
+
add_proxy_options(req_opts)
|
400
|
+
request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", req_opts)
|
342
401
|
request.on_complete do |response|
|
343
402
|
if response.success?
|
344
403
|
log.debug "azurestorage_gen2: Blob '#{blob_path}' has been created, response code: #{response.code}"
|
@@ -361,7 +420,14 @@ module Fluent::Plugin
|
|
361
420
|
params = {:action => "append", :position => "#{position}"}
|
362
421
|
auth_header = create_auth_header("patch", datestamp, "#{@azure_container}#{blob_path}", headers, params)
|
363
422
|
headers[:Authorization] = auth_header
|
364
|
-
|
423
|
+
req_opts = {
|
424
|
+
:method => :patch,
|
425
|
+
:params => params,
|
426
|
+
:headers => headers,
|
427
|
+
:body => content
|
428
|
+
}
|
429
|
+
add_proxy_options(req_opts)
|
430
|
+
request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", req_opts)
|
365
431
|
request.on_complete do |response|
|
366
432
|
if response.success?
|
367
433
|
log.debug "azurestorage_gen2: Blob '#{blob_path}' has been appended, response code: #{response.code}"
|
@@ -386,7 +452,13 @@ module Fluent::Plugin
|
|
386
452
|
params = {:action => "flush", :position => "#{position}"}
|
387
453
|
auth_header = create_auth_header("patch", datestamp, "#{@azure_container}#{blob_path}",headers, params)
|
388
454
|
headers[:Authorization] = auth_header
|
389
|
-
|
455
|
+
req_opts = {
|
456
|
+
:method => :patch,
|
457
|
+
:params => params,
|
458
|
+
:headers => headers
|
459
|
+
}
|
460
|
+
add_proxy_options(req_opts)
|
461
|
+
request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", req_opts)
|
390
462
|
request.on_complete do |response|
|
391
463
|
if response.success?
|
392
464
|
log.debug "azurestorage_gen2: Blob '#{blob_path}' flush was successful, response code: #{response.code}"
|
@@ -407,7 +479,13 @@ module Fluent::Plugin
|
|
407
479
|
content_length = -1
|
408
480
|
auth_header = create_auth_header("head", datestamp, "#{@azure_container}#{blob_path}", headers, params)
|
409
481
|
headers[:Authorization] = auth_header
|
410
|
-
|
482
|
+
req_opts = {
|
483
|
+
:method => :head,
|
484
|
+
:params => params,
|
485
|
+
:headers => headers
|
486
|
+
}
|
487
|
+
add_proxy_options(req_opts)
|
488
|
+
request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", req_opts)
|
411
489
|
request.on_complete do |response|
|
412
490
|
if response.success?
|
413
491
|
log.debug "azurestorage_gen2: Get blob properties for '#{blob_path}', response headers: #{response.headers}"
|
@@ -426,7 +504,7 @@ module Fluent::Plugin
|
|
426
504
|
end
|
427
505
|
|
428
506
|
private
|
429
|
-
def append_blob(content,
|
507
|
+
def append_blob(content, chunk, existing_content_length)
|
430
508
|
position = 0
|
431
509
|
log.debug "azurestorage_gen2: append_blob.start: Content size: #{content.length}"
|
432
510
|
loop do
|
@@ -475,6 +553,16 @@ module Fluent::Plugin
|
|
475
553
|
"SharedKey #{@azure_storage_account}:#{signed(method, datestamp, resource, headers, params)}"
|
476
554
|
end
|
477
555
|
end
|
556
|
+
|
557
|
+
private
|
558
|
+
def add_proxy_options(req_opts = {})
|
559
|
+
unless @proxy_url.nil?
|
560
|
+
req_opts[:proxy] = @proxy_url
|
561
|
+
unless @proxy_username.nil? || @proxy_password.nil?
|
562
|
+
req_opts[:proxyuserpwd] = "#{@proxy_username}:#{@proxy_password}"
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
478
566
|
|
479
567
|
private
|
480
568
|
def signed(method, datestamp, resource, headers, params)
|
@@ -544,6 +632,12 @@ module Fluent::Plugin
|
|
544
632
|
require 'uuidtools'
|
545
633
|
::UUIDTools::UUID.random_create.to_s
|
546
634
|
end
|
635
|
+
|
636
|
+
def hex_random(chunk)
|
637
|
+
unique_hex = Fluent::UniqueId.hex(chunk.unique_id)
|
638
|
+
unique_hex.reverse!
|
639
|
+
unique_hex[0...@hex_random_length]
|
640
|
+
end
|
547
641
|
|
548
642
|
def timekey_to_timeformat(timekey)
|
549
643
|
case timekey
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-azurestorage-gen2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oliver Szabo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -104,6 +104,26 @@ dependencies:
|
|
104
104
|
- - "~>"
|
105
105
|
- !ruby/object:Gem::Version
|
106
106
|
version: '1.4'
|
107
|
+
- !ruby/object:Gem::Dependency
|
108
|
+
name: concurrent-ruby
|
109
|
+
requirement: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '1.1'
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 1.1.5
|
117
|
+
type: :runtime
|
118
|
+
prerelease: false
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '1.1'
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: 1.1.5
|
107
127
|
- !ruby/object:Gem::Dependency
|
108
128
|
name: rake
|
109
129
|
requirement: !ruby/object:Gem::Requirement
|