vx-lib-logger 0.2.2 → 0.3.0

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
  SHA1:
3
- metadata.gz: 3126654f08b375c07b2f7ee34c7b00fcc5f18925
4
- data.tar.gz: a61a2a2730ac7978a294156fdf286e79c3191b4f
3
+ metadata.gz: 64c86508190e0c1df39d9df46c9a0914c4494b14
4
+ data.tar.gz: 67a98127683d996e8f4eae7412ef93871b40bdab
5
5
  SHA512:
6
- metadata.gz: 5473e79262d2851f91cb2c07711d6320f8e9a450ec7a1e98f27a3d661059be1d332d2ec8ad777342ea0ce7591dc1e820694ac05f95071c9c05cd7e961906cbad
7
- data.tar.gz: bba481584c45077e8563fecb3112b4bee9ea1118b7d38576d76db658b484ecdafdd75208c2f994860eb1cf2b7687417fa138cf3f91f6402c8ed3778eafa17e93
6
+ metadata.gz: 0ac21b0568bc6111366d950189fde48ff664f03b7e5c154f041ec25c1d15d54a40bd7c7a26e081f61f9b01fff3c6d7c60a62b25d8f671980edf74e870c1c756f
7
+ data.tar.gz: 983a53898174f7446157eca899a6c997b1a6c4ffde45f34a4bfae3db7adb3a671a95859a8efba04b595238a7544dfd7597e47ff0bf74e8c23105f6330715f57f
data/lib/vx/lib/logger.rb CHANGED
@@ -4,25 +4,41 @@ require File.expand_path("../logger/version", __FILE__)
4
4
  module Vx ; module Lib
5
5
  module Logger
6
6
 
7
- autoload :Instance, File.expand_path("../logger/instance", __FILE__)
7
+ autoload :LogstashDevice, File.expand_path("../logger/logstash_device", __FILE__)
8
8
  autoload :StdoutFormatter, File.expand_path("../logger/stdout_formatter", __FILE__)
9
- autoload :JournalFormatter, File.expand_path("../logger/journal_formatter", __FILE__)
10
- autoload :Logstash, File.expand_path("../logger/logstash", __FILE__)
11
- autoload :Sanitizer, File.expand_path("../logger/sanitizer", __FILE__)
9
+ autoload :LogstashFormatter,File.expand_path("../logger/logstash_formatter",__FILE__)
10
+ autoload :BaseLogger, File.expand_path("../logger/base_logger", __FILE__)
11
+ autoload :StdoutLogger, File.expand_path("../logger/stdout_logger", __FILE__)
12
+ autoload :LogstashLogger, File.expand_path("../logger/logstash_logger", __FILE__)
12
13
 
13
14
  module Rack
14
15
  autoload :HandleExceptions, File.expand_path("../logger/rack/handle_exceptions", __FILE__)
15
16
  end
16
17
 
17
- @@logstash = Logstash.new
18
- @@default = Instance.new(STDOUT, logstash: @@logstash)
18
+ @@progname = $0 && File.basename($0)
19
+ @@default = nil
20
+ @@logstash_device = nil
19
21
 
20
- def self.get(io = nil, options = {})
21
- Instance.new(io || STDOUT, options.merge(logstash: @@logstash))
22
+ def self.progname=(value)
23
+ @@progname = value
22
24
  end
23
25
 
24
- def self.default
25
- @@default
26
+ def self.progname
27
+ @@progname
28
+ end
29
+
30
+ def self.logstash_device
31
+ @@logstash_device ||= LogstashDevice.new
32
+ end
33
+
34
+ def self.get
35
+ @@default ||= begin
36
+ if logstash_device.enabled?
37
+ LogstashLogger.new
38
+ else
39
+ StdoutLogger.new(STDOUT)
40
+ end
41
+ end
26
42
  end
27
43
 
28
44
  def self.install_handle_exceptions_middleware
