RTALogger 0.1.4 → 2.0.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.
@@ -1,3 +1,3 @@
1
1
  module RTALogger
2
- VERSION = '0.1.4'.freeze
2
+ VERSION = '2.0.1'.freeze
3
3
  end
@@ -1,20 +1,36 @@
1
- require_relative 'log_formatter_text'
2
- require_relative 'log_formatter_json'
1
+ require_relative 'log_formatter_base'
3
2
 
4
3
  module RTALogger
5
4
  # Log factory to get new instance of log formatter
6
5
  module LogFactory
7
6
  def self.log_formatter_default
8
- RTALogger::LogFormatterJSON.new
9
- # RTALogger::LogFormatterText.new
7
+ create_formatter(:json)
10
8
  end
11
9
 
12
- def self.log_formatter_json
13
- RTALogger::LogFormatterJSON.new
10
+ def self.create_formatter(type, config_json = '')
11
+ lib_file = @log_formatters[type.to_sym]
12
+ raise "unregistered formatter class: #{type.to_s}" if lib_file.nil? || lib_file.empty?
13
+ begin
14
+ load lib_file
15
+ rescue
16
+ raise "unable to load formatter class file: #{lib_file}"
17
+ end
18
+
19
+ formatter_class_name = 'RTALogger::' + ('log_formatter_' + type.to_s).split('_').map(&:capitalize).join
20
+ formatter_class = Object.const_get(formatter_class_name)
21
+ return nil unless formatter_class
22
+ result = formatter_class.new
23
+
24
+ return result if config_json.empty?
25
+ result.load_config(config_json) if result.present?
26
+ return result
14
27
  end
15
28
 
16
- def self.log_formatter_text
17
- RTALogger::LogFormatterText.new
29
+ def self.register_log_formatter(type, class_file_name)
30
+ @log_formatters[type.to_sym] = class_file_name
18
31
  end
32
+
33
+ @log_formatters = {:text => 'log_formatter_text.rb',
34
+ :json => 'log_formatter_json.rb'}
19
35
  end
20
36
  end
@@ -1,56 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'log_repository_console'
4
- require_relative 'log_repository_file'
5
- require_relative 'log_repository_udp'
6
- require_relative 'log_repository_fluent'
7
-
8
3
  module RTALogger
9
4
  # this module generates object instance
10
5
  module LogFactory
11
- def self.new_log_repository_console
12
- LogRepositoryConsole.new
13
- end
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?
14
9
 
15
- def self.new_log_repository_file(file_path = 'log.txt', period = 'daily', shift_size = 1_048_576)
16
- LogRepositoryFile.new(file_path, period, shift_size)
17
- end
10
+ begin
11
+ load lib_file
12
+ rescue
13
+ raise "unable to load repository class file: #{lib_file}"
14
+ end
18
15
 
19
- def self.load_log_repository_file(config_json)
20
- file_path = config_json['File_Path'].to_s
21
- period = config_json['Roll_Period'].to_s
22
- shift_size = config_json['Roll_Size'].nil? ? 1_048_576 : config_json['Roll_Size'].to_i
23
- ::RTALogger::LogFactory.new_log_repository_file(file_path, period, shift_size)
24
- end
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
25
21
 
26
- def self.new_log_repository_udp(host = '127.0.0.1', port = 4913)
27
- LogRepositoryUDP.new(host, port)
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
28
26
  end
29
27
 
30
- def self.load_log_repository_udp(config_json)
31
- host = config_json['Host'].to_s
32
- port = config_json['Port'].nil? ? 4913 : config_json['Port'].to_i
33
- ::RTALogger::LogFactory.new_log_repository_udp(host, port)
28
+ def self.register_log_repository(type, class_file_name)
29
+ @log_repositories[type.to_sym] = class_file_name
34
30
  end
35
31
 
36
- def self.new_log_repository_fluent(host = 'localhost', port = '24224', tls_options = nil)
37
- LogRepositoryFluent.new(host, port, tls_options)
38
- end
39
-
40
- def self.load_log_repository_fluent(config_json)
41
- host = config_json['Host'].to_s
42
- port = config_json['Port'].to_s
43
- tls_options = config_json['TLS_Options']
44
- ::RTALogger::LogFactory.new_log_repository_fluent(host, port, tls_options)
45
- end
46
-
47
- def self.create_repository(type, config_json)
48
- result = nil
49
- result = new_log_repository_console if type.to_s.casecmp('Console').zero?
50
- result = load_log_repository_file(config_json) if type.to_s.casecmp('File').zero?
51
- result = load_log_repository_udp(config_json) if type.to_s.casecmp('UDP').zero?
52
- result = load_log_repository_fluent(config_json) if type.to_s.casecmp('Fluentd').zero?
53
- result
54
- end
32
+ @log_repositories = {:console => 'log_repository_console.rb',
33
+ :file => 'log_repository_file.rb',
34
+ :udp => 'log_repository_upd.rb',
35
+ :fluentd => 'log_repository_fluentd.rb'}
55
36
  end
56
37
  end
