influxdb-lineprotocol-parser 0.0.2 → 0.0.3
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/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
|
|