RTALogger 1.0.0 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4c558e31bfbc739d0ad9ebb218c96c61fdcc354b6ae9a9c0daa3ea4743786c3
4
- data.tar.gz: b00ec909d9a8791671e29e949fb19cfb31e59d7fbf353532a70bfb216e6b4e45
3
+ metadata.gz: f8fb5a3e4e0c67b6e485cf932ab274fc5a55539fb6432e76e119c0877d786c23
4
+ data.tar.gz: 57c69c4601f00d24c395fd42b8a75fe74020a5f9b5222b14e38fe9c673134c97
5
5
  SHA512:
6
- metadata.gz: c6296831235e737111217cf51f4e3d477620d588319fb0540760b948028b26f87361e03cc7c453dd00ab3c4553a26ad045791e2d9e64d1153017246e664348bd
7
- data.tar.gz: 39885f5f4f039199748d9201f632ac4e745bd41cced49971ddc70b9599281c556a2d85e3fb13332a76cb0b01d78f1efb88d510331071332ccfdcbd26528543a7
6
+ metadata.gz: 22b65c1867090cadd8aaff4f735ef401be30fe890e3164b7a45b5df40979ee0d5439d5c2fae66273c929e4c821abaa928b208b2e7c6ad535908be48b2923bea2
7
+ data.tar.gz: 191367dfa21447a54f6ad218ed0f66d0615297b126e6a9aeda446c82900f05fbd457fbe0f200d860885be4f2760dd04a62e008634bc525c2e8554d5784883fc5
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- RTALogger (1.0.0)
4
+ RTALogger (2.0.2)
5
5
  fluent-logger (~> 0.9)
6
6
  jbuilder (~> 2.10)
7
7
 
data/README.md CHANGED
@@ -7,26 +7,24 @@ All log manager's main features are configable through a json config file.
7
7
 
8
8
  Main purposes of developing this gem are:
9
9
  - Creating standard logging API to seperate application from existing variety of loggers.
10
- - Wrapping around existing loggers so get advantage of different loggers at the same time.
11
- - Make it possible to easily replace a logger component with a new one. (for example Rails standard Logger with Fluentd)
12
- without any changes in the consumer application.
13
- - Creating easy to use logger interface.
14
- - Apply some rules and restrictions about log structure and data format, which prevents chaos in application log information.
15
- - No interrupt or wait time for log consumer modules.
10
+ - Wrapping around existing loggers to get advantage of different loggers at the same time.
11
+ - Make it possible to easily replace a logger component with new one without any changes in the consumer application.(for example Rails standard Logger with Fluentd)
12
+ - Creating easy to use logger interface for developers.
13
+ - Apply some rules and restrictions about log structure and data format, which prevents chaos in application's log information.
14
+ - No interrupt, wait time or overhead for log consumer modules.
16
15
  - Utilize multiple log repositories at the same time in background (Console, File, UDP, FluentD, etc.)
17
- - Make it possible to implement customized log repositories.
16
+ - Make it possible to implement customize log repositories.
18
17
 
19
18
  Main Features:
20
19
  - Creating multiple log manager instances with different configuration is possible entire application.
21
20
  - Each log manager instance could be configured via a json file.
22
21
  - Each log manager instance could be config to use multiple log repositories such as Console, File, UDP, Fluentd.
23
22
  - Runtime configurations could be applied through log manager APIs.
24
- - By using multi threading techniques and also buffering techniques,
25
- all logging process will handled in seperated thread.
23
+ - By using multi threading and buffering techniques, all logging process will handled in seperated thread.
26
24
  So the log consumer modules should not be wait for log manager to finish the logging task.
27
25
  - Multiple standard log severity levels are available through topic APIs (debug, info, warning, error, fatal, unknown)
28
26
  - Main features could be set and manipulate through json configuration file.
29
- - And at the end, it is easy to use for ruby backend developers.
27
+ - And at the end, it is easy to use for ruby developers.
30
28
 
31
29
  ## Installation
32
30
 
@@ -36,11 +34,11 @@ Add this line to your application's Gemfile:
36
34
  gem 'RTALogger'
