bmc-daemon-lib 0.3.12 → 0.3.14
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/.ruby-version +1 -1
- data/Gemfile.lock +1 -1
- data/bmc-daemon-lib.gemspec +1 -1
- data/lib/bmc-daemon-lib.rb +1 -0
- data/lib/bmc-daemon-lib/logger_helper.rb +34 -28
- data/lib/bmc-daemon-lib/mq_consumer.rb +40 -78
- data/lib/bmc-daemon-lib/mq_endpoint.rb +78 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fef18aedd6818e48a75388b4846eed1888c99798
|
4
|
+
data.tar.gz: 6a9cc6898093c487798628a1bb2e2c5af6657d24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 646b6fe2be7e4716b3e50cd5b9307ba769105b949f65a0727c82c3d29053998002ee56d80d01f4fb84abaf36a8d93d69d69116a169ecc57739388c5e4d24916a
|
7
|
+
data.tar.gz: 7f8b49162ab83e593fe0b7a3b7572c71128591d48fca1af62666a7a60f7185faa30c53fc51a0fb670a197e2095d454669ee25544e9b92342e0bd2634f54f992d
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.3.0
|
data/Gemfile.lock
CHANGED
data/bmc-daemon-lib.gemspec
CHANGED
data/lib/bmc-daemon-lib.rb
CHANGED
@@ -10,4 +10,5 @@ require_relative "bmc-daemon-lib/logger_formatter"
|
|
10
10
|
require_relative "bmc-daemon-lib/logger_helper"
|
11
11
|
require_relative "bmc-daemon-lib/logger_pool"
|
12
12
|
require_relative "bmc-daemon-lib/worker_base"
|
13
|
+
require_relative "bmc-daemon-lib/mq_endpoint"
|
13
14
|
require_relative "bmc-daemon-lib/mq_consumer"
|
@@ -6,47 +6,24 @@ module BmcDaemonLib
|
|
6
6
|
protected
|
7
7
|
|
8
8
|
def log_info message, details = nil
|
9
|
-
|
9
|
+
log Logger::INFO, message, details
|
10
10
|
end
|
11
11
|
|
12
12
|
def log_error message, details = nil
|
13
|
-
|
13
|
+
log Logger::ERROR, message, details
|
14
14
|
end
|
15
15
|
|
16
16
|
def log_debug message, details = nil
|
17
|
-
|
17
|
+
log Logger::DEBUG, message, details
|
18
18
|
end
|
19
19
|
|
20
20
|
alias info log_info
|
21
21
|
alias error log_error
|
22
22
|
alias debug log_debug
|
23
23
|
|
24
|
-
|
24
|
+
def log severity, message, details = nil
|
25
|
+
fail "LoggerHelper.log: invalid logger" unless logger.respond_to? :add
|
25
26
|
|
26
|
-
# Builds prefix if LOG_PREFIX_FORMAT defined and caller has log_prefix method to provide values
|
27
|
-
def build_prefix
|
28
|
-
# Skip if no format defined
|
29
|
-
return unless defined?('LOG_PREFIX_FORMAT')
|
30
|
-
return unless LOG_PREFIX_FORMAT.is_a? String
|
31
|
-
|
32
|
-
# Skip if no values from user class
|
33
|
-
return unless respond_to?(:log_prefix, true)
|
34
|
-
values = log_prefix
|
35
|
-
|
36
|
-
# Change to an array if not already
|
37
|
-
values = [values] if values.is_a? String
|
38
|
-
|
39
|
-
# Stop if still not an array
|
40
|
-
return unless values.is_a? Array
|
41
|
-
|
42
|
-
# Finally format the string
|
43
|
-
return LOG_PREFIX_FORMAT % values.map(&:to_s)
|
44
|
-
|
45
|
-
rescue ArgumentError
|
46
|
-
return "INVALID_FORMAT"
|
47
|
-
end
|
48
|
-
|
49
|
-
def build_messages severity, message, details = nil
|
50
27
|
messages = []
|
51
28
|
|
52
29
|
prefix = build_prefix
|
@@ -68,5 +45,34 @@ module BmcDaemonLib
|
|
68
45
|
logger.add severity, messages
|
69
46
|
end
|
70
47
|
|
48
|
+
private
|
49
|
+
|
50
|
+
# Builds prefix if LOG_PREFIX_FORMAT defined and caller has log_prefix method to provide values
|
51
|
+
def build_prefix
|
52
|
+
# Skip if no format defined
|
53
|
+
return unless defined?('LOG_PREFIX_FORMAT')
|
54
|
+
return unless LOG_PREFIX_FORMAT.is_a? String
|
55
|
+
|
56
|
+
# At start, values is an empty array
|
57
|
+
values = nil
|
58
|
+
|
59
|
+
# Call the instance's method
|
60
|
+
if respond_to?(:log_prefix, true)
|
61
|
+
values = log_prefix
|
62
|
+
end
|
63
|
+
|
64
|
+
# Change to an array if a simple string
|
65
|
+
values = [values] if values.is_a? String
|
66
|
+
|
67
|
+
# Ensure we always have an array (method not found, or log_prefix returning something else)
|
68
|
+
values = [] unless values.is_a? Array
|
69
|
+
|
70
|
+
# Finally format the string
|
71
|
+
return LOG_PREFIX_FORMAT % values.map(&:to_s)
|
72
|
+
|
73
|
+
rescue ArgumentError => ex
|
74
|
+
return "(LOG_PREFIX_FORMAT has an invalid format)"
|
75
|
+
end
|
76
|
+
|
71
77
|
end
|
72
78
|
end
|
@@ -1,92 +1,65 @@
|
|
1
1
|
module BmcDaemonLib
|
2
|
-
|
3
|
-
# class ShouterChannelClosed < StandardError; end
|
4
|
-
# class ShouterPreconditionFailed < StandardError; end
|
5
|
-
# class ShouterInterrupted < StandardError; end
|
6
|
-
# class EndpointTopicContext < StandardError; end
|
7
|
-
class EndpointConnexionContext < StandardError; end
|
8
|
-
class EndpointConnectionError < StandardError; end
|
9
|
-
class EndpointSubscribeContext < StandardError; end
|
10
|
-
class EndpointSubscribeError < StandardError; end
|
11
|
-
|
12
|
-
class MqConsumer
|
13
|
-
include LoggerHelper
|
14
|
-
attr_reader :logger
|
2
|
+
class MqConsumerError < StandardError; end
|
15
3
|
|
16
|
-
|
4
|
+
class MqConsumer < MqEndpoint
|
17
5
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
6
|
+
include LoggerHelper
|
7
|
+
attr_reader :logger
|
21
8
|
|
22
|
-
def
|
23
|
-
|
9
|
+
def subscribe_to_queue name, context = nil
|
10
|
+
log_info "subscribe_to_queue [#{name}]"
|
24
11
|
|
25
12
|
# Queue for this rule
|
26
13
|
@queue = @channel.queue(name, auto_delete: false, durable: true)
|
27
14
|
|
28
15
|
# Create consumer on this queue
|
29
16
|
@queue.subscribe(manual_ack: AMQP_MANUAL_ACK, on_cancellation: :consumer_cancelled) do |delivery_info, metadata, payload|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
msg_tag = delivery_info.delivery_tag
|
17
|
+
handle_receive context, delivery_info, metadata, payload
|
18
|
+
end
|
19
|
+
end
|
34
20
|
|
35
|
-
|
21
|
+
def listen_to topic, rkey
|
22
|
+
# Exchange to this rule
|
23
|
+
exchange = @channel.topic(topic, durable: true, persistent: false)
|
36
24
|
|
37
|
-
|
38
|
-
|
25
|
+
log_info "listen_to [#{topic}] [#{rkey}] > [#{@queue.name}]"
|
26
|
+
@queue.bind exchange, routing_key: rkey
|
27
|
+
end
|
39
28
|
|
40
|
-
|
41
|
-
announce msg_rkey, msg_tag, msg_data, metadata, msg_exchange, payload.bytesize
|
29
|
+
protected
|
42
30
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
31
|
+
def handle_receive context, delivery_info, metadata, payload
|
32
|
+
# raise MqConsumerError, "testing!"
|
47
33
|
|
48
|
-
def announce msg_rkey, msg_tag, msg_data, metadata, msg_exchange, payload_bytesize
|
49
34
|
# Prepare data
|
35
|
+
msg_topic = delivery_info.exchange
|
36
|
+
msg_rkey = delivery_info.routing_key.force_encoding('UTF-8')
|
37
|
+
msg_tag = delivery_info.delivery_tag
|
50
38
|
msg_headers = metadata.headers || {}
|
51
39
|
|
40
|
+
# Extract payload
|
41
|
+
msg_data = payload_parse payload, metadata.content_type
|
42
|
+
|
52
43
|
# Announce match
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
44
|
+
payload_bytesize = payload.bytesize
|
45
|
+
log_message MSG_RECV, msg_topic, msg_rkey, msg_data, {
|
46
|
+
app_id: metadata.app_id,
|
47
|
+
channel_tag: "#{@channel.id}.#{msg_tag}",
|
48
|
+
content_type: metadata.content_type,
|
49
|
+
delay_ms: extract_delay(msg_headers),
|
50
|
+
body_size: format_bytes(payload_bytesize, "B"),
|
59
51
|
}
|
60
|
-
end
|
61
|
-
|
62
|
-
def bind_on topic, route
|
63
|
-
# Exchange to this rule
|
64
|
-
exchange = @channel.topic(topic, durable: true, persistent: false)
|
65
52
|
|
66
|
-
|
67
|
-
|
53
|
+
# Hand to the callback
|
54
|
+
handle_message context, metadata, delivery_info,
|
55
|
+
topic: msg_topic,
|
56
|
+
rkey: msg_rkey,
|
57
|
+
tag: msg_tag,
|
58
|
+
data: msg_data
|
68
59
|
end
|
69
60
|
|
70
61
|
def consumer_cancelled all={}
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
def identifier len
|
75
|
-
rand(36**len).to_s(36)
|
76
|
-
end
|
77
|
-
|
78
|
-
def log_message msg_way, msg_exchange, msg_key, msg_body = [], msg_attrs = {}
|
79
|
-
# Message header
|
80
|
-
info sprintf("%3s %-15s %s", msg_way, msg_exchange, msg_key)
|
81
|
-
|
82
|
-
# Body lines
|
83
|
-
if msg_body.is_a?(Enumerable) && !msg_body.empty?
|
84
|
-
body_json = JSON.pretty_generate(msg_body)
|
85
|
-
log_debug nil, body_json.lines
|
86
|
-
end
|
87
|
-
|
88
|
-
# Attributes lines
|
89
|
-
log_debug nil, msg_attrs if msg_attrs
|
62
|
+
log_error "consumer_cancelled remotely: #{all.inspect}"
|
90
63
|
end
|
91
64
|
|
92
65
|
def extract_delay msg_headers
|
@@ -101,19 +74,8 @@ module BmcDaemonLib
|
|
101
74
|
return ((Time.now - sent_at)*1000).round(2)
|
102
75
|
end
|
103
76
|
|
104
|
-
def
|
105
|
-
|
106
|
-
|
107
|
-
units = ["", "k", "M", "G", "T", "P" ]
|
108
|
-
index = ( Math.log(number) / Math.log(2) ).to_i / 10
|
109
|
-
converted = number.to_f / (1024 ** index)
|
110
|
-
|
111
|
-
truncated = converted.round(decimals)
|
112
|
-
return "#{truncated} #{units[index]}#{unit}"
|
113
|
-
end
|
114
|
-
|
115
|
-
def receive delivery_info, metadata, payload
|
116
|
-
debug "MqConsumer.receive"
|
77
|
+
def handle_message context, metadata, delivery_info, message = {}
|
78
|
+
log_error "MqConsumer.handle_message [#{context.to_s}] #{message.inspect}"
|
117
79
|
end
|
118
80
|
|
119
81
|
def payload_parse payload, content_type #, fields = []
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module BmcDaemonLib
|
2
|
+
# class ShouterResponseError < StandardError; end
|
3
|
+
# class ShouterChannelClosed < StandardError; end
|
4
|
+
# class ShouterPreconditionFailed < StandardError; end
|
5
|
+
# class ShouterInterrupted < StandardError; end
|
6
|
+
# class EndpointTopicContext < StandardError; end
|
7
|
+
class EndpointConnexionContext < StandardError; end
|
8
|
+
class EndpointConnectionError < StandardError; end
|
9
|
+
class EndpointSubscribeContext < StandardError; end
|
10
|
+
class EndpointSubscribeError < StandardError; end
|
11
|
+
|
12
|
+
class MqEndpoint
|
13
|
+
include LoggerHelper
|
14
|
+
attr_reader :logger
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def log_prefix
|
19
|
+
self.class.name.split('::').last
|
20
|
+
end
|
21
|
+
|
22
|
+
def log_message msg_way, msg_topic, msg_key, msg_body = [], msg_attrs = {}
|
23
|
+
# Message header
|
24
|
+
log_info sprintf("%4s %-20s %s", msg_way, msg_topic, msg_key)
|
25
|
+
|
26
|
+
# Message attributes
|
27
|
+
log_debug nil, msg_attrs if msg_attrs
|
28
|
+
|
29
|
+
# Body lines
|
30
|
+
if msg_body.is_a?(Enumerable) && !msg_body.empty?
|
31
|
+
body_json = JSON.pretty_generate(msg_body)
|
32
|
+
log_debug nil, body_json.lines
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def identifier len
|
37
|
+
rand(36**len).to_s(36)
|
38
|
+
end
|
39
|
+
|
40
|
+
def format_bytes number, unit="", decimals = 0
|
41
|
+
return "Ø" if number.nil? || number.to_f.zero?
|
42
|
+
|
43
|
+
units = ["", "k", "M", "G", "T", "P" ]
|
44
|
+
index = ( Math.log(number) / Math.log(2) ).to_i / 10
|
45
|
+
converted = number.to_f / (1024 ** index)
|
46
|
+
|
47
|
+
truncated = converted.round(decimals)
|
48
|
+
return "#{truncated} #{units[index]}#{unit}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Start connexion to RabbitMQ
|
52
|
+
def connect_to busconf
|
53
|
+
fail BmcDaemonLib::EndpointConnexionContext, "connect_to/busconf" unless busconf
|
54
|
+
log_info "connecting to bus", {
|
55
|
+
broker: busconf,
|
56
|
+
recover: AMQP_RECOVERY_INTERVAL,
|
57
|
+
heartbeat: AMQP_HEARTBEAT_INTERVAL,
|
58
|
+
prefetch: AMQP_PREFETCH
|
59
|
+
}
|
60
|
+
conn = Bunny.new busconf.to_s,
|
61
|
+
logger: @logger,
|
62
|
+
# heartbeat: :server,
|
63
|
+
automatically_recover: true,
|
64
|
+
network_recovery_interval: AMQP_RECOVERY_INTERVAL,
|
65
|
+
heartbeat_interval: AMQP_HEARTBEAT_INTERVAL,
|
66
|
+
read_write_timeout: AMQP_HEARTBEAT_INTERVAL*2
|
67
|
+
conn.start
|
68
|
+
|
69
|
+
rescue Bunny::TCPConnectionFailedForAllHosts, Bunny::AuthenticationFailureError, AMQ::Protocol::EmptyResponseError => e
|
70
|
+
fail BmcDaemonLib::EndpointConnectionError, "error connecting (#{e.class})"
|
71
|
+
rescue StandardError => e
|
72
|
+
fail BmcDaemonLib::EndpointConnectionError, "unknow (#{e.inspect})"
|
73
|
+
else
|
74
|
+
return conn
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bmc-daemon-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno MEDICI
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- lib/bmc-daemon-lib/logger_helper.rb
|
101
101
|
- lib/bmc-daemon-lib/logger_pool.rb
|
102
102
|
- lib/bmc-daemon-lib/mq_consumer.rb
|
103
|
+
- lib/bmc-daemon-lib/mq_endpoint.rb
|
103
104
|
- lib/bmc-daemon-lib/worker_base.rb
|
104
105
|
homepage: http://github.com/bmedici/bmc-daemon-lib
|
105
106
|
licenses:
|
@@ -121,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
122
|
version: '0'
|
122
123
|
requirements: []
|
123
124
|
rubyforge_project:
|
124
|
-
rubygems_version: 2.
|
125
|
+
rubygems_version: 2.6.6
|
125
126
|
signing_key:
|
126
127
|
specification_version: 4
|
127
128
|
summary: 'Shared utilities to build a daemon: logger, configuration, helpers'
|