RTALogger 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +58 -0
- data/LICENSE.txt +21 -0
- data/README.md +40 -0
- data/RTALogger.gemspec +31 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/RTALogger.rb +6 -0
- data/lib/RTALogger/version.rb +3 -0
- data/lib/factory/origin/log_factory_file_logger.rb +16 -0
- data/lib/factory/origin/log_factory_log_formatter.rb +11 -0
- data/lib/factory/origin/log_factory_manager.rb +14 -0
- data/lib/factory/origin/log_factory_propagator.rb +13 -0
- data/lib/factory/origin/log_factory_record.rb +12 -0
- data/lib/factory/origin/log_factory_repository.rb +44 -0
- data/lib/factory/origin/log_factory_topic.rb +12 -0
- data/lib/log_formatter.rb +8 -0
- data/lib/log_formatter_json.rb +21 -0
- data/lib/log_formatter_text.rb +18 -0
- data/lib/log_manager.rb +141 -0
- data/lib/log_propagator.rb +45 -0
- data/lib/log_record.rb +28 -0
- data/lib/log_repository.rb +31 -0
- data/lib/log_repository_console.rb +23 -0
- data/lib/log_repository_file.rb +25 -0
- data/lib/log_repository_udp.rb +25 -0
- data/lib/log_severity.rb +17 -0
- data/lib/log_test.rb +41 -0
- data/lib/log_test_db.rb +59 -0
- data/lib/log_topic.rb +57 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e8102f5e6bfb81e09e529d98b34039304aa7376d553e0df71e974a2eeaf6818d
|
4
|
+
data.tar.gz: 7a6558fa4df04b8bbaede48620644b7b85de448d96b7e93340d30f018a872461
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 590a74703f4605c4a0df2e3a5a1997bf1c0209182b961ef74769f4c037f7fefb8770240d317e6017d3cf9ae30f1fc1cbd4e489c6e5c7f083b36f04b6d6f64bc6
|
7
|
+
data.tar.gz: 1dd9d109f63173420be1bbb6306d76eda10140c4474aa8b4de27f46ef7dbadceec58d5ba8816b03fa53de2cb6ee6b793ae3726ade97728aa3de55ec592e30255
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
RTALogger (0.1.0)
|
5
|
+
fluentd (~> 1.11, >= 1.11.4)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
concurrent-ruby (1.1.7)
|
11
|
+
cool.io (1.7.0)
|
12
|
+
diff-lcs (1.4.4)
|
13
|
+
fluentd (1.11.4)
|
14
|
+
cool.io (>= 1.4.5, < 2.0.0)
|
15
|
+
http_parser.rb (>= 0.5.1, < 0.7.0)
|
16
|
+
msgpack (>= 1.3.1, < 2.0.0)
|
17
|
+
serverengine (>= 2.0.4, < 3.0.0)
|
18
|
+
sigdump (~> 0.2.2)
|
19
|
+
strptime (>= 0.2.2, < 1.0.0)
|
20
|
+
tzinfo (>= 1.0, < 3.0)
|
21
|
+
tzinfo-data (~> 1.0)
|
22
|
+
yajl-ruby (~> 1.0)
|
23
|
+
http_parser.rb (0.6.0)
|
24
|
+
msgpack (1.3.3)
|
25
|
+
rake (12.3.3)
|
26
|
+
rspec (3.10.0)
|
27
|
+
rspec-core (~> 3.10.0)
|
28
|
+
rspec-expectations (~> 3.10.0)
|
29
|
+
rspec-mocks (~> 3.10.0)
|
30
|
+
rspec-core (3.10.0)
|
31
|
+
rspec-support (~> 3.10.0)
|
32
|
+
rspec-expectations (3.10.0)
|
33
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
+
rspec-support (~> 3.10.0)
|
35
|
+
rspec-mocks (3.10.0)
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
+
rspec-support (~> 3.10.0)
|
38
|
+
rspec-support (3.10.0)
|
39
|
+
serverengine (2.2.2)
|
40
|
+
sigdump (~> 0.2.2)
|
41
|
+
sigdump (0.2.4)
|
42
|
+
strptime (0.2.5)
|
43
|
+
tzinfo (2.0.2)
|
44
|
+
concurrent-ruby (~> 1.0)
|
45
|
+
tzinfo-data (1.2020.4)
|
46
|
+
tzinfo (>= 1.0.0)
|
47
|
+
yajl-ruby (1.4.1)
|
48
|
+
|
49
|
+
PLATFORMS
|
50
|
+
ruby
|
51
|
+
|
52
|
+
DEPENDENCIES
|
53
|
+
RTALogger!
|
54
|
+
rake (~> 12.0)
|
55
|
+
rspec (~> 3.0)
|
56
|
+
|
57
|
+
BUNDLED WITH
|
58
|
+
2.1.4
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 =
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# RTALogger
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/RTALogger`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'RTALogger'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install RTALogger
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
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.
|
30
|
+
|
31
|
+
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).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/RTALogger.
|
36
|
+
|
37
|
+
|
38
|
+
## License
|
39
|
+
|
40
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/RTALogger.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'lib/RTALogger/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "RTALogger"
|
5
|
+
spec.version = RTALogger::VERSION
|
6
|
+
spec.authors = ["Babak Bahreini, RTA Backend Team"]
|
7
|
+
spec.email = ["b.bahreini@roundtableapps.com"]
|
8
|
+
|
9
|
+
|
10
|
+
spec.summary = %q{An easy to use, easy to extend log manager to prepare standard log API for developers }
|
11
|
+
spec.description = %q{RTA Log Manager has been designed and implemented to provide standard logging API for developers.This prevents chaos in log data format. Also provide multiple extendable log repositories including wrapping existing loggers, like 'Fluentd' or implement completely new custom logger. All main features of log manager are configeable through a json config file.}
|
12
|
+
spec.homepage = "https://github.com/BBahrainy/RTALogger.git"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
15
|
+
|
16
|
+
spec.metadata["allowed_push_host"] = "https://www.rubygems.org"
|
17
|
+
|
18
|
+
spec.metadata["homepage_uri"] = "https://github.com/BBahrainy/RTALogger.git"
|
19
|
+
spec.metadata["source_code_uri"] = "https://github.com/BBahrainy/RTALogger.git"
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/BBahrainy/RTALogger.git"
|
21
|
+
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
23
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
25
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
end
|
27
|
+
spec.bindir = "exe"
|
28
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ["lib"]
|
30
|
+
spec.add_dependency "fluentd", "~> 1.11", ">= 1.11.4"
|
31
|
+
end
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "RTALogger"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/RTALogger.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module RTALogger
|
5
|
+
# this module generates object instance
|
6
|
+
module LogFactory
|
7
|
+
def self.new_file_logger(file_path = 'log.txt', period = 'daily', shift_size = 1048576)
|
8
|
+
@ruby_logger = Logger.new(file_path, period, shift_size)
|
9
|
+
@ruby_logger.level = Logger::Severity::DEBUG
|
10
|
+
@ruby_logger.formatter = proc do |severity, datetime, progname, msg|
|
11
|
+
"#{msg}\n"
|
12
|
+
end
|
13
|
+
@ruby_logger
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../log_propagator'
|
4
|
+
#require_relative './log_repository_console'
|
5
|
+
|
6
|
+
module RTALogger
|
7
|
+
# this module generates object instance
|
8
|
+
module LogFactory
|
9
|
+
def self.new_log_propagator
|
10
|
+
LogPropagator.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../log_record'
|
4
|
+
|
5
|
+
module RTALogger
|
6
|
+
# this module generates object instance
|
7
|
+
module LogFactory
|
8
|
+
def self.new_log_record(log_topic, context_id, severity, *message)
|
9
|
+
LogRecord.new(log_topic, context_id, severity, message)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../log_repository_console'
|
4
|
+
require_relative '../../log_repository_file'
|
5
|
+
require_relative '../../log_repository_udp'
|
6
|
+
#require_relative '../../log_repository_db'
|
7
|
+
|
8
|
+
module RTALogger
|
9
|
+
# this module generates object instance
|
10
|
+
module LogFactory
|
11
|
+
def self.new_log_repository_console
|
12
|
+
LogRepositoryConsole.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.new_log_repository_file(file_path = 'log.txt', period = 'daily', shift_size = 1048576)
|
16
|
+
LogRepositoryFile.new(file_path, period, shift_size)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.load_log_repository_file(config_json)
|
20
|
+
file_path = config_json['File_Path'].to_s
|
21
|
+
period = config_json['Roll_Period'].to_s
|
22
|
+
shift_size = config_json['Roll_Size'].nil? ? 1048576 : config_json['Roll_Size'].to_i
|
23
|
+
::RTALogger::LogFactory.new_log_repository_file(file_path, period, shift_size)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.new_log_repository_udp(host = '127.0.0.1', port = 4913)
|
27
|
+
LogRepositoryUDP.new(host, port)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.load_log_repository_udp(config_json)
|
31
|
+
host = config_json['Host'].to_s
|
32
|
+
port = config_json['Port'].nil? ? 4913 : config_json['Port'].to_i
|
33
|
+
::RTALogger::LogFactory.new_log_repository_udp(host, port)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.create_repository(type, config_json)
|
37
|
+
result = nil
|
38
|
+
result = new_log_repository_console if type.to_s.upcase.eql?('Console'.upcase)
|
39
|
+
result = load_log_repository_file(config_json) if type.to_s.upcase.eql?('File'.upcase)
|
40
|
+
result = load_log_repository_udp(config_json) if type.to_s.upcase.eql?('UDP'.upcase)
|
41
|
+
result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
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, topic_title, level = WARN)
|
9
|
+
LogTopic.new(log_manager, topic_title, level)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'jbuilder'
|
2
|
+
require_relative 'log_formatter'
|
3
|
+
|
4
|
+
module RTALogger
|
5
|
+
class LogFormatterJSON
|
6
|
+
def format(log_record)
|
7
|
+
return '' unless log_record
|
8
|
+
|
9
|
+
jb = Jbuilder.new do |json|
|
10
|
+
json.occurred_at log_record.occurred_at.strftime("%F %H:%M:%S:%3N")
|
11
|
+
json.app_name log_record.app_name
|
12
|
+
json.topic_title log_record.topic_title
|
13
|
+
json.context_id log_record.context_id
|
14
|
+
json.severity log_record.severity
|
15
|
+
json.message log_record.message.flatten.join(' ')
|
16
|
+
end
|
17
|
+
|
18
|
+
jb.target!
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'log_formatter'
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
class LogFormatterText < LogFormatter
|
5
|
+
def format(log_record)
|
6
|
+
return '' unless log_record
|
7
|
+
|
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('|' , '$<$')
|
14
|
+
|
15
|
+
result
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/log_manager.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'thread'
|
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'
|
8
|
+
|
9
|
+
# the module will contain all logger requirements
|
10
|
+
module RTALogger
|
11
|
+
# the class is the main class
|
12
|
+
class LogManager
|
13
|
+
include Singleton
|
14
|
+
include LogSeverity
|
15
|
+
include RTALogger::LogFactory
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@enable = true
|
19
|
+
@app_name = ENV.fetch('RTALogger_App_Name', 'unknownApp')
|
20
|
+
@default_log_level = ENV.fetch('RTALogger_Log_Severity', ::RTALogger::LogSeverity::WARN)
|
21
|
+
@topic_semaphore = Mutex.new
|
22
|
+
@log_semaphore = Mutex.new
|
23
|
+
@buffer_size = ENV.fetch('RTALogger_Buffer_Size', 100)
|
24
|
+
@flush_size = @buffer_size * 20 / 100
|
25
|
+
@flush_wait_time = ENV.fetch('RTALogger_Flush_Wait_Seconds', 15)
|
26
|
+
@topics = {}
|
27
|
+
@log_records = []
|
28
|
+
@propagator = LogFactory.new_log_propagator
|
29
|
+
@last_flush_time = DateTime.now
|
30
|
+
@exit_flush_scheduler = false
|
31
|
+
initialize_flush_scheduler
|
32
|
+
ObjectSpace.define_finalizer(self, proc {
|
33
|
+
@exit_flush_scheduler = true
|
34
|
+
flush_all
|
35
|
+
})
|
36
|
+
@flush_scheduler.run
|
37
|
+
end
|
38
|
+
|
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) }
|
49
|
+
rescue StandardError => e
|
50
|
+
puts e.message
|
51
|
+
@propagator.drop_all_repositories
|
52
|
+
@propagator.add_log_repository(LogFactory.new_log_repository_console)
|
53
|
+
end
|
54
|
+
|
55
|
+
attr_accessor :enable
|
56
|
+
attr_accessor :app_name
|
57
|
+
attr_reader :propagator
|
58
|
+
|
59
|
+
def add_topic(topic_title, log_level = @default_log_level)
|
60
|
+
@topic_semaphore.synchronize {
|
61
|
+
@topics[topic_title.to_sym] ||= LogFactory.new_log_topic(self, topic_title, log_level)
|
62
|
+
}
|
63
|
+
|
64
|
+
@topics[topic_title.to_sym].enable = @enable
|
65
|
+
@topics[topic_title.to_sym]
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_log(log_record)
|
69
|
+
return unless @enable
|
70
|
+
@log_semaphore.synchronize { @log_records.push(log_record) }
|
71
|
+
check_for_flush
|
72
|
+
end
|
73
|
+
|
74
|
+
def update_topic_log_level(topic, log_level = WARN)
|
75
|
+
@topic_semaphore.synchronize { @topics[topic].log_level = log_level if @topics[topic] }
|
76
|
+
end
|
77
|
+
|
78
|
+
def update_all_topics_log_level(log_level = WARN)
|
79
|
+
@topic_semaphore.synchronize { @topics.keys.each { |topic| @topics[topic].log_level = log_level } }
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def load_config_from_file(config_file_name)
|
85
|
+
config_file = File.open config_file_name
|
86
|
+
config_json = JSON.load config_file
|
87
|
+
config_json = config_json['RTALogger']
|
88
|
+
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']
|
92
|
+
unless manager_name.to_s.strip.empty?
|
93
|
+
config_json = config_json['Log_Managers'].find { |item| item['Manager_Name'] == manager_name }
|
94
|
+
end
|
95
|
+
config_json ||= config_json['Log_Managers'][0]
|
96
|
+
raise 'Unable to extract RTA Log Manager configuration!' unless config_json
|
97
|
+
config_json
|
98
|
+
end
|
99
|
+
|
100
|
+
def initialize_flush_scheduler
|
101
|
+
@flush_scheduler = Thread.new do
|
102
|
+
loop do
|
103
|
+
elapsed_seconds = ((DateTime.now - @last_flush_time) * 24 * 60 * 60).to_i
|
104
|
+
flush if elapsed_seconds > @flush_wait_time
|
105
|
+
sleep(1)
|
106
|
+
break if @exit_flush_scheduler
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def check_for_flush
|
112
|
+
flush if count > @buffer_size
|
113
|
+
end
|
114
|
+
|
115
|
+
def count
|
116
|
+
@log_semaphore.synchronize { @log_records.count }
|
117
|
+
end
|
118
|
+
|
119
|
+
def flush
|
120
|
+
@last_flush_time = DateTime.now
|
121
|
+
@log_semaphore.synchronize do
|
122
|
+
@log_records[0...@flush_size].each { |log| propagate(log) }
|
123
|
+
end
|
124
|
+
@log_semaphore.synchronize { @log_records.shift(@flush_size) }
|
125
|
+
propagate_thread = Thread.new { @propagator.propagate }
|
126
|
+
propagate_thread.join
|
127
|
+
end
|
128
|
+
|
129
|
+
def flush_all
|
130
|
+
@log_semaphore.synchronize do
|
131
|
+
@log_records[0...@log_records.count].each { |log| propagate(log) }
|
132
|
+
@log_records.clear
|
133
|
+
end
|
134
|
+
@propagator.propagate
|
135
|
+
end
|
136
|
+
|
137
|
+
def propagate(log_record)
|
138
|
+
@propagator.add_log(log_record)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,45 @@
|
|
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
|
data/lib/log_record.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
# log data structure
|
5
|
+
class LogRecord
|
6
|
+
def initialize(log_topic, context_id, severity, *message)
|
7
|
+
@log_topic = log_topic
|
8
|
+
@context_id = context_id
|
9
|
+
@severity = severity
|
10
|
+
@message = message
|
11
|
+
@occurred_at = DateTime.now
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :context_id
|
15
|
+
attr_reader :severity
|
16
|
+
attr_reader :message
|
17
|
+
attr_reader :occurred_at
|
18
|
+
|
19
|
+
def app_name
|
20
|
+
@log_topic.log_manager.app_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def topic_title
|
24
|
+
@log_topic.topic_title
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
# base log repository class
|
5
|
+
class LogRepository
|
6
|
+
def initialize
|
7
|
+
@semaphore = Mutex.new
|
8
|
+
@log_records = []
|
9
|
+
@enable = true
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_log_records(items)
|
13
|
+
return 0 unless @enable
|
14
|
+
@semaphore.synchronize do
|
15
|
+
items.each { |item| @log_records.push(item.dup) }
|
16
|
+
end
|
17
|
+
flush_and_clear
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_accessor :enable
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def flush_and_clear
|
25
|
+
@semaphore.synchronize { @log_records.clear }
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :log_records
|
29
|
+
attr_reader :semaphore
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'log_repository'
|
2
|
+
require_relative 'factory/origin/log_factory_log_formatter'
|
3
|
+
|
4
|
+
module RTALogger
|
5
|
+
# show log items on console out put
|
6
|
+
class LogRepositoryConsole < LogRepository
|
7
|
+
def initialize
|
8
|
+
super
|
9
|
+
|
10
|
+
@formatter = RTALogger::LogFactory::log_formatter_default
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def flush_and_clear
|
16
|
+
semaphore.synchronize do
|
17
|
+
@log_records.each { |log_record| puts @formatter.format(log_record) }
|
18
|
+
end
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require_relative 'log_repository'
|
3
|
+
require_relative 'factory/origin/log_factory_file_logger'
|
4
|
+
require_relative 'factory/origin/log_factory_log_formatter'
|
5
|
+
|
6
|
+
module RTALogger
|
7
|
+
# show log items on console out put
|
8
|
+
class LogRepositoryFile < LogRepository
|
9
|
+
def initialize(file_path = 'log.txt', period = 'daily', shift_size = 1048576)
|
10
|
+
super()
|
11
|
+
@file_logger = RTALogger::LogFactory.new_file_logger(file_path, period, shift_size)
|
12
|
+
@formatter = RTALogger::LogFactory::log_formatter_default
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def flush_and_clear
|
18
|
+
semaphore.synchronize do
|
19
|
+
@log_records.each { |log_record| @file_logger.debug(@formatter.format(log_record)) }
|
20
|
+
end
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module RTALogger
|
4
|
+
# show log items on console out put
|
5
|
+
class LogRepositoryUDP < LogRepository
|
6
|
+
def initialize(host = '127.0.0.1', port = 4913)
|
7
|
+
super()
|
8
|
+
@host = host
|
9
|
+
@port = port
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def flush_and_clear
|
15
|
+
semaphore.synchronize do
|
16
|
+
u1 = UDPSocket.new
|
17
|
+
u1.bind(@host, @port)
|
18
|
+
@log_records.each { |log_record| u1.send log_record.to_s, 0, @host, @port}
|
19
|
+
u1.close
|
20
|
+
end
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/log_severity.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module RTALogger
|
2
|
+
# Logging severity.
|
3
|
+
module LogSeverity
|
4
|
+
# Low-level information, mostly for developers.
|
5
|
+
DEBUG = 0
|
6
|
+
# Generic (useful) information about system operation.
|
7
|
+
INFO = 1
|
8
|
+
# A warning.
|
9
|
+
WARN = 2
|
10
|
+
# A handleable error condition.
|
11
|
+
ERROR = 3
|
12
|
+
# An unhandleable error that results in a program crash.
|
13
|
+
FATAL = 4
|
14
|
+
# An unknown message that should always be logged.
|
15
|
+
UNKNOWN = 5
|
16
|
+
end
|
17
|
+
end
|
data/lib/log_test.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#require 'logger'
|
2
|
+
#require 'date'
|
3
|
+
require_relative 'factory/origin/log_factory_manager'
|
4
|
+
require_relative 'factory/origin/log_factory_repository'
|
5
|
+
require 'socket'
|
6
|
+
|
7
|
+
controller_name = 'test_controller'
|
8
|
+
userID = 5
|
9
|
+
|
10
|
+
log_manager = RTALogger::LogFactory.log_manager_instance
|
11
|
+
log_manager.app_name = 'myTestApp'
|
12
|
+
log_manager.config('../../../config/rta_logger_config.json')
|
13
|
+
#log_manager.propagator.add_log_repository(RTALogger::LogFactory.new_log_repository_console)
|
14
|
+
#log_manager.propagator.add_log_repository(RTALogger::LogFactory.new_log_repository_file('../../../log/log.txt'))
|
15
|
+
#log_manager.propagator.add_log_repository(RTALogger::LogFactory.new_log_repository_udp('127.0.0.1', 4913))
|
16
|
+
# log_manager.propagator.add_log_repository(RTALogger::LogFactory.new_log_repository_db)
|
17
|
+
|
18
|
+
topic = log_manager.add_topic(controller_name)
|
19
|
+
|
20
|
+
topic.info(userID, 'Controller Name=', controller_name, 'Called by client 1')
|
21
|
+
|
22
|
+
#logger.level = RTALogger::LogSeverity::INFO
|
23
|
+
#manager.update_topic_level(controller_name, RTALogger::LogSeverity::INFO)
|
24
|
+
|
25
|
+
log_manager.update_all_topics_log_level(RTALogger::LogSeverity::INFO)
|
26
|
+
|
27
|
+
topic.info(userID, 'Controller Name|', controller_name, 'Called by client |2|')
|
28
|
+
topic.error(userID, 'Controller Name=', controller_name, 'Called by client 3')
|
29
|
+
|
30
|
+
#sleep(10)
|
31
|
+
|
32
|
+
topic.info(userID, 'Controller Name=', controller_name, 'Called by client |4|')
|
33
|
+
topic.fatal(userID, 'Controller Name=', controller_name, 'Called by client 5')
|
34
|
+
topic.info(userID, 'Controller Name=', controller_name, 'Called by client 6')
|
35
|
+
|
36
|
+
#ruby_logger = Logger.new(STDOUT)
|
37
|
+
#ruby_logger.formatter = proc do |severity, datetime, progname, msg|
|
38
|
+
# "NICE: #{msg}\n"
|
39
|
+
#end
|
40
|
+
#ruby_logger.info('logged by ruby default logger')
|
41
|
+
|
data/lib/log_test_db.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#require 'active_record'
|
2
|
+
#require 'pg'
|
3
|
+
# require 'active_record' # uncomment for not Rails environment
|
4
|
+
|
5
|
+
#ActiveRecord::Base.establish_connection(:adapter => "postgresql",
|
6
|
+
# :username => "postgre",
|
7
|
+
# :database => "rails_test_development")
|
8
|
+
|
9
|
+
require 'log_record'
|
10
|
+
|
11
|
+
module RTALogger
|
12
|
+
class LogFormatter
|
13
|
+
def initialize(log_record,
|
14
|
+
delimiter = '|',
|
15
|
+
time_format = '%Y-%m-%d %H:%M:%S.%3N')
|
16
|
+
@log_record = log_record
|
17
|
+
@delimiter = delimiter
|
18
|
+
@time_format = time_format
|
19
|
+
@format_chance = format_chance
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_accessor :log_record
|
23
|
+
attr_accessor :delimiter
|
24
|
+
attr_accessor :time_format
|
25
|
+
|
26
|
+
def self.default_formatter(log_record)
|
27
|
+
LogFormatter.new(log_record)
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
result = "#{occurred_at}#{@delimiter}#{@log_record.app_name}#{@delimiter}"
|
32
|
+
result << "#{@log_record.topic_title}#{@delimiter}#{@log_record.context_id}"
|
33
|
+
result << "#{@delimiter}#{@log_record.severity}#{@delimiter}#{log_message}"
|
34
|
+
|
35
|
+
if @format_chance
|
36
|
+
result unless @format_chance.call(occurred_at,
|
37
|
+
@log_record.app_name,
|
38
|
+
@log_record.topic_title,
|
39
|
+
@log_record.context_id,
|
40
|
+
@log_record.severity,
|
41
|
+
log_message)
|
42
|
+
end
|
43
|
+
else
|
44
|
+
result
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def log_message
|
51
|
+
@log_record.message.join.gsub(delimiter, '&dlm&')
|
52
|
+
end
|
53
|
+
|
54
|
+
def occurred_at
|
55
|
+
@log_record.occurred_at.strftime(time_format)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
data/lib/log_topic.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# topic
|
2
|
+
|
3
|
+
require_relative './log_severity'
|
4
|
+
require_relative 'factory/origin/log_factory_record'
|
5
|
+
|
6
|
+
module RTALogger
|
7
|
+
# the main class to logging data
|
8
|
+
class LogTopic
|
9
|
+
include LogSeverity
|
10
|
+
include RTALogger::LogFactory
|
11
|
+
|
12
|
+
def initialize(log_manager, topic_title, log_level = WARN)
|
13
|
+
# Logger logger = Logger.new(Logger::DEBUG)
|
14
|
+
@enable = true
|
15
|
+
@log_manager = log_manager
|
16
|
+
@topic_title = topic_title.to_s.dup
|
17
|
+
@log_level = log_level
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_accessor :enable
|
21
|
+
attr_reader :log_manager
|
22
|
+
attr_reader :topic_title
|
23
|
+
attr_accessor :log_level
|
24
|
+
|
25
|
+
def debug(context_id, *message)
|
26
|
+
add(context_id, DEBUG, message) if @log_level.to_i <= DEBUG.to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
def info(context_id, *message)
|
30
|
+
add(context_id, INFO, message) if @log_level.to_i <= INFO.to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
def warning(context_id, *message)
|
34
|
+
add(context_id, WARN, message) if @log_level.to_i <= WARN.to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
def error(context_id, *message)
|
38
|
+
add(context_id, ERROR, message) if @log_level.to_i <= ERROR.to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
def fatal(context_id, *message)
|
42
|
+
add(context_id, FATAL, message) if @log_level.to_i <= FATAL.to_i
|
43
|
+
end
|
44
|
+
|
45
|
+
def unknown(context_id, *message)
|
46
|
+
add(context_id, UNKNOWN, message) if @log_level.to_i <= UNKNOWN.to_i
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def add(context_id, severity, *message)
|
52
|
+
return unless @enable
|
53
|
+
log_record = LogFactory.new_log_record(self, context_id, severity, message)
|
54
|
+
@log_manager.add_log(log_record)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: RTALogger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Babak Bahreini, RTA Backend Team
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-11-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fluentd
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.11'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.11.4
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.11'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.11.4
|
33
|
+
description: RTA Log Manager has been designed and implemented to provide standard
|
34
|
+
logging API for developers.This prevents chaos in log data format. Also provide
|
35
|
+
multiple extendable log repositories including wrapping existing loggers, like 'Fluentd'
|
36
|
+
or implement completely new custom logger. All main features of log manager are
|
37
|
+
configeable through a json config file.
|
38
|
+
email:
|
39
|
+
- b.bahreini@roundtableapps.com
|
40
|
+
executables: []
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- ".gitignore"
|
45
|
+
- ".rspec"
|
46
|
+
- ".travis.yml"
|
47
|
+
- Gemfile
|
48
|
+
- Gemfile.lock
|
49
|
+
- LICENSE.txt
|
50
|
+
- README.md
|
51
|
+
- RTALogger.gemspec
|
52
|
+
- Rakefile
|
53
|
+
- bin/console
|
54
|
+
- bin/setup
|
55
|
+
- lib/RTALogger.rb
|
56
|
+
- lib/RTALogger/version.rb
|
57
|
+
- lib/factory/origin/log_factory_file_logger.rb
|
58
|
+
- lib/factory/origin/log_factory_log_formatter.rb
|
59
|
+
- lib/factory/origin/log_factory_manager.rb
|
60
|
+
- lib/factory/origin/log_factory_propagator.rb
|
61
|
+
- lib/factory/origin/log_factory_record.rb
|
62
|
+
- lib/factory/origin/log_factory_repository.rb
|
63
|
+
- lib/factory/origin/log_factory_topic.rb
|
64
|
+
- lib/log_formatter.rb
|
65
|
+
- lib/log_formatter_json.rb
|
66
|
+
- lib/log_formatter_text.rb
|
67
|
+
- lib/log_manager.rb
|
68
|
+
- lib/log_propagator.rb
|
69
|
+
- lib/log_record.rb
|
70
|
+
- lib/log_repository.rb
|
71
|
+
- lib/log_repository_console.rb
|
72
|
+
- lib/log_repository_file.rb
|
73
|
+
- lib/log_repository_udp.rb
|
74
|
+
- lib/log_severity.rb
|
75
|
+
- lib/log_test.rb
|
76
|
+
- lib/log_test_db.rb
|
77
|
+
- lib/log_topic.rb
|
78
|
+
homepage: https://github.com/BBahrainy/RTALogger.git
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata:
|
82
|
+
allowed_push_host: https://www.rubygems.org
|
83
|
+
homepage_uri: https://github.com/BBahrainy/RTALogger.git
|
84
|
+
source_code_uri: https://github.com/BBahrainy/RTALogger.git
|
85
|
+
changelog_uri: https://github.com/BBahrainy/RTALogger.git
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 2.3.0
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubygems_version: 3.0.8
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: An easy to use, easy to extend log manager to prepare standard log API for
|
105
|
+
developers
|
106
|
+
test_files: []
|