@@ -0,0 +1,111 @@
1
+ module Vx ; module Lib ; module Logger
2
+
3
+ class BaseLogger
4
+
5
+ def formatter
6
+ @formatter ||= ->(_,_,_,m) { m }
7
+ end
8
+
9
+ def formatter=(val) ; end
10
+
11
+ def progname
12
+ Lib::Logger.progname
13
+ end
14
+
15
+ def progname=(val)
16
+ Lib::Logger.progname = val
17
+ end
18
+
19
+ def level
20
+ @logger.level
21
+ end
22
+
23
+ def level=(new_val)
24
+ @logger.level = new_val
25
+ end
26
+
27
+ [:fatal, :warn, :debug, :error, :info].each do |m|
28
+ define_method m do |*args|
29
+ process_message(m, *args)
30
+ end
31
+
32
+ define_method :"#{m}?" do
33
+ @logger.public_send :"#{m}?"
34
+ end
35
+ end
36
+
37
+ def handle(message, options = {})
38
+ be = Time.now.to_f
39
+ re = nil
40
+ ex = nil
41
+
42
+ begin
43
+ re = yield options
44
+ rescue Exception => e
45
+ ex = e
46
+ end
47
+
48
+ en = Time.now.to_f
49
+ options.merge!(duration: (en - be))
50
+
51
+ if ex
52
+ error message, options.merge!(exception: ex) if ex
53
+ raise ex
54
+ else
55
+ info message, options
56
+ end
57
+
58
+ re
59
+ end
60
+
61
+ private
62
+
63
+ def process_message(level, message, fields = {})
64
+
65
+ if fields[:exception] && fields[:exception].is_a?(Exception)
66
+ ex = fields.delete(:exception)
67
+ fields.merge!(
68
+ exception: [ex.class.to_s, ex.message].join(" - "),
69
+ backtrace: (ex.backtrace || []).map(&:to_s).join("\n"),
70
+ )
71
+ end
72
+
73
+ payload = {
74
+ thread_id: ::Thread.current.object_id,
75
+ }
76
+
77
+ if fields && fields != {}
78
+
79
+ duration = fields.delete(:duration)
80
+ if duration && duration.respond_to?(:to_f)
81
+ payload.merge!(duration: duration.to_f)
82
+ end
83
+
84
+ payload.merge!(
85
+ fields: sanitize_hash(fields)
86
+ )
87
+ end
88
+
89
+ @logger.public_send level, format_message(level, message, payload)
90
+ end
91
+
92
+ def sanitize_hash(payload)
93
+ payload = {} unless payload.is_a?(Hash)
94
+
95
+ payload.keys.each do |key_name|
96
+ value = payload[key_name]
97
+ unless value.is_a?(String)
98
+ payload[key_name] = value.to_s
99
+ end
100
+ end
101
+
102
+ payload
103
+ end
104
+
105
+ def format_message(level, message, payload)
106
+ raise NotImplementedError
107
+ end
108
+
109
+ end
110
+
111
+ end ; end ; end
@@ -4,7 +4,7 @@ require 'thread'
4
4
 
5
5
  module Vx ; module Lib ; module Logger
6
6
 
7
- class Logstash
7
+ class LogstashDevice
8
8
 
9
9
  def initialize
10
10
  @mutex = Mutex.new
@@ -58,7 +58,7 @@ module Vx ; module Lib ; module Logger
58
58
  end
59
59
 
60
60
  def warn(msg)
61
- $stderr.puts msg
61
+ $stderr.puts "[warn ] #{msg}"
62
62
  end
63
63
 
64
64
  def with_connection(&block)
@@ -77,7 +77,6 @@ module Vx ; module Lib ; module Logger
77
77
 
78
78
  def connect
79
79
  @io = TCPSocket.new(host, port).tap do |socket|
80
- warn "#{self.class} - connect to #{uri.to_s}"
81
80
  socket.sync = true
82
81
  end
83
82
  end
@@ -2,7 +2,7 @@ require 'oj'
2
2
 
3
3
  module Vx ; module Lib ; module Logger
4
4
 
5
- module JournalFormatter
5
+ module LogstashFormatter
6
6
 
7
7
  @@exe = $PROGRAM_NAME
8
8
  @@gid = ::Process.gid
