RTALogger 0.1.2 → 1.1.1
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 +186 -90
- data/lib/RTALogger/version.rb +1 -1
- data/lib/log_factory_log_formatter.rb +24 -8
- data/lib/log_factory_repository.rb +23 -42
- data/lib/log_factory_topic.rb +2 -2
- data/lib/log_formatter_base.rb +33 -0
- data/lib/log_formatter_json.rb +6 -3
- data/lib/log_formatter_text.rb +11 -8
- data/lib/log_manager.rb +124 -48
- data/lib/log_propagator.rb +17 -15
- data/lib/log_record.rb +1 -1
- data/lib/log_repository.rb +43 -1
- data/lib/log_repository_console.rb +5 -1
- data/lib/log_repository_file.rb +33 -3
- data/lib/log_repository_fluentd.rb +58 -0
- data/lib/log_repository_udp.rb +14 -6
- data/lib/log_topic.rb +24 -14
- data/lib/rta_logger_config.json +43 -22
- data/lib/sample.rb +12 -2
- data/lib/severity_level.rb +60 -0
- data/lib/string.rb +9 -0
- metadata +6 -6
- data/lib/log_factory_file_logger.rb +0 -17
- data/lib/log_formatter.rb +0 -8
- data/lib/log_repository_fluent.rb +0 -32
- data/lib/log_severity.rb +0 -17
data/lib/log_factory_topic.rb
CHANGED
@@ -5,8 +5,8 @@ require_relative 'log_topic'
|
|
5
5
|
module RTALogger
|
6
6
|
# this module generates object instance
|
7
7
|
module LogFactory
|
8
|
-
def self.new_log_topic(log_manager,
|
9
|
-
LogTopic.new(log_manager,
|
8
|
+
def self.new_log_topic(log_manager, title, level = WARN, enable = true)
|
9
|
+
LogTopic.new(log_manager, title, level, enable)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'jbuilder'
|
2
|
+
require_relative 'string'
|
3
|
+
|
4
|
+
module RTALogger
|
5
|
+
class LogFormatterBase
|
6
|
+
def initialize
|
7
|
+
@delimiter = '|'
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_accessor :delimiter
|
11
|
+
|
12
|
+
def load_config(config_json)
|
13
|
+
@delimiter = config_json['delimiter'].nil? ? true : config_json['delimiter']
|
14
|
+
end
|
15
|
+
|
16
|
+
def format(log_record)
|
17
|
+
log_record.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_builder
|
21
|
+
jb = Jbuilder.new do |json|
|
22
|
+
json.type self.class.to_s.split('::').last.underscore.sub('log_formatter_', '')
|
23
|
+
json.delimiter delimiter
|
24
|
+
end
|
25
|
+
|
26
|
+
jb
|
27
|
+
end
|
28
|
+
|
29
|
+
def reveal_config
|
30
|
+
to_builder.target!
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/log_formatter_json.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'jbuilder'
|
2
|
-
require_relative '
|
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
|
-
class
|
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,18 +1,21 @@
|
|
1
|
-
require_relative '
|
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
|
-
class LogFormatterText <
|
7
|
-
|
7
|
+
class LogFormatterText < LogFormatterBase
|
8
|
+
include SeverityLevel
|
9
|
+
|
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
|
-
result << delimiter << log_record.app_name
|
12
|
-
result << delimiter << log_record.topic_title
|
13
|
-
result << delimiter << log_record.context_id
|
14
|
-
result << delimiter << log_record.severity
|
15
|
-
result << delimiter << log_record.message.join(' ').gsub(delimiter, '$<$')
|
14
|
+
result << @delimiter << log_record.app_name
|
15
|
+
result << @delimiter << log_record.topic_title
|
16
|
+
result << @delimiter << log_record.context_id.to_s
|
17
|
+
result << @delimiter << parse_severity_level_to_s(log_record.severity)
|
18
|
+
result << @delimiter << log_record.message.join(' ').gsub(delimiter, '$<$')
|
16
19
|
|
17
20
|
result
|
18
21
|
end
|
data/lib/log_manager.rb
CHANGED
@@ -1,28 +1,34 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'thread'
|
3
3
|
require 'singleton'
|
4
|
+
require 'json'
|
5
|
+
require 'json/version'
|
6
|
+
require 'json/generic_object'
|
4
7
|
require_relative 'log_factory_propagator'
|
5
8
|
require_relative 'log_factory_repository'
|
6
9
|
require_relative 'log_factory_topic'
|
7
|
-
require_relative '
|
10
|
+
require_relative 'severity_level'
|
11
|
+
require 'jbuilder'
|
8
12
|
|
9
13
|
# the module will contain all logger requirements
|
10
14
|
module RTALogger
|
11
15
|
# the class is the main class
|
12
16
|
class LogManager
|
13
17
|
include Singleton
|
14
|
-
include
|
18
|
+
include SeverityLevel
|
15
19
|
include RTALogger::LogFactory
|
16
20
|
|
17
21
|
def initialize
|
18
22
|
@enable = true
|
19
|
-
@
|
20
|
-
@
|
23
|
+
@name = 'default_log_manager'
|
24
|
+
@app_name = ENV.fetch('RTA_LOGGER_APP_NAME', 'unknown_app')
|
25
|
+
@severity_level = ENV.fetch('RTA_LOGGER_SEVERITY_LEVEL', WARN)
|
26
|
+
@config_file_name = ''
|
21
27
|
@topic_semaphore = Mutex.new
|
22
28
|
@log_semaphore = Mutex.new
|
23
|
-
|
29
|
+
self.buffer_size = ENV.fetch('RTA_LOGGER_BUFFER_SIZE', 100)
|
24
30
|
@flush_size = @buffer_size * 20 / 100
|
25
|
-
|
31
|
+
self.flush_wait_time = ENV.fetch('RTA_LOGGER_FLUSH_WAIT_SECONDS', 15)
|
26
32
|
@topics = {}
|
27
33
|
@log_records = []
|
28
34
|
@propagator = LogFactory.new_log_propagator
|
@@ -36,36 +42,54 @@ module RTALogger
|
|
36
42
|
@flush_scheduler.run
|
37
43
|
end
|
38
44
|
|
39
|
-
|
40
|
-
|
45
|
+
attr_reader :name
|
46
|
+
attr_accessor :enable
|
47
|
+
attr_accessor :app_name
|
48
|
+
attr_reader :propagator
|
49
|
+
attr_accessor :default_severity_level
|
50
|
+
attr_reader :flush_size
|
51
|
+
attr_reader :topics
|
52
|
+
attr_reader :config_file_name
|
53
|
+
|
54
|
+
def buffer_size
|
55
|
+
@buffer_size
|
56
|
+
end
|
57
|
+
|
58
|
+
def buffer_size=(size)
|
59
|
+
@buffer_size = size < 100 ? 100 : size
|
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, manager_name = '')
|
71
|
+
config_json = load_config_from_json_file(file_name, manager_name)
|
72
|
+
@config_file_name = file_name if config_json
|
41
73
|
apply_config(config_json)
|
42
74
|
rescue StandardError => e
|
43
|
-
puts e.message
|
44
75
|
@propagator.drop_all_repositories
|
45
|
-
@propagator.add_log_repository(LogFactory.
|
76
|
+
@propagator.add_log_repository(LogFactory.create_repository(:console))
|
46
77
|
end
|
47
78
|
|
48
|
-
def config_use_json_string(config_string)
|
49
|
-
config_json = load_config_from_json_string(
|
79
|
+
def config_use_json_string(config_string, manager_name = '')
|
80
|
+
config_json = load_config_from_json_string(config_string, manager_name)
|
50
81
|
apply_config(config_json)
|
51
82
|
rescue StandardError => e
|
52
|
-
puts e.message
|
53
83
|
@propagator.drop_all_repositories
|
54
|
-
@propagator.add_log_repository(LogFactory.
|
84
|
+
@propagator.add_log_repository(LogFactory.create_repository(:console))
|
55
85
|
end
|
56
86
|
|
57
|
-
|
58
|
-
attr_accessor :app_name
|
59
|
-
attr_reader :propagator
|
60
|
-
attr_reader :default_log_level
|
61
|
-
|
62
|
-
def add_topic(topic_title, log_level = @default_log_level)
|
87
|
+
def add_topic(title, severity_level = @default_severity_level, enable = true)
|
63
88
|
@topic_semaphore.synchronize {
|
64
|
-
@topics[
|
89
|
+
@topics[title.to_sym] ||= LogFactory.new_log_topic(self, title, severity_level, enable)
|
65
90
|
}
|
66
91
|
|
67
|
-
@topics[
|
68
|
-
@topics[topic_title.to_sym]
|
92
|
+
@topics[title.to_sym]
|
69
93
|
end
|
70
94
|
|
71
95
|
def add_log(log_record)
|
@@ -74,59 +98,110 @@ module RTALogger
|
|
74
98
|
check_for_flush
|
75
99
|
end
|
76
100
|
|
77
|
-
def
|
78
|
-
@topic_semaphore.synchronize { @topics[topic].
|
101
|
+
def update_topic_enable(topic, enable = true)
|
102
|
+
@topic_semaphore.synchronize { @topics[topic.to_sym].enable = enable if @topics[topic.to_sym] }
|
79
103
|
end
|
80
104
|
|
81
|
-
def
|
82
|
-
@topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].
|
105
|
+
def update_all_topics_enable(enable = true)
|
106
|
+
@topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].enable = enable } }
|
107
|
+
end
|
108
|
+
|
109
|
+
def update_topic_severity_level(topic, severity_level = WARN)
|
110
|
+
@topic_semaphore.synchronize { @topics[topic.to_sym].severity_level = severity_level if @topics[topic.to_sym] }
|
111
|
+
end
|
112
|
+
|
113
|
+
def update_all_topics_severity_level(severity_level = WARN)
|
114
|
+
@topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].severity_level = severity_level } }
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_builder
|
118
|
+
@topic_semaphore.synchronize do
|
119
|
+
jb = Jbuilder.new do |json|
|
120
|
+
json.name name
|
121
|
+
json.enable enable
|
122
|
+
json.app_name app_name
|
123
|
+
json.config_file_name config_file_name
|
124
|
+
json.default_severity_level default_severity_level
|
125
|
+
json.buffer_size buffer_size
|
126
|
+
json.flush_size flush_size
|
127
|
+
json.flush_wait_time flush_wait_time
|
128
|
+
json.repositories do
|
129
|
+
json.array! @propagator.repositories.collect { |repository| repository.to_builder.attributes! }
|
130
|
+
end
|
131
|
+
json.topics do
|
132
|
+
json.array! topics.keys.collect { |topic_key| @topics[topic_key].to_builder.attributes! }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
jb
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def reveal_config
|
141
|
+
to_builder.target!
|
83
142
|
end
|
84
143
|
|
85
144
|
private
|
86
145
|
|
87
|
-
def load_config_from_json_file(config_file_name)
|
146
|
+
def load_config_from_json_file(config_file_name, manager_name = '')
|
88
147
|
config_file = File.open config_file_name
|
89
|
-
config_json = JSON.load
|
90
|
-
config_json = extract_config(config_json)
|
148
|
+
config_json = ::JSON.load(config_file)
|
149
|
+
config_json = extract_config(config_json, manager_name)
|
91
150
|
config_json
|
92
151
|
end
|
93
152
|
|
94
|
-
def load_config_from_json_string(config_string)
|
95
|
-
config_json = JSON.parse(config_string)
|
96
|
-
config_json = extract_config(config_json)
|
153
|
+
def load_config_from_json_string(config_string, manager_name = '')
|
154
|
+
config_json = ::JSON.parse(config_string)
|
155
|
+
config_json = extract_config(config_json, manager_name)
|
97
156
|
config_json
|
98
157
|
end
|
99
158
|
|
100
|
-
def extract_config(json_data)
|
101
|
-
config_json = json_data['
|
159
|
+
def extract_config(json_data, manager_name = '')
|
160
|
+
config_json = json_data['rta_logger']
|
102
161
|
raise 'RTALogger configuration not found!' unless config_json
|
103
|
-
raise 'Log_Managers section does not exists json configuration' unless config_json['
|
104
|
-
raise 'No config manager defined in json configuration' unless config_json['
|
105
|
-
manager_name = config_json['
|
162
|
+
raise 'Log_Managers section does not exists json configuration' unless config_json['log_managers']
|
163
|
+
raise 'No config manager defined in json configuration' unless config_json['log_managers'].count.positive?
|
164
|
+
manager_name = config_json['default_manager'] if manager_name.empty?
|
106
165
|
unless manager_name.to_s.strip.empty?
|
107
|
-
config_json = config_json['
|
166
|
+
config_json = config_json['log_managers'].find { |item| item['manager_name'] == manager_name }
|
108
167
|
end
|
109
|
-
config_json ||= config_json['
|
168
|
+
config_json ||= config_json['log_managers'][0]
|
110
169
|
raise 'Unable to extract RTA Log Manager configuration!' unless config_json
|
170
|
+
@name = manager_name if config_json
|
111
171
|
config_json
|
112
172
|
end
|
113
173
|
|
114
174
|
def apply_config(config_json)
|
115
175
|
raise 'json config not available' unless config_json
|
116
|
-
@enable = config_json['
|
117
|
-
@app_name = config_json['
|
118
|
-
@
|
119
|
-
|
120
|
-
|
176
|
+
@enable = config_json['enable'].nil? ? true : config_json['enable']
|
177
|
+
@app_name = config_json['app_name'] unless config_json['app_name'].empty?
|
178
|
+
@default_severity_level = parse_severity_level_to_i(config_json['severity_level']) if config_json['severity_level']
|
179
|
+
self.buffer_size = config_json['buffer_size'] if config_json['buffer_size']
|
180
|
+
self.flush_wait_time = config_json['flush_wait_seconds'] if config_json['flush_wait_seconds']
|
121
181
|
@propagator.drop_all_repositories
|
122
|
-
config_json
|
182
|
+
apply_config_repos(config_json)
|
183
|
+
apply_config_topics(config_json)
|
184
|
+
end
|
185
|
+
|
186
|
+
def apply_config_repos(config_json)
|
187
|
+
config_json['repositories']&.each { |item| @propagator.load_log_repository(item) }
|
188
|
+
end
|
189
|
+
|
190
|
+
def apply_config_topics(config_json)
|
191
|
+
config_json['topics']&.each do |topic|
|
192
|
+
next unless topic['title']
|
193
|
+
result_topic = add_topic(topic['title'])
|
194
|
+
next unless result_topic
|
195
|
+
result_topic.severity_level = parse_severity_level_to_i topic['severity_level'] if topic['severity_level']
|
196
|
+
result_topic.enable = topic['enable'] if topic['enable']
|
197
|
+
end
|
123
198
|
end
|
124
199
|
|
125
200
|
def initialize_flush_scheduler
|
126
201
|
@flush_scheduler = Thread.new do
|
127
202
|
loop do
|
128
203
|
elapsed_seconds = ((DateTime.now - @last_flush_time) * 24 * 60 * 60).to_i
|
129
|
-
flush if elapsed_seconds >
|
204
|
+
flush if elapsed_seconds > flush_wait_time
|
130
205
|
sleep(1)
|
131
206
|
break if @exit_flush_scheduler
|
132
207
|
end
|
@@ -153,7 +228,7 @@ module RTALogger
|
|
153
228
|
|
154
229
|
def flush_all
|
155
230
|
@log_semaphore.synchronize do
|
156
|
-
@log_records[0...@log_records.count].each { |log|
|
231
|
+
@log_records[0...@log_records.count].each { |log| propagate(log) }
|
157
232
|
@log_records.clear
|
158
233
|
end
|
159
234
|
@propagator.propagate
|
@@ -162,5 +237,6 @@ module RTALogger
|
|
162
237
|
def propagate(log_record)
|
163
238
|
@propagator.add_log(log_record)
|
164
239
|
end
|
240
|
+
|
165
241
|
end
|
166
242
|
end
|
data/lib/log_propagator.rb
CHANGED
@@ -5,39 +5,41 @@ module RTALogger
|
|
5
5
|
class LogPropagator
|
6
6
|
def initialize
|
7
7
|
@semaphore = Mutex.new
|
8
|
-
@
|
9
|
-
@
|
8
|
+
@records = []
|
9
|
+
@repositories = []
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
attr_reader :repositories
|
13
|
+
|
14
|
+
def add_log(record)
|
15
|
+
@semaphore.synchronize { @records.push(record.dup) }
|
14
16
|
end
|
15
17
|
|
16
|
-
def add_log_repository(
|
17
|
-
return unless
|
18
|
-
@
|
18
|
+
def add_log_repository(repository)
|
19
|
+
return unless repository.is_a? RTALogger::LogRepository
|
20
|
+
@repositories.push(repository) unless @repositories.include?(repository)
|
19
21
|
end
|
20
22
|
|
21
23
|
def load_log_repository(config_json)
|
22
|
-
type = config_json['
|
24
|
+
type = config_json['type']
|
23
25
|
return if type.to_s.strip.empty?
|
24
|
-
enable = config_json['
|
26
|
+
enable = config_json['enable'].nil? ? true : config_json['enable']
|
25
27
|
return unless enable
|
26
28
|
|
27
|
-
|
28
|
-
add_log_repository(
|
29
|
+
repository = ::RTALogger::LogFactory.create_repository(type, config_json)
|
30
|
+
add_log_repository(repository)
|
29
31
|
end
|
30
32
|
|
31
33
|
def drop_all_repositories
|
32
|
-
@semaphore.synchronize { @
|
34
|
+
@semaphore.synchronize { @repositories.clear }
|
33
35
|
end
|
34
36
|
|
35
37
|
def propagate
|
36
38
|
@semaphore.synchronize do
|
37
|
-
@
|
38
|
-
|
39
|
+
@repositories.each do |repository|
|
40
|
+
repository.add_log_records(@records)
|
39
41
|
end
|
40
|
-
@
|
42
|
+
@records.clear
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
data/lib/log_record.rb
CHANGED
data/lib/log_repository.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative 'string'
|
2
|
+
|
1
3
|
module RTALogger
|
2
4
|
# base log repository class
|
3
5
|
class LogRepository
|
@@ -5,8 +7,27 @@ module RTALogger
|
|
5
7
|
@semaphore = Mutex.new
|
6
8
|
@log_records = []
|
7
9
|
@enable = true
|
10
|
+
@formatter = RTALogger::LogFactory.log_formatter_default
|
8
11
|
end
|
9
12
|
|
13
|
+
# @@sub_classes = {}
|
14
|
+
|
15
|
+
# def self.create type
|
16
|
+
# requested_class = @@sub_classes[type]
|
17
|
+
# if requested_class
|
18
|
+
# requested_class.new
|
19
|
+
# else
|
20
|
+
# raise "Bad log repository type: #{type}"
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def self.register repository_name
|
25
|
+
# @@sub_classes[repository_name] = self
|
26
|
+
# end
|
27
|
+
|
28
|
+
attr_accessor :enable
|
29
|
+
attr_accessor :formatter
|
30
|
+
|
10
31
|
def add_log_records(items)
|
11
32
|
return 0 unless @enable
|
12
33
|
@semaphore.synchronize do
|
@@ -15,7 +36,28 @@ module RTALogger
|
|
15
36
|
flush_and_clear
|
16
37
|
end
|
17
38
|
|
18
|
-
|
39
|
+
def load_config(config_json)
|
40
|
+
@enable = config_json['enable'].nil? ? true : config_json['enable']
|
41
|
+
|
42
|
+
formatter_config = config_json['formatter']
|
43
|
+
if formatter_config && formatter_config['type']
|
44
|
+
@formatter = LogFactory.create_formatter(formatter_config['type'], formatter_config)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_builder
|
49
|
+
jb = Jbuilder.new do |json|
|
50
|
+
json.type self.class.to_s.split('::').last.underscore.sub('log_repository_', '')
|
51
|
+
json.enable enable
|
52
|
+
json.formatter @formatter.to_builder.attributes!
|
53
|
+
end
|
54
|
+
|
55
|
+
jb
|
56
|
+
end
|
57
|
+
|
58
|
+
def reveal_config
|
59
|
+
to_builder.target!
|
60
|
+
end
|
19
61
|
|
20
62
|
protected
|
21
63
|
|