RTALogger 0.1.0 → 1.0.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.idea/.gitignore +2 -0
  3. data/.idea/.rakeTasks +7 -0
  4. data/.idea/RTALogger.iml +29 -0
  5. data/.idea/misc.xml +7 -0
  6. data/.idea/modules.xml +8 -0
  7. data/.idea/vcs.xml +6 -0
  8. data/Gemfile +1 -0
  9. data/Gemfile.lock +21 -23
  10. data/README.md +326 -4
  11. data/RTALogger.gemspec +2 -1
  12. data/lib/RTALogger.rb +2 -4
  13. data/lib/RTALogger/version.rb +1 -1
  14. data/lib/log_factory_log_formatter.rb +35 -0
  15. data/lib/{factory/origin/log_factory_manager.rb → log_factory_manager.rb} +1 -3
  16. data/lib/{factory/origin/log_factory_propagator.rb → log_factory_propagator.rb} +1 -2
  17. data/lib/{factory/origin/log_factory_record.rb → log_factory_record.rb} +1 -1
  18. data/lib/log_factory_repository.rb +37 -0
  19. data/lib/log_factory_topic.rb +12 -0
  20. data/lib/log_formatter.rb +11 -1
  21. data/lib/log_formatter_json.rb +4 -2
  22. data/lib/log_formatter_text.rb +8 -6
  23. data/lib/log_manager.rb +126 -40
  24. data/lib/log_propagator.rb +44 -45
  25. data/lib/log_record.rb +27 -28
  26. data/lib/log_repository.rb +26 -4
  27. data/lib/log_repository_console.rb +8 -3
  28. data/lib/log_repository_file.rb +24 -6
  29. data/lib/log_repository_fluent.rb +49 -0
  30. data/lib/log_repository_udp.rb +14 -7
  31. data/lib/log_topic.rb +26 -18
  32. data/lib/rta_logger_config.json +59 -0
  33. data/lib/sample.rb +48 -0
  34. data/lib/severity_level.rb +60 -0
  35. metadata +34 -20
  36. data/lib/factory/origin/log_factory_file_logger.rb +0 -16
  37. data/lib/factory/origin/log_factory_log_formatter.rb +0 -11
  38. data/lib/factory/origin/log_factory_repository.rb +0 -44
  39. data/lib/factory/origin/log_factory_topic.rb +0 -12
  40. data/lib/log_severity.rb +0 -17
  41. data/lib/log_test.rb +0 -41
  42. data/lib/log_test_db.rb +0 -59
@@ -27,5 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.bindir = "exe"
28
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
- spec.add_dependency "fluentd", "~> 1.11", ">= 1.11.4"
30
+ spec.add_dependency "fluent-logger", "~> 0.9"
31
+ spec.add_dependency "jbuilder", "~> 2.10"
31
32
  end
@@ -1,6 +1,4 @@
1
- require "RTALogger/version"
2
-
1
+ require 'RTALogger/version'
2
+ # main namespace of the log manager
3
3
  module RTALogger
4
- class Error < StandardError; end
5
- # Your code goes here...
6
4
  end
@@ -1,3 +1,3 @@
1
1
  module RTALogger
2
- VERSION = "0.1.0"
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -0,0 +1,35 @@
1
+ module RTALogger
2
+ # Log factory to get new instance of log formatter
3
+ module LogFactory
4
+ def self.log_formatter_default
5
+ create_formatter(:json)
6
+ end
7
+
8
+ def self.create_formatter(type, config_json = '')
9
+ lib_file = @log_formatters[type.to_sym]
10
+ raise "unregistered formatter class: #{type.to_s}" if lib_file.nil? || lib_file.empty?
11
+
12
+ begin
13
+ load lib_file
14
+ rescue
15
+ raise "unable to load formatter class file: #{lib_file}"
16
+ end
17
+
18
+ formatter_class_name = 'RTALogger::' + ('log_formatter_' + type.to_s).split('_').map(&:capitalize).join
19
+ formatter_class = Object.const_get(formatter_class_name)
20
+ return nil unless formatter_class
21
+ result = formatter_class.new
22
+
23
+ return result if config_json.empty?
24
+ result.load_config(config_json) if result.present?
25
+ return result
26
+ end
27
+
28
+ def self.register_log_formatter(type, class_file_name)
29
+ @log_formatters[type.to_sym] = class_file_name
30
+ end
31
+
32
+ @log_formatters = {:text => 'log_formatter_text.rb',
33
+ :json => 'log_formatter_json.rb'}
34
+ end
35
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../log_manager'
3
+ require_relative 'log_manager'
4
4
 
