RTALogger 1.1.0 → 2.1.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/Gemfile.lock +1 -1
- data/README.md +261 -85
- data/lib/RTALogger/version.rb +1 -1
- data/lib/log_factory_filter.rb +33 -0
- data/lib/log_filter_base.rb +39 -0
- data/lib/log_filter_context.rb +13 -0
- data/lib/log_filter_message.rb +13 -0
- data/lib/log_filter_topic.rb +13 -0
- data/lib/log_formatter_json.rb +4 -1
- data/lib/log_formatter_text.rb +5 -2
- data/lib/log_manager.rb +72 -32
- data/lib/log_propagator.rb +62 -6
- data/lib/log_record.rb +4 -0
- data/lib/log_repository.rb +65 -2
- data/lib/log_repository_console.rb +1 -1
- data/lib/log_repository_file.rb +6 -1
- data/lib/log_repository_fluentd.rb +51 -8
- data/lib/log_topic.rb +11 -0
- data/lib/rta_logger_config.json +26 -8
- data/lib/sample.rb +2 -1
- data/lib/severity_level.rb +39 -31
- metadata +7 -2
data/lib/RTALogger/version.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'log_filter_base'
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
# Log factory to get new instance of log filter
|
5
|
+
module LogFactory
|
6
|
+
def self.create_filter(type, config_json = '')
|
7
|
+
lib_file = @log_filters[type.to_sym]
|
8
|
+
raise "unregistered filter class: #{type.to_s}" if lib_file.nil? || lib_file.empty?
|
9
|
+
begin
|
10
|
+
load lib_file
|
11
|
+
rescue
|
12
|
+
raise "unable to load formatter class file: #{lib_file}"
|
13
|
+
end
|
14
|
+
|
15
|
+
filter_class_name = 'RTALogger::' + ('log_filter_' + type.to_s).split('_').map(&:capitalize).join
|
16
|
+
filter_class = Object.const_get(filter_class_name)
|
17
|
+
return nil unless filter_class
|
18
|
+
result = filter_class.new
|
19
|
+
|
20
|
+
return result if config_json.empty?
|
21
|
+
result.load_config(config_json) if result.present?
|
22
|
+
return result
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.register_log_filter(type, class_file_name)
|
26
|
+
@log_filters[type.to_sym] = class_file_name
|
27
|
+
end
|
28
|
+
|
29
|
+
@log_filters = {:topic => 'log_filter_topic.rb',
|
30
|
+
:context => 'log_filter_context.rb',
|
31
|
+
:message => 'log_filter_message.rb'}
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RTALogger
|
2
|
+
class LogFilterBase
|
3
|
+
def initialize
|
4
|
+
@title = self.class.to_s.split('::').last.underscore
|
5
|
+
@enable = true
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_accessor :title
|
9
|
+
attr_accessor :enable
|
10
|
+
attr_accessor :default_regex
|
11
|
+
|
12
|
+
def match_conditions(log_record)
|
13
|
+
return true if !@enable
|
14
|
+
return log_record.present?
|
15
|
+
end
|
16
|
+
|
17
|
+
def load_config(config_json)
|
18
|
+
@title = config_json['title'] if config_json['title'].present?
|
19
|
+
@enable = config_json['enable'].nil? ? true : config_json['enable'].present?
|
20
|
+
@default_regex = config_json['default_regex'] if config_json['default_regex'].present?
|
21
|
+
end
|
22
|
+
|
23
|
+
def apply_run_time_config(config_json)
|
24
|
+
@enable = config_json['enable'].nil? ? true : config_json['enable'].present?
|
25
|
+
@default_regex = config_json['default_regex'] if config_json['default_regex'].present?
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_builder
|
29
|
+
jb = Jbuilder.new do |json|
|
30
|
+
json.type self.class.to_s.split('::').last.underscore.sub('log_filter_', '')
|
31
|
+
json.title @title
|
32
|
+
json.enable @enable
|
33
|
+
json.default_regex @default_regex
|
34
|
+
end
|
35
|
+
|
36
|
+
jb
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'log_filter_base'
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
class LogFilterContext < LogFilterBase
|
5
|
+
def match_conditions(log_record)
|
6
|
+
return true if !@enable
|
7
|
+
result = super
|
8
|
+
return result unless result
|
9
|
+
|
10
|
+
return default_regex.present? ? (Regexp.new(@default_regex).match(log_record.context_id.to_s)) : result
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'log_filter_base'
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
class LogFilterMessage < LogFilterBase
|
5
|
+
def match_conditions(log_record)
|
6
|
+
return true if !@enable
|
7
|
+
result = super
|
8
|
+
return result unless result
|
9
|
+
|
10
|
+
return default_regex.present? ? (Regexp.new(@default_regex).match(log_record.full_message)) : result
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'log_filter_base'
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
class LogFilterTopic < LogFilterBase
|
5
|
+
def match_conditions(log_record)
|
6
|
+
return true if !@enable
|
7
|
+
result = super
|
8
|
+
return result unless result
|
9
|
+
|
10
|
+
return default_regex.present? ? (Regexp.new(@default_regex).match(log_record.topic_title)) : result
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/log_formatter_json.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'jbuilder'
|
2
2
|
require_relative 'log_formatter_base'
|
3
|
+
require_relative 'severity_level'
|
3
4
|
|
4
5
|
module RTALogger
|
5
6
|
# json formatter which receive log_record and
|
6
7
|
# returns it's data as json string
|
7
8
|
class LogFormatterJson < LogFormatterBase
|
9
|
+
include SeverityLevel
|
10
|
+
|
8
11
|
def format(log_record)
|
9
12
|
return '' unless log_record
|
10
13
|
|
@@ -13,7 +16,7 @@ module RTALogger
|
|
13
16
|
json.app_name log_record.app_name
|
14
17
|
json.topic_title log_record.topic_title
|
15
18
|
json.context_id log_record.context_id
|
16
|
-
json.severity log_record.severity
|
19
|
+
json.severity parse_severity_level_to_s(log_record.severity)
|
17
20
|
json.message log_record.message.flatten.join(' ')
|
18
21
|
end
|
19
22
|
|
data/lib/log_formatter_text.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
require_relative 'log_formatter_base'
|
2
|
+
require_relative 'severity_level'
|
2
3
|
|
3
4
|
module RTALogger
|
4
5
|
# text formatter which receive log_record and
|
5
6
|
# returns it's data as delimited text string
|
6
7
|
class LogFormatterText < LogFormatterBase
|
8
|
+
include SeverityLevel
|
9
|
+
|
7
10
|
def format(log_record)
|
8
11
|
return '' unless log_record
|
9
12
|
|
10
13
|
result = log_record.occurred_at.strftime('%F %H:%M:%S:%3N')
|
11
14
|
result << @delimiter << log_record.app_name
|
12
15
|
result << @delimiter << log_record.topic_title
|
13
|
-
result << @delimiter << log_record.context_id
|
14
|
-
result << @delimiter << log_record.severity
|
16
|
+
result << @delimiter << log_record.context_id.to_s
|
17
|
+
result << @delimiter << parse_severity_level_to_s(log_record.severity)
|
15
18
|
result << @delimiter << log_record.message.join(' ').gsub(delimiter, '$<$')
|
16
19
|
|
17
20
|
result
|
data/lib/log_manager.rb
CHANGED
@@ -20,15 +20,14 @@ module RTALogger
|
|
20
20
|
|
21
21
|
def initialize
|
22
22
|
@enable = true
|
23
|
-
@
|
23
|
+
@title = 'default_log_manager'
|
24
24
|
@app_name = ENV.fetch('RTA_LOGGER_APP_NAME', 'unknown_app')
|
25
|
-
@severity_level = ENV.fetch('RTA_LOGGER_SEVERITY_LEVEL',
|
25
|
+
@severity_level = ENV.fetch('RTA_LOGGER_SEVERITY_LEVEL', INFO)
|
26
26
|
@config_file_name = ''
|
27
27
|
@topic_semaphore = Mutex.new
|
28
28
|
@log_semaphore = Mutex.new
|
29
|
-
|
30
|
-
|
31
|
-
@flush_wait_time = ENV.fetch('RTA_LOGGER_FLUSH_WAIT_SECONDS', 15)
|
29
|
+
self.buffer_size = ENV.fetch('RTA_LOGGER_BUFFER_SIZE', 100)
|
30
|
+
self.flush_wait_time = ENV.fetch('RTA_LOGGER_FLUSH_WAIT_SECONDS', 15)
|
32
31
|
@topics = {}
|
33
32
|
@log_records = []
|
34
33
|
@propagator = LogFactory.new_log_propagator
|
@@ -42,19 +41,34 @@ module RTALogger
|
|
42
41
|
@flush_scheduler.run
|
43
42
|
end
|
44
43
|
|
45
|
-
attr_reader :
|
44
|
+
attr_reader :title
|
46
45
|
attr_accessor :enable
|
47
46
|
attr_accessor :app_name
|
48
47
|
attr_reader :propagator
|
49
48
|
attr_accessor :default_severity_level
|
50
|
-
attr_accessor :buffer_size
|
51
49
|
attr_reader :flush_size
|
52
|
-
attr_accessor :flush_wait_time
|
53
50
|
attr_reader :topics
|
54
51
|
attr_reader :config_file_name
|
55
52
|
|
56
|
-
def
|
57
|
-
|
53
|
+
def buffer_size
|
54
|
+
@buffer_size
|
55
|
+
end
|
56
|
+
|
57
|
+
def buffer_size=(size)
|
58
|
+
@buffer_size = size < 100 ? 100 : size
|
59
|
+
@flush_size = @buffer_size * 20 / 100
|
60
|
+
end
|
61
|
+
|
62
|
+
def flush_wait_time
|
63
|
+
@flush_wait_time
|
64
|
+
end
|
65
|
+
|
66
|
+
def flush_wait_time=(time_in_seconds)
|
67
|
+
@flush_wait_time = time_in_seconds < 10 ? 10 : time_in_seconds
|
68
|
+
end
|
69
|
+
|
70
|
+
def config_use_json_file(file_name, title = '')
|
71
|
+
config_json = load_config_from_json_file(file_name, title)
|
58
72
|
@config_file_name = file_name if config_json
|
59
73
|
apply_config(config_json)
|
60
74
|
rescue StandardError => e
|
@@ -62,8 +76,8 @@ module RTALogger
|
|
62
76
|
@propagator.add_log_repository(LogFactory.create_repository(:console))
|
63
77
|
end
|
64
78
|
|
65
|
-
def config_use_json_string(config_string,
|
66
|
-
config_json = load_config_from_json_string(config_string,
|
79
|
+
def config_use_json_string(config_string, title = '')
|
80
|
+
config_json = load_config_from_json_string(config_string, title)
|
67
81
|
apply_config(config_json)
|
68
82
|
rescue StandardError => e
|
69
83
|
@propagator.drop_all_repositories
|
@@ -100,10 +114,22 @@ module RTALogger
|
|
100
114
|
@topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].severity_level = severity_level } }
|
101
115
|
end
|
102
116
|
|
117
|
+
def topic_by_title(title)
|
118
|
+
result = nil
|
119
|
+
@topic_semaphore.synchronize do
|
120
|
+
@topics.keys.each do |topic_key|
|
121
|
+
result = @topics[topic_key.to_sym] if topic_key.to_s.casecmp(title).zero?
|
122
|
+
break if result
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
return result
|
127
|
+
end
|
128
|
+
|
103
129
|
def to_builder
|
104
130
|
@topic_semaphore.synchronize do
|
105
131
|
jb = Jbuilder.new do |json|
|
106
|
-
json.
|
132
|
+
json.title title
|
107
133
|
json.enable enable
|
108
134
|
json.app_name app_name
|
109
135
|
json.config_file_name config_file_name
|
@@ -112,7 +138,8 @@ module RTALogger
|
|
112
138
|
json.flush_size flush_size
|
113
139
|
json.flush_wait_time flush_wait_time
|
114
140
|
json.repositories do
|
115
|
-
json.array! @propagator.repositories.collect { |repository| repository.to_builder.attributes! }
|
141
|
+
# json.array! @propagator.repositories.collect { |repository| repository.to_builder.attributes! }
|
142
|
+
json.array! @propagator.to_builder
|
116
143
|
end
|
117
144
|
json.topics do
|
118
145
|
json.array! topics.keys.collect { |topic_key| @topics[topic_key].to_builder.attributes! }
|
@@ -127,33 +154,51 @@ module RTALogger
|
|
127
154
|
to_builder.target!
|
128
155
|
end
|
129
156
|
|
157
|
+
def apply_run_time_config(config_json)
|
158
|
+
return unless config_json
|
159
|
+
@enable = config_json['enable'] unless config_json['enable'].nil?
|
160
|
+
@default_severity_level = parse_severity_level_to_s(config_json['severity_level']) unless config_json['severity_level'].nil?
|
161
|
+
self.buffer_size = config_json['buffer_size'] unless config_json['buffer_size'].nil?
|
162
|
+
self.flush_wait_time = config_json['flush_wait_time'] unless config_json['flush_wait_time'].nil?
|
163
|
+
@propagator.apply_run_time_config(config_json)
|
164
|
+
apply_run_time_config_topics(config_json)
|
165
|
+
end
|
166
|
+
|
130
167
|
private
|
131
168
|
|
132
|
-
def
|
169
|
+
def apply_run_time_config_topics(config_json)
|
170
|
+
config_json['topics']&.each do |topic_config|
|
171
|
+
next if topic_config['title'].nil?
|
172
|
+
topic = topic_by_title(topic_config['title'])
|
173
|
+
topic.apply_run_time_config(topic_config) if topic.present?
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def load_config_from_json_file(config_file_name, title = '')
|
133
178
|
config_file = File.open config_file_name
|
134
179
|
config_json = ::JSON.load(config_file)
|
135
|
-
config_json = extract_config(config_json,
|
180
|
+
config_json = extract_config(config_json, title)
|
136
181
|
config_json
|
137
182
|
end
|
138
183
|
|
139
|
-
def load_config_from_json_string(config_string,
|
184
|
+
def load_config_from_json_string(config_string, title = '')
|
140
185
|
config_json = ::JSON.parse(config_string)
|
141
|
-
config_json = extract_config(config_json,
|
186
|
+
config_json = extract_config(config_json, title)
|
142
187
|
config_json
|
143
188
|
end
|
144
189
|
|
145
|
-
def extract_config(json_data,
|
190
|
+
def extract_config(json_data, title = '')
|
146
191
|
config_json = json_data['rta_logger']
|
147
192
|
raise 'RTALogger configuration not found!' unless config_json
|
148
193
|
raise 'Log_Managers section does not exists json configuration' unless config_json['log_managers']
|
149
194
|
raise 'No config manager defined in json configuration' unless config_json['log_managers'].count.positive?
|
150
|
-
|
151
|
-
unless
|
152
|
-
config_json = config_json['log_managers'].find { |item| item['
|
195
|
+
title = config_json['default_manager'] if title.empty?
|
196
|
+
unless title.to_s.strip.empty?
|
197
|
+
config_json = config_json['log_managers'].find { |item| item['title'] == title }
|
153
198
|
end
|
154
199
|
config_json ||= config_json['log_managers'][0]
|
155
200
|
raise 'Unable to extract RTA Log Manager configuration!' unless config_json
|
156
|
-
@
|
201
|
+
@title = title if config_json
|
157
202
|
config_json
|
158
203
|
end
|
159
204
|
|
@@ -162,17 +207,12 @@ module RTALogger
|
|
162
207
|
@enable = config_json['enable'].nil? ? true : config_json['enable']
|
163
208
|
@app_name = config_json['app_name'] unless config_json['app_name'].empty?
|
164
209
|
@default_severity_level = parse_severity_level_to_i(config_json['severity_level']) if config_json['severity_level']
|
165
|
-
|
166
|
-
|
167
|
-
@propagator.
|
168
|
-
apply_config_repos(config_json)
|
210
|
+
self.buffer_size = config_json['buffer_size'] if config_json['buffer_size']
|
211
|
+
self.flush_wait_time = config_json['flush_wait_seconds'] if config_json['flush_wait_seconds']
|
212
|
+
@propagator.load_repositories(config_json)
|
169
213
|
apply_config_topics(config_json)
|
170
214
|
end
|
171
215
|
|
172
|
-
def apply_config_repos(config_json)
|
173
|
-
config_json['repositories']&.each { |item| @propagator.load_log_repository(item) }
|
174
|
-
end
|
175
|
-
|
176
216
|
def apply_config_topics(config_json)
|
177
217
|
config_json['topics']&.each do |topic|
|
178
218
|
next unless topic['title']
|
@@ -187,7 +227,7 @@ module RTALogger
|
|
187
227
|
@flush_scheduler = Thread.new do
|
188
228
|
loop do
|
189
229
|
elapsed_seconds = ((DateTime.now - @last_flush_time) * 24 * 60 * 60).to_i
|
190
|
-
flush if elapsed_seconds >
|
230
|
+
flush if elapsed_seconds > flush_wait_time
|
191
231
|
sleep(1)
|
192
232
|
break if @exit_flush_scheduler
|
193
233
|
end
|
data/lib/log_propagator.rb
CHANGED
@@ -6,7 +6,7 @@ module RTALogger
|
|
6
6
|
def initialize
|
7
7
|
@semaphore = Mutex.new
|
8
8
|
@records = []
|
9
|
-
@repositories =
|
9
|
+
@repositories = {}
|
10
10
|
end
|
11
11
|
|
12
12
|
attr_reader :repositories
|
@@ -16,31 +16,87 @@ module RTALogger
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def add_log_repository(repository)
|
19
|
+
return if repository.nil? || repository.title.to_s.empty?
|
19
20
|
return unless repository.is_a? RTALogger::LogRepository
|
20
|
-
@repositories.
|
21
|
+
@semaphore.synchronize { @repositories[repository.title.to_sym] = repository unless @repositories[repository.title.to_sym].present? }
|
21
22
|
end
|
22
23
|
|
23
24
|
def load_log_repository(config_json)
|
24
25
|
type = config_json['type']
|
25
26
|
return if type.to_s.strip.empty?
|
26
|
-
enable = config_json['enable'].nil? ? true : config_json['enable']
|
27
|
-
return unless enable
|
28
27
|
|
29
28
|
repository = ::RTALogger::LogFactory.create_repository(type, config_json)
|
30
29
|
add_log_repository(repository)
|
31
30
|
end
|
32
31
|
|
32
|
+
def load_repositories(config_json)
|
33
|
+
return if config_json.nil?
|
34
|
+
|
35
|
+
@semaphore.synchronize do
|
36
|
+
@repositories.clear
|
37
|
+
config_json['repositories']&.each do |repository_config|
|
38
|
+
type = repository_config['type']
|
39
|
+
next if type.to_s.strip.empty?
|
40
|
+
|
41
|
+
repository = ::RTALogger::LogFactory.create_repository(type, repository_config)
|
42
|
+
@repositories[repository.title.to_sym] = repository unless @repositories[repository.title.to_sym].present?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
33
47
|
def drop_all_repositories
|
34
48
|
@semaphore.synchronize { @repositories.clear }
|
35
49
|
end
|
36
50
|
|
51
|
+
def repository_by_title(title)
|
52
|
+
result = nil
|
53
|
+
@semaphore.synchronize do
|
54
|
+
@repositories.keys.each do |repository_key|
|
55
|
+
result = @repositories[repository_key.to_sym] if repository_key.to_s.casecmp(title).zero?
|
56
|
+
break if result
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
return result
|
61
|
+
end
|
62
|
+
|
63
|
+
def apply_run_time_config(config_json)
|
64
|
+
return unless config_json
|
65
|
+
apply_run_time_config_repositories(config_json)
|
66
|
+
end
|
67
|
+
|
37
68
|
def propagate
|
38
69
|
@semaphore.synchronize do
|
39
|
-
@repositories.each do |
|
40
|
-
|
70
|
+
@repositories.keys.each do |repository_key|
|
71
|
+
@repositories[repository_key.to_sym].add_log_records(@records)
|
41
72
|
end
|
42
73
|
@records.clear
|
43
74
|
end
|
44
75
|
end
|
76
|
+
|
77
|
+
def to_builder
|
78
|
+
result = nil
|
79
|
+
@semaphore.synchronize do
|
80
|
+
result = @repositories&.keys.collect { |repository_key| @repositories[repository_key].to_builder.attributes! }
|
81
|
+
end
|
82
|
+
|
83
|
+
return result
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def apply_run_time_config_repositories(config_json)
|
89
|
+
config_json['repositories']&.each do |repository_config|
|
90
|
+
next if repository_config['title'].nil?
|
91
|
+
repository = repository_by_title(repository_config['title'])
|
92
|
+
if repository.present?
|
93
|
+
repository.apply_run_time_config(repository_config)
|
94
|
+
else
|
95
|
+
repository = ::RTALogger::LogFactory.create_repository(repository_config['type'], config_json)
|
96
|
+
add_log_repository(repository)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
45
101
|
end
|
46
102
|
end
|