@@ -0,0 +1,35 @@
1
+ require 'json'
2
+ require 'thread'
3
+ require 'socket'
4
+
5
+ module Vx ; module Lib ; module Logger
6
+
7
+ class LogstashLogger < BaseLogger
8
+
9
+ attr_reader :params, :logger, :logstash
10
+
11
+ def initialize(params = {})
12
+ @params = params
13
+
14
+ @logger = ::Logger.new(logstash_device)
15
+ @logger.formatter = self.formatter
16
+ @logger.progname = self.progname
17
+ end
18
+
19
+ def close
20
+ logstash_device.close
21
+ end
22
+
23
+ private
24
+
25
+ def logstash_device
26
+ Lib::Logger.logstash_device
27
+ end
28
+
29
+ def format_message(level, message, payload)
30
+ LogstashFormatter.call(level, progname, message, payload)
31
+ end
32
+
33
+ end
34
+
35
+ end ; end ; end
@@ -16,7 +16,7 @@ module Vx ; module Lib ; module Logger
16
16
 
17
17
  def notify(exception, env)
18
18
  unless ignore?(exception)
19
- Lib::Logger.default.fatal(
19
+ Lib::Logger.get.fatal(
20
20
  "Unhandled exception: #{exception.class} - #{exception.message}",
21
21
  clean_env(env).merge(exception: exception)
22
22
  )
@@ -2,18 +2,6 @@ module Vx ; module Lib ; module Logger
2
2
 
3
3
  module Sanitizer
4
4
 
5
- def self.hash(payload)
6
- payload = {} unless payload.is_a?(Hash)
7
-
8
- payload.keys.each do |key_name|
9
- value = payload[key_name]
10
- unless value.is_a?(String)
11
- payload[key_name] = value.to_s
12
- end
13
- end
14
-
15
- payload
16
- end
17
5
 
18
6
  end
19
7
 
@@ -5,8 +5,17 @@ module Vx ; module Lib ; module Logger
5
5
  module StdoutFormatter
6
6
 
7
7
  def self.call(level, message, payload)
8
- payload = ::Oj.dump(payload, mode: :compat)
9
- "[#{level}] #{message} :--: #{payload}\n"
8
+ if payload[:fields] && payload[:fields] != {}
9
+ payload = " " + ::Oj.dump(payload[:fields], mode: :compat)
10
+ else
11
+ payload = ""
12
+ end
13
+
14
+ if level.length < 5
15
+ level = "#{level} "
16
+ end
17
+
18
+ "[#{level}] #{message}#{payload}\n"
10
19
  end
11
20
 
12
21
  end
@@ -0,0 +1,27 @@
1
+ require 'json'
2
+ require 'thread'
3
+ require 'socket'
4
+
5
+ module Vx ; module Lib ; module Logger
6
+
7
+ class StdoutLogger < BaseLogger
8
+
9
+ attr_reader :params, :logger, :logstash
10
+
11
+ def initialize(io, params = {})
12
+ @params = params
13
+
14
+ @logger = ::Logger.new(io, 7, 50_000_000)
15
+ @logger.formatter = self.formatter
16
+ @logger.progname = self.progname
17
+ end
18
+
19
+ private
20
+
21
+ def format_message(level, message, payload)
22
+ StdoutFormatter.call(level, message, payload)
23
+ end
24
+
25
+ end
26
+
27
+ end ; end ; end
@@ -1,7 +1,7 @@
1
1
  module Vx
2
2
  module Lib
3
3
  module Logger
4
- VERSION = "0.2.2"
4
+ VERSION = "0.3.0"
5
5
  end
6
6
  end
7
7
  end
@@ -1,14 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Vx::Lib::Logger do
4
- it "should get a new instance" do
4
+ it "should get a new instance of stdout logger" do
5
5
  inst = Vx::Lib::Logger.get
6
6
  assert inst
7
7
  end
8
8
 
9
- it "should get default instance" do
10
- inst = Vx::Lib::Logger.default
11
- assert inst
12
- end
13
-
14
9
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Vx::Lib::Logger::Logstash do
3
+ describe Vx::Lib::Logger::LogstashDevice do
4
4
 
5
5
  before do
6
6
  ENV['LOGSTASH_HOST'] = 'localhost:9999'
@@ -12,7 +12,7 @@ describe Vx::Lib::Logger::Logstash do
12
12
 
13
13
  it "should successfuly connect" do
14
14
  re = with_socket do
15
- log = Vx::Lib::Logger::Logstash.new
15
+ log = Vx::Lib::Logger::LogstashDevice.new
16
16
  log.write("Hello\n")
17
17
  log.close
18
18
  end
@@ -20,7 +20,7 @@ describe Vx::Lib::Logger::Logstash do
20
20
  end
21
21
 
22
22
  it "should successfuly lost connection" do
23
- log = Vx::Lib::Logger::Logstash.new
23
+ log = Vx::Lib::Logger::LogstashDevice.new
24
24
 
25
25
  re = with_socket do
26
26
  log.write("Hello\n")
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Vx::Lib::Logger::LogstashLogger do
4
+
5
+ before do
6
+ ENV['LOGSTASH_HOST'] = 'localhost:9999'
7
+
8
+ @log = Vx::Lib::Logger::LogstashLogger.new
9
+ assert @log
10
+ end
11
+
12
+ after do
13
+ ENV['LOGSTASH_HOST'] = nil
14
+ end
15
+
16
+ [:fatal, :warn, :debug, :error, :info].each do |m|
17
+ it "should write #{m} message" do
18
+ re = with_socket do
19
+ @log.public_send(m, "send #{m}")
20
+ @log.close
21
+ end
22
+ assert_match(/send #{m}/, re)
23
+ end
24
+ end
25
+
26
+ it "should write message with params" do
27
+ re = with_socket do
28
+ @log.info "text message", param: :value
29
+ @log.close
30
+ end
31
+ assert_match(/text message/, re)
32
+ assert_match(/"param":/, re)
33
+ assert_match(/:"value"/, re)
34
+ end
35
+
36
+ it "should write message with exception in params" do
37
+ re = with_socket do
38
+ @log.info "text message", exception: Exception.new("got!")
39
+ @log.close
40
+ end
41
+ assert_match(/text message/, re)
42
+ assert_match(/"exception":/, re)
43
+ assert_match(/:"Exception - got!"/, re)
44
+ end
45
+
46
+ it "should dump invalid unicode key" do
47
+ re = with_socket do
48
+ @log.info "Le Caf\xc3\xa9 \xa9", key: "Le Caf\xc3\xa9 \xa9"
49
+ @log.close
50
+ end
51
+ assert_match(/Le Caf/, re)
52
+ end
53
+
54
+ end
@@ -2,25 +2,26 @@ require 'spec_helper'
2
2
 
3
3
  require 'stringio'
4
4
 
5
- describe Vx::Lib::Logger::Instance do
5
+ describe Vx::Lib::Logger::StdoutLogger do
6
6
 
7
7
  before do
8
8
  @out = StringIO.new
9
- @log = Vx::Lib::Logger.get(@out)
9
+ @log = Vx::Lib::Logger::StdoutLogger.new(@out)
10
10
  assert @log
11
11
  end
12
12
 
13
13
  [:fatal, :warn, :debug, :error, :info].each do |m|
14
14
  it "should write #{m} message" do
15
15
  @log.public_send(m, "send #{m}")
16
- text = "[#{m}] send #{m} :--: {\"thread_id\":#{tid}}\n"
16
+ level = m.length < 5 ? "#{m} " : m
17
+ text = "[#{level}] send #{m}\n"
17
18
  assert_equal text, get_out
18
19
  end
19
20
  end
20
21
 
21
22
  it "should write message with params" do
22
23
  @log.info "text message", param: :value
23
- text = "[info] text message :--: {\"thread_id\":#{tid},\"fields\":{\"param\":\"value\"}}\n"
24
+ text = "[info ] text message {\"param\":\"value\"}\n"
24
25
  assert_equal text, get_out
25
26
  end
26
27
 
@@ -31,7 +32,7 @@ describe Vx::Lib::Logger::Instance do
31
32
 
32
33
  it "should write message with exception in params" do
33
34
  @log.info "text message", exception: Exception.new("got!")
34
- text = "[info] text message :--: {\"thread_id\":#{tid},\"fields\":{\"exception\":\"Exception - got!\",\"backtrace\":\"\"}}\n"
35
+ text = "[info ] text message {\"exception\":\"Exception - got!\",\"backtrace\":\"\"}\n"
35
36
  assert_equal text, get_out
36
37
  end
37
38
 
@@ -39,7 +40,7 @@ describe Vx::Lib::Logger::Instance do
39
40
  @log.handle "text message" do
40
41
  sleep 0.1
41
42
  end
42
- assert_match(/duration/, get_out)
43
+ assert_match(/text message/, get_out)
43
44
 
44
45
  begin
45
46
  @log.handle "text message", key: :value do
@@ -49,7 +50,6 @@ describe Vx::Lib::Logger::Instance do
49
50
  end
50
51
 
51
52
  body = get_out
52
- assert_match(/duration/, body)
53
53
  assert_match(/key/, body)
54
54
  assert_match(/value/, body)
55
55
  assert_match(/got\!/, body)
@@ -58,24 +58,10 @@ describe Vx::Lib::Logger::Instance do
58
58
 
59
59
  it "should dump invalid unicode key" do
60
60
  @log.info "Le Caf\xc3\xa9 \xa9", key: "Le Caf\xc3\xa9 \xa9"
61
- text = "[info] Le Café \xA9 :--: {\"thread_id\":#{tid},\"fields\":{\"key\":\"Le Café \xA9\"}}\n"
61
+ text = "[info ] Le Café \xA9 {\"key\":\"Le Café \xA9\"}\n"
62
62
  assert_equal text, get_out
63
63
  end
64
64
 
65
- it "should write message with logstash" do
66
- begin
67
- ENV['LOGSTASH_HOST'] = 'localhost:9999'
68
- log = Vx::Lib::Logger.get(@out)
69
- re = with_socket do
70
- log.info "Hello"
71
- end
72
- assert_match(/Hello/, re)
73
- assert_match(/Hello/, get_out)
74
- ensure
75
- ENV['LOGSTASH_HOST'] = nil
76
- end
77
- end
78
-
79
65
  def get_out
80
66
  @out.rewind
81
67
  body = @out.read
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vx-lib-logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Galinsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-04 00:00:00.000000000 Z
11
+ date: 2015-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -65,17 +65,20 @@ files:
65
65
  - README.md
66
66
  - Rakefile
67
67
  - lib/vx/lib/logger.rb
68
- - lib/vx/lib/logger/instance.rb
69
- - lib/vx/lib/logger/journal_formatter.rb
70
- - lib/vx/lib/logger/logstash.rb
68
+ - lib/vx/lib/logger/base_logger.rb
69
+ - lib/vx/lib/logger/logstash_device.rb
70
+ - lib/vx/lib/logger/logstash_formatter.rb
71
+ - lib/vx/lib/logger/logstash_logger.rb
71
72
  - lib/vx/lib/logger/rack/handle_exceptions.rb
72
73
  - lib/vx/lib/logger/sanitizer.rb
73
74
  - lib/vx/lib/logger/stdout_formatter.rb
75
+ - lib/vx/lib/logger/stdout_logger.rb
74
76
  - lib/vx/lib/logger/version.rb
75
- - spec/lib/instance_spec.rb
76
77
  - spec/lib/logger_spec.rb
77
- - spec/lib/logstash_spec.rb
78
+ - spec/lib/logstash_device_spec.rb
79
+ - spec/lib/logstash_logger_spec.rb
78
80
  - spec/lib/rack_handle_exceptions_spec.rb
81
+ - spec/lib/stdout_logger_spec.rb
79
82
  - spec/spec_helper.rb
80
83
  - vexor.yml
81
84
  - vx-lib-logger.gemspec
@@ -104,8 +107,9 @@ signing_key:
104
107
  specification_version: 4
105
108
  summary: summary
106
109
  test_files:
107
- - spec/lib/instance_spec.rb
108
110
  - spec/lib/logger_spec.rb
109
- - spec/lib/logstash_spec.rb
111
+ - spec/lib/logstash_device_spec.rb
112
+ - spec/lib/logstash_logger_spec.rb
110
113
  - spec/lib/rack_handle_exceptions_spec.rb
114
+ - spec/lib/stdout_logger_spec.rb
111
115
  - spec/spec_helper.rb
@@ -1,134 +0,0 @@
1
- require 'json'
2
- require 'thread'
3
- require 'socket'
4
-
5
- module Vx ; module Lib ; module Logger
6
-
7
- class Instance
8
-
9
- attr_reader :params, :logger, :logstash
10
-
11
- def initialize(io, params = {})
12
- @logstash = params.delete(:logstash)
13
- @params = params
14
-
15
- @progname = @params.delete(:progname)
16
-
17
- @progname ||= begin
18
- pname = $PROGRAM_NAME
19
- pname && File.basename(pname)
20
- end
21
-
22
- @formatter = ->(_,_,_,m) { m }
23
-
24
- @logger = ::Logger.new(io, 7, 50_000_000)
25
- @logger.formatter = @formatter
26
- @logger.progname = @progname
27
-
28
- @logstash_logger = ::Logger.new(logstash)
29
- @logstash_logger.formatter = @formatter
30
- @logstash_logger.progname = @progname
31
- end
32
-
33
- [:fatal, :warn, :debug, :error, :info].each do |m|
34
- define_method m do |*args|
35
- process_message(m, *args)
36
- end
37
-
38
- define_method :"#{m}?" do
39
- @logger.public_send :"#{m}?"
40
- end
41
- end
42
-
43
- def level
44
- @logger.level
45
- end
46
-
47
- def level=(new_val)
48
- @logger.level = new_val
49
- @logstash_logger.level = new_val
50
- end
51
-
52
- def progname=(new_val)
53
- @progname = new_val
54
- end
55
-
56
- def formatter ; nil ; end
57
- def formatter=(val) ; nil ; end
58
-
59
- def handle(message, options = {})
60
- be = Time.now.to_f
61
- re = nil
62
- ex = nil
63
-
64
- begin
65
- re = yield options
66
- rescue Exception => e
67
- ex = e
68
- end
69
-
70
- en = Time.now.to_f
71
- options.merge!(duration: (en - be))
72
-
73
- if ex
74
- error message, options.merge!(exception: ex) if ex
75
- raise ex
76
- else
77
- info message, options
78
- end
79
-
80
- re
81
- end
82
-
83
- private
84
-
85
- def process_message(level, message, options = {})
86
-
87
- if level.to_s == 'fatal'
88
- puts caller.inspect
89
- end
90
-
91
- if options[:exception] && options[:exception].is_a?(Exception)
92
- ex = options.delete(:exception)
93
- options.merge!(
94
- exception: [ex.class.to_s, ex.message].join(" - "),
95
- backtrace: (ex.backtrace || []).map(&:to_s).join("\n"),
96
- )
97
- end
98
-
99
- body = {
100
- thread_id: ::Thread.current.object_id,
101
- }
102
-
103
- if options && options != {}
104
-
105
- duration = options.delete(:duration)
106
- if duration && duration.respond_to?(:to_f)
107
- body.merge!(duration: duration.to_f)
108
- end
109
-
110
- body.merge!(
111
- fields: Sanitizer.hash(options)
112
- )
113
- end
114
-
115
-
116
- @logger.public_send level, format_stdout(level, message, body)
117
-
118
- if logstash.enabled?
119
- @logstash_logger.public_send level, format_journal(level, message, body)
120
- end
121
- end
122
-
123
- def format_stdout(level, message, payload)
124
- StdoutFormatter.call(level, message, payload)
125
- end
126
-
127
- def format_journal(level, message, payload)
128
- JournalFormatter.call(level, @progname, message, payload)
129
-
130
- end
131
-
132
- end
133
-
134
- end ; end ; end