fluent-plugin-wendelin 0.1.alpha1

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
+ SHA1:
3
+ metadata.gz: 690acc01d3867ddd46c6cb0709553e512aeafad6
4
+ data.tar.gz: 3186bc8fe9cb69b7700d13a4b907e6b3a78f0553
5
+ SHA512:
6
+ metadata.gz: 74bcf2e5e9aecb28cb4966d49382b73d6ec803337e0e6cdaaf022c1a86aaf00ab2287c5cb1610d23eddd6220ea71129b84cb9f851bfa25934662f5ab2f5ffae2
7
+ data.tar.gz: 09b83cf665ee08f06b1114e717b169e14660d3de01bfac97679cfb951b600f68b5d24eb18f574e882ca69578ad3ee417ccb45ec3b80072f856239ba1105c81c8
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ /.bundle/
2
+ /Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # gem's dependencies are in .gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (C) 2015 Nexedi SA and Contributors
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ fluent-plugin-wendelin
2
+ ======================
3
+
4
+ This is output plugin for [Fluentd][] to forward data to [Wendelin][] system.
5
+
6
+ [Fluentd]: http://fluentd.org/
7
+ [Wendelin]: http://wendelin.io/
8
+
9
+
10
+ Configuration
11
+ -------------
12
+
13
+ A sample configuration to setup ingestion of data for a tag to Wendelin:
14
+
15
+ ```apache
16
+ <match your.sensor.tag>
17
+ @type wendelin
18
+ @id wendelin_out
19
+
20
+ streamtool_uri <Wendelin_URL>/erp5/portal_ingestion_policies/<YOUR_INGESTION_POLICY_ID>
21
+ user <your_wendelin_user>
22
+ password <your_wendelin_password>
23
+
24
+ # all parameters of BufferedOutput & Output classes are supported too, e.g.
25
+ # `buffer_type`, `flush_interval`, `num_threads`, `log_level`, etc - see
26
+ # their code near:
27
+ #
28
+ # https://github.com/fluent/fluentd/blob/master/lib/fluent/output.rb#L182
29
+ #
30
+ # logging setup description:
31
+ #
32
+ # http://docs.fluentd.org/articles/logging
33
+
34
+ buffer_type memory
35
+ #buffer_path "#{ENV['HOME']/var}"
36
+ flush_interval 5s
37
+ </match>
38
+ ```
39
+
40
+ See *example/to_wendelin.conf* for fully setup example.
41
+
42
+
43
+ TODO
44
+ ----
45
+
46
+ - make content to be posted over HTTP as raw (instead of urlencode data).
47
+ - HTTPS certificates are currently not verified.
48
+ - X.509 certificates instead of user / password.
49
+ - cleanup
@@ -0,0 +1,90 @@
1
+ # Example configuration of Wendelin output for Fluentd
2
+
3
+ ## built-in TCP input, so we can accept messages from other fluentd(s) and so
4
+ ## that fluent-cat works:
5
+ ## $ echo <json|msgpack> | fluent-cat <tag>
6
+ <source>
7
+ @type forward
8
+ @id forward_input
9
+ </source>
10
+
11
+
12
+ # HTTP input
13
+ # http://localhost:8888/<tag>?json=<json>
14
+ <source>
15
+ @type http
16
+ @id http_input
17
+ port 8888
18
+ </source>
19
+
20
+
21
+ ## output tag=sensor.** to Wendelin
22
+ <match <YOUR_SENSOR_TAG>.**>
23
+ @type wendelin
24
+ @id wendelin_out
25
+
26
+ streamtool_uri <Wendelin_URL>/erp5/portal_ingestion_policies/<YOUR_INGESTION_POLICY_ID>
27
+ # TODO ^^^ do not check peer's certificate
28
+ user <your_wendelin_user>
29
+ password <your_wendelin_password>
30
+
31
+ # all parameters of BufferedOutput & Output classes are supported too, e.g.
32
+ # `buffer_type`, `flush_interval`, `num_threads`, `log_level`, etc - see
33
+ # their code near:
34
+ #
35
+ # https://github.com/fluent/fluentd/blob/master/lib/fluent/output.rb#L182
36
+ #
37
+ # logging setup description:
38
+ #
39
+ # http://docs.fluentd.org/articles/logging
40
+
41
+ buffer_type memory
42
+ #buffer_path "#{ENV['HOME']/var}"
43
+ flush_interval 5s
44
+ </match>
45
+
46
+
47
+
48
+
49
+ # ---- monitoring & debugging ----
50
+
51
+
52
+ # Listen HTTP for monitoring
53
+ # http://localhost:24220/api/plugins
54
+ # http://localhost:24220/api/plugins?type=TYPE
55
+ # http://localhost:24220/api/plugins?tag=MYTAG
56
+ <source>
57
+ @type monitor_agent
58
+ @id monitor_agent_input
59
+
60
+ port 24220
61
+ </source>
62
+
63
+ # Listen DRb for debug
64
+ <source>
65
+ @type debug_agent
66
+ @id debug_agent_input
67
+
68
+ bind 127.0.0.1
69
+ port 24230
70
+ </source>
71
+
72
+
73
+ ## match tag=debug.** and dump to console
74
+ <match debug.**>
75
+ @type stdout
76
+ @id stdout_output
77
+ </match>
78
+
79
+
80
+ ## match fluent's internal events
81
+ #<match fluent.**>
82
+ # @type null
83
+ #</match>
84
+
85
+ ## match not matched logs and write to file
86
+ #<match **>
87
+ # @type file
88
+ # path /var/log/fluent/else
89
+ # compress gz
90
+ #</match>
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = "fluent-plugin-wendelin"
3
+ gem.version = "0.1.alpha1"
4
+ gem.authors = ["Kirill Smelkov"]
5
+ gem.email = ["kirr@nexedi.com"]
6
+ gem.summary = %q{Fluentd output to Wendelin}
7
+ gem.description = %q{Fluentd output plugin to forward data to Wendelin system}
8
+ gem.homepage = "https://lab.nexedi.cn/nexedi/fluent-plugin-wendelin"
9
+ gem.license = "APLv2"
10
+
11
+ gem.files = `git ls-files -z`.split("\x0")
12
+ gem.require_paths = ["lib"]
13
+
14
+ gem.add_runtime_dependency "fluentd", "~> 0"
15
+ # ? net/http
16
+ # ? openssl
17
+ end
@@ -0,0 +1,88 @@
1
+ # Fluentd output plugin to ingest data to Wendelin system
2
+ # Copyright (C) 2015 Nexedi SA and Contributors.
3
+ # Kirill Smelkov <kirr@nexedi.com>
4
+ #
5
+ # This program is free software: you can Use, Study, Modify and Redistribute
6
+ # it under the terms of the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+
19
+ # This plugin hooks into Fluentd in a way similiar to out_forward and
20
+ # out_secure_forward and outputs event stream to a Wendelin HTTP endpoint.
21
+
22
+ require 'fluent/output'
23
+ require_relative 'wendelin_client'
24
+
25
+
26
+ module Fluent
27
+
28
+ class WendelinOutput < ObjectBufferedOutput # XXX verify base class
29
+ Plugin.register_output('wendelin', self)
30
+
31
+ # where Wendelin's Input Stream Tool is located,
32
+ # ex http://example.com/erp5/portal_ingestion_policies/example_ingestion
33
+ config_param :streamtool_uri, :string
34
+
35
+ # credentials to authenticate this fluentd to wendelin
36
+ # by default credentials are not used
37
+ # TODO user/password -> certificate
38
+ config_param :user, :string, :default => nil
39
+ config_param :password, :string, :default => nil
40
+
41
+
42
+ def configure(conf)
43
+ super
44
+
45
+ credentials = {}
46
+ if @user
47
+ credentials['user'] = @user
48
+ credentials['password'] = @password
49
+ end
50
+ @wendelin = WendelinClient.new(@streamtool_uri, credentials)
51
+ end
52
+
53
+ def start
54
+ super
55
+ # TODO
56
+ end
57
+
58
+ def shutdown
59
+ super
60
+ # TODO
61
+ end
62
+
63
+
64
+ # hooked to ObjectBufferedOutput - write out records from a buffer chunk for a tag.
65
+ #
66
+ # NOTE this is called from a separate thread (see OutputThread and BufferedOutput)
67
+ def write_objects(tag, chunk)
68
+ # NOTE if this fail and raises -> it will unroll to BufferedOutput#try_flush
69
+ # which detects errors and retries outputting logs up to retry maxcount
70
+ # times and aborts outputting current logs if all try fail.
71
+ #
72
+ # This way, we don't need to code rescue here.
73
+
74
+ # NOTE tag is 1, and chunk stores an event stream, usually [] of
75
+ # (timestamp, record) in msgpack, but it general it could be arbitrary
76
+ # data - we send it as-is.
77
+ data_chunk = chunk.read()
78
+
79
+ # for input_stream_ref use tag as-is - it will be processed/translated
80
+ # further on server by Wendelin
81
+ reference = tag
82
+
83
+ @wendelin.ingest(reference, data_chunk)
84
+ end
85
+
86
+ end
87
+
88
+ end
@@ -0,0 +1,98 @@
1
+ # module to ingest data to a Wendelin through HTTP endpoint
2
+ # Copyright (C) 2015 Nexedi SA and Contributors.
3
+ # Kirill Smelkov <kirr@nexedi.com>
4
+ #
5
+ # This program is free software: you can Use, Study, Modify and Redistribute
6
+ # it under the terms of the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+
19
+ require 'net/http'
20
+ require 'openssl'
21
+
22
+ # show request/response traces or not
23
+ $trace = false
24
+
25
+
26
+ # class representing a Wendelin client
27
+ class WendelinClient
28
+
29
+ # `streamtool_uri` - URI pointing to portal_input_data_stream "mountpoint"
30
+ # `credentials` # {'user' => _, 'password' => _} TODO change to certificate
31
+ def initialize(streamtool_uri, credentials)
32
+ @streamtool_uri = streamtool_uri
33
+ @credentials = credentials
34
+ end
35
+
36
+
37
+ # ingest `data_chunk` to a stream referenced as `reference`
38
+ def ingest(reference, data_chunk)
39
+ uri = URI("#{@streamtool_uri}/ingest?reference=#{reference}")
40
+ req = Net::HTTP::Post.new(uri)
41
+ if @credentials.has_key?('user')
42
+ req.basic_auth @credentials['user'], @credentials['password']
43
+ end
44
+
45
+ # TODO ensure content-type is 'raw', e.g. this way
46
+ # (but then querystring ?reference=... is lost)
47
+ # req.body = data_chunk
48
+ # req.content_type = 'application/octet-stream'
49
+ req.set_form_data('data_chunk' => data_chunk)
50
+
51
+ if $trace
52
+ puts '>>> REQUEST'
53
+ puts "method\t=> #{req.method}"
54
+ puts "path\t=> #{req.path}"
55
+ puts "uri\t=> #{req.uri}"
56
+ puts "body\t=> #{req.body}"
57
+ puts "body_stream\t=> #{req.body_stream}"
58
+ req.each {|h| puts "#{h}:\t#{req[h]}"}
59
+ puts
60
+ end
61
+
62
+ begin
63
+ # TODO keep connection open (so that every new ingest does not do
64
+ # full connect again)
65
+ res = Net::HTTP.start(uri.hostname, uri.port,
66
+ :use_ssl => (uri.scheme == 'https'),
67
+ # NOTE = "do not check server cert"
68
+ # TODO move this out to conf parameters
69
+ :verify_mode => OpenSSL::SSL::VERIFY_NONE
70
+ ) do |http|
71
+ http.request(req)
72
+ end
73
+
74
+ rescue
75
+ # some http/ssl/other connection error
76
+ puts "HTTP ERROR:"
77
+ raise
78
+
79
+ else
80
+ if $trace
81
+ puts '>>> RESPONSE'
82
+ res.each {|h| puts "#{h}:\t#{res[h]}"}
83
+ puts "code\t=> #{res.code}"
84
+ puts "msg\t=> #{res.message}"
85
+ puts "class\t=> #{res.class}"
86
+ puts "body:", res.body
87
+ end
88
+
89
+ if res.kind_of?(Net::HTTPSuccess) # res.code is 2XX
90
+ #puts "ingested ok"
91
+ else
92
+ puts "FAIL:"
93
+ res.value
94
+ end
95
+ end
96
+ end
97
+
98
+ end
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # ingest several data streams concurently forever
3
+ require_relative 'wendelin_test'
4
+
5
+ def runingest(stream_ref)
6
+ i = 0
7
+ while true
8
+ data_chunk = ", #{i} (#{stream_ref})"
9
+ #puts "ingest #{stream_ref}, #{data_chunk}"
10
+ ingest stream_ref, data_chunk
11
+ i = i + 1
12
+ sleep 0.1
13
+ end
14
+ end
15
+
16
+
17
+ t31 = Thread.new { runingest 'ABC-HELLO-01.cat' }
18
+ t32 = Thread.new { runingest 'ABC-HELLO-01.tac' }
19
+
20
+ t31.join # wait forever
data/test/ingest.rb ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # manually test erp5_data_streams ingestion via Ruby HTTP lib
3
+ # XXX draft/stub
4
+
5
+ require_relative 'wendelin_test'
6
+ require 'msgpack'
7
+
8
+ #puts [1,2,'hello'].to_msgpack
9
+ ingest 'ABC-HELLO-01.cat', [1,2,'hello'].to_msgpack
10
+ #ingest 'ABC-HELLO-01.cat', ', hello'
11
+ #ingest 'ABC-HELLO-01.tac', ', magic'
@@ -0,0 +1,22 @@
1
+ # simple ingest() for wendelin tests
2
+ # (without need for providing streamtool uri, credentials, etc)
3
+
4
+ # load wendelin_clinet.rb from in-tree
5
+ here = File.dirname(__FILE__)
6
+ $LOAD_PATH << File.expand_path(File.join(here, '../lib'))
7
+ require 'fluent/plugin/wendelin_client'
8
+
9
+ # FIXME hardcoded
10
+ $user = 'user'
11
+ $password = 'password'
12
+
13
+ # FIXME hardcoded & shortcut for tests
14
+ $erp5 = "https://example.com/erp5" # erp5 root
15
+ $streamtool = "#{$erp5}/portal_input_data_streams" # where Input Stream Tool is mounted
16
+
17
+ $wendelin = WendelinClient.new($streamtool, {'user' => $user, 'password' => $password})
18
+
19
+
20
+ def ingest(input_stream_ref, data_chunk)
21
+ $wendelin.ingestDataChunk(input_stream_ref, data_chunk)
22
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-wendelin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.alpha1
5
+ platform: ruby
6
+ authors:
7
+ - Kirill Smelkov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-25 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: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Fluentd output plugin to forward data to Wendelin system
28
+ email:
29
+ - kirr@nexedi.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - Gemfile
36
+ - LICENSE.txt
37
+ - README.md
38
+ - example/to_wendelin.conf
39
+ - fluent-plugin-wendelin.gemspec
40
+ - lib/fluent/plugin/out_wendelin.rb
41
+ - lib/fluent/plugin/wendelin_client.rb
42
+ - test/ingest-torture.rb
43
+ - test/ingest.rb
44
+ - test/wendelin_test.rb
45
+ homepage: https://lab.nexedi.cn/nexedi/fluent-plugin-wendelin
46
+ licenses:
47
+ - APLv2
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">"
61
+ - !ruby/object:Gem::Version
62
+ version: 1.3.1
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.2.2
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Fluentd output to Wendelin
69
+ test_files: []