fluent-plugin-mqtt-io 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dbaced6d7ef1c77842544fb27125007e2b9635c5
4
+ data.tar.gz: ab568a296508ad1a8f65fb5349193b2cd999c78f
5
+ SHA512:
6
+ metadata.gz: ca0f40329239b618e5b5d588f9579c3b57d05db0786ff6ba5091fabc64f3cd27f5aa5d0be50d46900a60100ccfb791a7ee8acbcfd6acbbc7ce22d36fdb5a255b
7
+ data.tar.gz: ce8103acef9c93ae89ef2f747f7fcc69142ed49a960fe8dee684fa78a6c6f2817d0d3ba23a6e5fa450cdbef37114b1bca4338b131b77ca1298d10eded731cf0a
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.2
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-mqtt-io.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Toyokazu Akiyama
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Fluent::Plugin::Mqtt::IO
2
+
3
+ Fluent plugin for MQTT Input/Output
4
+ Mqtt::IO Plugin is deeply inspired by Fluent::Plugin::Mqtt.
5
+
6
+ https://github.com/yuuna/fluent-plugin-mqtt
7
+
8
+ Mqtt::IO plugin focus on federating components, e.g. sensors, messaging platform and databases.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'fluent-plugin-mqtt-io'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install fluent-plugin-mqtt-io
23
+
24
+
25
+ ## Usage
26
+
27
+ fluent-plugin-mqtt provides Input and Output Plugins for MQTT.
28
+
29
+ Input Plugin can be used via source directive in the configuration.
30
+
31
+ ```
32
+
33
+ <source>
34
+ type mqtt
35
+ bind 127.0.0.1
36
+ port 1883
37
+ </source>
38
+
39
+ ```
40
+
41
+ The default MQTT topic is "#". Configurable options are the following:
42
+
43
+ - bind: IP address of MQTT broker
44
+ - port: Port number of MQTT broker
45
+ - topic: Topic name to be subscribed
46
+ - username: User name for authentication
47
+ - password: Password for authentication
48
+ - ssl: set true if you want to use SSL/TLS. If set to true, the following parameter must be provided
49
+ - ca_file: CA certificate file path
50
+ - key_file: private key file path
51
+ - cert_file: certificate file path
52
+ - format: Input parser can be chosen, e.g. json, xml
53
+
54
+ Input Plugin supports @label directive.
55
+
56
+ Output Plugin can be used via match directive.
57
+
58
+ ```
59
+
60
+ <match topic.**>
61
+ type mqtt
62
+ bind 127.0.0.1
63
+ port 1883
64
+ </match>
65
+
66
+ ```
67
+
68
+ The options are basically the same as Input Plugin. The difference is the following.
69
+
70
+ - time_key: An attribute name used for timestamp field. Default is 'timestamp'.
71
+ - time_format: Output format of timestamp field. Default is ISO8601. You can specify your own format by using TimeParser.
72
+ - topic_rewrite_pattern: Regexp pattern to extract replacement words from received topic or tag name
73
+ - topic_rewrite_replacement: Topic name used for the publish using extracted pattern
74
+
75
+ If you use different source, e.g. the other MQTT broker, log file and so on, there is no need to specifie topic rewriting. Skip the following descriptions.
76
+
77
+ The topic name or tag name, e.g. "topic", received from an event can not be published without modification because if MQTT input plugin connecting to the identical MQTT broker is used as a source, the same message will become an input repeatedly. In order to support data conversion in single MQTT domain, simple topic rewriting should be supported. Since topic is rewritten using #gsub method, 'pattern' and 'replacement' are the same as #gsub arguments.
78
+
79
+
80
+ ```
81
+
82
+ <match topic.**>
83
+ type mqtt
84
+ bind 127.0.0.1
85
+ port 1883
86
+ topic_rewrite_pattern '^([\w\/]+)$'
87
+ topic_rewrite_replacement '\1/rewritten'
88
+ </match>
89
+
90
+ ```
91
+
92
+ You can also use mqtt_buf type which is implemented as BufferedOutput.
93
+
94
+ ```
95
+
96
+ <match topic.**>
97
+ type mqtt_buf
98
+ bind 127.0.0.1
99
+ port 1883
100
+ topic_rewrite_pattern '^([\w\/]+)$'
101
+ topic_rewrite_replacement '\1/rewritten'
102
+ # You can specify Buffer Plugin options
103
+ buffer_type memory
104
+ flush_interval 1s
105
+ </match>
106
+
107
+ ```
108
+
109
+
110
+ ## Contributing
111
+
112
+ 1. Fork it ( http://github.com/toyokazu/fluent-plugin-mqtt-io/fork )
113
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
114
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
115
+ 4. Push to the branch (`git push origin my-new-feature`)
116
+ 5. Create new Pull Request
117
+
118
+
119
+ ## License
120
+
121
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
122
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-mqtt-io"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Toyokazu Akiyama"]
9
+ spec.email = ["toyokazu@gmail.com"]
10
+
11
+ spec.summary = %q{fluentd input/output plugin for mqtt broker}
12
+ spec.description = %q{fluentd input/output plugin for mqtt broker}
13
+ spec.homepage = "https://github.com/toyokazu/fluent-plugin-mqtt-io"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.bindir = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.10"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "mqtt"
25
+ end
@@ -0,0 +1,78 @@
1
+ module Fluent
2
+ class MqttInput < Input
3
+ Plugin.register_input('mqtt', self)
4
+
5
+ config_param :port, :integer, :default => 1883
6
+ config_param :bind, :string, :default => '127.0.0.1'
7
+ config_param :topic, :string, :default => '#'
8
+ config_param :format, :string, :default => 'none'
9
+ config_param :username, :string, :default => nil
10
+ config_param :password, :string, :default => nil
11
+ config_param :ssl, :bool, :default => nil
12
+ config_param :ca_file, :string, :default => nil
13
+ config_param :key_file, :string, :default => nil
14
+ config_param :cert_file, :string, :default => nil
15
+
16
+ require 'mqtt'
17
+
18
+ # Define `router` method of v0.12 to support v0.10 or earlier
19
+ unless method_defined?(:router)
20
+ define_method("router") { Fluent::Engine }
21
+ end
22
+
23
+ def configure(conf)
24
+ super
25
+ @bind ||= conf['bind']
26
+ @topic ||= conf['topic']
27
+ @port ||= conf['port']
28
+ @username ||= conf['username']
29
+ @password ||= conf['password']
30
+ configure_parser(conf)
31
+ end
32
+
33
+ def configure_parser(conf)
34
+ @parser = Plugin.new_parser(conf['format'])
35
+ @parser.configure(conf)
36
+ end
37
+
38
+ def start
39
+ $log.debug "start mqtt #{@bind}"
40
+ opts = {
41
+ host: @bind,
42
+ port: @port,
43
+ username: @username,
44
+ password: @password
45
+ }
46
+ opts[:ssl] = @ssl if @ssl
47
+ opts[:ca_file] = @ca if @ca
48
+ opts[:cert_file] = @crt if @crt
49
+ opts[:key_file] = @key if @key
50
+ @connect = MQTT::Client.connect(opts)
51
+ @connect.subscribe(@topic)
52
+
53
+ @thread = Thread.new do
54
+ @connect.get do |topic,message|
55
+ emit topic, message
56
+ end
57
+ end
58
+ end
59
+
60
+ def emit topic, message
61
+ begin
62
+ topic.gsub!("/","\.")
63
+ @parser.parse(message) {|time, record|
64
+ $log.debug "#{topic}, #{time}, #{record}"
65
+ router.emit(topic, time, record)
66
+ }
67
+ rescue Exception => e
68
+ $log.error :error => e.to_s
69
+ $log.debug_backtrace(e.backtrace)
70
+ end
71
+ end
72
+
73
+ def shutdown
74
+ @thread.kill
75
+ @connect.disconnect
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,94 @@
1
+ module Fluent
2
+ module MqttOutputMixin
3
+ # config_param defines a parameter. You can refer a parameter via @path instance variable
4
+ # Without :default, a parameter is required.
5
+
6
+ def self.included(base)
7
+ base.config_param :port, :integer, :default => 1883
8
+ base.config_param :bind, :string, :default => '127.0.0.1'
9
+ base.config_param :username, :string, :default => nil
10
+ base.config_param :password, :string, :default => nil
11
+ base.config_param :ssl, :bool, :default => nil
12
+ base.config_param :ca_file, :string, :default => nil
13
+ base.config_param :key_file, :string, :default => nil
14
+ base.config_param :cert_file, :string, :default => nil
15
+ base.config_param :time_key, :string, :default => 'timestamp'
16
+ base.config_param :time_format, :string, :default => nil
17
+ base.config_param :topic_rewrite_pattern, :string, :default => nil
18
+ base.config_param :topic_rewrite_replacement, :string, :default => nil
19
+ end
20
+
21
+ require 'mqtt'
22
+
23
+ # This method is called before starting.
24
+ # 'conf' is a Hash that includes configuration parameters.
25
+ # If the configuration is invalid, raise Fluent::ConfigError.
26
+ def configure(conf)
27
+ super
28
+
29
+ # You can also refer raw parameter via conf[name].
30
+ @bind ||= conf['bind']
31
+ @port ||= conf['port']
32
+ @username ||= conf['username']
33
+ @password ||= conf['password']
34
+ @time_key ||= conf['time_key']
35
+ @time_format ||= conf['time_format']
36
+ @topic_rewrite_pattern ||= conf['topic_rewrite_pattern']
37
+ @topic_rewrite_replacement ||= conf['topic_rewrite_replacement']
38
+ end
39
+
40
+ # This method is called when starting.
41
+ # Open sockets or files here.
42
+ def start
43
+ super
44
+
45
+ $log.debug "start mqtt #{@bind}"
46
+ opts = {
47
+ host: @bind,
48
+ port: @port,
49
+ username: @username,
50
+ password: @password
51
+ }
52
+ opts[:ssl] = @ssl if @ssl
53
+ opts[:ca_file] = @ca if @ca
54
+ opts[:cert_file] = @crt if @crt
55
+ opts[:key_file] = @key if @key
56
+ @connect = MQTT::Client.connect(opts)
57
+ end
58
+
59
+ # This method is called when shutting down.
60
+ # Shutdown the thread and close sockets or files here.
61
+ def shutdown
62
+ super
63
+
64
+ @connect.disconnect
65
+ end
66
+
67
+ def format_time(time)
68
+ if @time_format.nil?
69
+ Time.at(time).iso8601
70
+ else
71
+ time_parser = TimeParser.new(@time_format)
72
+ time_parser.parse(time)
73
+ end
74
+ end
75
+
76
+ def rewrite_tag(tag)
77
+ if @topic_rewrite_pattern.nil?
78
+ tag.gsub("\.", "/")
79
+ else
80
+ tag.gsub("\.", "/").gsub(Regexp.new(@topic_rewrite_pattern), @topic_rewrite_replacement)
81
+ end
82
+ end
83
+
84
+ def json_parse message
85
+ begin
86
+ y = Yajl::Parser.new
87
+ y.parse(message)
88
+ rescue
89
+ $log.error "JSON parse error", :error => $!.to_s, :error_class => $!.class.to_s
90
+ $log.warn_backtrace $!.backtrace
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,20 @@
1
+ module Fluent
2
+ class MqttOutput < Output
3
+ require 'fluent/plugin/mqtt_output_mixin'
4
+ include Fluent::MqttOutputMixin
5
+
6
+ # First, register the plugin. NAME is the name of this plugin
7
+ # and identifies the plugin in the configuration file.
8
+ Fluent::Plugin.register_output('mqtt', self)
9
+
10
+ def emit(tag, es, chain)
11
+ es.each {|time,record|
12
+ $log.debug "#{tag}, #{format_time(time)}, #{record}"
13
+ @connect.publish(rewrite_tag(tag), record.merge(@time_key => format_time(time)).to_json)
14
+ }
15
+ $log.flush
16
+
17
+ chain.next
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ module Fluent
2
+ class MqttOutput < BufferedOutput
3
+ require 'fluent/plugin/mqtt_output_mixin'
4
+ include Fluent::MqttOutputMixin
5
+
6
+ # First, register the plugin. NAME is the name of this plugin
7
+ # and identifies the plugin in the configuration file.
8
+ Fluent::Plugin.register_output('mqtt_buf', self)
9
+
10
+ # This method is called when an event reaches to Fluentd.
11
+ # Convert the event to a raw string.
12
+ def format(tag, time, record)
13
+ [tag, time, record].to_json + "\n"
14
+ end
15
+
16
+ # This method is called every flush interval. Write the buffer chunk
17
+ # to files or databases here.
18
+ # 'chunk' is a buffer chunk that includes multiple formatted
19
+ # events. You can use 'data = chunk.read' to get all events and
20
+ # 'chunk.open {|io| ... }' to get IO objects.
21
+ #
22
+ # NOTE! This method is called by internal thread, not Fluentd's main thread. So IO wait doesn't affect other plugins.
23
+ def write(chunk)
24
+ json = json_parse(chunk.read)
25
+ $log.debug "#{json[0]}, #{format_time(json[1])}, #{json[2]}"
26
+ @connect.publish(rewrite_tag(json[0]), (json[2].merge(@time_key => format_time(json[1]))).to_json)
27
+ $log.flush
28
+ end
29
+ end
30
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+ unless ENV.has_key?('VERBOSE')
16
+ nulllogger = Object.new
17
+ nulllogger.instance_eval {|obj|
18
+ def method_missing(method, *args)
19
+ # pass
20
+ end
21
+ }
22
+ $log = nulllogger
23
+ end
24
+
25
+ class Test::Unit::TestCase
26
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-mqtt-io
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Toyokazu Akiyama
8
+ autorequire:
9
+ bindir: []
10
+ cert_chain: []
11
+ date: 2015-11-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mqtt
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: fluentd input/output plugin for mqtt broker
56
+ email:
57
+ - toyokazu@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - CODE_OF_CONDUCT.md
65
+ - Gemfile
66
+ - LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - fluent-plugin-mqtt-io.gemspec
70
+ - lib/fluent/plugin/in_mqtt.rb
71
+ - lib/fluent/plugin/mqtt_output_mixin.rb
72
+ - lib/fluent/plugin/out_mqtt.rb
73
+ - lib/fluent/plugin/out_mqtt_buf.rb
74
+ - test/helper.rb
75
+ homepage: https://github.com/toyokazu/fluent-plugin-mqtt-io
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
+ rubyforge_project:
95
+ rubygems_version: 2.4.5
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: fluentd input/output plugin for mqtt broker
99
+ test_files:
100
+ - test/helper.rb