RTALogger 1.1.0 → 2.1.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.
@@ -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