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 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
@@ -0,0 +1,3 @@
1
+ Release 0.1.0 - 2020/02/23
2
+
3
+ * First release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # Deduplication records for [Fluentd](http://fluentd.org) with a influxdb output plugin
2
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.test_files = FileList['test/test_*.rb']
9
+ test.verbose = true
10
+ end
11
+
12
+ task :default => [:build]
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