37
35
  ```
38
36
 
39
- And then execute:
37
+ Then execute:
40
38
 
41
39
  $ bundle install
42
40
 
43
- Or install it yourself as:
41
+ Or install it yourself via following command:
44
42
 
45
43
  $ gem install RTALogger
46
44
 
@@ -51,21 +49,22 @@ To add gem to your rails application:
51
49
  ## Usage
52
50
  #### RTA Log Data Structure
53
51
  To use log manager APIs, first step is to have a quick review on Log Data Structure
54
- - Application: The root of each log data record is Application, which specify the log data owner application.
52
+ - Application: The root of each log data record is the Application name, which specify the log data owner application.
55
53
  - Topic: By adding multiple topics to log manager you can categorize log data in logical topics.
56
54
  - Context: Under each topic, one or multiple contexts (in one level) could be defined.
57
- - As an instance the Application could by 'MyEShopApp', one of Topics could be 'Authentication' and
58
- Contexts could be 'uer_name' which attend in application authorization process.
59
- - The next step is log severity level, which determines that the log record severity (debug, information, warning, error, fatal, unknown)
55
+ - As an instance for Application 'MyEShopApp', one of Topics could be 'Authentication' and
56
+ Context could be 'uer_name' which attend in application authorization process.
57
+ - The next step is log severity level, which determines the log record severity (debug, information, warning, error, fatal, unknown)
60
58
  - At last the final element is log message, which contains log message data.
61
59
 
62
60
  ### Which Log Severity Levels to use
63
- - DEBUG = 0 : Low-level information, mostly for developers.
64
- - INFO = 1 : Generic (useful) information about system operation.
65
- - WARN = 2 : A warning, which it does NOT cause crashing the process.
66
- - ERROR = 3 : A handleable error condition.
67
- - FATAL = 4 : An un-handleable error that results in a program crash.
68
- - UNKNOWN = 5 : An unknown message that should always be logged.
61
+ - TRACE = 0 : all information that helps us to trace the processing of an incoming request through our application.
62
+ - DEBUG = 1 : Low-level information, mostly for developers.
63
+ - INFO = 2 : Generic (useful) information about system operation.
64
+ - WARN = 3 : A warning, which it does NOT cause crashing the process.
65
+ - ERROR = 4 : A handleable error condition.
66
+ - FATAL = 5 : An un-handleable error that results in a program crash.
67
+ - UNKNOWN = 6 : An unknown message that should always be logged.
69
68
 
70
69
  ### Time for coding
71
70
  - create log manager instance:
@@ -88,41 +87,61 @@ To use log manager APIs, first step is to have a quick review on Log Data Struct
88
87
  {
89
88
  "default_manager": "develop",
90
89
  "log_managers":
91
- [
92
- {
93
- "manager_name": "develop",
94
- "enable": true,
95
- "app_name": "TestApp",
96
- "severity_level": "debug",
97
- "buffer_size": 100,
98
- "flush_wait_seconds": 15,
99
- "repos":
100
- [
101
- {
102
- "enable": true,
103
- "type": "console",
104
- "formatter": "delimited_text",
105
- "delimiter": "|"
106
- },
107
- {
108
- "enable": true,
109
- "type": "File",
110
- "file_path": "./log/log.txt",
111
- "roll_period": "daily",
112
- "roll_size": "1048576",
113
- "formatter": "delimited_text",
114
- "delimiter": "|"
115
- },
116
- {
117
- "enable": true,
118
- "type": "fluentd",
119
- "host": "localhost",
120
- "port": "8888",
121
- "formatter": "json"
122
- }
123
- ]
124
- }
125
- ]
90
+ [
91
+ {
92
+ "title": "develop",
93
+ "enable": true,
94
+ "app_name": "TestApp",
95
+ "severity_level": "trace",
96
+ "buffer_size": 100,
97
+ "flush_wait_seconds": 10,
98
+ "repositories":
99
+ [
100
+ {
101
+ "type": "console",
102
+ "title": "console_repo_1",
103
+ "enable": true,
104
+ "formatter":
105
+ {
106
+ "type": "text",
107
+ "delimiter": "|"
108
+ }
109
+ },
110
+ {
111
+ "type": "file",
112
+ "title": "file_repo_1",
113
+ "enable": true,
114
+ "file_path": "log.txt",
115
+ "roll_period": "daily",
116
+ "roll_size": "1048576",
117
+ "formatter":
118
+ {
119
+ "type": "json",
120
+ "delimiter": "|"
121
+ }
122
+ },
123
+ {
124
+ "enable": true,
125
+ "title": "console_repo_1",
126
+ "type": "fluentd",
127
+ "host": "localhost",
128
+ "port": "8888",
129
+ "formatter":
130
+ {
131
+ "type": "json"
132
+ }
133
+ }
134
+ ],
135
+ "topics":
136
+ [
137
+ {
138
+ "title": "test",
139
+ "enable": true,
140
+ "severity_level": "WARN"
141
+ }
142
+ ]
143
+ }
144
+ ]
126
145
  }
127
146
  }
128
147
  ```
@@ -138,21 +157,25 @@ To use log manager APIs, first step is to have a quick review on Log Data Struct
138
157
  # Assume user 'Tom' is trying to authenticate we will use user_name as log Context_id
139
158
  user_name = 'Tom'
140
159
  topic = log_manager.add_topic('Authentication')
