fluent-plugin-mqtt-io 0.4.4 → 0.5.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 +4 -4
- data/README.md +2 -1
- data/fluent-plugin-mqtt-io.gemspec +3 -3
- data/lib/fluent/plugin/in_mqtt.rb +14 -11
- data/lib/fluent/plugin/mqtt_proxy.rb +49 -36
- data/lib/fluent/plugin/out_mqtt.rb +19 -11
- metadata +13 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed837b9979b990f051238be99dac2c17ba2feb7b35c0f56910f706c3c426944a
|
4
|
+
data.tar.gz: 52628c53314f60215b6b97854103a3e99c0f313fe5a5031b1e6ed87e16cfc918
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2b38c5196fa566997d647fe63d3b2af44b323d218b5ec2c8e613cfa6662bd64401fbc99a68935950ddeb9b1b128f7571357e885276dfae5c6fbaaab62c088e9
|
7
|
+
data.tar.gz: 2d96a742d31d3b638f989999ea5c4919c95f61c64156d46d2dc01263842b036cf584bccc596c11634a3b95f358e84c112ce7b4c64b9eafc6fe48c367f0518381
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ Mqtt::IO Plugin is deeply inspired by Fluent::Plugin::Mqtt.
|
|
5
5
|
|
6
6
|
https://github.com/yuuna/fluent-plugin-mqtt
|
7
7
|
|
8
|
-
Mqtt::IO plugin focus on federating components, e.g. sensors, messaging platform and databases.
|
8
|
+
Mqtt::IO plugin focus on federating components, e.g. sensors, messaging platform and databases. Connection encryption/decryption (TLS) is supported by ruby-mqtt but end-to-end encryption/decryption is not supported in this plugin. [fluent-plugin-jwt-filter](https://github.com/toyokazu/fluent-plugin-jwt-filter) can be used to encrypt/decrypt messages using JSON Web Token technology.
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -83,6 +83,7 @@ The default MQTT topic is "#". Configurable options are the following:
|
|
83
83
|
- **initial_interval**: An initial value of retry interval (s) (default 1)
|
84
84
|
- **retry_inc_ratio**: An increase ratio of retry interval per connection failure (default 2 (double)). It may be better to set the value to 1 in a mobile environment for eager reconnection.
|
85
85
|
- **max_retry_interval**: Maximum value of retry interval (default 300)
|
86
|
+
- **max_retry_freq**: Threshold of retry frequency described by a number of retries per minutes. This option is provided for detecting failure via proxy services, e.g. ssh port forwarding. When the thresold is exceeded, MqttProxy::ExceedRetryFrequencyThresholdException is raised and the fluentd will be restarted. So, it is enough to be specified once for a MQTT server at a source/match directive in your configuration (default 10)
|
86
87
|
|
87
88
|
Input Plugin supports @label directive.
|
88
89
|
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "fluent-plugin-mqtt-io"
|
7
|
-
spec.version = "0.
|
7
|
+
spec.version = "0.5.0"
|
8
8
|
spec.authors = ["Toyokazu Akiyama"]
|
9
9
|
spec.email = ["toyokazu@gmail.com"]
|
10
10
|
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_dependency 'fluentd', [">= 0.14.0", "< 2"]
|
25
25
|
spec.add_dependency "mqtt", "~> 0.5"
|
26
26
|
|
27
|
-
spec.add_development_dependency "bundler", "
|
28
|
-
spec.add_development_dependency "rake", "~>
|
27
|
+
spec.add_development_dependency "bundler", [">= 1.14", "< 2.3"]
|
28
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
29
29
|
spec.add_development_dependency "test-unit"
|
30
30
|
end
|
@@ -20,11 +20,6 @@ module Fluent::Plugin
|
|
20
20
|
config_param :@type, :string, default: 'none'
|
21
21
|
end
|
22
22
|
|
23
|
-
# bulk_trans is deprecated
|
24
|
-
# multiple entries must be inputted as an Array
|
25
|
-
#config_param :bulk_trans, :bool, default: true
|
26
|
-
#config_param :bulk_trans_sep, :string, default: "\t"
|
27
|
-
|
28
23
|
config_section :monitor, required: false, multi: false do
|
29
24
|
desc 'Record received time into message or not.'
|
30
25
|
config_param :recv_time, :bool, default: false
|
@@ -66,20 +61,28 @@ module Fluent::Plugin
|
|
66
61
|
:in_mqtt
|
67
62
|
end
|
68
63
|
|
69
|
-
def
|
70
|
-
@get_thread.
|
64
|
+
def exit_thread
|
65
|
+
@get_thread.exit if !@get_thread.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
def disconnect
|
69
|
+
begin
|
70
|
+
@client.disconnect if @client.connected?
|
71
|
+
rescue => e
|
72
|
+
log.error "Error in in_mqtt#disconnect,#{e.class},#{e.message}"
|
73
|
+
end
|
74
|
+
exit_thread
|
71
75
|
end
|
72
76
|
|
73
|
-
def
|
74
|
-
|
77
|
+
def terminate
|
78
|
+
exit_thread
|
75
79
|
super
|
76
80
|
end
|
77
81
|
|
78
82
|
def after_connection
|
79
83
|
if @client.connected?
|
80
84
|
@client.subscribe(@topic)
|
81
|
-
|
82
|
-
@get_thread = Thread.new do
|
85
|
+
@get_thread = thread_create(:in_mqtt_get) do
|
83
86
|
@client.get do |topic, message|
|
84
87
|
emit(topic, message)
|
85
88
|
end
|
@@ -20,8 +20,10 @@ module Fluent::Plugin
|
|
20
20
|
base.config_param :initial_interval, :integer, default: 1
|
21
21
|
base.desc 'Specify increasing ratio of connection retry interval.'
|
22
22
|
base.config_param :retry_inc_ratio, :integer, default: 2
|
23
|
-
base.desc 'Specify maximum connection retry interval.'
|
23
|
+
base.desc 'Specify the maximum connection retry interval.'
|
24
24
|
base.config_param :max_retry_interval, :integer, default: 300
|
25
|
+
base.desc 'Specify threshold of retry frequency as number of retries per minutes. Frequency is monitored per retry.'
|
26
|
+
base.config_param :max_retry_freq, :integer, default: 10
|
25
27
|
|
26
28
|
base.config_section :security, required: false, multi: false do
|
27
29
|
### User based authentication
|
@@ -44,11 +46,20 @@ module Fluent::Plugin
|
|
44
46
|
|
45
47
|
class MqttError < StandardError; end
|
46
48
|
|
49
|
+
class ExceedRetryFrequencyThresholdException < StandardError; end
|
50
|
+
|
47
51
|
def current_plugin_name
|
48
52
|
# should be implemented
|
49
53
|
end
|
50
54
|
|
51
55
|
def start_proxy
|
56
|
+
# Start a thread from main thread for handling a thread generated
|
57
|
+
# by MQTT::Client#get (in_mqtt). Dummy thread is used for out_mqtt
|
58
|
+
# to keep the same implementation style.
|
59
|
+
@proxy_thread = thread_create("#{current_plugin_name}_proxy".to_sym, &method(:proxy))
|
60
|
+
end
|
61
|
+
|
62
|
+
def proxy
|
52
63
|
log.debug "start mqtt proxy for #{current_plugin_name}"
|
53
64
|
log.debug "start to connect mqtt broker #{@host}:#{@port}"
|
54
65
|
opts = {
|
@@ -68,12 +79,13 @@ module Fluent::Plugin
|
|
68
79
|
end
|
69
80
|
|
70
81
|
init_retry_interval
|
82
|
+
@retry_sequence = []
|
71
83
|
@client = MQTT::Client.new(opts)
|
72
84
|
connect
|
73
85
|
end
|
74
86
|
|
75
87
|
def shutdown_proxy
|
76
|
-
|
88
|
+
disconnect
|
77
89
|
end
|
78
90
|
|
79
91
|
def init_retry_interval
|
@@ -81,29 +93,43 @@ module Fluent::Plugin
|
|
81
93
|
end
|
82
94
|
|
83
95
|
def increment_retry_interval
|
84
|
-
return @
|
96
|
+
return @max_retry_interval if @retry_interval >= @max_retry_interval
|
85
97
|
@retry_interval = @retry_interval * @retry_inc_ratio
|
86
98
|
end
|
87
99
|
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
100
|
+
def update_retry_sequence(e)
|
101
|
+
@retry_sequence << {time: Time.now, error: "#{e.class}: #{e.message}"}
|
102
|
+
# delete old retry records
|
103
|
+
while @retry_sequence[0][:time] < Time.now - 60
|
104
|
+
@retry_sequence.shift
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def check_retry_frequency
|
109
|
+
return if @retry_sequence.size <= 1
|
110
|
+
if @retry_sequence.size > @max_retry_freq
|
111
|
+
log.error "Retry frequency threshold is exceeded: #{@retry_sequence}"
|
112
|
+
raise ExceedRetryFrequencyThresholdException
|
97
113
|
end
|
98
114
|
end
|
99
115
|
|
100
|
-
def
|
101
|
-
|
116
|
+
def retry_connect(e, message)
|
117
|
+
log.error "#{message},#{e.class},#{e.message}"
|
118
|
+
log.error "Retry in #{@retry_interval} sec"
|
119
|
+
update_retry_sequence(e)
|
120
|
+
check_retry_frequency
|
121
|
+
disconnect
|
122
|
+
sleep @retry_interval
|
123
|
+
increment_retry_interval
|
124
|
+
connect
|
125
|
+
# never reach here
|
102
126
|
end
|
103
127
|
|
104
|
-
def
|
128
|
+
def disconnect
|
105
129
|
# should be implemented
|
106
|
-
|
130
|
+
end
|
131
|
+
|
132
|
+
def terminate
|
107
133
|
end
|
108
134
|
|
109
135
|
def rescue_disconnection
|
@@ -114,22 +140,13 @@ module Fluent::Plugin
|
|
114
140
|
begin
|
115
141
|
yield
|
116
142
|
rescue MQTT::ProtocolException => e
|
117
|
-
# TODO:
|
118
|
-
# Thread created via fluentd thread API, e.g. thread_create,
|
119
|
-
# cannot catch MQTT::ProtocolException raised from @read_thread
|
120
|
-
# in ruby-mqtt. So, the current version uses plugin local thread
|
121
|
-
# @connect_thread to catch it.
|
122
143
|
retry_connect(e, "Protocol error occurs in #{current_plugin_name}.")
|
123
|
-
raise MqttError, "Protocol error occurs."
|
124
144
|
rescue Timeout::Error => e
|
125
145
|
retry_connect(e, "Timeout error occurs in #{current_plugin_name}.")
|
126
|
-
raise Timeout::Error, "Timeout error occurs."
|
127
146
|
rescue SystemCallError => e
|
128
147
|
retry_connect(e, "System call error occurs in #{current_plugin_name}.")
|
129
|
-
raise SystemCallError, "System call error occurs."
|
130
148
|
rescue StandardError=> e
|
131
149
|
retry_connect(e, "The other error occurs in #{current_plugin_name}.")
|
132
|
-
raise StandardError, "The other error occurs."
|
133
150
|
rescue MQTT::NotConnectedException=> e
|
134
151
|
# Since MQTT::NotConnectedException is raised only on publish,
|
135
152
|
# connection error should be catched before this error.
|
@@ -137,7 +154,7 @@ module Fluent::Plugin
|
|
137
154
|
# to prevent waistful increment of retry interval.
|
138
155
|
#log.error "MQTT not connected exception occurs.,#{e.class},#{e.message}"
|
139
156
|
#retry_connect(e, "MQTT not connected exception occurs.")
|
140
|
-
raise MqttError, "MQTT not connected exception occurs in #{current_plugin_name}."
|
157
|
+
#raise MqttError, "MQTT not connected exception occurs in #{current_plugin_name}."
|
141
158
|
end
|
142
159
|
end
|
143
160
|
|
@@ -148,16 +165,12 @@ module Fluent::Plugin
|
|
148
165
|
end
|
149
166
|
|
150
167
|
def connect
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
init_retry_interval
|
158
|
-
thread = after_connection
|
159
|
-
thread.join
|
160
|
-
end
|
168
|
+
rescue_disconnection do
|
169
|
+
@client.connect
|
170
|
+
log.debug "connected to mqtt broker #{@host}:#{@port} for #{current_plugin_name}"
|
171
|
+
init_retry_interval
|
172
|
+
thread = after_connection
|
173
|
+
thread.join
|
161
174
|
end
|
162
175
|
end
|
163
176
|
end
|
@@ -89,27 +89,35 @@ module Fluent::Plugin
|
|
89
89
|
# Shutdown the thread and close sockets or files here.
|
90
90
|
def shutdown
|
91
91
|
shutdown_proxy
|
92
|
-
|
92
|
+
exit_thread
|
93
93
|
super
|
94
94
|
end
|
95
95
|
|
96
|
-
def
|
97
|
-
@dummy_thread.
|
96
|
+
def exit_thread
|
97
|
+
@dummy_thread.exit if !@dummy_thread.nil?
|
98
98
|
end
|
99
99
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
def disconnect
|
101
|
+
begin
|
102
|
+
@client.disconnect if @client.connected?
|
103
|
+
rescue => e
|
104
|
+
log.error "Error in out_mqtt#disconnect,#{e.class},#{e.message}"
|
104
105
|
end
|
105
|
-
|
106
|
+
exit_thread
|
106
107
|
end
|
107
108
|
|
108
|
-
def
|
109
|
-
|
109
|
+
def terminate
|
110
|
+
exit_thread
|
110
111
|
super
|
111
112
|
end
|
112
113
|
|
114
|
+
def after_connection
|
115
|
+
@dummy_thread = thread_create(:out_mqtt_dummy) do
|
116
|
+
Thread.stop
|
117
|
+
end
|
118
|
+
@dummy_thread
|
119
|
+
end
|
120
|
+
|
113
121
|
def current_plugin_name
|
114
122
|
:out_mqtt
|
115
123
|
end
|
@@ -148,7 +156,7 @@ module Fluent::Plugin
|
|
148
156
|
end
|
149
157
|
|
150
158
|
def publish(tag, time, record)
|
151
|
-
log.debug "MqttOutput::#{caller_locations(1,1)[0].label}: #{rewrite_tag(
|
159
|
+
log.debug "MqttOutput::#{caller_locations(1,1)[0].label}: #{rewrite_tag(tag)}, #{time}, #{add_send_time(record)}"
|
152
160
|
@client.publish(
|
153
161
|
rewrite_tag(tag),
|
154
162
|
@formatter.format(tag, time, add_send_time(record)),
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-mqtt-io
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toyokazu Akiyama
|
8
8
|
autorequire:
|
9
9
|
bindir: []
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -48,30 +48,36 @@ dependencies:
|
|
48
48
|
name: bundler
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - "
|
51
|
+
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '1.14'
|
54
|
+
- - "<"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '2.3'
|
54
57
|
type: :development
|
55
58
|
prerelease: false
|
56
59
|
version_requirements: !ruby/object:Gem::Requirement
|
57
60
|
requirements:
|
58
|
-
- - "
|
61
|
+
- - ">="
|
59
62
|
- !ruby/object:Gem::Version
|
60
63
|
version: '1.14'
|
64
|
+
- - "<"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '2.3'
|
61
67
|
- !ruby/object:Gem::Dependency
|
62
68
|
name: rake
|
63
69
|
requirement: !ruby/object:Gem::Requirement
|
64
70
|
requirements:
|
65
71
|
- - "~>"
|
66
72
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
73
|
+
version: '13.0'
|
68
74
|
type: :development
|
69
75
|
prerelease: false
|
70
76
|
version_requirements: !ruby/object:Gem::Requirement
|
71
77
|
requirements:
|
72
78
|
- - "~>"
|
73
79
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
80
|
+
version: '13.0'
|
75
81
|
- !ruby/object:Gem::Dependency
|
76
82
|
name: test-unit
|
77
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -127,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
133
|
- !ruby/object:Gem::Version
|
128
134
|
version: '0'
|
129
135
|
requirements: []
|
130
|
-
rubygems_version: 3.
|
136
|
+
rubygems_version: 3.1.4
|
131
137
|
signing_key:
|
132
138
|
specification_version: 4
|
133
139
|
summary: fluentd input/output plugin for mqtt broker
|