fluent-plugin-influxdb-deduplication 0.1.0
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/ChangeLog +3 -0
- data/Gemfile +3 -0
- data/README.md +2 -0
- data/Rakefile +12 -0
- data/VERSION +1 -0
- data/fluent-plugin-influxdb-deduplication.gemspec +21 -0
- data/lib/fluent/plugin/filter_influxdb_deduplication.rb +75 -0
- data/test/test_filter_influxdb_deduplication.rb +105 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: aac38463aad973daa8abf8f04c51c51e3654be687c70fbfa4d2ded133075fe0d
|
4
|
+
data.tar.gz: 5fff6893e6240e861740968e45754665f50484e44ac08ea37f93d472381b4c6f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 91b7f1f3c930937daeec8811bddb31f3e5e5718de6842fa57d7243534455cf8570835035017749ee22f1fea2ecef7c228deb08e8a47a4a2a74b5bfb1e6be6821
|
7
|
+
data.tar.gz: 5efdea5ff2243289eb2b73420f6bedae059d0b5157f2d6711f16f781f48cf8935dfd12c9a54c36f937c93ac8f4f724e23db4b1078a936864d4ea9221d6ae7921
|
data/ChangeLog
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "fluent-plugin-influxdb-deduplication"
|
6
|
+
gem.description = "Filter plugin for deduplicating records for influxdb"
|
7
|
+
gem.summary = gem.description
|
8
|
+
gem.version = File.read("VERSION").strip
|
9
|
+
gem.authors = ["Marc Adams"]
|
10
|
+
gem.email = "marc.adams.ge@gmail.com"
|
11
|
+
#gem.platform = Gem::Platform::RUBY
|
12
|
+
gem.license = 'MIT'
|
13
|
+
gem.files = `git ls-files`.split("\n")
|
14
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
16
|
+
gem.require_paths = ['lib']
|
17
|
+
|
18
|
+
gem.add_dependency "fluentd", [">= 1.0", "< 2"]
|
19
|
+
gem.add_development_dependency "rake", ">= 0.9.2"
|
20
|
+
gem.add_development_dependency("test-unit", ["~> 3.1.4"])
|
21
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'fluent/plugin/filter'
|
2
|
+
|
3
|
+
module Fluent
|
4
|
+
class Plugin::InfluxdbDeduplicationFilter < Plugin::Filter
|
5
|
+
Fluent::Plugin.register_filter('influxdb_deduplication', self)
|
6
|
+
|
7
|
+
config_param :time_key, :string, default: nil,
|
8
|
+
desc: <<-DESC
|
9
|
+
The output time key to use.
|
10
|
+
DESC
|
11
|
+
|
12
|
+
config_param :out_of_order, :string, default: nil,
|
13
|
+
desc: <<-DESC
|
14
|
+
If not nil, the field takes the value true if the record arrives in order and false otherwise
|
15
|
+
DESC
|
16
|
+
|
17
|
+
def configure(conf)
|
18
|
+
super
|
19
|
+
|
20
|
+
unless @time_key
|
21
|
+
raise Fluent::ConfigError, "a time key must be set"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def start
|
26
|
+
super
|
27
|
+
|
28
|
+
@last_timestamp = 0
|
29
|
+
@sequence = 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def filter(tag, time, record)
|
33
|
+
if time.is_a?(Integer)
|
34
|
+
input_time = Fluent::EventTime.new(time)
|
35
|
+
elsif time.is_a?(Fluent::EventTime)
|
36
|
+
input_time = time
|
37
|
+
else
|
38
|
+
@log.error("unreadable time")
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
|
42
|
+
nano_time = input_time.sec * 1000000000
|
43
|
+
|
44
|
+
if input_time.sec < @last_timestamp
|
45
|
+
@log.debug("out of sequence timestamp")
|
46
|
+
if @out_of_order
|
47
|
+
record[@out_of_order] = true
|
48
|
+
record[@time_key] = nano_time
|
49
|
+
else
|
50
|
+
@log.debug("out of order record dropped")
|
51
|
+
return nil
|
52
|
+
end
|
53
|
+
elsif input_time.sec == @last_timestamp && @sequence < 999999999
|
54
|
+
@sequence = @sequence + 1
|
55
|
+
record[@time_key] = nano_time + @sequence
|
56
|
+
if @out_of_order
|
57
|
+
record[@out_of_order] = false
|
58
|
+
end
|
59
|
+
elsif input_time.sec == @last_timestamp && @sequence == 999999999
|
60
|
+
@log.error("received more then 999999999 records in a second")
|
61
|
+
return nil
|
62
|
+
else
|
63
|
+
@sequence = 0
|
64
|
+
@last_timestamp = input_time.sec
|
65
|
+
record[@time_key] = nano_time
|
66
|
+
if @out_of_order
|
67
|
+
record[@out_of_order] = false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
record
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'fluent/test'
|
3
|
+
require 'fluent/test/driver/filter'
|
4
|
+
require 'fluent/plugin/filter_influxdb_deduplication'
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
class InfluxdbDeduplicationFilterTest < Test::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
Fluent::Test.setup
|
10
|
+
@tag = 'test.tag'
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_driver(conf)
|
14
|
+
Fluent::Test::Driver::Filter.new(Fluent::Plugin::InfluxdbDeduplicationFilter).configure(conf)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_configure
|
18
|
+
d = create_driver %[
|
19
|
+
time_key my_time_key
|
20
|
+
]
|
21
|
+
|
22
|
+
time_key = d.instance.instance_variable_get(:@time_key)
|
23
|
+
assert time_key == "my_time_key"
|
24
|
+
|
25
|
+
assert_raises Fluent::ConfigError do
|
26
|
+
create_driver ""
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_in_sequence
|
31
|
+
d = create_driver %[
|
32
|
+
time_key time_key
|
33
|
+
]
|
34
|
+
|
35
|
+
time0 = Fluent::EventTime.new(1613910640)
|
36
|
+
time1 = Fluent::EventTime.new(1613910643)
|
37
|
+
|
38
|
+
d.run(default_tag: @tag) do
|
39
|
+
d.feed(time0, { "k1" => 0 })
|
40
|
+
d.feed(time0, { "k1" => 1 })
|
41
|
+
d.feed(time0, { "k1" => 2 })
|
42
|
+
d.feed(time1, { "k1" => 3 })
|
43
|
+
d.feed(time1, { "k1" => 4 })
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_equal [
|
47
|
+
[time0, { "k1" => 0, "time_key" => 1613910640000000000 }],
|
48
|
+
[time0, { "k1" => 1, "time_key" => 1613910640000000001 }],
|
49
|
+
[time0, { "k1" => 2, "time_key" => 1613910640000000002 }],
|
50
|
+
[time1, { "k1" => 3, "time_key" => 1613910643000000000 }],
|
51
|
+
[time1, { "k1" => 4, "time_key" => 1613910643000000001 }]
|
52
|
+
], d.filtered
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_out_of_sequence_dropped
|
56
|
+
d = create_driver %[
|
57
|
+
time_key time_key
|
58
|
+
]
|
59
|
+
|
60
|
+
time0 = Fluent::EventTime.new(1613910640)
|
61
|
+
time1 = Fluent::EventTime.new(1613910643)
|
62
|
+
|
63
|
+
d.run(default_tag: @tag) do
|
64
|
+
d.feed(time0, { "k1" => 0 })
|
65
|
+
d.feed(time1, { "k1" => 1 })
|
66
|
+
d.feed(time0, { "k1" => 2 })
|
67
|
+
d.feed(time1, { "k1" => 3 })
|
68
|
+
d.feed(time1, { "k1" => 4 })
|
69
|
+
end
|
70
|
+
|
71
|
+
assert_equal [
|
72
|
+
[time0, { "k1" => 0, "time_key" => 1613910640000000000 }],
|
73
|
+
[time1, { "k1" => 1, "time_key" => 1613910643000000000 }],
|
74
|
+
[time1, { "k1" => 3, "time_key" => 1613910643000000001 }],
|
75
|
+
[time1, { "k1" => 4, "time_key" => 1613910643000000002 }]
|
76
|
+
], d.filtered
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_out_of_sequence_field
|
80
|
+
d = create_driver %[
|
81
|
+
time_key time_key
|
82
|
+
out_of_order ooo_field
|
83
|
+
]
|
84
|
+
|
85
|
+
time0 = Fluent::EventTime.new(1613910640)
|
86
|
+
time1 = Fluent::EventTime.new(1613910643)
|
87
|
+
|
88
|
+
d.run(default_tag: @tag) do
|
89
|
+
d.feed(time0, { "k1" => 0 })
|
90
|
+
d.feed(time1, { "k1" => 1 })
|
91
|
+
d.feed(time0, { "k1" => 2 })
|
92
|
+
d.feed(time1, { "k1" => 3 })
|
93
|
+
d.feed(time1, { "k1" => 4 })
|
94
|
+
end
|
95
|
+
|
96
|
+
assert_equal [
|
97
|
+
[time0, { "k1" => 0, "time_key" => 1613910640000000000, "ooo_field" => false }],
|
98
|
+
[time1, { "k1" => 1, "time_key" => 1613910643000000000, "ooo_field" => false }],
|
99
|
+
[time0, { "k1" => 2, "time_key" => 1613910640000000000, "ooo_field" => true }],
|
100
|
+
[time1, { "k1" => 3, "time_key" => 1613910643000000001, "ooo_field" => false }],
|
101
|
+
[time1, { "k1" => 4, "time_key" => 1613910643000000002, "ooo_field" => false }]
|
102
|
+
], d.filtered
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-influxdb-deduplication
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marc Adams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-02-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fluentd
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.9.2
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.9.2
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: test-unit
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 3.1.4
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 3.1.4
|
61
|
+
description: Filter plugin for deduplicating records for influxdb
|
62
|
+
email: marc.adams.ge@gmail.com
|
63
|
+
executables: []
|
64
|
+
extensions: []
|
65
|
+
extra_rdoc_files: []
|
66
|
+
files:
|
67
|
+
- ChangeLog
|
68
|
+
- Gemfile
|
69
|
+
- README.md
|
70
|
+
- Rakefile
|
71
|
+
- VERSION
|
72
|
+
- fluent-plugin-influxdb-deduplication.gemspec
|
73
|
+
- lib/fluent/plugin/filter_influxdb_deduplication.rb
|
74
|
+
- test/test_filter_influxdb_deduplication.rb
|
75
|
+
homepage:
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubygems_version: 3.0.3
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Filter plugin for deduplicating records for influxdb
|
98
|
+
test_files:
|
99
|
+
- test/test_filter_influxdb_deduplication.rb
|