5
5
  module RTALogger
6
6
  # this module generates object instance
@@ -8,7 +8,5 @@ module RTALogger
8
8
  def self.log_manager_instance
9
9
  RTALogger::LogManager.instance
10
10
  end
11
-
12
-
13
11
  end
14
12
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../log_propagator'
4
- #require_relative './log_repository_console'
3
+ require_relative 'log_propagator'
5
4
 
6
5
  module RTALogger
7
6
  # this module generates object instance
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../log_record'
3
+ require_relative 'log_record'
4
4
 
5
5
  module RTALogger
6
6
  # this module generates object instance
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RTALogger
4
+ # this module generates object instance
5
+ module LogFactory
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?
9
+
10
+ begin
11
+ load lib_file
12
+ rescue
13
+ raise "unable to load repository class file: #{lib_file}"
14
+ end
15
+
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
21
+
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
26
+ end
27
+
28
+ def self.register_log_repository(type, class_file_name)
29
+ @log_repositories[type.to_sym] = class_file_name
30
+ end
31
+
32
+ @log_repositories = {:console => 'log_repository_console.rb',
33
+ :file => 'log_repository_file.rb',
34
+ :udp => 'log_repository_upd.rb',
35
+ :fluentd => 'log_repository_fluetnd.rb'}
36
+ end
37
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'log_topic'
4
+
5
+ module RTALogger
6
+ # this module generates object instance
7
+ module LogFactory
8
+ def self.new_log_topic(log_manager, title, level = WARN, enable = true)
9
+ LogTopic.new(log_manager, title, level, enable)
10
+ end
11
+ end
12
+ end
@@ -1,8 +1,18 @@
1
+ # Log Formatter base class
1
2
  module RTALogger
2
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
+
3
14
  def format(log_record)
4
15
  log_record.to_s
5
16
  end
6
17
  end
7
18
  end
8
-
@@ -2,12 +2,14 @@ require 'jbuilder'
2
2
  require_relative 'log_formatter'
3
3
 
4
4
  module RTALogger
5
- class LogFormatterJSON
5
+ # json formatter which receive log_record and
6
+ # returns it's data as json string
7
+ class LogFormatterJson < LogFormatter
6
8
  def format(log_record)
7
9
  return '' unless log_record
8
10
 
9
11
  jb = Jbuilder.new do |json|
10
- json.occurred_at log_record.occurred_at.strftime("%F %H:%M:%S:%3N")
12
+ json.occurred_at log_record.occurred_at.strftime('%F %H:%M:%S:%3N')
11
13
  json.app_name log_record.app_name
12
14
  json.topic_title log_record.topic_title
13
15
  json.context_id log_record.context_id
@@ -1,16 +1,18 @@
1
1
  require_relative 'log_formatter'
2
2
 
3
3
  module RTALogger
4
+ # text formatter which receive log_record and
5
+ # returns it's data as delimited text string
4
6
  class LogFormatterText < LogFormatter
5
7
  def format(log_record)
6
8
  return '' unless log_record
7
9
 
8
- result = log_record.occurred_at.strftime("%F %H:%M:%S:%3N")
9
- result << '|' << log_record.app_name
10
- result << '|' << log_record.topic_title
11
- result << '|' << log_record.context_id
12
- result << '|' << log_record.severity
13
- result << '|' << log_record.message.join(' ').gsub('|' , '$<$')
10
+ 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
16
 
15
17
  result
16
18
  end
@@ -1,28 +1,34 @@
1
1
  require 'date'
2
2
  require 'thread'
3
3
  require 'singleton'