160
+ topic.trace(user_name, 'Authentication process began for:', user_name)
141
161
  topic.debug(user_name, 'use_id is nil for user:', user_name)
142
162
  topic.info(user_name, 'User ', user_name , ' is trying to login.')
143
163
  topic.warning(user_name, 'Authentication failed for user ', user_name)
144
164
  topic.error(user_name, 'Error connecting to data base for user ', user_name)
145
165
  topic.fatal(user_name, 'Authentication service has been stopped working')
146
166
  topic.unknown(user_name, 'An unknown error occured during authentication. user name:', user_name)
167
+ topic.trace(user_name, 'Authentication process end for:', user_name)
147
168
  ```
148
169
  the result will be:
149
170
  ```
150
- {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":0,"message":"user_id is nil for user: Tom"}
151
- {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":1,"message":"User Tom is trying to login"}
152
- {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":2,"message":"Authentication failed for user Tom"}
153
- {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":3,"message":"Error connecting to data base for user Tom"}
154
- {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":4,"message":"Authentication service has been stopped working"}
155
- {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":5,"message":"An unknown error occured during authentication. user name: Tom"}
171
+ {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":"TRACE","message"Authentication process began for: Tom"}
172
+ {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":"DEBUG","message":"user_id is nil for user: Tom"}
173
+ {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":"INFO","message":"User Tom is trying to login"}
174
+ {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":"WARN","message":"Authentication failed for user Tom"}
175
+ {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":"ERROR","message":"Error connecting to data base for user Tom"}
176
+ {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":"FATAL","message":"Authentication service has been stopped working"}
177
+ {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":"UNKNOWN","message":"An unknown error occured during authentication. user name: Tom"}
178
+ {"occurred_at":"2020-11-04 15:56:58:785","app_name":"TestApp","topic_title":"Authentication","context_id":"Tom","severity":"TRACE","message"Authentication process end for: Tom"}
156
179
  ```
157
180
  - json config file sample
158
181
  ```json
@@ -163,17 +186,18 @@ the result will be:
163
186
  "log_managers":
164
187
  [
165
188
  {
166
- "manager_name": "develop",
189
+ "title": "develop",
167
190
  "enable": true,
168
191
  "app_name": "TestApp",
169
- "severity_level": "debug",
192
+ "severity_level": "trace",
170
193
  "buffer_size": 100,
171
- "flush_wait_seconds": 15,
172
- "repos":
194
+ "flush_wait_seconds": 10,
195
+ "repositories":
173
196
  [
174
197
  {
175
- "enable": true,
176
198
  "type": "console",
199
+ "title": "console_repo_1",
200
+ "enable": true,
177
201
  "formatter":
178
202
  {
179
203
  "type": "text",
@@ -181,19 +205,21 @@ the result will be:
181
205
  }
182
206
  },
183
207
  {
184
- "enable": false,
185
208
  "type": "file",
209
+ "title": "file_repo_1",
210
+ "enable": true,
186
211
  "file_path": "log.txt",
187
212
  "roll_period": "daily",
188
213
  "roll_size": "1048576",
189
214
  "formatter":
190
215
  {
191
- "type": "text",
216
+ "type": "json",
192
217
  "delimiter": "|"
193
218
  }
194
219
  },
195
220
  {
196
- "enable": false,
221
+ "enable": true,
222
+ "title": "console_repo_1",
197
223
  "type": "fluentd",
198
224
  "host": "localhost",
199
225
  "port": "8888",
@@ -208,7 +234,7 @@ the result will be:
208
234
  {
209
235
  "title": "test",
210
236
  "enable": true,
211
- "severity_level": "info"
237
+ "severity_level": "WARN"
212
238
  }
213
239
  ]
214
240
  }
@@ -216,7 +242,7 @@ the result will be:
216
242
  }
217
243
  }
218
244
  ```
219
- - json config file structure
245
+ ### json config file structure
220
246
  ```comment
221
247
  As we described you cap apply RTA log manager using a json config file.
222
248
 
@@ -228,16 +254,16 @@ the result will be:
228
254
  multiple log manager configuration in Log_Managers array.
229
255
  - log_managers : the array of LogManagers with different configuration.
230
256
  It is possible to define multiple log manager configurations for differen usages.
231
- - manager_name: the name of log manager. It will be used to define the default log manager.
257
+ - title: the name of log manager. It will be used to define the default log manager.
232
258
  - enable: (true/false) The value of this property activate or deactivate entire log manager.
233
259
  - app_name: Application name as the owner of log data.
234
260
  - severity_level: Defines which level of log data will be stored in log repositories.
235
- - buffer_size: The memory buffer size (number of buffered log objects) to
261
+ - buffer_size: Minimune possible value for this attribute is 100 and defines memory buffer size (number of buffered log objects) to
236
262
  decread api consumers wait time. when the buffer is full the flush operation will
237
263
  save buffered logs to log repositoies.
238
- - flush_wait_seconds: Time in soconds which log managers wait to flush buffered log objects
264
+ - flush_wait_seconds: Minimum possible value for this attribure is 10 seconds and defines time in soconds which log managers wait to flush buffered log records
239
265
  to log repository.
240
- - repos: Array of log repositories. It is possible to define multiple log repositories to
266
+ - repositories: Array of log repositories. It is possible to define multiple log repositories to
241
267
  store log data. there are variaty of log repositories and it is possible to
242
268
  add new ones. Each item in Repos array will configure a log repository.
243
269
  Pre-defined types are described below, also it's possible to implement your custome repo type
@@ -282,7 +308,7 @@ the result will be:
282
308
  - severity_level: Defines which level of log data will be stored in log repositories.
283
309
  - enable: [true/false] to enable or disable logging process of the topic.
284
310
  ```
285
- - Some useful features
311
+ ###Some useful features
286
312
  ```ruby
287
313
  # change log manager app name at run time
288
314
  log_manager.app_name = 'myTestApp'
@@ -298,8 +324,32 @@ the result will be:
298
324
 
299
325
  # enable or disable all topic if necessary
300
326
  log_manager.update_all_topics_enable([true/false])
327
+
328
+ # to get log manager configuration as json object use to_builder method
329
+ log_manager.to_builder
330
+
331
+ # to get log manager configuration as json string use reveal_config method
332
+ log_manager.reveal_config
333
+
334
+ # to apply some limited changes on log manager functionality at run time
335
+ # config_json parameter should carry a json object which contains the configuration
336
+ # structure described before in 'json configuration file structure' section.
337
+ # Attention: these changes will apply to manager but will not save.
338
+ # So during next load these changes will be lost. Save changes will be available in
339
+ # next version.
340
+ # Attention: only following attributes could be change at run time:
341
+ # log_manager.enable
342
+ # log_manager.default_severity_level
343
+ # log_manager.buffer_size (minimum is 100)
344
+ # log_manager.flush_wait_time (minimum 15 second)
345
+ # repository.enable
346
+ # topic.enable
347
+ # topic.severity_level
348
+ # Other attributes could only change via config file via manager config_use_json_file
349
+ log_manager.apply_run_time_config(config_json)
301
350
  ```
302
- - Implement and Expand
351
+ ### Implement and Expand
352
+ #### Implement new log repository
303
353
  It is possible to implement new log repositories. There will be fue rules to implement and
304
354
  integrate new customized log repository with RTALogger LogManager.
305
355
 
@@ -309,7 +359,7 @@ the result will be:
309
359
 
310
360
  3- Also appropriate naming convention is necessary.
311
361
  As an example if you are implementing a Console Repo, your class name should be LogRepositoryConsole and
312
- your source code in a ruby file and name it log_repository_console.rb
362
+ your source code should be placed in a ruby file and name it log_repository_console.rb
313
363
 
314
364
  4- After implementing your own log repository, you should register the class at run-time using the following syntax:
315
365
  ```ruby
@@ -346,17 +396,10 @@ module RTALogger
346
396
  end
347
397
  ```
348
398
 
349
- ## Development
350
-
351
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
352
-
353
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
354
-
355
399
  ## Contributing
356
400
 
357
401
  Bug reports and pull requests are welcome on GitHub at https://github.com/BBahrainy/RTALogger.
358
402
 
359
-
360
403
  ## License
361
404
 
362
405
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,3 +1,3 @@
1
1
  module RTALogger
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '2.0.2'.freeze
3
3
  end
@@ -1,3 +1,5 @@
1
+ require_relative 'log_formatter_base'
2
+
1
3
  module RTALogger
2
4
  # Log factory to get new instance of log formatter
3
5
  module LogFactory
@@ -8,7 +10,6 @@ module RTALogger
8
10
  def self.create_formatter(type, config_json = '')
9
11
  lib_file = @log_formatters[type.to_sym]
10
12
  raise "unregistered formatter class: #{type.to_s}" if lib_file.nil? || lib_file.empty?
11
-
12
13
  begin
13
14
  load lib_file
14
15
  rescue
@@ -30,6 +31,6 @@ module RTALogger
30
31
  end
31
32
 
32
33
  @log_formatters = {:text => 'log_formatter_text.rb',
33
- :json => 'log_formatter_json.rb'}
34
+ :json => 'log_formatter_json.rb'}
34
35
  end
35
36
  end
@@ -32,6 +32,6 @@ module RTALogger
32
32
  @log_repositories = {:console => 'log_repository_console.rb',
33
33
  :file => 'log_repository_file.rb',
34
34
  :udp => 'log_repository_upd.rb',
35
- :fluentd => 'log_repository_fluetnd.rb'}
35
+ :fluentd => 'log_repository_fluentd.rb'}
36
36
  end
37
37
  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 < LogFormatter
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
- 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
+ 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,32 +41,45 @@ 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
61
- puts e.message
62
75
  @propagator.drop_all_repositories
63
76
  @propagator.add_log_repository(LogFactory.create_repository(:console))
64
77
  end
65
78
 
66
- def config_use_json_string(config_string, manager_name = '')
67
- 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)
68
81
  apply_config(config_json)
69
82
  rescue StandardError => e
70
- puts e.message
71
83
  @propagator.drop_all_repositories
72
84
  @propagator.add_log_repository(LogFactory.create_repository(:console))
73
85
  end
@@ -102,10 +114,22 @@ module RTALogger
102
114
  @topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].severity_level = severity_level } }
103
115
  end
104
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
+
105
129
  def to_builder
106
130
  @topic_semaphore.synchronize do
107
131
  jb = Jbuilder.new do |json|
108
- json.name name
132
+ json.title title
109
133
  json.enable enable
110
134
  json.app_name app_name
111
135
  json.config_file_name config_file_name
@@ -113,6 +137,9 @@ module RTALogger
113
137
  json.buffer_size buffer_size
114
138
  json.flush_size flush_size
115
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
116
143
  json.topics do
117
144
  json.array! topics.keys.collect { |topic_key| @topics[topic_key].to_builder.attributes! }
118
145
  end
@@ -126,33 +153,50 @@ module RTALogger
126
153
  to_builder.target!
127
154
  end
128
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
171
+ end
172
+
129
173
  private
130
174
 
131
- def load_config_from_json_file(config_file_name, manager_name = '')
175
+ def load_config_from_json_file(config_file_name, title = '')
132
176
  config_file = File.open config_file_name
133
177
  config_json = ::JSON.load(config_file)
134
- config_json = extract_config(config_json, manager_name)
178
+ config_json = extract_config(config_json, title)
135
179
  config_json
136
180
  end
137
181
 
138
- def load_config_from_json_string(config_string, manager_name = '')
182
+ def load_config_from_json_string(config_string, title = '')
139
183
  config_json = ::JSON.parse(config_string)
140
- config_json = extract_config(config_json, manager_name)
184
+ config_json = extract_config(config_json, title)
141
185
  config_json
142
186
  end
143
187
 
144
- def extract_config(json_data, manager_name = '')
188
+ def extract_config(json_data, title = '')
145
189
  config_json = json_data['rta_logger']
146
190
  raise 'RTALogger configuration not found!' unless config_json
147
191
  raise 'Log_Managers section does not exists json configuration' unless config_json['log_managers']
148
192
  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?
150
- unless manager_name.to_s.strip.empty?
151
- config_json = config_json['log_managers'].find { |item| item['manager_name'] == manager_name }
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 }
152
196
  end
153
197
  config_json ||= config_json['log_managers'][0]
154
198
  raise 'Unable to extract RTA Log Manager configuration!' unless config_json
155
- @name = manager_name if config_json
199
+ @title = title if config_json
156
200
  config_json
157
201
  end
158
202
 
@@ -161,15 +205,15 @@ module RTALogger
161
205
  @enable = config_json['enable'].nil? ? true : config_json['enable']
162
206
  @app_name = config_json['app_name'] unless config_json['app_name'].empty?
163
207
  @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']
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']
166
210
  @propagator.drop_all_repositories
167
211
  apply_config_repos(config_json)
168
212
  apply_config_topics(config_json)
169
213
  end
170
214
 
171
215
  def apply_config_repos(config_json)
172
- config_json['repos']&.each { |item| @propagator.load_log_repository(item) }
216
+ config_json['repositories']&.each { |item| @propagator.load_log_repository(item) }
173
217
  end
174
218
 
175
219
  def apply_config_topics(config_json)
@@ -186,7 +230,7 @@ module RTALogger
186
230
  @flush_scheduler = Thread.new do
187
231
  loop do
188
232
  elapsed_seconds = ((DateTime.now - @last_flush_time) * 24 * 60 * 60).to_i
189
- flush if elapsed_seconds > @flush_wait_time
233
+ flush if elapsed_seconds > flush_wait_time
190
234
  sleep(1)
191
235
  break if @exit_flush_scheduler
192
236
  end
@@ -5,17 +5,19 @@ module RTALogger
5
5
  class LogPropagator
6
6
  def initialize
7
7
  @semaphore = Mutex.new
8
- @log_records = []
9
- @log_repositories = []
8
+ @records = []
9
+ @repositories = []
10
10
  end
11
11
 
12
- def add_log(log_record)
13
- @semaphore.synchronize { @log_records.push(log_record.dup) }
12
+ attr_reader :repositories
13
+
14
+ def add_log(record)
15
+ @semaphore.synchronize { @records.push(record.dup) }
14
16
  end
15
17
 
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)
18
+ def add_log_repository(repository)
19
+ return unless repository.is_a? RTALogger::LogRepository
20
+ @repositories.push(repository) unless @repositories.include?(repository)
19
21
  end
20
22
 
21
23
  def load_log_repository(config_json)
@@ -24,20 +26,44 @@ module RTALogger
24
26
  enable = config_json['enable'].nil? ? true : config_json['enable']
25
27
  return unless enable
26
28
 
27
- log_repository = ::RTALogger::LogFactory.create_repository(type, config_json)
28
- add_log_repository(log_repository)
29
+ repository = ::RTALogger::LogFactory.create_repository(type, config_json)
30
+ add_log_repository(repository)
29
31
  end
30
32
 
31
33
  def drop_all_repositories
32
- @semaphore.synchronize { @log_repositories.clear }
34
+ @semaphore.synchronize { @repositories.clear }
35
+ end
36
+
37
+ def repository_by_title(title)
38
+ result = nil
39
+ @semaphore.synchronize do
40
+ @repositories.keys.each do |repository_key|
41
+ result = @repositories[repository_key.to_sym] if repository_key.to_s.casecmp(title).zero?
42
+ break if result
43
+ end
44
+ end
45
+
46
+ return result
47
+ end
48
+
49
+ def apply_run_time_config(config_json)
50
+ return unless config_json
51
+
52
+ if config_json['repositories']
53
+ config_json['repositories'].each do |repository_config|
54
+ next if repository_config['title'].nil?
55
+ repository = repository_by_title(repository_config['title'])
56
+ repository.apply_run_time_config(repository_config) if repository
57
+ end
58
+ end
33
59
  end
34
60
 
35
61
  def propagate
36
62
  @semaphore.synchronize do
37
- @log_repositories.each do |log_repository|
38
- log_repository.add_log_records(@log_records)
63
+ @repositories.each do |repository|
64
+ repository.add_log_records(@records)
39
65
  end
40
- @log_records.clear
66
+ @records.clear
41
67
  end
42
68
  end
43
69
  end
@@ -1,10 +1,14 @@
1
+ require_relative 'string'
2
+
1
3
  module RTALogger
2
4
  # base log repository class
3
5
  class LogRepository
4
6
  def initialize
5
7
  @semaphore = Mutex.new
6
8
  @log_records = []
9
+ @title = self.class.to_s.split('::').last.underscore
7
10
  @enable = true
11
+ @formatter = RTALogger::LogFactory.log_formatter_default
8
12
  end
9
13
 
10
14
  # @@sub_classes = {}
@@ -22,7 +26,9 @@ module RTALogger
22
26
  # @@sub_classes[repository_name] = self
23
27
  # end
24
28
 
29
+ attr_accessor :title
25
30
  attr_accessor :enable
31
+ attr_accessor :formatter
26
32
 
27
33
  def add_log_records(items)
28
34
  return 0 unless @enable
@@ -34,13 +40,32 @@ module RTALogger
34
40
 
35
41
  def load_config(config_json)
36
42
  @enable = config_json['enable'].nil? ? true : config_json['enable']
37
-
43
+ @title = config_json['title'].nil? ? self.class.to_s.split('::').last.underscore : config_json['title']
38
44
  formatter_config = config_json['formatter']
39
45
  if formatter_config && formatter_config['type']
40
46
  @formatter = LogFactory.create_formatter(formatter_config['type'], formatter_config)
41
47
  end
42
48
  end
43
49
 
50
+ def to_builder
51
+ jb = Jbuilder.new do |json|
52
+ json.type self.class.to_s.split('::').last.underscore.sub('log_repository_', '')
53
+ json.enable enable
54
+ json.formatter @formatter.to_builder.attributes!
55
+ end
56
+
57
+ jb
58
+ end
59
+
60
+ def reveal_config
61
+ to_builder.target!
62
+ end
63
+
64
+ def apply_run_time_config(config_json)
65
+ return unless config_json
66
+ @enable = config_json['enable'] unless config_json['enable'].nil?
67
+ end
68
+
44
69
  protected
45
70
 
46
71
  def flush_and_clear
@@ -6,8 +6,6 @@ module RTALogger
6
6
  class LogRepositoryConsole < LogRepository
7
7
  def initialize
8
8
  super
9
-
10
- @formatter = RTALogger::LogFactory.log_formatter_default
11
9
  end
12
10
 
13
11
  def load_config(config_json)
@@ -7,8 +7,10 @@ module RTALogger
7
7
  class LogRepositoryFile < LogRepository
8
8
  def initialize(file_path = 'log.txt', period = 'daily', shift_size = 1_048_576)
9
9
  super()
10
- @file_logger = create_ruby_logger(file_path, period, shift_size)
11
- @formatter = RTALogger::LogFactory.log_formatter_default
10
+ @file_path = file_path
11
+ @period = period
12
+ @shift_size = shift_size
13
+ @file_logger = create_ruby_logger(@file_path, @period, @shift_size)
12
14
  end
13
15
 
14
16
  def load_config(config_json)
@@ -20,6 +22,15 @@ module RTALogger
20
22
  @file_logger = create_ruby_logger(file_path, period, shift_size)
21
23
  end
22
24
 
25
+ def to_builder
26
+ json = super
27
+ json.enable enable
28
+ json.file_path @file_path
29
+ json.period @period
30
+ json.shift_size @shift_size
31
+
32
+ json
33
+ end
23
34
  # register :file
24
35
 
25
36
  protected
@@ -2,10 +2,11 @@ require 'fluent-logger'
2
2
  require_relative 'log_repository'
3
3
 
4
4
  module RTALogger
5
- class LogRepositoryFluent < LogRepository
5
+ class LogRepositoryFluentd < LogRepository
6
6
  def initialize(host = 'localhost', port = 24224, tls_options = nil)
7
7
  super()
8
- @formatter = RTALogger::LogFactory.log_formatter_json
8
+ @host = host
9
+ @port = port
9
10
  @fluent_logger = create_fluentd_logger(host, port, tls_options)
10
11
  end
11
12
 
@@ -19,6 +20,14 @@ module RTALogger
19
20
  @fluent_logger = create_fluentd_logger(host, port, tls_options)
20
21
  end
21
22
 
23
+ def to_builder
24
+ json = super
25
+ json.enable enable
26
+ json.host @host
27
+ json.port @port
28
+
29
+ json
30
+ end
22
31
  # register :fluentd
23
32
 
24
33
  protected
@@ -21,6 +21,10 @@ module RTALogger
21
21
  attr_reader :title
22
22
  attr_accessor :severity_level
23
23
 
24
+ def trace(context_id, *message)
25
+ add(context_id, TRACE, message) if @severity_level.to_i <= TRACE.to_i
26
+ end
27
+
24
28
  def debug(context_id, *message)
25
29
  add(context_id, DEBUG, message) if @severity_level.to_i <= DEBUG.to_i
26
30
  end
@@ -54,6 +58,13 @@ module RTALogger
54
58
 
55
59
  jb
56
60
  end
61
+
62
+ def apply_run_time_config(config_json)
63
+ return unless config_json
64
+ @enable = config_json['enable'] unless config_json['enable'].nil?
65
+ @severity_level = parse_severity_level_to_i(config_json['severity_level']) unless config_json['severity_level'].nil?
66
+ end
67
+
57
68
  private
58
69
 
59
70
  def add(context_id, severity, *message)
@@ -5,17 +5,18 @@
5
5
  "log_managers":
6
6
  [
7
7
  {
8
- "manager_name": "develop",
8
+ "title": "develop",
9
9
  "enable": true,
10
10
  "app_name": "TestApp",
11
- "severity_level": "debug",
11
+ "severity_level": "trace",
12
12
  "buffer_size": 100,
13
- "flush_wait_seconds": 15,
14
- "repos":
13
+ "flush_wait_seconds": 10,
14
+ "repositories":
15
15
  [
16
16
  {
17
- "enable": true,
18
17
  "type": "console",
18
+ "title": "console_repo_1",
19
+ "enable": true,
19
20
  "formatter":
20
21
  {
21
22
  "type": "text",
@@ -23,19 +24,21 @@
23
24
  }
24
25
  },
25
26
  {
26
- "enable": true,
27
27
  "type": "file",
28
+ "title": "file_repo_1",
29
+ "enable": true,
28
30
  "file_path": "log.txt",
29
31
  "roll_period": "daily",
30
32
  "roll_size": "1048576",
31
33
  "formatter":
32
34
  {
33
- "type": "text",
35
+ "type": "json",
34
36
  "delimiter": "|"
35
37
  }
36
38
  },
37
39
  {
38
40
  "enable": true,
41
+ "title": "console_repo_1",
39
42
  "type": "fluentd",
40
43
  "host": "localhost",
41
44
  "port": "8888",
@@ -4,7 +4,6 @@ require_relative 'log_factory_repository'
4
4
  controller_name = 'test_controller'
5
5
  userID = 5
6
6
 
7
-
8
7
  # RTALogger::LogFactory.register_log_repository :console, 'log_repository_console.rb'
9
8
 
10
9
  # create log manager instance
@@ -29,6 +28,7 @@ test_topic = log_manager.add_topic('test')
29
28
  # test_topic.enable = false
30
29
 
31
30
  # add log information to log topic
31
+ topic.trace(userID, 'Controller Name=', controller_name, 'trace')
32
32
  topic.debug(userID, 'Controller Name=', controller_name, 'debug')
33
33
  topic.info(userID, 'Controller Name=', controller_name, 'information')
34
34
  topic.warning(userID, 'Controller Name=', controller_name, 'warning')
@@ -1,60 +1,68 @@
1
1
  module RTALogger
2
2
  # Logging severity.
3
3
  module SeverityLevel
4
+ # all information that helps us to trace the processing of an incoming request through our application
5
+ TRACE = 0
4
6
  # Low-level information, mostly for developers.
5
- DEBUG = 0
7
+ DEBUG = 1
6
8
  # Generic (useful) information about system operation.
7
- INFO = 1
9
+ INFO = 2
8
10
  # A warning.
9
- WARN = 2
11
+ WARN = 3
10
12
  # A handleable error condition.
11
- ERROR = 3
13
+ ERROR = 4
12
14
  # An un-handleable error that results in a program crash.
13
- FATAL = 4
15
+ FATAL = 5
14
16
  # An unknown message that should always be logged.
15
- UNKNOWN = 5
17
+ UNKNOWN = 6
16
18
 
17
19
 
18
20
  def parse_severity_level_to_i(severity_level)
19
21
  return severity_level if severity_level.is_a? ::Integer
20
22
 
21
23
  case severity_level.upcase
22
- when 'DEBUG'
24
+ when 'TRACE'
23
25
  0
24
- when 'INFO'
26
+ when 'DEBUG'
25
27
  1
28
+ when 'INFO'
29
+ 2
26
30
  when 'INFORMATIONّٔ'
27
- 1
28
- when 'WARN'
29
31
  2
32
+ when 'WARN'
33
+ 3
30
34
  when 'WARNING'
31
- 2
35
+ 5
32
36
  when 'ERROR'
33
- 3
34
- when 'FATAL'
35
37
  4
36
- when 'UNKNOWN'
38
+ when 'FATAL'
37
39
  5
40
+ when 'UNKNOWN'
41
+ 6
42
+ else
43
+ 2
38
44
  end
39
- end
45
+ end
40
46
 
41
- def parse_severity_level_to_s(severity_level)
42
- return severity_level if severity_level.is_a? ::String
47
+ def parse_severity_level_to_s(severity_level)
48
+ return severity_level if severity_level.is_a? ::String
43
49
 
44
- case severity_level.to_i
45
- when 0
46
- 'DEBUG'
47
- when 1
48
- 'INFO'
49
- when 2
50
- 'WARN'
51
- when 3
52
- 'ERROR'
53
- when 4
54
- 'FATAL'
55
- when 5
56
- 'UNKNOWN'
57
- end
50
+ case severity_level.to_i
51
+ when 0
52
+ 'TRACE'
53
+ when 1
54
+ 'DEBUG'
55
+ when 2
56
+ 'INFO'
57
+ when 3
58
+ 'WARN'
59
+ when 4
60
+ 'ERROR'
61
+ when 5
62
+ 'FATAL'
63
+ when 6
64
+ 'UNKNOWN'
58
65
  end
59
66
  end
60
67
  end
68
+ end
@@ -0,0 +1,9 @@
1
+ class String
2
+ def underscore
3
+ self.gsub(/::/, '/').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: RTALogger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Babak Bahreini, RTA Backend Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-22 00:00:00.000000000 Z
11
+ date: 2020-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluent-logger
@@ -74,7 +74,7 @@ files:
74
74
  - lib/log_factory_record.rb
75
75
  - lib/log_factory_repository.rb
76
76
  - lib/log_factory_topic.rb
77
- - lib/log_formatter.rb
77
+ - lib/log_formatter_base.rb
78
78
  - lib/log_formatter_json.rb
79
79
  - lib/log_formatter_text.rb
80
80
  - lib/log_manager.rb
@@ -83,12 +83,13 @@ files:
83
83
  - lib/log_repository.rb
84
84
  - lib/log_repository_console.rb
85
85
  - lib/log_repository_file.rb
86
- - lib/log_repository_fluent.rb
86
+ - lib/log_repository_fluentd.rb
87
87
  - lib/log_repository_udp.rb
88
88
  - lib/log_topic.rb
89
89
  - lib/rta_logger_config.json
90
90
  - lib/sample.rb
91
91
  - lib/severity_level.rb
92
+ - lib/string.rb
92
93
  homepage: https://github.com/BBahrainy/RTALogger.git
93
94
  licenses:
94
95
  - MIT
@@ -1,18 +0,0 @@
1
- # Log Formatter base class
2
- module RTALogger
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
-
14
- def format(log_record)
15
- log_record.to_s
16
- end
17
- end
18
- end