@@ -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, topic_title, level = WARN)
9
- LogTopic.new(log_manager, topic_title, level)
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
@@ -1,10 +1,13 @@
1
1
  require 'jbuilder'
2
- require_relative 'log_formatter'
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 LogFormatterJSON
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
 
@@ -1,18 +1,21 @@
1
- require_relative 'log_formatter'
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 < LogFormatter
7
- def format(log_record, delimiter = '|')
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
@@ -1,28 +1,33 @@
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 'log_severity'
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 LogSeverity
18
+ include SeverityLevel
15
19
  include RTALogger::LogFactory
16
20
 
17
21
  def initialize
18
22
  @enable = true
19
- @app_name = ENV.fetch('RTALogger_App_Name', 'unknownApp')
20
- @default_log_level = ENV.fetch('RTALogger_Log_Severity', ::RTALogger::LogSeverity::WARN)
23
+ @title = 'default_log_manager'
24
+ @app_name = ENV.fetch('RTA_LOGGER_APP_NAME', 'unknown_app')
25
+ @severity_level = ENV.fetch('RTA_LOGGER_SEVERITY_LEVEL', INFO)
26
+ @config_file_name = ''
21
27
  @topic_semaphore = Mutex.new
22
28
  @log_semaphore = Mutex.new
23
- @buffer_size = ENV.fetch('RTALogger_Buffer_Size', 100)
24
- @flush_size = @buffer_size * 20 / 100
25
- @flush_wait_time = ENV.fetch('RTALogger_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)
26
31
  @topics = {}
27
32
  @log_records = []
28
33
  @propagator = LogFactory.new_log_propagator
@@ -36,36 +41,55 @@ module RTALogger
36
41
  @flush_scheduler.run
37
42
  end
38
43
 
39
- def config_use_json_file(config_file_name, manager_name = '')
40
- config_json = load_config_from_json_file(config_file_name, manager_name)
44
+ attr_reader :title
45
+ attr_accessor :enable
46
+ attr_accessor :app_name
47
+ attr_reader :propagator
48
+ attr_accessor :default_severity_level
49
+ attr_reader :flush_size
50
+ attr_reader :topics
51
+ attr_reader :config_file_name
52
+
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)
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.new_log_repository_console)
76
+ @propagator.add_log_repository(LogFactory.create_repository(:console))
46
77
  end
47
78
 
48
- def config_use_json_string(config_string, manager_name = '')
49
- config_json = load_config_from_json_string(config_string, manager_name)
79
+ def config_use_json_string(config_string, title = '')
80
+ config_json = load_config_from_json_string(config_string, title)
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.new_log_repository_console)
84
+ @propagator.add_log_repository(LogFactory.create_repository(:console))
55
85
  end
56
86
 
57
- attr_accessor :enable
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[topic_title.to_sym] ||= LogFactory.new_log_topic(self, topic_title, log_level)
89
+ @topics[title.to_sym] ||= LogFactory.new_log_topic(self, title, severity_level, enable)
65
90
  }
66
91
 
67
- @topics[topic_title.to_sym].enable = @enable
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,139 @@ module RTALogger
74
98
  check_for_flush
75
99
  end
76
100
 
77
- def update_topic_log_level(topic, log_level = WARN)
78
- @topic_semaphore.synchronize { @topics[topic].log_level = log_level if @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 update_all_topics_log_level(log_level = WARN)
82
- @topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].log_level = log_level } }
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 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
+
129
+ def to_builder
130
+ @topic_semaphore.synchronize do
131
+ jb = Jbuilder.new do |json|
132
+ json.title title
133
+ json.enable enable
134
+ json.app_name app_name
135
+ json.config_file_name config_file_name
136
+ json.default_severity_level default_severity_level
137
+ json.buffer_size buffer_size
138
+ json.flush_size flush_size
139
+ json.flush_wait_time flush_wait_time
140
+ json.repositories do
141
+ json.array! @propagator.repositories.collect { |repository| repository.to_builder.attributes! }
142
+ end
143
+ json.topics do
144
+ json.array! topics.keys.collect { |topic_key| @topics[topic_key].to_builder.attributes! }
145
+ end
146
+ end
147
+
148
+ jb
149
+ end
150
+ end
151
+
152
+ def reveal_config
153
+ to_builder.target!
154
+ end
155
+
156
+ def apply_run_time_config(config_json)
157
+ return unless config_json
158
+ @enable = config_json['enable'] unless config_json['enable'].nil?
159
+ @default_severity_level = parse_severity_level_to_i(config_json['severity_level']) unless config_json['severity_level'].nil?
160
+ self.buffer_size = config_json['buffer_size'] unless config_json['buffer_size'].nil?
161
+ self.flush_wait_time = config_json['flush_wait_time'] unless config_json['flush_wait_time'].nil?
162
+ @propagator.apply_run_time_config(config_json)
163
+
164
+ if config_json['topics']
165
+ config_json['topics'].each do |topic_config|
166
+ next if topic_config['title'].nil?
167
+ topic = topic_by_title(topic_config['title'])
168
+ topic.apply_run_time_config(topic_config) if topic
169
+ end
170
+ end
83
171
  end
84
172
 
85
173
  private
86
174
 
