fluent-plugin-kusto 0.0.1.beta
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 +7 -0
- data/Gemfile +8 -0
- data/LICENSE +21 -0
- data/README.md +201 -0
- data/lib/fluent/plugin/auth/aad_tokenprovider.rb +105 -0
- data/lib/fluent/plugin/auth/azcli_tokenprovider.rb +51 -0
- data/lib/fluent/plugin/auth/mi_tokenprovider.rb +92 -0
- data/lib/fluent/plugin/auth/tokenprovider_base.rb +57 -0
- data/lib/fluent/plugin/auth/wif_tokenprovider.rb +50 -0
- data/lib/fluent/plugin/client.rb +155 -0
- data/lib/fluent/plugin/conffile.rb +155 -0
- data/lib/fluent/plugin/ingester.rb +136 -0
- data/lib/fluent/plugin/kusto_error_handler.rb +126 -0
- data/lib/fluent/plugin/kusto_query.rb +67 -0
- data/lib/fluent/plugin/out_kusto.rb +423 -0
- data/test/helper.rb +9 -0
- data/test/plugin/test_azcli_tokenprovider.rb +37 -0
- data/test/plugin/test_e2e_kusto.rb +683 -0
- data/test/plugin/test_out_kusto_config.rb +86 -0
- data/test/plugin/test_out_kusto_format.rb +280 -0
- data/test/plugin/test_out_kusto_process.rb +150 -0
- data/test/plugin/test_out_kusto_start.rb +429 -0
- data/test/plugin/test_out_kusto_try_write.rb +382 -0
- data/test/plugin/test_out_kusto_write.rb +370 -0
- metadata +171 -0
@@ -0,0 +1,370 @@
|
|
1
|
+
# rubocop:disable all
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'ostruct'
|
5
|
+
require_relative '../helper'
|
6
|
+
require 'fluent/test/driver/output'
|
7
|
+
require 'fluent/plugin/out_kusto'
|
8
|
+
require 'mocha/test_unit'
|
9
|
+
|
10
|
+
class KustoOutputWriteTest < Test::Unit::TestCase
|
11
|
+
setup do
|
12
|
+
Fluent::Test.setup
|
13
|
+
@driver = Fluent::Test::Driver::Output.new(Fluent::Plugin::KustoOutput).configure(<<-CONF)
|
14
|
+
@type kusto
|
15
|
+
endpoint https://example.kusto.windows.net
|
16
|
+
database_name testdb
|
17
|
+
table_name testtable
|
18
|
+
client_id dummy-client-id
|
19
|
+
client_secret dummy-secret
|
20
|
+
tenant_id dummy-tenant
|
21
|
+
buffered true
|
22
|
+
auth_type aad
|
23
|
+
CONF
|
24
|
+
end
|
25
|
+
|
26
|
+
class FakeKustoError < StandardError
|
27
|
+
def initialize(msg, permanent)
|
28
|
+
super(msg)
|
29
|
+
@permanent = permanent
|
30
|
+
end
|
31
|
+
|
32
|
+
def permanent?
|
33
|
+
@permanent
|
34
|
+
end
|
35
|
+
|
36
|
+
def is_permanent?
|
37
|
+
permanent?
|
38
|
+
end
|
39
|
+
|
40
|
+
def failure_code
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def failure_sub_code
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def logger_stub
|
50
|
+
m = mock
|
51
|
+
m.stubs(:debug)
|
52
|
+
m.stubs(:error)
|
53
|
+
m.stubs(:info)
|
54
|
+
m.stubs(:warn)
|
55
|
+
m
|
56
|
+
end
|
57
|
+
|
58
|
+
def ingester_stub
|
59
|
+
m = mock
|
60
|
+
m.stubs(:upload_data_to_blob_and_queue)
|
61
|
+
m
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_mocks(ingester: nil, logger: nil)
|
65
|
+
@driver.instance.instance_variable_set(:@ingester, ingester) if ingester
|
66
|
+
@driver.instance.instance_variable_set(:@logger, logger) if logger
|
67
|
+
end
|
68
|
+
|
69
|
+
def chunk_stub(data: 'testdata', tag: 'test.tag', unique_id: 'uniqueid'.b, metadata: nil)
|
70
|
+
c = mock
|
71
|
+
c.stubs(:read).returns(data)
|
72
|
+
c.stubs(:metadata).returns(metadata || OpenStruct.new(tag: tag))
|
73
|
+
c.stubs(:unique_id).returns(unique_id)
|
74
|
+
c
|
75
|
+
end
|
76
|
+
|
77
|
+
test 'write uploads compressed data to blob and queue' do
|
78
|
+
ingester_mock = mock
|
79
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once.with do |_data, blob_name, _db, _table|
|
80
|
+
assert_match(/fluentd_event_worker\d+_test\.tag_[0-9a-f]+\.json\.gz/, blob_name)
|
81
|
+
true
|
82
|
+
end
|
83
|
+
logger_mock = logger_stub
|
84
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
85
|
+
chunk = chunk_stub
|
86
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
87
|
+
end
|
88
|
+
|
89
|
+
test 'write raises error on permanent Kusto error' do
|
90
|
+
ingester_mock = mock
|
91
|
+
kusto_error = FakeKustoError.new('permanent fail', true)
|
92
|
+
KustoErrorHandler.stubs(:extract_kusto_error_type).returns(:permanent)
|
93
|
+
KustoErrorHandler.stubs(:from_kusto_error_type).returns(kusto_error)
|
94
|
+
ingester_mock.stubs(:upload_data_to_blob_and_queue).raises(StandardError, 'fail')
|
95
|
+
logger_mock = mock
|
96
|
+
logger_mock.stubs(:debug)
|
97
|
+
logger_mock.expects(:error).at_least_once
|
98
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
99
|
+
chunk = chunk_stub
|
100
|
+
assert_raise(FakeKustoError) { @driver.instance.write(chunk) }
|
101
|
+
end
|
102
|
+
|
103
|
+
test 'write raises error on non-permanent Kusto error (triggers retry)' do
|
104
|
+
ingester_mock = mock
|
105
|
+
kusto_error = FakeKustoError.new('transient fail', false)
|
106
|
+
KustoErrorHandler.stubs(:extract_kusto_error_type).returns(:transient)
|
107
|
+
KustoErrorHandler.stubs(:from_kusto_error_type).returns(kusto_error)
|
108
|
+
ingester_mock.stubs(:upload_data_to_blob_and_queue).raises(StandardError, 'fail')
|
109
|
+
logger_mock = mock
|
110
|
+
logger_mock.stubs(:debug)
|
111
|
+
logger_mock.expects(:error).at_least_once
|
112
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
113
|
+
chunk = chunk_stub
|
114
|
+
assert_raise(FakeKustoError) { @driver.instance.write(chunk) }
|
115
|
+
end
|
116
|
+
|
117
|
+
test 'write raises error on unknown error' do
|
118
|
+
ingester_mock = mock
|
119
|
+
KustoErrorHandler.stubs(:extract_kusto_error_type).returns(nil)
|
120
|
+
ingester_mock.stubs(:upload_data_to_blob_and_queue).raises(IOError, 'io fail')
|
121
|
+
logger_mock = mock
|
122
|
+
logger_mock.stubs(:debug)
|
123
|
+
logger_mock.expects(:error).at_least_once
|
124
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
125
|
+
chunk = chunk_stub
|
126
|
+
assert_raise(IOError) { @driver.instance.write(chunk) }
|
127
|
+
end
|
128
|
+
|
129
|
+
test 'write calls logger.info on success' do
|
130
|
+
ingester_mock = ingester_stub
|
131
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
132
|
+
logger_mock = logger_stub
|
133
|
+
logger_mock.stubs(:info)
|
134
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
135
|
+
chunk = chunk_stub
|
136
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
137
|
+
end
|
138
|
+
|
139
|
+
test 'write calls logger.error with correct message on permanent error' do
|
140
|
+
ingester_mock = mock
|
141
|
+
kusto_error = FakeKustoError.new('permanent fail', true)
|
142
|
+
KustoErrorHandler.stubs(:extract_kusto_error_type).returns(:permanent)
|
143
|
+
KustoErrorHandler.stubs(:from_kusto_error_type).returns(kusto_error)
|
144
|
+
ingester_mock.stubs(:upload_data_to_blob_and_queue).raises(StandardError, 'fail')
|
145
|
+
logger_mock = mock
|
146
|
+
logger_mock.stubs(:debug)
|
147
|
+
logger_mock.stubs(:error)
|
148
|
+
logger_mock.expects(:error).with(regexp_matches(/Dropping chunk .* due to permanent Kusto error/)).at_least_once
|
149
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
150
|
+
chunk = chunk_stub
|
151
|
+
assert_raise(FakeKustoError) { @driver.instance.write(chunk) }
|
152
|
+
end
|
153
|
+
|
154
|
+
test 'write works with different chunk metadata' do
|
155
|
+
ingester_mock = mock
|
156
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
157
|
+
logger_mock = mock
|
158
|
+
logger_mock.stubs(:debug)
|
159
|
+
logger_mock.stubs(:error)
|
160
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
161
|
+
chunk = chunk_stub(tag: 'other.tag', unique_id: 'otherid'.b)
|
162
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
163
|
+
end
|
164
|
+
|
165
|
+
test 'write handles empty chunk data' do
|
166
|
+
ingester_mock = ingester_stub
|
167
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
168
|
+
logger_mock = logger_stub
|
169
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
170
|
+
chunk = chunk_stub(data: '')
|
171
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
172
|
+
end
|
173
|
+
|
174
|
+
test 'write handles chunk.read raising error' do
|
175
|
+
ingester_mock = ingester_stub
|
176
|
+
logger_mock = logger_stub
|
177
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
178
|
+
chunk = chunk_stub
|
179
|
+
chunk.stubs(:read).raises(IOError, 'read fail')
|
180
|
+
assert_raise(IOError) { @driver.instance.write(chunk) }
|
181
|
+
end
|
182
|
+
|
183
|
+
test 'write retries on non-permanent Kusto error up to buffer retry_max_times' do
|
184
|
+
# Simulate Fluentd's retry mechanism by calling write multiple times
|
185
|
+
ingester_mock = mock
|
186
|
+
kusto_error = FakeKustoError.new('transient fail', false)
|
187
|
+
KustoErrorHandler.stubs(:extract_kusto_error_type).returns(:transient)
|
188
|
+
KustoErrorHandler.stubs(:from_kusto_error_type).returns(kusto_error)
|
189
|
+
ingester_mock.stubs(:upload_data_to_blob_and_queue).raises(StandardError, 'fail')
|
190
|
+
logger_mock = mock
|
191
|
+
logger_mock.stubs(:debug)
|
192
|
+
logger_mock.stubs(:error)
|
193
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
194
|
+
chunk = chunk_stub
|
195
|
+
# Simulate retry_max_times = 3
|
196
|
+
3.times do
|
197
|
+
assert_raise(FakeKustoError) { @driver.instance.write(chunk) }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
test 'write stops retrying if permanent error occurs after retries' do
|
202
|
+
ingester_mock = mock
|
203
|
+
# First 2 attempts: non-permanent error, 3rd attempt: permanent error
|
204
|
+
kusto_error_transient = FakeKustoError.new('transient fail', false)
|
205
|
+
kusto_error_permanent = FakeKustoError.new('permanent fail', true)
|
206
|
+
KustoErrorHandler.stubs(:extract_kusto_error_type).returns(:transient, :transient, :permanent)
|
207
|
+
KustoErrorHandler.stubs(:from_kusto_error_type).returns(kusto_error_transient, kusto_error_transient,
|
208
|
+
kusto_error_permanent)
|
209
|
+
ingester_mock.stubs(:upload_data_to_blob_and_queue).raises(StandardError, 'fail')
|
210
|
+
logger_mock = mock
|
211
|
+
logger_mock.stubs(:debug)
|
212
|
+
logger_mock.stubs(:error)
|
213
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
214
|
+
chunk = chunk_stub
|
215
|
+
2.times { assert_raise(FakeKustoError) { @driver.instance.write(chunk) } }
|
216
|
+
assert_raise(FakeKustoError) { @driver.instance.write(chunk) } # Should be permanent error
|
217
|
+
end
|
218
|
+
|
219
|
+
test 'write succeeds after retries if error goes away' do
|
220
|
+
ingester_mock = mock
|
221
|
+
kusto_error = FakeKustoError.new('transient fail', false)
|
222
|
+
KustoErrorHandler.stubs(:extract_kusto_error_type).returns(:transient, :transient, nil)
|
223
|
+
KustoErrorHandler.stubs(:from_kusto_error_type).returns(kusto_error, kusto_error)
|
224
|
+
# First 2 attempts raise, 3rd attempt succeeds
|
225
|
+
ingester_mock.stubs(:upload_data_to_blob_and_queue).raises(StandardError, 'fail').then.raises(StandardError,
|
226
|
+
'fail').then.returns(true)
|
227
|
+
logger_mock = mock
|
228
|
+
logger_mock.stubs(:debug)
|
229
|
+
logger_mock.stubs(:error)
|
230
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
231
|
+
chunk = chunk_stub
|
232
|
+
2.times { assert_raise(FakeKustoError) { @driver.instance.write(chunk) } }
|
233
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
234
|
+
end
|
235
|
+
|
236
|
+
test 'write handles chunk with nil metadata' do
|
237
|
+
ingester_mock = ingester_stub
|
238
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
239
|
+
logger_mock = logger_stub
|
240
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
241
|
+
chunk = chunk_stub(metadata: nil)
|
242
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
243
|
+
end
|
244
|
+
|
245
|
+
test 'write handles chunk with nil unique_id' do
|
246
|
+
ingester_mock = ingester_stub
|
247
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
248
|
+
logger_mock = logger_stub
|
249
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
250
|
+
chunk = chunk_stub(unique_id: nil)
|
251
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
252
|
+
end
|
253
|
+
|
254
|
+
test 'write handles chunk with nil tag' do
|
255
|
+
ingester_mock = ingester_stub
|
256
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
257
|
+
logger_mock = logger_stub
|
258
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
259
|
+
chunk = chunk_stub(tag: nil)
|
260
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
261
|
+
end
|
262
|
+
|
263
|
+
test 'write handles chunk with very large data' do
|
264
|
+
ingester_mock = ingester_stub
|
265
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
266
|
+
logger_mock = logger_stub
|
267
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
268
|
+
chunk = chunk_stub(data: 'x' * 10_000_000)
|
269
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
270
|
+
end
|
271
|
+
|
272
|
+
test 'write handles logger that only responds to error' do
|
273
|
+
ingester_mock = mock
|
274
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
275
|
+
logger_mock = mock
|
276
|
+
def logger_mock.debug(*)
|
277
|
+
raise NoMethodError
|
278
|
+
end
|
279
|
+
logger_mock.stubs(:error)
|
280
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
281
|
+
chunk = chunk_stub
|
282
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
283
|
+
end
|
284
|
+
|
285
|
+
test 'write handles logger.error raising exception' do
|
286
|
+
ingester_mock = mock
|
287
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
288
|
+
logger_mock = mock
|
289
|
+
logger_mock.stubs(:debug)
|
290
|
+
def logger_mock.error(*)
|
291
|
+
raise 'logger error'
|
292
|
+
end
|
293
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
294
|
+
chunk = chunk_stub
|
295
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
296
|
+
end
|
297
|
+
|
298
|
+
test 'write is thread safe with concurrent calls' do
|
299
|
+
set_mocks(ingester: ingester_stub, logger: logger_stub)
|
300
|
+
chunk = chunk_stub
|
301
|
+
threads = 5.times.map do
|
302
|
+
Thread.new { assert_nothing_raised { @driver.instance.write(chunk) } }
|
303
|
+
end
|
304
|
+
threads.each(&:join)
|
305
|
+
end
|
306
|
+
|
307
|
+
test 'write handles logger with info but not error' do
|
308
|
+
ingester_mock = mock
|
309
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
310
|
+
logger_mock = mock
|
311
|
+
logger_mock.stubs(:info)
|
312
|
+
def logger_mock.error(*)
|
313
|
+
raise NoMethodError
|
314
|
+
end
|
315
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
316
|
+
chunk = chunk_stub
|
317
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
318
|
+
end
|
319
|
+
|
320
|
+
test 'write handles chunk.metadata without tag method' do
|
321
|
+
ingester_mock = mock
|
322
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
323
|
+
logger_mock = mock
|
324
|
+
logger_mock.stubs(:info)
|
325
|
+
logger_mock.stubs(:error)
|
326
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
327
|
+
metadata_obj = Object.new
|
328
|
+
chunk = mock
|
329
|
+
chunk.stubs(:read).returns('testdata')
|
330
|
+
chunk.stubs(:metadata).returns(metadata_obj)
|
331
|
+
chunk.stubs(:unique_id).returns('uniqueid'.b)
|
332
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
333
|
+
end
|
334
|
+
|
335
|
+
test 'write handles unique_id as integer' do
|
336
|
+
ingester_mock = ingester_stub
|
337
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
338
|
+
logger_mock = logger_stub
|
339
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
340
|
+
chunk = chunk_stub(unique_id: 12_345)
|
341
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
342
|
+
end
|
343
|
+
|
344
|
+
test 'write handles unique_id as array' do
|
345
|
+
ingester_mock = ingester_stub
|
346
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
347
|
+
logger_mock = logger_stub
|
348
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
349
|
+
chunk = chunk_stub(unique_id: [1, 2, 3])
|
350
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
351
|
+
end
|
352
|
+
|
353
|
+
test 'write handles chunk.read returning nil' do
|
354
|
+
ingester_mock = ingester_stub
|
355
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
356
|
+
logger_mock = logger_stub
|
357
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
358
|
+
chunk = chunk_stub(data: nil)
|
359
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
360
|
+
end
|
361
|
+
|
362
|
+
test 'write handles tag and unique_id with unicode and invalid bytes' do
|
363
|
+
ingester_mock = ingester_stub
|
364
|
+
ingester_mock.expects(:upload_data_to_blob_and_queue).once
|
365
|
+
logger_mock = logger_stub
|
366
|
+
set_mocks(ingester: ingester_mock, logger: logger_mock)
|
367
|
+
chunk = chunk_stub(tag: "t\u2603\xFF", unique_id: "\xFF\xFE\xFD".b)
|
368
|
+
assert_nothing_raised { @driver.instance.write(chunk) }
|
369
|
+
end
|
370
|
+
end
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-kusto
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.beta
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Komal Rani
|
8
|
+
- Kusto OSS IDC Team
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2025-08-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 2.6.9
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 2.6.9
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 13.2.1
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 13.2.1
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: test-unit
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 3.6.7
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 3.6.7
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: fluentd
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.0'
|
63
|
+
- - "<"
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '2'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '1.0'
|
73
|
+
- - "<"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2'
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: rubocop
|
78
|
+
requirement: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.0'
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: dotenv
|
92
|
+
requirement: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.0'
|
97
|
+
type: :runtime
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.0'
|
104
|
+
description: Fluentd output plugin to ingest logs into Azure Data Explorer (Kusto),
|
105
|
+
supporting managed identity and AAD authentication, with multi-worker and buffer
|
106
|
+
support.
|
107
|
+
email:
|
108
|
+
- t-komalrani+microsoft@microsoft.com
|
109
|
+
- kustoossidc@microsoft.com
|
110
|
+
executables: []
|
111
|
+
extensions: []
|
112
|
+
extra_rdoc_files: []
|
113
|
+
files:
|
114
|
+
- Gemfile
|
115
|
+
- LICENSE
|
116
|
+
- README.md
|
117
|
+
- lib/fluent/plugin/auth/aad_tokenprovider.rb
|
118
|
+
- lib/fluent/plugin/auth/azcli_tokenprovider.rb
|
119
|
+
- lib/fluent/plugin/auth/mi_tokenprovider.rb
|
120
|
+
- lib/fluent/plugin/auth/tokenprovider_base.rb
|
121
|
+
- lib/fluent/plugin/auth/wif_tokenprovider.rb
|
122
|
+
- lib/fluent/plugin/client.rb
|
123
|
+
- lib/fluent/plugin/conffile.rb
|
124
|
+
- lib/fluent/plugin/ingester.rb
|
125
|
+
- lib/fluent/plugin/kusto_error_handler.rb
|
126
|
+
- lib/fluent/plugin/kusto_query.rb
|
127
|
+
- lib/fluent/plugin/out_kusto.rb
|
128
|
+
- test/helper.rb
|
129
|
+
- test/plugin/test_azcli_tokenprovider.rb
|
130
|
+
- test/plugin/test_e2e_kusto.rb
|
131
|
+
- test/plugin/test_out_kusto_config.rb
|
132
|
+
- test/plugin/test_out_kusto_format.rb
|
133
|
+
- test/plugin/test_out_kusto_process.rb
|
134
|
+
- test/plugin/test_out_kusto_start.rb
|
135
|
+
- test/plugin/test_out_kusto_try_write.rb
|
136
|
+
- test/plugin/test_out_kusto_write.rb
|
137
|
+
homepage: https://github.com/Azure/azure-kusto-fluentd
|
138
|
+
licenses:
|
139
|
+
- Apache-2.0
|
140
|
+
metadata:
|
141
|
+
fluentd_plugin: 'true'
|
142
|
+
fluentd_group: output
|
143
|
+
post_install_message:
|
144
|
+
rdoc_options: []
|
145
|
+
require_paths:
|
146
|
+
- lib
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '2.5'
|
152
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">"
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: 1.3.1
|
157
|
+
requirements: []
|
158
|
+
rubygems_version: 3.0.3.1
|
159
|
+
signing_key:
|
160
|
+
specification_version: 4
|
161
|
+
summary: A custom Fluentd output plugin for Azure Kusto ingestion.
|
162
|
+
test_files:
|
163
|
+
- test/helper.rb
|
164
|
+
- test/plugin/test_azcli_tokenprovider.rb
|
165
|
+
- test/plugin/test_e2e_kusto.rb
|
166
|
+
- test/plugin/test_out_kusto_config.rb
|
167
|
+
- test/plugin/test_out_kusto_format.rb
|
168
|
+
- test/plugin/test_out_kusto_process.rb
|
169
|
+
- test/plugin/test_out_kusto_start.rb
|
170
|
+
- test/plugin/test_out_kusto_try_write.rb
|
171
|
+
- test/plugin/test_out_kusto_write.rb
|