fluent-plugin-bigquery 0.0.1 → 0.0.2
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 +2 -3
- data/lib/fluent/plugin/bigquery/version.rb +1 -1
- data/lib/fluent/plugin/out_bigquery.rb +110 -26
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: caee66954ca996b43797e050825d5115dcd132f8
|
4
|
+
data.tar.gz: 040afb42fa0fe48f61a90d11e9ea5684d170974c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15aed88d76491c467ff6e865381d1d78884d632f998c71569e53faadb1acf18d572e4459b55d4ff5a3e57121365cf1ec90c4c292726e492bcfdac6a52ab7f815
|
7
|
+
data.tar.gz: a5ed1a27a117a6f54a2931741c2ffdf37b856e54074af94e2740e70ed361fa21f4790a20e926d675019d1280574497303825562be0b75097200b5e58dd49646c
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# fluent-plugin-
|
1
|
+
# fluent-plugin-bigquery
|
2
2
|
|
3
3
|
Fluentd output plugin to load/insert data into Google BigQuery.
|
4
4
|
|
@@ -131,8 +131,7 @@ With this configuration, flushing will be done in 0.25 seconds after record inpu
|
|
131
131
|
|
132
132
|
* support Load API
|
133
133
|
* with automatically configured flush/buffer options
|
134
|
-
* support
|
135
|
-
* and support optional data fields
|
134
|
+
* support optional data fields
|
136
135
|
* support NULLABLE/REQUIRED/REPEATED field options
|
137
136
|
* OAuth installed application credentials support
|
138
137
|
* Google API discovery expiration
|
@@ -126,25 +126,25 @@ module Fluent
|
|
126
126
|
|
127
127
|
@tablelist = @tables ? @tables.split(',') : [@table]
|
128
128
|
|
129
|
-
@fields =
|
129
|
+
@fields = RecordSchema.new
|
130
130
|
if @field_string
|
131
131
|
@field_string.split(',').each do |fieldname|
|
132
|
-
@fields
|
132
|
+
@fields.register_field fieldname, :string
|
133
133
|
end
|
134
134
|
end
|
135
135
|
if @field_integer
|
136
136
|
@field_integer.split(',').each do |fieldname|
|
137
|
-
@fields
|
137
|
+
@fields.register_field fieldname, :integer
|
138
138
|
end
|
139
139
|
end
|
140
140
|
if @field_float
|
141
141
|
@field_float.split(',').each do |fieldname|
|
142
|
-
@fields
|
142
|
+
@fields.register_field fieldname, :float
|
143
143
|
end
|
144
144
|
end
|
145
145
|
if @field_boolean
|
146
146
|
@field_boolean.split(',').each do |fieldname|
|
147
|
-
@fields
|
147
|
+
@fields.register_field fieldname, :boolean
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
@@ -204,7 +204,7 @@ module Fluent
|
|
204
204
|
"rows" => rows
|
205
205
|
}
|
206
206
|
)
|
207
|
-
|
207
|
+
unless res.success?
|
208
208
|
# api_error? -> client cache clear
|
209
209
|
@cached_client = nil
|
210
210
|
|
@@ -227,32 +227,14 @@ module Fluent
|
|
227
227
|
raise NotImplementedError # TODO
|
228
228
|
end
|
229
229
|
|
230
|
-
def format_record(record)
|
231
|
-
out = {}
|
232
|
-
@fields.each do |key, type|
|
233
|
-
value = record[key]
|
234
|
-
next if value.nil? # field does not exists, or null value
|
235
|
-
out[key] = case type
|
236
|
-
when :string then record[key].to_s
|
237
|
-
when :integer then record[key].to_i
|
238
|
-
when :float then record[key].to_f
|
239
|
-
when :boolean then !!record[key]
|
240
|
-
# when :record
|
241
|
-
else
|
242
|
-
raise "BUG: unknown field type #{type}"
|
243
|
-
end
|
244
|
-
end
|
245
|
-
out
|
246
|
-
end
|
247
|
-
|
248
230
|
def format_stream(tag, es)
|
249
231
|
super
|
250
232
|
buf = ''
|
251
233
|
es.each do |time, record|
|
252
234
|
row = if @time_field
|
253
|
-
|
235
|
+
@fields.format(record.merge({@time_field => @timef.format(time)}))
|
254
236
|
else
|
255
|
-
|
237
|
+
@fields.format(record)
|
256
238
|
end
|
257
239
|
buf << {"json" => row}.to_msgpack unless row.empty?
|
258
240
|
end
|
@@ -292,5 +274,107 @@ module Fluent
|
|
292
274
|
# client.authorization = flow.authorize # browser authentication !
|
293
275
|
# client
|
294
276
|
# end
|
277
|
+
|
278
|
+
class FieldSchema
|
279
|
+
def format(value)
|
280
|
+
raise NotImplementedError, "Must implement in a subclass"
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
class StringFieldSchema < FieldSchema
|
285
|
+
def type
|
286
|
+
:string
|
287
|
+
end
|
288
|
+
|
289
|
+
def format(value)
|
290
|
+
value.to_s
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
class IntegerFieldSchema < FieldSchema
|
295
|
+
def type
|
296
|
+
:integer
|
297
|
+
end
|
298
|
+
|
299
|
+
def format(value)
|
300
|
+
value.to_i
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
class FloatFieldSchema < FieldSchema
|
305
|
+
def type
|
306
|
+
:float
|
307
|
+
end
|
308
|
+
|
309
|
+
def format(value)
|
310
|
+
value.to_f
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
class BooleanFieldSchema < FieldSchema
|
315
|
+
def type
|
316
|
+
:boolean
|
317
|
+
end
|
318
|
+
|
319
|
+
def format(value)
|
320
|
+
!!value
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
class RecordSchema < FieldSchema
|
325
|
+
FIELD_TYPES = {
|
326
|
+
:string => StringFieldSchema,
|
327
|
+
:integer => IntegerFieldSchema,
|
328
|
+
:float => FloatFieldSchema,
|
329
|
+
:boolean => BooleanFieldSchema
|
330
|
+
}.freeze
|
331
|
+
|
332
|
+
def initialize
|
333
|
+
@fields = {}
|
334
|
+
end
|
335
|
+
|
336
|
+
def type
|
337
|
+
:record
|
338
|
+
end
|
339
|
+
|
340
|
+
def [](name)
|
341
|
+
@fields[name]
|
342
|
+
end
|
343
|
+
|
344
|
+
def register_field(name, type)
|
345
|
+
raise ConfigError, "field #{name} is registered twice" if @fields.key?(name)
|
346
|
+
if name[/\./]
|
347
|
+
recordname = $`
|
348
|
+
fieldname = $'
|
349
|
+
register_record_field(recordname)
|
350
|
+
@fields[recordname].register_field(fieldname, type)
|
351
|
+
else
|
352
|
+
schema = FIELD_TYPES[type]
|
353
|
+
raise ConfigError, "[Bug] Invalid field type #{type}" unless schema
|
354
|
+
@fields[name] = schema.new
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def format(record)
|
359
|
+
out = {}
|
360
|
+
@fields.each do |key, schema|
|
361
|
+
value = record[key]
|
362
|
+
next if value.nil? # field does not exists, or null value
|
363
|
+
out[key] = schema.format(value)
|
364
|
+
end
|
365
|
+
out
|
366
|
+
end
|
367
|
+
|
368
|
+
private
|
369
|
+
def register_record_field(name)
|
370
|
+
if !@fields.key?(name)
|
371
|
+
@fields[name] = RecordSchema.new
|
372
|
+
else
|
373
|
+
unless @fields[name].kind_of?(RecordSchema)
|
374
|
+
raise ConfigError, "field #{name} is required to be a record but already registered as #{@field[name]}"
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
295
379
|
end
|
296
380
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-bigquery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TAGOMORI Satoshi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|