chili_logger 0.0.9.1 → 0.1.3
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/.byebug_history +47 -105
- data/.gitignore +2 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +20 -13
- data/README.md +131 -93
- data/chili_logger.gemspec +2 -1
- data/lib/brokers/main_broker.rb +47 -0
- data/lib/brokers/rabbit_broker.rb +17 -31
- data/lib/brokers/sqs_broker.rb +43 -19
- data/lib/chili_logger.rb +16 -29
- data/lib/chili_logger/version.rb +1 -1
- data/lib/current_log_accessor.rb +1 -5
- data/lib/errors/logging_error_handler/logging_error_handler.rb +23 -8
- data/lib/helpers/logs_coverage/coverage_writer.rb +4 -2
- data/lib/helpers/values/default.rb +2 -2
- data/lib/helpers/values/secrets/aws_secrets_manager.rb +39 -0
- data/lib/helpers/values/secrets/secrets.rb +29 -0
- data/lib/unpublished_logs_manager/unpublished_logs_manager.rb +47 -0
- data/log/chili-logger-coverage.yml +8 -2
- metadata +22 -14
- data/chili_logger-0.0.6.gem +0 -0
- data/chili_logger-0.0.7.gem +0 -0
- data/chili_logger-0.0.8.gem +0 -0
- data/chili_logger-0.0.9.gem +0 -0
data/chili_logger.gemspec
CHANGED
@@ -11,7 +11,8 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.homepage = 'https://gitlab.com/chiligumdev/chili_logger'
|
12
12
|
spec.license = 'MIT'
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
14
|
-
spec.add_dependency 'aws-sdk', '~>
|
14
|
+
spec.add_dependency 'aws-sdk-sqs', '~> 1.30.0'
|
15
|
+
spec.add_dependency 'aws-sdk-secretsmanager', '~> 1.36.0'
|
15
16
|
spec.add_dependency 'bunny'
|
16
17
|
spec.add_dependency 'httparty'
|
17
18
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'errors/error_messages/config_error'
|
2
|
+
require 'brokers/rabbit_broker'
|
3
|
+
|
4
|
+
# class for centralizing Creative's logging logic
|
5
|
+
class ChiliLogger
|
6
|
+
# class that configures and manages all supported brokers
|
7
|
+
class MainBroker
|
8
|
+
def initialize(broker_name, broker_config, logging_error_handler)
|
9
|
+
@default = ChiliLogger::Values::Default.new
|
10
|
+
@logging_error_handler = logging_error_handler
|
11
|
+
broker_config ||= {}
|
12
|
+
validate_config(broker_config)
|
13
|
+
|
14
|
+
broker_name ||= @default.msg_broker
|
15
|
+
broker_class = supported_brokers[broker_name.to_sym]
|
16
|
+
unsupported_broker_error(broker_name) unless broker_class
|
17
|
+
|
18
|
+
@broker = broker_class.new(broker_config)
|
19
|
+
end
|
20
|
+
|
21
|
+
def publish(message)
|
22
|
+
return if ChiliLogger.instance.deactivated
|
23
|
+
|
24
|
+
@broker.publish(message)
|
25
|
+
rescue StandardError => e
|
26
|
+
@logging_error_handler.handle_error(e, message)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def validate_config(config)
|
32
|
+
invalid_config_err = ':msg_broker_config must be a hash'
|
33
|
+
raise(ChiliLogger::ConfigError, invalid_config_err) unless [Hash, NilClass].include?(config.class)
|
34
|
+
end
|
35
|
+
|
36
|
+
def unsupported_broker_error(broker_name)
|
37
|
+
err_msg = "'#{broker_name}' is not a supported broker_name. Supported broker_names: #{supported_brokers}"
|
38
|
+
raise(ConfigError, err_msg)
|
39
|
+
end
|
40
|
+
|
41
|
+
def supported_brokers
|
42
|
+
{
|
43
|
+
rabbitmq: RabbitBroker
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,23 +1,21 @@
|
|
1
1
|
require 'bunny'
|
2
2
|
require 'brokers/sqs_broker'
|
3
|
+
require 'helpers/values/secrets/secrets'
|
3
4
|
|
4
5
|
# class for centralizing Creative's logging logic
|
5
6
|
class ChiliLogger
|
6
7
|
# class that configures and manages the RabbitMQ client
|
7
8
|
class RabbitBroker
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def config(config)
|
13
|
-
validate_config(config)
|
9
|
+
def initialize(custom_config = {})
|
10
|
+
custom_config ||= {}
|
11
|
+
config = rabbit_config(custom_config)
|
14
12
|
|
15
13
|
@user = config[:user]
|
16
14
|
@password = config[:password]
|
17
15
|
@ip = config[:ip]
|
18
16
|
@port = config[:port]
|
19
17
|
@exchange_name = config[:exchange_name]
|
20
|
-
@routing_key_overwriter =
|
18
|
+
@routing_key_overwriter = custom_config[:routing_key_overwriter]
|
21
19
|
|
22
20
|
connect
|
23
21
|
end
|
@@ -30,39 +28,22 @@ class ChiliLogger
|
|
30
28
|
|
31
29
|
@channel = @connection.create_channel
|
32
30
|
@exchange = @channel.topic(@exchange_name, durable: true)
|
33
|
-
|
34
31
|
rescue StandardError => e
|
35
32
|
puts 'Could not connect to RabbitMQ due to the following error:'
|
36
33
|
puts e
|
37
34
|
end
|
38
35
|
|
39
|
-
def
|
40
|
-
@connection.close
|
41
|
-
end
|
42
|
-
|
43
|
-
def publish(message, routing_key)
|
36
|
+
def publish(message)
|
44
37
|
return if ChiliLogger.instance.deactivated
|
45
38
|
|
46
|
-
# if no routing_key was provided when configuring RabbitBroker, than use the
|
47
|
-
|
48
|
-
key = @routing_key_overwriter || routing_key
|
39
|
+
# if no routing_key was provided when configuring RabbitBroker, than use the message's description tag
|
40
|
+
key = @routing_key_overwriter || message[:desc] || message['desc']
|
49
41
|
@exchange.publish(message.to_json, routing_key: key)
|
50
42
|
puts "sent message to #{@exchange_name}, with routing_key = '#{key}'"
|
51
|
-
|
52
|
-
rescue StandardError => e
|
53
|
-
@logging_error_handler.handle_error(e, message)
|
54
43
|
end
|
55
44
|
|
56
45
|
private
|
57
46
|
|
58
|
-
def invalid_config_format_error
|
59
|
-
'The configuration object must be a Hash'
|
60
|
-
end
|
61
|
-
|
62
|
-
def config_attr_error(attr)
|
63
|
-
"The configuration object must include a ':#{attr}' attribute"
|
64
|
-
end
|
65
|
-
|
66
47
|
def connection_config
|
67
48
|
{
|
68
49
|
user: @user,
|
@@ -72,11 +53,16 @@ class ChiliLogger
|
|
72
53
|
}
|
73
54
|
end
|
74
55
|
|
75
|
-
def
|
76
|
-
|
56
|
+
def rabbit_config(custom_config)
|
57
|
+
default_secrets = Values::Secrets.new.get_secrets_collection('ChiliLoggerRabbitCredentials')
|
58
|
+
default_keys = %i[user password ip port exchange_name]
|
59
|
+
config = {}
|
60
|
+
|
61
|
+
default_keys.each do |key|
|
62
|
+
config[key] = custom_config[key] || default_secrets[key.to_s]
|
63
|
+
end
|
77
64
|
|
78
|
-
|
79
|
-
main_config_keys.each { |key| raise(ChiliLogger::ConfigError, config_attr_error(key)) unless config[key] }
|
65
|
+
config
|
80
66
|
end
|
81
67
|
end
|
82
68
|
end
|
data/lib/brokers/sqs_broker.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'aws-sdk'
|
1
|
+
require 'aws-sdk-sqs'
|
2
2
|
|
3
3
|
# class for centralizing Creative's logging logic
|
4
4
|
class ChiliLogger
|
@@ -6,21 +6,50 @@ class ChiliLogger
|
|
6
6
|
module AWS
|
7
7
|
# class that handles errors when message broker can't be reached, etc...
|
8
8
|
class SqsBroker
|
9
|
-
def initialize(
|
10
|
-
|
11
|
-
|
9
|
+
def initialize(custom_config = {})
|
10
|
+
custom_config ||= {}
|
11
|
+
|
12
|
+
@default_secrets = Values::Secrets.new.get_secrets_collection('ChiliLoggerSQSCredentials')
|
12
13
|
@default = ChiliLogger::Values::Default.new
|
14
|
+
@queue_name = custom_config[:queue_name] || @default_secrets['queue_name']
|
13
15
|
|
16
|
+
@sqs_config = sqs_config(custom_config)
|
14
17
|
@sqs = Aws::SQS::Client.new(@sqs_config)
|
18
|
+
|
19
|
+
ENV['AWS_REGION'] = @sqs_config[:region] # Aws::SQS::QueuePoller requires region as an env variable
|
20
|
+
@poller = Aws::SQS::QueuePoller.new(queue_url(@queue_name), skip_delete: true)
|
15
21
|
end
|
16
22
|
|
17
23
|
def publish(message = @default.sqs_message)
|
24
|
+
return if ChiliLogger.instance.deactivated
|
25
|
+
|
18
26
|
message_body = { body: message }
|
19
27
|
queue_message = queue_message(message_body)
|
20
28
|
|
21
29
|
@sqs.send_message(queue_message)
|
22
30
|
end
|
23
31
|
|
32
|
+
def fetch_messages
|
33
|
+
return if ChiliLogger.instance.deactivated
|
34
|
+
|
35
|
+
messages = []
|
36
|
+
remaining_msgs = num_of_msgs_in_queue
|
37
|
+
return messages unless remaining_msgs.positive?
|
38
|
+
|
39
|
+
@poller.poll do |sqs_msg|
|
40
|
+
messages << { fallback_broker_msg: sqs_msg, log: JSON.parse(sqs_msg.body)['body']['log'] }
|
41
|
+
|
42
|
+
remaining_msgs -= 1
|
43
|
+
throw :stop_polling if remaining_msgs <= 0 # prevents infinite loop
|
44
|
+
end
|
45
|
+
|
46
|
+
messages
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete_message(msg)
|
50
|
+
@poller.delete_messages([msg])
|
51
|
+
end
|
52
|
+
|
24
53
|
private
|
25
54
|
|
26
55
|
def queue_message(message_body)
|
@@ -36,25 +65,20 @@ class ChiliLogger
|
|
36
65
|
@sqs.get_queue_url(queue_name: queue_name).queue_url
|
37
66
|
end
|
38
67
|
|
39
|
-
def
|
40
|
-
|
68
|
+
def num_of_msgs_in_queue
|
69
|
+
sqs_queue_attrs = @sqs.get_queue_attributes(queue_url: queue_url(@queue_name), attribute_names: ['All'])
|
70
|
+
sqs_queue_attrs.attributes['ApproximateNumberOfMessages'].to_i
|
41
71
|
end
|
42
72
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
73
|
+
def sqs_config(custom_config)
|
74
|
+
default_keys = %i[region access_key_id secret_access_key]
|
75
|
+
config = {}
|
46
76
|
|
47
|
-
|
48
|
-
|
77
|
+
default_keys.each do |key|
|
78
|
+
config[key] = custom_config[key] || @default_secrets[key.to_s]
|
79
|
+
end
|
49
80
|
|
50
|
-
|
51
|
-
main_config_keys.each { |key| raise(ChiliLogger::ConfigError, config_attr_error(key)) unless config[key] }
|
52
|
-
|
53
|
-
{
|
54
|
-
region: config[:region],
|
55
|
-
access_key_id: config[:access_key_id],
|
56
|
-
secret_access_key: config[:secret_access_key]
|
57
|
-
}
|
81
|
+
config
|
58
82
|
end
|
59
83
|
end
|
60
84
|
end
|
data/lib/chili_logger.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'brokers/main_broker'
|
1
3
|
require 'chili_logger/version'
|
2
4
|
require 'current_log_accessor'
|
3
|
-
require 'errors/error_messages/config_error'
|
4
5
|
require 'errors/logging_error_handler/logging_error_handler'
|
5
|
-
require 'brokers/rabbit_broker'
|
6
|
-
require 'message_writer/message_writer'
|
7
|
-
require 'brokers/sqs_broker'
|
8
6
|
require 'helpers/values/default'
|
9
7
|
require 'helpers/values/type_uniformizer/desc'
|
10
8
|
require 'helpers/values/type_uniformizer/user'
|
11
9
|
require 'helpers/values/type_uniformizer/main_content'
|
12
|
-
require '
|
10
|
+
require 'message_writer/message_writer'
|
11
|
+
require 'unpublished_logs_manager/unpublished_logs_manager'
|
13
12
|
|
14
13
|
# class for centralizing Creative's logging logic
|
15
14
|
class ChiliLogger
|
@@ -32,6 +31,7 @@ class ChiliLogger
|
|
32
31
|
config_logging_error_handler(config)
|
33
32
|
config_msg_writer(config)
|
34
33
|
config_msg_broker(config)
|
34
|
+
config_unpublished_logs_manager
|
35
35
|
|
36
36
|
@current_log_accessor = CurrentLogAccessor.new(@msg_broker, @msg_writer)
|
37
37
|
end
|
@@ -59,16 +59,16 @@ class ChiliLogger
|
|
59
59
|
end
|
60
60
|
|
61
61
|
message = @msg_writer.write(options)
|
62
|
-
|
62
|
+
@msg_broker.publish(message)
|
63
|
+
end
|
63
64
|
|
64
|
-
|
65
|
+
def republish_unpublished_logs
|
66
|
+
@unpublished_logs_manager.republish
|
65
67
|
end
|
66
68
|
|
67
69
|
private
|
68
70
|
|
69
71
|
def config_logging_error_handler(general_config)
|
70
|
-
return @logging_error_handler = nil if @deactivated
|
71
|
-
|
72
72
|
fallback_name = general_config[:fallback_broker]
|
73
73
|
fallback_config = general_config[:fallback_broker_config]
|
74
74
|
@logging_error_handler = LoggingErrorHandler.new(fallback_name, fallback_config)
|
@@ -76,8 +76,8 @@ class ChiliLogger
|
|
76
76
|
|
77
77
|
def config_msg_writer(general_config)
|
78
78
|
msg_writer_config = {
|
79
|
-
env: general_config[:log_env],
|
80
|
-
layer: general_config[:log_layer],
|
79
|
+
env: general_config[:log_env]&.downcase,
|
80
|
+
layer: general_config[:log_layer]&.downcase,
|
81
81
|
server_url: general_config[:server_url],
|
82
82
|
cloud_provider: general_config[:cloud_provider]
|
83
83
|
}
|
@@ -86,26 +86,13 @@ class ChiliLogger
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def config_msg_broker(general_config)
|
89
|
-
msg_broker_name = general_config[:msg_broker_name]
|
90
|
-
msg_broker_config = general_config[:msg_broker_config]
|
91
|
-
@msg_broker = supported_msg_brokers[msg_broker_name.to_sym]
|
92
|
-
raise(ConfigError, broker_name_error(msg_broker_name)) unless @msg_broker
|
93
|
-
|
94
|
-
# TODO: implement MessageBroker class, an interface between ChiliLogger and possible brokers.
|
95
|
-
# TODO: add "supported_msg_broker", "broker_name_error" and "return @msg_broker if @deactivated" to MessageBroker
|
96
|
-
# prevents broker from even starting connection if ChiliLogger is deactivated
|
97
|
-
return @msg_broker if @deactivated
|
89
|
+
msg_broker_name = general_config[:msg_broker_name]
|
90
|
+
msg_broker_config = general_config[:msg_broker_config]
|
98
91
|
|
99
|
-
@msg_broker.
|
92
|
+
@msg_broker = MainBroker.new(msg_broker_name, msg_broker_config, @logging_error_handler)
|
100
93
|
end
|
101
94
|
|
102
|
-
def
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
def supported_msg_brokers
|
107
|
-
{
|
108
|
-
rabbitmq: RabbitBroker.new(@logging_error_handler)
|
109
|
-
}
|
95
|
+
def config_unpublished_logs_manager
|
96
|
+
@unpublished_logs_manager = UnpublishedLogsManager.new(@msg_broker, @logging_error_handler)
|
110
97
|
end
|
111
98
|
end
|
data/lib/chili_logger/version.rb
CHANGED
data/lib/current_log_accessor.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'message_writer/message_writer'
|
2
|
-
require 'helpers/values/default'
|
3
2
|
require 'helpers/values/type_uniformizer/desc'
|
4
3
|
require 'helpers/values/type_uniformizer/main_content'
|
5
4
|
require 'helpers/values/type_uniformizer/user'
|
6
|
-
require 'byebug'
|
7
5
|
|
8
6
|
# class for centralizing Creative's logging logic
|
9
7
|
class ChiliLogger
|
@@ -20,11 +18,9 @@ class ChiliLogger
|
|
20
18
|
|
21
19
|
def publish(**options)
|
22
20
|
update_current_log(options)
|
23
|
-
|
24
21
|
message = @msg_writer.write(desc: desc, user: user, main_content: main_content)
|
25
|
-
|
22
|
+
@msg_broker.publish(message)
|
26
23
|
|
27
|
-
@msg_broker.publish(message, routing_key)
|
28
24
|
clear_log_info
|
29
25
|
end
|
30
26
|
|
@@ -5,31 +5,46 @@ require 'errors/error_messages/config_error'
|
|
5
5
|
class ChiliLogger
|
6
6
|
# class that handles errors when message broker can't be reached, etc...
|
7
7
|
class LoggingErrorHandler
|
8
|
-
def initialize(fallback_name, config)
|
9
|
-
|
8
|
+
def initialize(fallback_name = nil, config = {})
|
9
|
+
@default = ChiliLogger::Values::Default.new
|
10
|
+
config ||= {}
|
11
|
+
validate_config(config)
|
10
12
|
|
11
|
-
fallback_name
|
12
|
-
fallback_broker_class = supported_fallback_brokers[fallback_name]
|
13
|
+
fallback_name ||= @default.fallback_broker
|
14
|
+
fallback_broker_class = supported_fallback_brokers[fallback_name.to_sym]
|
13
15
|
unsupported_fallback_broker_error unless fallback_broker_class
|
14
16
|
|
15
17
|
@fallback_broker = fallback_broker_class.new(config)
|
16
18
|
end
|
17
19
|
|
18
20
|
def handle_error(error, log = nil)
|
21
|
+
return if ChiliLogger.instance.deactivated
|
22
|
+
|
19
23
|
message = message(error, log)
|
20
24
|
@fallback_broker.publish(message)
|
21
25
|
rescue StandardError => e
|
22
|
-
puts '
|
23
|
-
There was a problem with both the Message Broker and the Fallback Broker simultaneously.
|
26
|
+
puts 'There was a problem with both the Message Broker and the Fallback Broker simultaneously.
|
24
27
|
To keep the application running and prevent downtime,
|
25
28
|
ChiliLogger will ignore this errors and discard the log it was currently trying to publish.
|
26
|
-
Please note that logs are being permanently lost.
|
27
|
-
'
|
29
|
+
Please note that logs are being permanently lost.'
|
28
30
|
puts e
|
29
31
|
end
|
30
32
|
|
33
|
+
def fetch_unpublished_logs
|
34
|
+
@fallback_broker.fetch_messages
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_unpublished_log(msg)
|
38
|
+
@fallback_broker.delete_message(msg)
|
39
|
+
end
|
40
|
+
|
31
41
|
private
|
32
42
|
|
43
|
+
def validate_config(config)
|
44
|
+
invalid_config_err = ':fallback_broker_config must be a hash'
|
45
|
+
raise(ChiliLogger::ConfigError, invalid_config_err) unless [Hash, NilClass].include?(config.class)
|
46
|
+
end
|
47
|
+
|
33
48
|
def message(error, log)
|
34
49
|
{
|
35
50
|
error_type: error.class.name,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'fileutils'
|
3
|
-
require '
|
3
|
+
require 'byebug'
|
4
4
|
|
5
5
|
# class for centralizing Creative's logging logic
|
6
6
|
class ChiliLogger
|
@@ -22,8 +22,10 @@ class ChiliLogger
|
|
22
22
|
|
23
23
|
def self.read_file
|
24
24
|
file_exists = File.file?(file_path)
|
25
|
+
file = file_exists ? YAML.load_file(file_path) : {}
|
25
26
|
|
26
|
-
|
27
|
+
# workaround for a bug in YAML lib, in which #load_file returns nil if file is empty, instead of an empty hash
|
28
|
+
file.nil? ? {} : file
|
27
29
|
end
|
28
30
|
|
29
31
|
def self.write_file(file)
|