la_logger 0.0.1
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.
- checksums.yaml +15 -0
- data/.rspec +2 -0
- data/Gemfile +13 -0
- data/Procfile +1 -0
- data/README.md +35 -0
- data/benchmark/singleton.rb +36 -0
- data/config/fluent.conf +49 -0
- data/la_logger.gemspec +20 -0
- data/lib/la_logger/version.rb +6 -0
- data/lib/la_logger.rb +57 -0
- data/spec/helpers/io_helper.rb +30 -0
- data/spec/helpers/mongo_helper.rb +26 -0
- data/spec/la_logger_spec.rb +75 -0
- data/spec/spec_helper.rb +10 -0
- data/tuser.rb +21 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MmMzNjQ0YTZhMWFmYTYxMDI3MmUzODYxM2VmNWZiNDFhMjBkZWY3NA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZmNiOTRjOGIyODdlYjdmMWI4NjIwMWZiYTJkNGJmNzA3MmVjMGNkMw==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NTZhNmZkMmFkMzYzMTliNDMzYmUyNzQyYTg2N2YxN2ZiN2U2MTIzMWE5Nzkz
|
10
|
+
MmM5NmExYjljMTExNWM1YzI0NmY1YjA2NzUwZDVhNTM4ODBjMTk4NmQ0OWUw
|
11
|
+
ZWVmZjEwMzJhOGIyNTE4NmUwODdiMzRhY2Q4ZDYzNTgwYmRmYTU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YzI2ZTA2YWMyNDdhMjFlM2Q1NGNiNjliMDY1Y2ZkMWYxZWYxMzJkNjFhYTYz
|
14
|
+
YzZmM2VmZjk3ZjAwOTEwYmJhYzVkZDBlNDdiNjE3MThlMDAxMGJmYTQxMDMw
|
15
|
+
MDhiYzY3MmFlYjUxODcyOWRlMjM1ODFkMTI5Yjk5ODc5NWJlYWI=
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Procfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
logger: fluentd -c config/fluent.conf
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# LaLogger: A general logger module wraps Fluentd-logger
|
2
|
+
|
3
|
+
Require: ruby 1.9.x, fluent-logger (not working on JRuby without modification).
|
4
|
+
|
5
|
+
## Concepts
|
6
|
+
|
7
|
+
- Include into any class, expose a singleton logger object and `log_xxx` functions:
|
8
|
+
|
9
|
+
class LoggerUser
|
10
|
+
def logger
|
11
|
+
# initialize tag and log level, default level is 'WARN'
|
12
|
+
LaLogger.new('la.logger.tag', LaLogger::ERROR)
|
13
|
+
end
|
14
|
+
|
15
|
+
def logger_this
|
16
|
+
logger.error('oops! an error happend!', {extra: 'data'})
|
17
|
+
logger.post('custom.tag', {custom: 'message'})
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
- Silently fails-over to `STDOUT` if `ENV['FLUENTD']` not defined.
|
22
|
+
|
23
|
+
To use fluentd service, define: `ENV[FLUENTD] = 'localhost:24224'`
|
24
|
+
somewhere in your code before use the logger. Default port `24224` is optional.
|
25
|
+
|
26
|
+
You can use an additional `ENV['FLUENTD_TAG']` to initialize default tag for the
|
27
|
+
fluent-logger.
|
28
|
+
|
29
|
+
Note: as logger object is wrapped by a singleton class, there is no effect to
|
30
|
+
change this setting after logger object has created.
|
31
|
+
|
32
|
+
## Severities
|
33
|
+
|
34
|
+
Imported from ruby's default `Logger::Severity`, namely: `debug, info, warn, error,
|
35
|
+
fatal, unknown`.
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
3
|
+
require 'fluent-logger'
|
4
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
5
|
+
|
6
|
+
ENV['FLUENTD'] = 'localhost'
|
7
|
+
require 'la_logger'
|
8
|
+
|
9
|
+
n = 5000
|
10
|
+
Benchmark.bm do |x|
|
11
|
+
x.report('FluentLogger.new') do
|
12
|
+
n.times do
|
13
|
+
Fluent::Logger::FluentLogger.new(
|
14
|
+
nil, host: 'localhost', port: 24224
|
15
|
+
).post('la.logger1', {error: 'test message'})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
x.report('FluentLogger preload') do
|
20
|
+
logger = Fluent::Logger::FluentLogger.new(
|
21
|
+
nil, host: 'localhost', port: 24224
|
22
|
+
)
|
23
|
+
n.times do
|
24
|
+
logger.post('la.logger1', {error: 'test message'})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
x.report('LaLogger.new') do
|
29
|
+
n.times { LaLogger.new.error('la.logger3', 'test message') }
|
30
|
+
end
|
31
|
+
|
32
|
+
x.report('LaLogger preload') do
|
33
|
+
logger = LaLogger.new
|
34
|
+
n.times { logger.error('la.logger2', 'test message') }
|
35
|
+
end
|
36
|
+
end
|
data/config/fluent.conf
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
## built-in TCP input
|
3
|
+
## $ echo <json> | fluent-cat <tag>
|
4
|
+
<source>
|
5
|
+
type forward
|
6
|
+
</source>
|
7
|
+
|
8
|
+
## File input
|
9
|
+
## read apache logs with tag=apache.access
|
10
|
+
#<source>
|
11
|
+
# type tail
|
12
|
+
# format apache
|
13
|
+
# path /var/log/httpd-access.log
|
14
|
+
# tag apache.access
|
15
|
+
#</source>
|
16
|
+
|
17
|
+
# Listen HTTP for monitoring
|
18
|
+
# http://localhost:24220/api/plugins
|
19
|
+
# http://localhost:24220/api/plugins?type=TYPE
|
20
|
+
# http://localhost:24220/api/plugins?tag=MYTAG
|
21
|
+
<source>
|
22
|
+
type monitor_agent
|
23
|
+
port 24220
|
24
|
+
</source>
|
25
|
+
|
26
|
+
# Listen DRb for debug
|
27
|
+
# <source>
|
28
|
+
# type debug_agent
|
29
|
+
# port 24230
|
30
|
+
# </source>
|
31
|
+
|
32
|
+
<match la.**>
|
33
|
+
# plugin type
|
34
|
+
type mongo
|
35
|
+
|
36
|
+
# mongodb host + port
|
37
|
+
host localhost
|
38
|
+
port 27017
|
39
|
+
|
40
|
+
# mongodb db + collection
|
41
|
+
database lamancha_log
|
42
|
+
tag_mapped
|
43
|
+
collection default
|
44
|
+
|
45
|
+
remove_tag_prefix la.
|
46
|
+
|
47
|
+
# interval
|
48
|
+
flush_interval 1s
|
49
|
+
</match>
|
data/la_logger.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
require 'la_logger/version'
|
3
|
+
|
4
|
+
Gem::Specification.new 'la_logger', LaLogger::VERSION do |s|
|
5
|
+
s.description = 'A singleton wrapper for fluent logger object.'
|
6
|
+
s.summary = 'Wrap fluent logger as a singleton object, silently fail-over to STDOUT if fluentd service not defined.'
|
7
|
+
s.authors = ['Huang Wei']
|
8
|
+
s.email = 'huangw@7lime.com'
|
9
|
+
s.homepage = 'https://github.com/7lime/la_logger-gem'
|
10
|
+
s.files = `git ls-files`.split("\n") - %w[.gitignore Rakefile]
|
11
|
+
s.license = 'MIT'
|
12
|
+
s.test_files = Dir.glob('{spec,test}/**/*.rb')
|
13
|
+
|
14
|
+
s.add_dependency 'fluent-logger'
|
15
|
+
s.add_development_dependency 'rspec', '~> 2.5'
|
16
|
+
s.add_development_dependency 'mongo'
|
17
|
+
s.add_development_dependency 'bson_ext'
|
18
|
+
s.add_development_dependency 'simplecov', '~> 2.5'
|
19
|
+
end
|
20
|
+
|
data/lib/la_logger.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'singleton'
|
5
|
+
require 'fluent-logger'
|
6
|
+
require 'logger'
|
7
|
+
|
8
|
+
# LaLogger: wraper for fluent-logger
|
9
|
+
class LaLogger
|
10
|
+
extend Forwardable
|
11
|
+
include Logger::Severity
|
12
|
+
|
13
|
+
attr_accessor :tag, :level
|
14
|
+
|
15
|
+
# singleton logger object
|
16
|
+
class Logger
|
17
|
+
include Singleton
|
18
|
+
attr_reader :logger
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
if ENV['FLUENTD']
|
22
|
+
host_, port_ = ENV['FLUENTD'].split ':'
|
23
|
+
host_ ||= 'localhost'
|
24
|
+
port_ ||= 24224
|
25
|
+
@logger = Fluent::Logger::FluentLogger.new(
|
26
|
+
ENV['FLUENTD_TAG'], host: host_.to_s, port: port_.to_i
|
27
|
+
)
|
28
|
+
else
|
29
|
+
@logger = Fluent::Logger::ConsoleLogger.open($stderr)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# initialize a la_logger object, with a singleton internal @logger
|
35
|
+
def initialize(tag = nil, level = nil)
|
36
|
+
@tag = tag
|
37
|
+
@level = level || WARN
|
38
|
+
end
|
39
|
+
|
40
|
+
# getter for the singleton logger
|
41
|
+
def logger
|
42
|
+
@logger ||= Logger.instance.logger
|
43
|
+
end
|
44
|
+
|
45
|
+
# define 6 log methods
|
46
|
+
[:debug, :info, :warn, :error,
|
47
|
+
:fatal, :unknown].each_with_index do |met, lvl|
|
48
|
+
define_method(met) do |message, tag = nil, data = {}|
|
49
|
+
data[met] = message || ''
|
50
|
+
tag ||= @tag
|
51
|
+
logger.post(tag, data) if @level <= lvl
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# use LaLogger.new.post() directly.
|
56
|
+
def_delegator :logger, :post
|
57
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# record stdout and stderr output as strings for testing against expectation
|
4
|
+
module IOHelper
|
5
|
+
def capture_stdout(&block)
|
6
|
+
original_stdout = $stdout
|
7
|
+
$stdout = fake = StringIO.new
|
8
|
+
begin
|
9
|
+
yield
|
10
|
+
rescue SystemExit
|
11
|
+
$stdout = original_stdout # fake rubocop
|
12
|
+
ensure
|
13
|
+
$stdout = original_stdout
|
14
|
+
end
|
15
|
+
fake.string
|
16
|
+
end
|
17
|
+
|
18
|
+
def capture_stderr(&block)
|
19
|
+
original_stdout = $stderr
|
20
|
+
$stderr = fake = StringIO.new
|
21
|
+
begin
|
22
|
+
yield
|
23
|
+
rescue SystemExit
|
24
|
+
$stdout = original_stdout # fake rubocop
|
25
|
+
ensure
|
26
|
+
$stderr = original_stdout
|
27
|
+
end
|
28
|
+
fake.string
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
include Mongo
|
3
|
+
|
4
|
+
# require 'bson_ext'
|
5
|
+
|
6
|
+
module MongoHelper
|
7
|
+
def db
|
8
|
+
MongoClient.new('localhost', 27017).db('lamancha_log')
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_last_logs(col)
|
12
|
+
db.collection(col).find({}, { limit: 5 }).sort(time: :desc).to_a
|
13
|
+
end
|
14
|
+
|
15
|
+
def cleanup
|
16
|
+
db.collections.each { |c| c.drop }
|
17
|
+
end
|
18
|
+
|
19
|
+
def has_log(tag, level, value)
|
20
|
+
sleep 2
|
21
|
+
get_last_logs(tag).each do |ld|
|
22
|
+
return true if ld[level] == value
|
23
|
+
end
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
ENV['FLUENTD'] = 'localhost'
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'la_logger'
|
5
|
+
|
6
|
+
#require 'helpers/io_helper'
|
7
|
+
#include IOHelper
|
8
|
+
|
9
|
+
require 'helpers/mongo_helper'
|
10
|
+
include MongoHelper
|
11
|
+
|
12
|
+
# first test class
|
13
|
+
class UserA
|
14
|
+
def logger
|
15
|
+
@logger ||= LaLogger.new('la.user_a', LaLogger::INFO)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_log_error(msg = 'error message from A')
|
19
|
+
logger.error(msg)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_log_info(msg = 'info message from A')
|
23
|
+
logger.info(msg)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# second test class
|
28
|
+
class UserB
|
29
|
+
def logger
|
30
|
+
@logger ||= LaLogger.new('la.user_b')
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_log_error(msg = 'error message from B')
|
34
|
+
logger.error(msg)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_log_info(msg = 'info message from B')
|
38
|
+
logger.info(msg)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe LaLogger do
|
43
|
+
describe 'singleton' do
|
44
|
+
it 'same logger globally' do
|
45
|
+
LaLogger.new.logger.equal?(LaLogger.new.logger).should be_true
|
46
|
+
LaLogger.new.logger.equal?(UserA.new.logger.logger).should be_true
|
47
|
+
UserB.new.logger.logger.equal?(UserA.new.logger.logger).should be_true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'default level' do
|
52
|
+
it 'log error messages' do
|
53
|
+
LaLogger.new('la.global').error('error message from global')
|
54
|
+
has_log('global', 'error', 'error message from global').should be_true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'through class' do
|
59
|
+
it 'record error for both A and B' do
|
60
|
+
UserA.new.test_log_error('through a test')
|
61
|
+
has_log('user_a', 'error', 'through a test').should be_true
|
62
|
+
UserB.new.test_log_error('through b test')
|
63
|
+
has_log('user_b', 'error', 'through b test').should be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'record info only for A' do
|
67
|
+
UserA.new.test_log_info('info through a test')
|
68
|
+
has_log('user_a', 'info', 'info through a test').should be_true
|
69
|
+
UserB.new.test_log_info('info through b test')
|
70
|
+
has_log('user_b', 'info', 'info through b test').should be_false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
after(:all) { cleanup }
|
75
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/tuser.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__)) + '/lib'
|
2
|
+
|
3
|
+
require 'la_logger'
|
4
|
+
|
5
|
+
LaLogger.logger.post('La', {message: 'La Mon'})
|
6
|
+
|
7
|
+
class User
|
8
|
+
include LaLogger
|
9
|
+
|
10
|
+
def say
|
11
|
+
log_error('An error occured.')
|
12
|
+
end
|
13
|
+
|
14
|
+
def say_other
|
15
|
+
logger_init('La Mancha')
|
16
|
+
log_error('Error occured again.')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
User.new.say
|
21
|
+
User.new.say_other
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: la_logger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Huang Wei
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-09-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fluent-logger
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mongo
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bson_ext
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.5'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.5'
|
83
|
+
description: A singleton wrapper for fluent logger object.
|
84
|
+
email: huangw@7lime.com
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- .rspec
|
90
|
+
- Gemfile
|
91
|
+
- Procfile
|
92
|
+
- README.md
|
93
|
+
- benchmark/singleton.rb
|
94
|
+
- config/fluent.conf
|
95
|
+
- la_logger.gemspec
|
96
|
+
- lib/la_logger.rb
|
97
|
+
- lib/la_logger/version.rb
|
98
|
+
- spec/helpers/io_helper.rb
|
99
|
+
- spec/helpers/mongo_helper.rb
|
100
|
+
- spec/la_logger_spec.rb
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
- tuser.rb
|
103
|
+
homepage: https://github.com/7lime/la_logger-gem
|
104
|
+
licenses:
|
105
|
+
- MIT
|
106
|
+
metadata: {}
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 2.0.6
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: Wrap fluent logger as a singleton object, silently fail-over to STDOUT if
|
127
|
+
fluentd service not defined.
|
128
|
+
test_files:
|
129
|
+
- spec/helpers/io_helper.rb
|
130
|
+
- spec/helpers/mongo_helper.rb
|
131
|
+
- spec/la_logger_spec.rb
|
132
|
+
- spec/spec_helper.rb
|