influxdb-lineprotocol-parser 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/influxdb/lineprotocol/parser.rb +111 -47
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8e433f4f34e310f1886a551df2e5673f8f3ca4831f786cb22bb490b31740dc5
|
4
|
+
data.tar.gz: 5fd20ecf8b09f2fa682fff68dad78fdecd6c47c87f9cbe0d887ba57d4978565b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0273635beaf425e9d284219ac2e513bb3bc467fd10f65e6e9600e368743bfa26ac5e22edba50a50778e20313355dd3a1c79b9ecc6e89b8157626c3db3efe627
|
7
|
+
data.tar.gz: c8e24fde968761c85a6eecaa6d6a51bde1976a950b167bed45b53636e70644d5a18f9394bf857473d813df9bfa7915bd2f62a00d8e4f8257ec1173ce32b453cf
|
@@ -17,7 +17,7 @@ require 'logger'
|
|
17
17
|
##
|
18
18
|
# Extension to InfluxDB module.
|
19
19
|
#
|
20
|
-
module
|
20
|
+
module InfluxDB
|
21
21
|
##
|
22
22
|
# Line Protocol module.
|
23
23
|
#
|
@@ -27,9 +27,15 @@ module InfluxDBExt
|
|
27
27
|
# Line Protocol parser.
|
28
28
|
#
|
29
29
|
class Parser
|
30
|
-
def initialize(logger: nil, log_level: :warn)
|
30
|
+
def initialize(logger: nil, log_level: :warn, escapes: nil)
|
31
31
|
@log = logger || ::Logger.new(STDERR)
|
32
32
|
@log.level = log_level
|
33
|
+
case escapes
|
34
|
+
when :compat
|
35
|
+
@unescapes = InfluxDB::LineProtocol::CompatUnescapes.new
|
36
|
+
else
|
37
|
+
@unescapes = InfluxDB::LineProtocol::Unescapes.new
|
38
|
+
end
|
33
39
|
enter_initial
|
34
40
|
end
|
35
41
|
|
@@ -40,9 +46,11 @@ module InfluxDBExt
|
|
40
46
|
#
|
41
47
|
# If block is not given, returns a list of points in data.
|
42
48
|
#
|
49
|
+
# The data can be a String, or a single Integer or an Array of Integers.
|
50
|
+
# The Integers are assumed to be UTF-8 bytes.
|
51
|
+
#
|
43
52
|
def each_point(data)
|
44
|
-
|
45
|
-
buf = data.to_s.encode(UTF_8).bytes.freeze
|
53
|
+
buf = bytes(data)
|
46
54
|
i = 0
|
47
55
|
len = buf.size
|
48
56
|
|
@@ -82,14 +90,14 @@ module InfluxDBExt
|
|
82
90
|
BACKSLASH = 92
|
83
91
|
COMMA = 44
|
84
92
|
EQUALS = 61
|
85
|
-
HASH =
|
93
|
+
HASH = 35
|
86
94
|
NEWLINE = 10
|
87
95
|
NULL = 0
|
88
96
|
SPACE = 32
|
89
97
|
TAB = 9
|
90
98
|
|
91
99
|
# Start (and end) marker of a string field value (not special anywhere else)
|
92
|
-
QUOTATION_MARK =
|
100
|
+
QUOTATION_MARK = 34
|
93
101
|
|
94
102
|
# Start markers of a numeric field value (not special anywhere else)
|
95
103
|
PLUS_SIGN = 43
|
@@ -117,7 +125,7 @@ module InfluxDBExt
|
|
117
125
|
when COMMA
|
118
126
|
@log.error "initial: missing measurement"
|
119
127
|
@state = :invalid
|
120
|
-
|
128
|
+
i + 1
|
121
129
|
when HASH # comment
|
122
130
|
@state = :comment
|
123
131
|
i + 1
|
@@ -139,21 +147,21 @@ module InfluxDBExt
|
|
139
147
|
i += 1
|
140
148
|
else
|
141
149
|
c = buf[i]
|
150
|
+
raise "unsupported input type" unless c.is_a? Integer
|
142
151
|
case c
|
143
152
|
when BACKSLASH
|
144
153
|
@escaped = true
|
145
154
|
i += 1
|
146
155
|
when COMMA # start of tag set.
|
147
|
-
@point = {series: decode(buf
|
156
|
+
@point = {series: decode(buf, start, i-1), tags: {}, values: {}}
|
148
157
|
@state = :tag_key
|
149
158
|
return i+1
|
150
159
|
when NEWLINE
|
151
160
|
@log.error("measurement: missing fields")
|
152
|
-
|
153
|
-
|
154
|
-
return i+1
|
161
|
+
@state = :invalid
|
162
|
+
return i
|
155
163
|
when SPACE # start of field set
|
156
|
-
@point = {series: decode(buf
|
164
|
+
@point = {series: decode(buf, start, i-1), values: {}}
|
157
165
|
@state = :field_key
|
158
166
|
i, _ = whitespace(buf, i + 1, len)
|
159
167
|
return i
|
@@ -176,23 +184,24 @@ module InfluxDBExt
|
|
176
184
|
i += 1
|
177
185
|
else
|
178
186
|
c = buf[i]
|
187
|
+
raise "unsupported input type" unless c.is_a? Integer
|
179
188
|
case c
|
180
189
|
when BACKSLASH
|
181
190
|
@escaped = true
|
182
191
|
i += 1
|
183
192
|
when EQUALS
|
184
|
-
@key = decode(buf
|
193
|
+
@key = decode(buf, start, i-1)
|
185
194
|
if @key == ""
|
186
195
|
@log.error("tag_key: empty key")
|
187
196
|
@state = :invalid
|
188
|
-
return
|
197
|
+
return i
|
189
198
|
end
|
190
199
|
@state = :tag_value
|
191
200
|
return i+1
|
192
201
|
when NEWLINE
|
193
202
|
@log.error("tag key: newline")
|
194
|
-
|
195
|
-
return i
|
203
|
+
@state = :invalid
|
204
|
+
return i
|
196
205
|
else
|
197
206
|
i += 1
|
198
207
|
end
|
@@ -212,21 +221,22 @@ module InfluxDBExt
|
|
212
221
|
i += 1
|
213
222
|
else
|
214
223
|
c = buf[i]
|
224
|
+
raise "unsupported input type" unless c.is_a? Integer
|
215
225
|
case c
|
216
226
|
when BACKSLASH
|
217
227
|
@escaped = true
|
218
228
|
i += 1
|
219
229
|
when COMMA
|
220
|
-
@point[:tags][@key] = decode(buf
|
230
|
+
@point[:tags][@key] = decode(buf, start, i-1)
|
221
231
|
@key = nil
|
222
232
|
@state = :tag_key
|
223
233
|
return i+1
|
224
234
|
when NEWLINE
|
225
235
|
@log.error("tag value: newline")
|
226
|
-
|
227
|
-
return i
|
236
|
+
@state = :invalid
|
237
|
+
return i
|
228
238
|
when SPACE
|
229
|
-
@point[:tags][@key] = decode(buf
|
239
|
+
@point[:tags][@key] = decode(buf, start, i-1)
|
230
240
|
@key = nil
|
231
241
|
@state = :field_key
|
232
242
|
i, _ = whitespace(buf, i + 1, len)
|
@@ -250,23 +260,24 @@ module InfluxDBExt
|
|
250
260
|
i += 1
|
251
261
|
else
|
252
262
|
c = buf[i]
|
263
|
+
raise "unsupported input type" unless c.is_a? Integer
|
253
264
|
case c
|
254
265
|
when BACKSLASH
|
255
266
|
@escaped = true
|
256
267
|
i += 1
|
257
268
|
when EQUALS
|
258
|
-
@key = decode(buf
|
269
|
+
@key = decode(buf, start, i-1)
|
259
270
|
if @key == ""
|
260
271
|
@log.error("field key: empty key")
|
261
272
|
@state = :invalid
|
262
|
-
return
|
273
|
+
return i
|
263
274
|
end
|
264
275
|
@state = :field_value
|
265
276
|
return i+1
|
266
277
|
when NEWLINE
|
267
278
|
@log.error("field key: newline")
|
268
|
-
|
269
|
-
return i
|
279
|
+
@state = :invalid
|
280
|
+
return i
|
270
281
|
else
|
271
282
|
i += 1
|
272
283
|
end
|
@@ -283,6 +294,7 @@ module InfluxDBExt
|
|
283
294
|
return len
|
284
295
|
end
|
285
296
|
c = buf[i]
|
297
|
+
raise "unsupported input type" unless c.is_a? Integer
|
286
298
|
case c
|
287
299
|
when LATIN_CAPITAL_LETTER_F, LATIN_CAPITAL_LETTER_T, LATIN_SMALL_LETTER_F, LATIN_SMALL_LETTER_T
|
288
300
|
@state = :field_value_boolean
|
@@ -296,7 +308,7 @@ module InfluxDBExt
|
|
296
308
|
else
|
297
309
|
@log.error("field value: invalid")
|
298
310
|
@state = :invalid
|
299
|
-
|
311
|
+
i
|
300
312
|
end
|
301
313
|
end
|
302
314
|
|
@@ -308,23 +320,24 @@ module InfluxDBExt
|
|
308
320
|
i += 1
|
309
321
|
else
|
310
322
|
c = buf[i]
|
323
|
+
raise "unsupported input type" unless c.is_a? Integer
|
311
324
|
case c
|
312
325
|
when BACKSLASH
|
313
326
|
@escaped = true
|
314
327
|
i += 1
|
315
328
|
when COMMA
|
316
|
-
value = decode(buf
|
329
|
+
value = decode(buf, start, i-1)
|
317
330
|
if value.nil?
|
318
331
|
@log.error("field value boolean: invalid boolean")
|
319
332
|
@state = :invalid
|
320
|
-
return
|
333
|
+
return i
|
321
334
|
end
|
322
335
|
@point[:values][@key] = value
|
323
336
|
@key = nil
|
324
337
|
@state = :field_key
|
325
338
|
return i+1
|
326
339
|
when NEWLINE
|
327
|
-
value = decode(buf
|
340
|
+
value = decode(buf, start, i-1)
|
328
341
|
if value.nil?
|
329
342
|
@log.error("field value boolean: invalid boolean")
|
330
343
|
enter_initial
|
@@ -335,11 +348,11 @@ module InfluxDBExt
|
|
335
348
|
@state = :complete
|
336
349
|
return i+1
|
337
350
|
when SPACE
|
338
|
-
value = decode(buf
|
351
|
+
value = decode(buf, start, i-1)
|
339
352
|
if value.nil?
|
340
353
|
@log.error("field value boolean: invalid boolean")
|
341
354
|
@state = :invalid
|
342
|
-
return
|
355
|
+
return i
|
343
356
|
end
|
344
357
|
@point[:values][@key] = value
|
345
358
|
@key = nil
|
@@ -365,34 +378,35 @@ module InfluxDBExt
|
|
365
378
|
i += 1
|
366
379
|
else
|
367
380
|
c = buf[i]
|
381
|
+
raise "unsupported input type" unless c.is_a? Integer
|
368
382
|
case c
|
369
383
|
when BACKSLASH
|
370
384
|
@escaped = true
|
371
385
|
i += 1
|
372
386
|
when COMMA
|
373
|
-
value = decode(buf
|
387
|
+
value = decode(buf, start, i-1)
|
374
388
|
if value.nil?
|
375
389
|
@log.error("field value numeric: invalid number")
|
376
390
|
@state = :invalid
|
377
|
-
return
|
391
|
+
return i
|
378
392
|
end
|
379
393
|
@point[:values][@key] = value
|
380
394
|
@key = nil
|
381
395
|
@state = :field_key
|
382
396
|
return i+1
|
383
397
|
when NEWLINE
|
384
|
-
value = decode(buf
|
398
|
+
value = decode(buf, start, i-1)
|
385
399
|
if value.nil?
|
386
400
|
@log.error("field value numeric: invalid number")
|
387
401
|
@state = :invalid
|
388
|
-
return
|
402
|
+
return i
|
389
403
|
end
|
390
404
|
@point[:values][@key] = value
|
391
405
|
@key = nil
|
392
406
|
@state = :complete
|
393
407
|
return i+1
|
394
408
|
when SPACE
|
395
|
-
value = decode(buf
|
409
|
+
value = decode(buf, start, i-1)
|
396
410
|
if value.nil?
|
397
411
|
@log.error("field value numeric: invalid number")
|
398
412
|
@state = :invalid
|
@@ -422,16 +436,17 @@ module InfluxDBExt
|
|
422
436
|
i += 1
|
423
437
|
else
|
424
438
|
c = buf[i]
|
439
|
+
raise "unsupported input type" unless c.is_a? Integer
|
425
440
|
case c
|
426
441
|
when BACKSLASH
|
427
442
|
@escaped = true
|
428
443
|
i += 1
|
429
444
|
when QUOTATION_MARK
|
430
|
-
value = decode(buf
|
445
|
+
value = decode(buf, start, i-1)
|
431
446
|
if value.nil?
|
432
447
|
@log.error("field value string: invalid string")
|
433
448
|
@state = :invalid
|
434
|
-
return
|
449
|
+
return i
|
435
450
|
end
|
436
451
|
@point[:values][@key] = value
|
437
452
|
@key = nil
|
@@ -450,7 +465,9 @@ module InfluxDBExt
|
|
450
465
|
|
451
466
|
def field_value_string_end(buf, i, len)
|
452
467
|
if i < len
|
453
|
-
|
468
|
+
c = buf[i]
|
469
|
+
raise "unsupported input type" unless c.is_a? Integer
|
470
|
+
case c
|
454
471
|
when COMMA
|
455
472
|
@state = :field_key
|
456
473
|
i + 1
|
@@ -463,7 +480,7 @@ module InfluxDBExt
|
|
463
480
|
i
|
464
481
|
else
|
465
482
|
@state = :invalid
|
466
|
-
|
483
|
+
i
|
467
484
|
end
|
468
485
|
else
|
469
486
|
len
|
@@ -478,16 +495,17 @@ module InfluxDBExt
|
|
478
495
|
i += 1
|
479
496
|
else
|
480
497
|
c = buf[i]
|
498
|
+
raise "unsupported input type" unless c.is_a? Integer
|
481
499
|
case c
|
482
500
|
when BACKSLASH
|
483
501
|
@escaped = true
|
484
502
|
i += 1
|
485
503
|
when NEWLINE
|
486
|
-
value = decode(buf
|
504
|
+
value = decode(buf, start, i-1)
|
487
505
|
if value.nil?
|
488
506
|
@log.error("timestamp: invalid timestamp")
|
489
507
|
@state = :invalid
|
490
|
-
return
|
508
|
+
return i
|
491
509
|
end
|
492
510
|
@point[:timestamp] = value
|
493
511
|
@key = nil
|
@@ -508,6 +526,7 @@ module InfluxDBExt
|
|
508
526
|
i = line_end(buf, i, len)
|
509
527
|
if i < len
|
510
528
|
enter_initial
|
529
|
+
i += 1
|
511
530
|
end
|
512
531
|
i
|
513
532
|
end
|
@@ -516,18 +535,19 @@ module InfluxDBExt
|
|
516
535
|
i = line_end(buf, i, len)
|
517
536
|
if i < len
|
518
537
|
enter_initial
|
538
|
+
i += 1
|
519
539
|
end
|
520
540
|
i
|
521
541
|
end
|
522
542
|
|
523
543
|
# Starting from position i,
|
524
|
-
# returns the index of the
|
525
|
-
# Returns len if no such byte is found
|
544
|
+
# returns the index of the newline.
|
545
|
+
# Returns len if no such byte is found.
|
526
546
|
def line_end(buf, i, len)
|
527
547
|
while i < len
|
528
548
|
c = buf[i]
|
549
|
+
raise "unsupported input type" unless c.is_a? Integer
|
529
550
|
if c == NEWLINE
|
530
|
-
i += 1
|
531
551
|
return i
|
532
552
|
end
|
533
553
|
i += 1
|
@@ -541,6 +561,7 @@ module InfluxDBExt
|
|
541
561
|
def whitespace(buf, i, len)
|
542
562
|
while i < len
|
543
563
|
c = buf[i]
|
564
|
+
raise "unsupported input type" unless c.is_a? Integer
|
544
565
|
if c != SPACE && c != TAB && c != NULL
|
545
566
|
return [i, c]
|
546
567
|
end
|
@@ -549,12 +570,16 @@ module InfluxDBExt
|
|
549
570
|
[len, nil]
|
550
571
|
end
|
551
572
|
|
552
|
-
def decode(buf)
|
553
|
-
str = @buf.nil?
|
573
|
+
def decode(buf, start, i)
|
574
|
+
str = if @buf.nil?
|
575
|
+
(start <= i) ? string(buf[start..i]) : ""
|
576
|
+
else
|
577
|
+
(start <= i) ? string(@buf + buf[start..i]) : string(@buf)
|
578
|
+
end
|
554
579
|
@buf = nil
|
555
580
|
case @state
|
556
581
|
when :measurement
|
557
|
-
str
|
582
|
+
@unescapes.unescape(:measurement, str)
|
558
583
|
when :tag_key
|
559
584
|
str
|
560
585
|
when :tag_value
|
@@ -595,9 +620,48 @@ module InfluxDBExt
|
|
595
620
|
end
|
596
621
|
end
|
597
622
|
|
623
|
+
def bytes(data)
|
624
|
+
case data
|
625
|
+
when nil
|
626
|
+
[].freeze
|
627
|
+
when Integer
|
628
|
+
[data].freeze
|
629
|
+
when String
|
630
|
+
data.encode(UTF_8).bytes.freeze
|
631
|
+
when Array
|
632
|
+
data
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
598
636
|
def string(buf)
|
599
637
|
buf.pack(UTF_8_PACK_FORMAT).force_encoding(UTF_8)
|
600
638
|
end
|
639
|
+
end # Parser
|
640
|
+
|
641
|
+
class CompatUnescapes
|
642
|
+
def unescape(field, value)
|
643
|
+
case field
|
644
|
+
when :measurement
|
645
|
+
value.gsub(/\\([, ])/, '\\1')
|
646
|
+
# escaped comma anywhere
|
647
|
+
# escaped space anywhere
|
648
|
+
end
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
652
|
+
class Unescapes
|
653
|
+
def unescape(field, value)
|
654
|
+
case field
|
655
|
+
when :measurement
|
656
|
+
# 1. escaped hash, null, or tab at the beginning
|
657
|
+
# 2. escaped comma, space, or newline anywhere
|
658
|
+
# 3. escaped backslash at the end
|
659
|
+
value
|
660
|
+
.sub(/^\\([#\0\t])/, '\\1')
|
661
|
+
.gsub(/\\([, \n])/, '\\1')
|
662
|
+
.sub(/\\\\$/, '\\')
|
663
|
+
end
|
664
|
+
end
|
601
665
|
end
|
602
666
|
end
|
603
667
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: influxdb-lineprotocol-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikko Värri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-05-
|
11
|
+
date: 2019-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'Streaming parser for InfluxDB line protocol.
|
14
14
|
|