4
- require_relative 'factory/origin/log_factory_propagator'
5
- require_relative 'factory/origin/log_factory_repository'
6
- require_relative 'factory/origin/log_factory_topic'
7
- require_relative './log_severity'
4
+ require 'json'
5
+ require 'json/version'
6
+ require 'json/generic_object'
7
+ require_relative 'log_factory_propagator'
8
+ require_relative 'log_factory_repository'
9
+ require_relative 'log_factory_topic'
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
+ @name = 'default_log_manager'
24
+ @app_name = ENV.fetch('RTA_LOGGER_APP_NAME', 'unknown_app')
25
+ @severity_level = ENV.fetch('RTA_LOGGER_SEVERITY_LEVEL', WARN)
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)
29
+ @buffer_size = ENV.fetch('RTA_LOGGER_BUFFER_SIZE', 100)
24
30
  @flush_size = @buffer_size * 20 / 100
25
- @flush_wait_time = ENV.fetch('RTALogger_Flush_Wait_Seconds', 15)
31
+ @flush_wait_time = ENV.fetch('RTA_LOGGER_FLUSH_WAIT_SECONDS', 15)
26
32
  @topics = {}
27
33
  @log_records = []
28
34
  @propagator = LogFactory.new_log_propagator
@@ -36,33 +42,42 @@ module RTALogger
36
42
  @flush_scheduler.run
37
43
  end
38
44
 
39
- def config(config_file_name)
40
- config_json = load_config_from_file(config_file_name)
41
- raise 'json config not available' unless config_json
42
- @enable = config_json['Enable'].nil? ? true : config_json['Enable']
43
- @app_name = config_json['App_Name'] if config_json['App_Name'].present?
44
- @default_log_level = config_json['Log_Severity'] if config_json['Log_Severity'].present?
45
- @buffer_siz = config_json['Buffer_Size'] if config_json['Buffer_Size'].present?
46
- @flush_wait_time = config_json['Flush_Wait_Seconds'] if config_json['Flush_Wait_Seconds'].present?
47
- @propagator.drop_all_repositories
48
- config_json['Repos']&.each { |item| @propagator.load_log_repository(item) }
45
+ attr_reader :name
46
+ attr_accessor :enable
47
+ attr_accessor :app_name
48
+ attr_reader :propagator
49
+ attr_accessor :default_severity_level
50
+ attr_accessor :buffer_size
51
+ attr_reader :flush_size
52
+ attr_accessor :flush_wait_time
53
+ attr_reader :topics
54
+ attr_reader :config_file_name
55
+
56
+ def config_use_json_file(file_name, manager_name = '')
57
+ config_json = load_config_from_json_file(file_name, manager_name)
58
+ @config_file_name = file_name if config_json
59
+ apply_config(config_json)
49
60
  rescue StandardError => e
50
61
  puts e.message
51
62
  @propagator.drop_all_repositories
52
- @propagator.add_log_repository(LogFactory.new_log_repository_console)
63
+ @propagator.add_log_repository(LogFactory.create_repository(:console))
53
64
  end
54
65
 
55
- attr_accessor :enable
56
- attr_accessor :app_name
57
- attr_reader :propagator
66
+ def config_use_json_string(config_string, manager_name = '')
67
+ config_json = load_config_from_json_string(config_string, manager_name)
68
+ apply_config(config_json)
69
+ rescue StandardError => e
70
+ puts e.message
71
+ @propagator.drop_all_repositories
72
+ @propagator.add_log_repository(LogFactory.create_repository(:console))
73
+ end
58
74
 
59
- def add_topic(topic_title, log_level = @default_log_level)
75
+ def add_topic(title, severity_level = @default_severity_level, enable = true)
60
76
  @topic_semaphore.synchronize {
61
- @topics[topic_title.to_sym] ||= LogFactory.new_log_topic(self, topic_title, log_level)
77
+ @topics[title.to_sym] ||= LogFactory.new_log_topic(self, title, severity_level, enable)
62
78
  }
63
79
 
64
- @topics[topic_title.to_sym].enable = @enable
65
- @topics[topic_title.to_sym]
80
+ @topics[title.to_sym]
66
81
  end
