RTALogger 0.1.4 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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