RTALogger 1.1.0 → 2.1.0

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 = '1.1.0'.freeze
2
+ VERSION = '2.1.0'.freeze
3
3
  end
@@ -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
@@ -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
 
@@ -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
@@ -20,15 +20,14 @@ module RTALogger
20
20
 
21
21
  def initialize
22
22
  @enable = true
23
- @name = 'default_log_manager'
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', WARN)
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
- @buffer_size = ENV.fetch('RTA_LOGGER_BUFFER_SIZE', 100)
30
- @flush_size = @buffer_size * 20 / 100
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 :name
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 config_use_json_file(file_name, manager_name = '')
57
- config_json = load_config_from_json_file(file_name, manager_name)
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, manager_name = '')
66
- 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)
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.name name
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 load_config_from_json_file(config_file_name, manager_name = '')
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, manager_name)
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, manager_name = '')
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, manager_name)
186
+ config_json = extract_config(config_json, title)
142
187
  config_json
143
188
  end
144
189
 
145
- def extract_config(json_data, manager_name = '')
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
- manager_name = config_json['default_manager'] if manager_name.empty?
151
- unless manager_name.to_s.strip.empty?
152
- config_json = config_json['log_managers'].find { |item| item['manager_name'] == manager_name }
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
- @name = manager_name if config_json
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
- @buffer_size = config_json['buffer_size'] if config_json['buffer_size']
166
- @flush_wait_time = config_json['flush_wait_seconds'] if config_json['flush_wait_seconds']
167
- @propagator.drop_all_repositories
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 > @flush_wait_time
230
+ flush if elapsed_seconds > flush_wait_time
191
231
  sleep(1)
192
232
  break if @exit_flush_scheduler
193
233
  end
@@ -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.push(repository) unless @repositories.include?(repository)
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 |repository|
40
- repository.add_log_records(@records)
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