RTALogger 0.1.0 → 1.0.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/.idea/.gitignore +2 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/RTALogger.iml +29 -0
- data/.idea/misc.xml +7 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +21 -23
- data/README.md +326 -4
- data/RTALogger.gemspec +2 -1
- data/lib/RTALogger.rb +2 -4
- data/lib/RTALogger/version.rb +1 -1
- data/lib/log_factory_log_formatter.rb +35 -0
- data/lib/{factory/origin/log_factory_manager.rb → log_factory_manager.rb} +1 -3
- data/lib/{factory/origin/log_factory_propagator.rb → log_factory_propagator.rb} +1 -2
- data/lib/{factory/origin/log_factory_record.rb → log_factory_record.rb} +1 -1
- data/lib/log_factory_repository.rb +37 -0
- data/lib/log_factory_topic.rb +12 -0
- data/lib/log_formatter.rb +11 -1
- data/lib/log_formatter_json.rb +4 -2
- data/lib/log_formatter_text.rb +8 -6
- data/lib/log_manager.rb +126 -40
- data/lib/log_propagator.rb +44 -45
- data/lib/log_record.rb +27 -28
- data/lib/log_repository.rb +26 -4
- data/lib/log_repository_console.rb +8 -3
- data/lib/log_repository_file.rb +24 -6
- data/lib/log_repository_fluent.rb +49 -0
- data/lib/log_repository_udp.rb +14 -7
- data/lib/log_topic.rb +26 -18
- data/lib/rta_logger_config.json +59 -0
- data/lib/sample.rb +48 -0
- data/lib/severity_level.rb +60 -0
- metadata +34 -20
- data/lib/factory/origin/log_factory_file_logger.rb +0 -16
- data/lib/factory/origin/log_factory_log_formatter.rb +0 -11
- data/lib/factory/origin/log_factory_repository.rb +0 -44
- data/lib/factory/origin/log_factory_topic.rb +0 -12
- data/lib/log_severity.rb +0 -17
- data/lib/log_test.rb +0 -41
- data/lib/log_test_db.rb +0 -59
data/RTALogger.gemspec
CHANGED
@@ -27,5 +27,6 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.bindir = "exe"
|
28
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
29
|
spec.require_paths = ["lib"]
|
30
|
-
spec.add_dependency "
|
30
|
+
spec.add_dependency "fluent-logger", "~> 0.9"
|
31
|
+
spec.add_dependency "jbuilder", "~> 2.10"
|
31
32
|
end
|
data/lib/RTALogger.rb
CHANGED
data/lib/RTALogger/version.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
module RTALogger
|
2
|
+
# Log factory to get new instance of log formatter
|
3
|
+
module LogFactory
|
4
|
+
def self.log_formatter_default
|
5
|
+
create_formatter(:json)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.create_formatter(type, config_json = '')
|
9
|
+
lib_file = @log_formatters[type.to_sym]
|
10
|
+
raise "unregistered formatter class: #{type.to_s}" if lib_file.nil? || lib_file.empty?
|
11
|
+
|
12
|
+
begin
|
13
|
+
load lib_file
|
14
|
+
rescue
|
15
|
+
raise "unable to load formatter class file: #{lib_file}"
|
16
|
+
end
|
17
|
+
|
18
|
+
formatter_class_name = 'RTALogger::' + ('log_formatter_' + type.to_s).split('_').map(&:capitalize).join
|
19
|
+
formatter_class = Object.const_get(formatter_class_name)
|
20
|
+
return nil unless formatter_class
|
21
|
+
result = formatter_class.new
|
22
|
+
|
23
|
+
return result if config_json.empty?
|
24
|
+
result.load_config(config_json) if result.present?
|
25
|
+
return result
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.register_log_formatter(type, class_file_name)
|
29
|
+
@log_formatters[type.to_sym] = class_file_name
|
30
|
+
end
|
31
|
+
|
32
|
+
@log_formatters = {:text => 'log_formatter_text.rb',
|
33
|
+
:json => 'log_formatter_json.rb'}
|
34
|
+
end
|
35
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'log_manager'
|
4
4
|
|
5
5
|
module RTALogger
|
6
6
|
# this module generates object instance
|
@@ -8,7 +8,5 @@ module RTALogger
|
|
8
8
|
def self.log_manager_instance
|
9
9
|
RTALogger::LogManager.instance
|
10
10
|
end
|
11
|
-
|
12
|
-
|
13
11
|
end
|
14
12
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
# this module generates object instance
|
5
|
+
module LogFactory
|
6
|
+
def self.create_repository(type, config_json = '')
|
7
|
+
lib_file = @log_repositories[type.to_sym]
|
8
|
+
raise "unregistered repository class: #{type.to_s}" if lib_file.nil? || lib_file.empty?
|
9
|
+
|
10
|
+
begin
|
11
|
+
load lib_file
|
12
|
+
rescue
|
13
|
+
raise "unable to load repository class file: #{lib_file}"
|
14
|
+
end
|
15
|
+
|
16
|
+
# repo_class_name = 'RTALogger::' + type.split('_').map(&:capitalize).join
|
17
|
+
repo_class_name = 'RTALogger::' + ('log_repository_' + type.to_s).split('_').map(&:capitalize).join
|
18
|
+
repo_class = Object.const_get(repo_class_name)
|
19
|
+
return nil unless repo_class
|
20
|
+
result = repo_class.new
|
21
|
+
|
22
|
+
# result = LogRepository.create type.to_sym
|
23
|
+
return result if config_json.empty?
|
24
|
+
result.load_config(config_json) if result.present?
|
25
|
+
return result
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.register_log_repository(type, class_file_name)
|
29
|
+
@log_repositories[type.to_sym] = class_file_name
|
30
|
+
end
|
31
|
+
|
32
|
+
@log_repositories = {:console => 'log_repository_console.rb',
|
33
|
+
:file => 'log_repository_file.rb',
|
34
|
+
:udp => 'log_repository_upd.rb',
|
35
|
+
:fluentd => 'log_repository_fluetnd.rb'}
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'log_topic'
|
4
|
+
|
5
|
+
module RTALogger
|
6
|
+
# this module generates object instance
|
7
|
+
module LogFactory
|
8
|
+
def self.new_log_topic(log_manager, title, level = WARN, enable = true)
|
9
|
+
LogTopic.new(log_manager, title, level, enable)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/log_formatter.rb
CHANGED
@@ -1,8 +1,18 @@
|
|
1
|
+
# Log Formatter base class
|
1
2
|
module RTALogger
|
2
3
|
class LogFormatter
|
4
|
+
def initialize
|
5
|
+
@delimiter = '|'
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_accessor :delimiter
|
9
|
+
|
10
|
+
def load_config(config_json)
|
11
|
+
@delimiter = config_json['delimiter'].nil? ? true : config_json['delimiter']
|
12
|
+
end
|
13
|
+
|
3
14
|
def format(log_record)
|
4
15
|
log_record.to_s
|
5
16
|
end
|
6
17
|
end
|
7
18
|
end
|
8
|
-
|
data/lib/log_formatter_json.rb
CHANGED
@@ -2,12 +2,14 @@ require 'jbuilder'
|
|
2
2
|
require_relative 'log_formatter'
|
3
3
|
|
4
4
|
module RTALogger
|
5
|
-
|
5
|
+
# json formatter which receive log_record and
|
6
|
+
# returns it's data as json string
|
7
|
+
class LogFormatterJson < LogFormatter
|
6
8
|
def format(log_record)
|
7
9
|
return '' unless log_record
|
8
10
|
|
9
11
|
jb = Jbuilder.new do |json|
|
10
|
-
json.occurred_at log_record.occurred_at.strftime(
|
12
|
+
json.occurred_at log_record.occurred_at.strftime('%F %H:%M:%S:%3N')
|
11
13
|
json.app_name log_record.app_name
|
12
14
|
json.topic_title log_record.topic_title
|
13
15
|
json.context_id log_record.context_id
|
data/lib/log_formatter_text.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
require_relative 'log_formatter'
|
2
2
|
|
3
3
|
module RTALogger
|
4
|
+
# text formatter which receive log_record and
|
5
|
+
# returns it's data as delimited text string
|
4
6
|
class LogFormatterText < LogFormatter
|
5
7
|
def format(log_record)
|
6
8
|
return '' unless log_record
|
7
9
|
|
8
|
-
result = log_record.occurred_at.strftime(
|
9
|
-
result <<
|
10
|
-
result <<
|
11
|
-
result <<
|
12
|
-
result <<
|
13
|
-
result <<
|
10
|
+
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
16
|
|
15
17
|
result
|
16
18
|
end
|
data/lib/log_manager.rb
CHANGED
@@ -1,28 +1,34 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'thread'
|
3
3
|
require 'singleton'
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
require_relative '
|
4
|
+
require 'json'
|
5
|
+
require 'json/version'
|
6
|
+
require 'json/generic_object'
|
7
|
+
require_relative 'log_factory_propagator'
|
8
|
+
require_relative 'log_factory_repository'
|
9
|
+
require_relative 'log_factory_topic'
|
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
|
-
@buffer_size = ENV.fetch('
|
29
|
+
@buffer_size = ENV.fetch('RTA_LOGGER_BUFFER_SIZE', 100)
|
24
30
|
@flush_size = @buffer_size * 20 / 100
|
25
|
-
@flush_wait_time = ENV.fetch('
|
31
|
+
@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,33 +42,42 @@ module RTALogger
|
|
36
42
|
@flush_scheduler.run
|
37
43
|
end
|
38
44
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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_accessor :buffer_size
|
51
|
+
attr_reader :flush_size
|
52
|
+
attr_accessor :flush_wait_time
|
53
|
+
attr_reader :topics
|
54
|
+
attr_reader :config_file_name
|
55
|
+
|
56
|
+
def config_use_json_file(file_name, manager_name = '')
|
57
|
+
config_json = load_config_from_json_file(file_name, manager_name)
|
58
|
+
@config_file_name = file_name if config_json
|
59
|
+
apply_config(config_json)
|
49
60
|
rescue StandardError => e
|
50
61
|
puts e.message
|
51
62
|
@propagator.drop_all_repositories
|
52
|
-
@propagator.add_log_repository(LogFactory.
|
63
|
+
@propagator.add_log_repository(LogFactory.create_repository(:console))
|
53
64
|
end
|
54
65
|
|
55
|
-
|
56
|
-
|
57
|
-
|
66
|
+
def config_use_json_string(config_string, manager_name = '')
|
67
|
+
config_json = load_config_from_json_string(config_string, manager_name)
|
68
|
+
apply_config(config_json)
|
69
|
+
rescue StandardError => e
|
70
|
+
puts e.message
|
71
|
+
@propagator.drop_all_repositories
|
72
|
+
@propagator.add_log_repository(LogFactory.create_repository(:console))
|
73
|
+
end
|
58
74
|
|
59
|
-
def add_topic(
|
75
|
+
def add_topic(title, severity_level = @default_severity_level, enable = true)
|
60
76
|
@topic_semaphore.synchronize {
|
61
|
-
@topics[
|
77
|
+
@topics[title.to_sym] ||= LogFactory.new_log_topic(self, title, severity_level, enable)
|
62
78
|
}
|
63
79
|
|
64
|
-
@topics[
|
65
|
-
@topics[topic_title.to_sym]
|
80
|
+
@topics[title.to_sym]
|
66
81
|
end
|
67
82
|
|
68
83
|
def add_log(log_record)
|
@@ -71,32 +86,102 @@ module RTALogger
|
|
71
86
|
check_for_flush
|
72
87
|
end
|
73
88
|
|
74
|
-
def
|
75
|
-
@topic_semaphore.synchronize { @topics[topic].
|
89
|
+
def update_topic_enable(topic, enable = true)
|
90
|
+
@topic_semaphore.synchronize { @topics[topic.to_sym].enable = enable if @topics[topic.to_sym] }
|
91
|
+
end
|
92
|
+
|
93
|
+
def update_all_topics_enable(enable = true)
|
94
|
+
@topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].enable = enable } }
|
95
|
+
end
|
96
|
+
|
97
|
+
def update_topic_severity_level(topic, severity_level = WARN)
|
98
|
+
@topic_semaphore.synchronize { @topics[topic.to_sym].severity_level = severity_level if @topics[topic.to_sym] }
|
76
99
|
end
|
77
100
|
|
78
|
-
def
|
79
|
-
@topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].
|
101
|
+
def update_all_topics_severity_level(severity_level = WARN)
|
102
|
+
@topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].severity_level = severity_level } }
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_builder
|
106
|
+
@topic_semaphore.synchronize do
|
107
|
+
jb = Jbuilder.new do |json|
|
108
|
+
json.name name
|
109
|
+
json.enable enable
|
110
|
+
json.app_name app_name
|
111
|
+
json.config_file_name config_file_name
|
112
|
+
json.default_severity_level default_severity_level
|
113
|
+
json.buffer_size buffer_size
|
114
|
+
json.flush_size flush_size
|
115
|
+
json.flush_wait_time flush_wait_time
|
116
|
+
json.topics do
|
117
|
+
json.array! topics.keys.collect { |topic_key| @topics[topic_key].to_builder.attributes! }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
jb
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def reveal_config
|
126
|
+
to_builder.target!
|
80
127
|
end
|
81
128
|
|
82
129
|
private
|
83
130
|
|
84
|
-
def
|
131
|
+
def load_config_from_json_file(config_file_name, manager_name = '')
|
85
132
|
config_file = File.open config_file_name
|
86
|
-
config_json = JSON.load
|
87
|
-
config_json = config_json
|
133
|
+
config_json = ::JSON.load(config_file)
|
134
|
+
config_json = extract_config(config_json, manager_name)
|
135
|
+
config_json
|
136
|
+
end
|
137
|
+
|
138
|
+
def load_config_from_json_string(config_string, manager_name = '')
|
139
|
+
config_json = ::JSON.parse(config_string)
|
140
|
+
config_json = extract_config(config_json, manager_name)
|
141
|
+
config_json
|
142
|
+
end
|
143
|
+
|
144
|
+
def extract_config(json_data, manager_name = '')
|
145
|
+
config_json = json_data['rta_logger']
|
88
146
|
raise 'RTALogger configuration not found!' unless config_json
|
89
|
-
raise 'Log_Managers section does not exists json configuration' unless config_json['
|
90
|
-
raise 'No config manager defined in json configuration' unless config_json['
|
91
|
-
manager_name = config_json['
|
147
|
+
raise 'Log_Managers section does not exists json configuration' unless config_json['log_managers']
|
148
|
+
raise 'No config manager defined in json configuration' unless config_json['log_managers'].count.positive?
|
149
|
+
manager_name = config_json['default_manager'] if manager_name.empty?
|
92
150
|
unless manager_name.to_s.strip.empty?
|
93
|
-
config_json = config_json['
|
151
|
+
config_json = config_json['log_managers'].find { |item| item['manager_name'] == manager_name }
|
94
152
|
end
|
95
|
-
config_json ||= config_json['
|
153
|
+
config_json ||= config_json['log_managers'][0]
|
96
154
|
raise 'Unable to extract RTA Log Manager configuration!' unless config_json
|
155
|
+
@name = manager_name if config_json
|
97
156
|
config_json
|
98
157
|
end
|
99
158
|
|
159
|
+
def apply_config(config_json)
|
160
|
+
raise 'json config not available' unless config_json
|
161
|
+
@enable = config_json['enable'].nil? ? true : config_json['enable']
|
162
|
+
@app_name = config_json['app_name'] unless config_json['app_name'].empty?
|
163
|
+
@default_severity_level = parse_severity_level_to_i(config_json['severity_level']) if config_json['severity_level']
|
164
|
+
@buffer_size = config_json['buffer_size'] if config_json['buffer_size']
|
165
|
+
@flush_wait_time = config_json['flush_wait_seconds'] if config_json['flush_wait_seconds']
|
166
|
+
@propagator.drop_all_repositories
|
167
|
+
apply_config_repos(config_json)
|
168
|
+
apply_config_topics(config_json)
|
169
|
+
end
|
170
|
+
|
171
|
+
def apply_config_repos(config_json)
|
172
|
+
config_json['repos']&.each { |item| @propagator.load_log_repository(item) }
|
173
|
+
end
|
174
|
+
|
175
|
+
def apply_config_topics(config_json)
|
176
|
+
config_json['topics']&.each do |topic|
|
177
|
+
next unless topic['title']
|
178
|
+
result_topic = add_topic(topic['title'])
|
179
|
+
next unless result_topic
|
180
|
+
result_topic.severity_level = parse_severity_level_to_i topic['severity_level'] if topic['severity_level']
|
181
|
+
result_topic.enable = topic['enable'] if topic['enable']
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
100
185
|
def initialize_flush_scheduler
|
101
186
|
@flush_scheduler = Thread.new do
|
102
187
|
loop do
|
@@ -128,7 +213,7 @@ module RTALogger
|
|
128
213
|
|
129
214
|
def flush_all
|
130
215
|
@log_semaphore.synchronize do
|
131
|
-
@log_records[0...@log_records.count].each { |log|
|
216
|
+
@log_records[0...@log_records.count].each { |log| propagate(log) }
|
132
217
|
@log_records.clear
|
133
218
|
end
|
134
219
|
@propagator.propagate
|
@@ -137,5 +222,6 @@ module RTALogger
|
|
137
222
|
def propagate(log_record)
|
138
223
|
@propagator.add_log(log_record)
|
139
224
|
end
|
225
|
+
|
140
226
|
end
|
141
227
|
end
|
data/lib/log_propagator.rb
CHANGED
@@ -1,45 +1,44 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@
|
9
|
-
@
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
log_repository
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
1
|
+
require_relative 'log_repository'
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
# propagate log records to multiple log repositories
|
5
|
+
class LogPropagator
|
6
|
+
def initialize
|
7
|
+
@semaphore = Mutex.new
|
8
|
+
@log_records = []
|
9
|
+
@log_repositories = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_log(log_record)
|
13
|
+
@semaphore.synchronize { @log_records.push(log_record.dup) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_log_repository(log_repository)
|
17
|
+
return unless log_repository.is_a? RTALogger::LogRepository
|
18
|
+
@log_repositories.push(log_repository) unless @log_repositories.include?(log_repository)
|
19
|
+
end
|
20
|
+
|
21
|
+
def load_log_repository(config_json)
|
22
|
+
type = config_json['type']
|
23
|
+
return if type.to_s.strip.empty?
|
24
|
+
enable = config_json['enable'].nil? ? true : config_json['enable']
|
25
|
+
return unless enable
|
26
|
+
|
27
|
+
log_repository = ::RTALogger::LogFactory.create_repository(type, config_json)
|
28
|
+
add_log_repository(log_repository)
|
29
|
+
end
|
30
|
+
|
31
|
+
def drop_all_repositories
|
32
|
+
@semaphore.synchronize { @log_repositories.clear }
|
33
|
+
end
|
34
|
+
|
35
|
+
def propagate
|
36
|
+
@semaphore.synchronize do
|
37
|
+
@log_repositories.each do |log_repository|
|
38
|
+
log_repository.add_log_records(@log_records)
|
39
|
+
end
|
40
|
+
@log_records.clear
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|