67
82
 
68
83
  def add_log(log_record)
@@ -71,32 +86,102 @@ module RTALogger
71
86
  check_for_flush
72
87
  end
73
88
 
74
- def update_topic_log_level(topic, log_level = WARN)
75
- @topic_semaphore.synchronize { @topics[topic].log_level = log_level if @topics[topic] }
89
+ def update_topic_enable(topic, enable = true)
90
+ @topic_semaphore.synchronize { @topics[topic.to_sym].enable = enable if @topics[topic.to_sym] }
91
+ end
92
+
93
+ def update_all_topics_enable(enable = true)
94
+ @topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].enable = enable } }
95
+ end
96
+
97
+ def update_topic_severity_level(topic, severity_level = WARN)
98
+ @topic_semaphore.synchronize { @topics[topic.to_sym].severity_level = severity_level if @topics[topic.to_sym] }
76
99
  end
77
100
 
78
- def update_all_topics_log_level(log_level = WARN)
79
- @topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].log_level = log_level } }
101
+ def update_all_topics_severity_level(severity_level = WARN)
102
+ @topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].severity_level = severity_level } }
103
+ end
104
+
105
+ def to_builder
106
+ @topic_semaphore.synchronize do
107
+ jb = Jbuilder.new do |json|
108
+ json.name name
109
+ json.enable enable
110
+ json.app_name app_name
111
+ json.config_file_name config_file_name
112
+ json.default_severity_level default_severity_level
113
+ json.buffer_size buffer_size
114
+ json.flush_size flush_size
115
+ json.flush_wait_time flush_wait_time
116
+ json.topics do
117
+ json.array! topics.keys.collect { |topic_key| @topics[topic_key].to_builder.attributes! }
118
+ end
119
+ end
120
+
121
+ jb
122
+ end
123
+ end
124
+
125
+ def reveal_config
126
+ to_builder.target!
80
127
  end
81
128
 
82
129
  private
83
130
 
84
- def load_config_from_file(config_file_name)
131
+ def load_config_from_json_file(config_file_name, manager_name = '')
85
132
  config_file = File.open config_file_name
86
- config_json = JSON.load config_file
87
- config_json = config_json['RTALogger']
133
+ config_json = ::JSON.load(config_file)
134
+ config_json = extract_config(config_json, manager_name)
135
+ config_json
136
+ end
137
+
138
+ def load_config_from_json_string(config_string, manager_name = '')
139
+ config_json = ::JSON.parse(config_string)
140
+ config_json = extract_config(config_json, manager_name)
141
+ config_json
142
+ end
143
+
144
+ def extract_config(json_data, manager_name = '')
145
+ config_json = json_data['rta_logger']
88
146
  raise 'RTALogger configuration not found!' unless config_json
89
- raise 'Log_Managers section does not exists json configuration' unless config_json['Log_Managers']
90
- raise 'No config manager defined in json configuration' unless config_json['Log_Managers'].count.positive?
91
- manager_name = config_json['Default_Manager']
147
+ raise 'Log_Managers section does not exists json configuration' unless config_json['log_managers']
148
+ 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?
92
150
  unless manager_name.to_s.strip.empty?
93
- config_json = config_json['Log_Managers'].find { |item| item['Manager_Name'] == manager_name }
151
+ config_json = config_json['log_managers'].find { |item| item['manager_name'] == manager_name }
94
152
  end
95
- config_json ||= config_json['Log_Managers'][0]
153
+ config_json ||= config_json['log_managers'][0]
96
154
  raise 'Unable to extract RTA Log Manager configuration!' unless config_json
155
+ @name = manager_name if config_json
97
156
  config_json
98
157
  end
99
158
 