87
- def load_config_from_json_file(config_file_name, manager_name = '')
175
+ def load_config_from_json_file(config_file_name, title = '')
88
176
  config_file = File.open config_file_name
89
- config_json = JSON.load config_file
90
- config_json = extract_config(config_json, manager_name)
177
+ config_json = ::JSON.load(config_file)
178
+ config_json = extract_config(config_json, title)
91
179
  config_json
92
180
  end
93
181
 
94
- def load_config_from_json_string(config_string, manager_name = '')
95
- config_json = JSON.parse(config_string)
96
- config_json = extract_config(config_json, manager_name)
182
+ def load_config_from_json_string(config_string, title = '')
183
+ config_json = ::JSON.parse(config_string)
184
+ config_json = extract_config(config_json, title)
97
185
  config_json
98
186
  end
99
187
 
100
- def extract_config(json_data, manager_name = '')
101
- config_json = json_data['RTALogger']
188
+ def extract_config(json_data, title = '')
189
+ config_json = json_data['rta_logger']
102
190
  raise 'RTALogger configuration not found!' unless config_json
103
- raise 'Log_Managers section does not exists json configuration' unless config_json['Log_Managers']
104
- raise 'No config manager defined in json configuration' unless config_json['Log_Managers'].count.positive?
105
- manager_name = config_json['Default_Manager'] if manager_name.blank?
106
- unless manager_name.to_s.strip.empty?
107
- config_json = config_json['Log_Managers'].find { |item| item['Manager_Name'] == manager_name }
191
+ raise 'Log_Managers section does not exists json configuration' unless config_json['log_managers']
192
+ raise 'No config manager defined in json configuration' unless config_json['log_managers'].count.positive?
193
+ title = config_json['default_manager'] if title.empty?
194
+ unless title.to_s.strip.empty?
195
+ config_json = config_json['log_managers'].find { |item| item['title'] == title }
108
196
  end
109
- config_json ||= config_json['Log_Managers'][0]
197
+ config_json ||= config_json['log_managers'][0]
110
198
  raise 'Unable to extract RTA Log Manager configuration!' unless config_json
199
+ @title = title if config_json
111
200
  config_json
112
201
  end
113
202
 
114
203
  def apply_config(config_json)
115
204
  raise 'json config not available' unless config_json
116
- @enable = config_json['Enable'].nil? ? true : config_json['Enable']
117
- @app_name = config_json['App_Name'] if config_json['App_Name'].present?
118
- @default_log_level = config_json['Log_Severity'] if config_json['Log_Severity'].present?
119
- @buffer_siz = config_json['Buffer_Size'] if config_json['Buffer_Size'].present?
120
- @flush_wait_time = config_json['Flush_Wait_Seconds'] if config_json['Flush_Wait_Seconds'].present?
205
+ @enable = config_json['enable'].nil? ? true : config_json['enable']
206
+ @app_name = config_json['app_name'] unless config_json['app_name'].empty?
207
+ @default_severity_level = parse_severity_level_to_i(config_json['severity_level']) if config_json['severity_level']
208
+ self.buffer_size = config_json['buffer_size'] if config_json['buffer_size']
209
+ self.flush_wait_time = config_json['flush_wait_seconds'] if config_json['flush_wait_seconds']
121
210
  @propagator.drop_all_repositories
122
- config_json['Repos']&.each { |item| @propagator.load_log_repository(item) }
211
+ apply_config_repos(config_json)
212
+ apply_config_topics(config_json)
213
+ end
214
+
215
+ def apply_config_repos(config_json)
216
+ config_json['repositories']&.each { |item| @propagator.load_log_repository(item) }
217
+ end
218
+
219
+ def apply_config_topics(config_json)
220
+ config_json['topics']&.each do |topic|
221
+ next unless topic['title']
222
+ result_topic = add_topic(topic['title'])
223
+ next unless result_topic
224
+ result_topic.severity_level = parse_severity_level_to_i topic['severity_level'] if topic['severity_level']
225
+ result_topic.enable = topic['enable'] if topic['enable']
226
+ end
123
227
  end
124
228
 
125
229
  def initialize_flush_scheduler
126
230
  @flush_scheduler = Thread.new do
127
231
  loop do
128
232
  elapsed_seconds = ((DateTime.now - @last_flush_time) * 24 * 60 * 60).to_i
129
- flush if elapsed_seconds > @flush_wait_time
233
+ flush if elapsed_seconds > flush_wait_time
130
234
  sleep(1)
131
235
  break if @exit_flush_scheduler
132
236
  end
@@ -153,7 +257,7 @@ module RTALogger
153
257
 
154
258
  def flush_all
155
259
  @log_semaphore.synchronize do
156
- @log_records[0...@log_records.count].each { |log| propagate(log) }
260
+ @log_records[0...@log_records.count].each { |log| propagate(log) }
157
261
  @log_records.clear
158
262
  end
159
263
  @propagator.propagate
@@ -162,5 +266,6 @@ module RTALogger
162
266
  def propagate(log_record)
163
267
  @propagator.add_log(log_record)
164
268
  end
269
+
165
270
  end
166
271
  end