159
+ def apply_config(config_json)
160
+ raise 'json config not available' unless config_json
161
+ @enable = config_json['enable'].nil? ? true : config_json['enable']
162
+ @app_name = config_json['app_name'] unless config_json['app_name'].empty?
163
+ @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']
166
+ @propagator.drop_all_repositories
167
+ apply_config_repos(config_json)
168
+ apply_config_topics(config_json)
169
+ end
170
+
171
+ def apply_config_repos(config_json)
172
+ config_json['repos']&.each { |item| @propagator.load_log_repository(item) }
173
+ end
174
+
175
+ def apply_config_topics(config_json)
176
+ config_json['topics']&.each do |topic|
177
+ next unless topic['title']
178
+ result_topic = add_topic(topic['title'])
179
+ next unless result_topic
180
+ result_topic.severity_level = parse_severity_level_to_i topic['severity_level'] if topic['severity_level']
181
+ result_topic.enable = topic['enable'] if topic['enable']
182
+ end
183
+ end
184
+
100
185
  def initialize_flush_scheduler
101
186
  @flush_scheduler = Thread.new do
102
187
  loop do
@@ -128,7 +213,7 @@ module RTALogger
128
213
 
129
214
  def flush_all
130
215
  @log_semaphore.synchronize do
131
- @log_records[0...@log_records.count].each { |log| propagate(log) }
216
+ @log_records[0...@log_records.count].each { |log| propagate(log) }
132
217
  @log_records.clear
133
218
  end
134
219
  @propagator.propagate
@@ -137,5 +222,6 @@ module RTALogger
137
222
  def propagate(log_record)
138
223
  @propagator.add_log(log_record)
139
224
  end
225
+
140
226
  end
141
227
  end
@@ -1,45 +1,44 @@
1
- require 'thread'
2
- require_relative './log_repository'
3
-
4
- module RTALogger
5
- # propagate log records to multiple log repositories
6
- class LogPropagator
7
- def initialize
8
- @semaphore = Mutex.new
9
- @log_records = []
10
- @log_repositories = []
11
- end
12
-
13
- def add_log(log_record)
14
- @semaphore.synchronize { @log_records.push(log_record.dup) }
15
- end
16
-
17
- def add_log_repository(log_repository)
18
- return unless log_repository.is_a? RTALogger::LogRepository
19
- @log_repositories.push(log_repository) unless @log_repositories.include?(log_repository)
20
- end
21
-
22
- def load_log_repository(config_json)
23
- type = config_json['Type']
24
- return if type.to_s.strip.empty?
25
- enable = config_json['Enable'].nil? ? true : config_json['Enable']
26
- return unless enable
27
-
28
- log_repository = ::RTALogger::LogFactory.create_repository(type, config_json)
29
- add_log_repository(log_repository)
30
- end
31
-
32
- def drop_all_repositories
33
- @semaphore.synchronize { @log_repositories.clear }
34
- end
35
-
36
- def propagate
37
- @semaphore.synchronize do
38
- @log_repositories.each do |log_repository|
39
- log_repository.add_log_records(@log_records)
40
- end
41
- @log_records.clear
42
- end
43
- end
44
- end
45
- end
1
+ require_relative 'log_repository'
2
+
3
+ module RTALogger
4
+ # propagate log records to multiple log repositories
5
+ class LogPropagator
6
+ def initialize
7
+ @semaphore = Mutex.new
8
+ @log_records = []
9
+ @log_repositories = []
10
+ end
11
+
12
+ def add_log(log_record)
13
+ @semaphore.synchronize { @log_records.push(log_record.dup) }
14
+ end
15
+
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)
19
+ end
20
+
21
+ def load_log_repository(config_json)
22
+ type = config_json['type']
23
+ return if type.to_s.strip.empty?
24
+ enable = config_json['enable'].nil? ? true : config_json['enable']
25
+ return unless enable
26
+
27
+ log_repository = ::RTALogger::LogFactory.create_repository(type, config_json)
28
+ add_log_repository(log_repository)
29
+ end
30
+
31
+ def drop_all_repositories
32
+ @semaphore.synchronize { @log_repositories.clear }
33
+ end
34
+
35
+ def propagate
36
+ @semaphore.synchronize do
37
+ @log_repositories.each do |log_repository|
38
+ log_repository.add_log_records(@log_records)
39
+ end
40
+ @log_records.clear
41
+ end
42
+ end
43
+ end
44
+ end