steno 1.2.4 → 1.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/NOTICE +14 -0
- data/Rakefile +6 -8
- data/bin/steno-prettify +24 -25
- data/lib/steno/codec/base.rb +1 -1
- data/lib/steno/codec/json.rb +24 -14
- data/lib/steno/codec.rb +2 -2
- data/lib/steno/config.rb +23 -30
- data/lib/steno/context.rb +3 -3
- data/lib/steno/json_prettifier.rb +31 -30
- data/lib/steno/log_level.rb +1 -2
- data/lib/steno/logger.rb +22 -26
- data/lib/steno/record.rb +5 -15
- data/lib/steno/sink/base.rb +2 -3
- data/lib/steno/sink/counter.rb +4 -8
- data/lib/steno/sink/eventlog.rb +16 -17
- data/lib/steno/sink/fluentd.rb +4 -5
- data/lib/steno/sink/io.rb +8 -12
- data/lib/steno/sink/syslog.rb +19 -15
- data/lib/steno/sink.rb +6 -6
- data/lib/steno/tagged_logger.rb +2 -3
- data/lib/steno/version.rb +1 -1
- data/lib/steno.rb +16 -21
- data/spec/spec_helper.rb +4 -4
- data/spec/support/barrier.rb +2 -2
- data/spec/support/shared_context_specs.rb +4 -4
- data/spec/unit/config_spec.rb +134 -133
- data/spec/unit/context_spec.rb +19 -19
- data/spec/unit/core_ext_spec.rb +14 -14
- data/spec/unit/json_codec_spec.rb +43 -23
- data/spec/unit/json_prettifier_spec.rb +25 -25
- data/spec/unit/log_level_spec.rb +8 -9
- data/spec/unit/logger_spec.rb +53 -53
- data/spec/unit/record_spec.rb +15 -15
- data/spec/unit/sink/counter_spec.rb +7 -7
- data/spec/unit/sink/eventlog_spec.rb +14 -15
- data/spec/unit/sink/fluentd_spec.rb +28 -28
- data/spec/unit/sink/io_spec.rb +62 -62
- data/spec/unit/sink/syslog_spec.rb +54 -30
- data/spec/unit/steno_spec.rb +33 -33
- data/spec/unit/tagged_logger_spec.rb +20 -18
- data/steno.gemspec +28 -28
- metadata +62 -53
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MzUzMjIwZTNjYTAzYWIyZDE2MmNmNTNiOTBkMzIzZmRiMDJmMGFkOQ==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 288b5abe607dd9f6bd602815ebc1886736196f0b0aa826d81e1c9cbc3785e142
|
4
|
+
data.tar.gz: 3684b30c332791771282d0cc35a3bd971ca4d709b388718727062c27ba255560
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZDRlYjY5NzEzMjA5NmI0NTQwMmE0MjBiNDBkNTc2NDQ2ZGIxZTVkNDhhNzA2
|
11
|
-
MDFiNWMxMjhhOTA2YzUyYzMxN2ZhMzk1YjZlYmIzYjdkZDk2ZjM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
Zjc3ZmVkY2QzNWZjZDUxYWNiYWQ5MWRhYjlkNjM2ZTg1Nzc0MDBhNWNlZWY4
|
14
|
-
ZDUzYjg1YWJiZDUxYzlkN2E0ZDg1NTk5YzMwMzdiMzRkMGZhNDdhOTMyMWUw
|
15
|
-
ZDE0YTVmNTBkZWI1MmNjNGEyNjgyOWI1YWQyYTRkNjgzNTFhZWY=
|
6
|
+
metadata.gz: d92167feac3ae2409d8692c13aabe84c66ca442d6573e68bbdeb76484ecde81c62bd28acc85bb3b6ea41f88ebccecea2ac62a3da2e3dd31492ed62bcf5d4ce83
|
7
|
+
data.tar.gz: cfbb78af6e114eeaf121d6ae1ca7a9b84bd625f1eedbf45c1beeb74706504134f4fc76207d26fb78bfdf30260d55a1dcbb83fb1898cab7b047fbacbd19164455
|
data/NOTICE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Steno
|
2
|
+
|
3
|
+
Copyright (c) 2015 - Present CloudFoundry.org Foundation, Inc. All Rights Reserved.
|
4
|
+
|
5
|
+
This project contains software that is Copyright (c) 2012-2015 Pivotal Software, Inc.
|
6
|
+
|
7
|
+
Other copyright notices for portions of this software are listed in the LICENSE file.
|
8
|
+
|
9
|
+
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
10
|
+
You may not use this product except in compliance with the License.
|
11
|
+
|
12
|
+
This product may include a number of subcomponents with separate copyright notices
|
13
|
+
and license terms. Your use of these subcomponents is subject to the terms and
|
14
|
+
conditions of the subcomponent's license, as noted in the LICENSE file.
|
data/Rakefile
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
|
-
require
|
3
|
-
require "rspec/core/rake_task"
|
2
|
+
require 'rspec/core/rake_task'
|
4
3
|
|
5
|
-
task :
|
4
|
+
task default: :spec
|
6
5
|
|
7
|
-
desc
|
8
|
-
RSpec::Core::RakeTask.new(
|
6
|
+
desc 'Run all specs'
|
7
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
9
8
|
t.rspec_opts = %w[--color --format documentation]
|
10
9
|
end
|
11
10
|
|
12
|
-
desc
|
13
|
-
RSpec::Core::RakeTask.new(
|
11
|
+
desc 'Run all specs and provide output for ci'
|
12
|
+
RSpec::Core::RakeTask.new('spec:ci' => 'ci:setup:rspec') do |t|
|
14
13
|
t.rspec_opts = %w[--no-color --format documentation]
|
15
14
|
end
|
16
|
-
|
data/bin/steno-prettify
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'optparse'
|
4
|
+
require 'yajl'
|
5
5
|
|
6
|
-
require
|
6
|
+
require 'steno/json_prettifier'
|
7
7
|
|
8
|
-
Signal.trap(
|
8
|
+
Signal.trap('INT') { exit }
|
9
9
|
|
10
10
|
def prettify_io(io, prettifier, ignore_parse_error = false)
|
11
11
|
lineno = 1
|
@@ -25,7 +25,7 @@ def prettify_io(io, prettifier, ignore_parse_error = false)
|
|
25
25
|
if ignore_parse_error
|
26
26
|
print line
|
27
27
|
else
|
28
|
-
|
28
|
+
warn "steno-prettify: Malformed json at line #{lineno}, '#{line.strip}'"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -35,14 +35,13 @@ end
|
|
35
35
|
|
36
36
|
def prettify_file(path, prettifier, ignore_parse_error = false)
|
37
37
|
begin
|
38
|
-
f = File.open(path,
|
39
|
-
rescue => e
|
40
|
-
|
38
|
+
f = File.open(path, 'r')
|
39
|
+
rescue StandardError => e
|
40
|
+
warn "steno-prettify: Failed opening '#{path}', #{e}"
|
41
41
|
return
|
42
42
|
end
|
43
43
|
|
44
44
|
prettify_io(f, prettifier, ignore_parse_error)
|
45
|
-
|
46
45
|
ensure
|
47
46
|
f.close if f
|
48
47
|
end
|
@@ -51,33 +50,33 @@ excluded_fields = []
|
|
51
50
|
ignore_parse_error = false
|
52
51
|
|
53
52
|
option_parser = OptionParser.new do |op|
|
54
|
-
op.banner
|
55
|
-
Usage: steno-prettify [OPTS] [FILE...]
|
53
|
+
op.banner = <<~EOT
|
54
|
+
Usage: steno-prettify [OPTS] [FILE...]
|
56
55
|
|
57
|
-
Parses json formatted log lines from FILE(s), or stdin,
|
58
|
-
and displays a more human friendly version of each line to stdout.
|
56
|
+
Parses json formatted log lines from FILE(s), or stdin,
|
57
|
+
and displays a more human friendly version of each line to stdout.
|
59
58
|
|
60
|
-
Examples (shamelessly stolen from `man cat`):
|
59
|
+
Examples (shamelessly stolen from `man cat`):
|
61
60
|
|
62
|
-
|
63
|
-
|
61
|
+
steno-prettify f - g
|
62
|
+
Prettify f's contents, then standard input, then g's contents.
|
64
63
|
|
65
|
-
|
66
|
-
|
64
|
+
steno-prettify
|
65
|
+
Prettify contents of stdin.
|
67
66
|
|
68
|
-
Options:
|
69
|
-
EOT
|
67
|
+
Options:
|
68
|
+
EOT
|
70
69
|
|
71
|
-
op.on(
|
70
|
+
op.on('-h', '--help', 'Display help') do
|
72
71
|
puts op
|
73
72
|
exit
|
74
73
|
end
|
75
74
|
|
76
|
-
op.on(
|
75
|
+
op.on('-a', '--align', 'Omit location and data in order to provide well-aligned logs') do
|
77
76
|
excluded_fields = %w[location data]
|
78
77
|
end
|
79
78
|
|
80
|
-
op.on(
|
79
|
+
op.on('-s', '--no-messages', 'Donot complain about errors in parsing logs') do
|
81
80
|
ignore_parse_error = true
|
82
81
|
end
|
83
82
|
end
|
@@ -88,10 +87,10 @@ STDOUT.sync = true
|
|
88
87
|
prettifier = Steno::JsonPrettifier.new(excluded_fields)
|
89
88
|
|
90
89
|
inputs = ARGV.dup
|
91
|
-
inputs <<
|
90
|
+
inputs << '-' if inputs.empty?
|
92
91
|
|
93
92
|
inputs.each do |path|
|
94
|
-
if path ==
|
93
|
+
if path == '-'
|
95
94
|
prettify_io(STDIN, prettifier, ignore_parse_error)
|
96
95
|
else
|
97
96
|
prettify_file(path, prettifier, ignore_parse_error)
|
data/lib/steno/codec/base.rb
CHANGED
data/lib/steno/codec/json.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require 'yajl'
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'steno/codec/base'
|
4
4
|
|
5
5
|
module Steno
|
6
6
|
module Codec
|
@@ -8,29 +8,39 @@ module Steno
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class Steno::Codec::Json < Steno::Codec::Base
|
11
|
+
def initialize(opts = {})
|
12
|
+
@iso8601_timestamps = opts[:iso8601_timestamps] || false
|
13
|
+
end
|
14
|
+
|
11
15
|
def encode_record(record)
|
12
16
|
msg =
|
13
17
|
if record.message.valid_encoding?
|
14
18
|
record.message
|
15
19
|
else
|
16
20
|
# Treat the message as an arbitrary sequence of bytes.
|
17
|
-
escape_nonprintable_ascii(record.message.dup.force_encoding(
|
21
|
+
escape_nonprintable_ascii(record.message.dup.force_encoding('BINARY'))
|
18
22
|
end
|
19
23
|
|
20
24
|
h = {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
'timestamp' => record.timestamp.to_f,
|
26
|
+
'message' => msg,
|
27
|
+
'log_level' => record.log_level.to_s,
|
28
|
+
'source' => record.source,
|
29
|
+
'data' => record.data,
|
30
|
+
'thread_id' => record.thread_id,
|
31
|
+
'fiber_id' => record.fiber_id,
|
32
|
+
'process_id' => record.process_id,
|
33
|
+
'file' => record.file,
|
34
|
+
'lineno' => record.lineno,
|
35
|
+
'method' => record.method
|
32
36
|
}
|
33
37
|
|
38
|
+
h['timestamp'] = Time.at(record.timestamp).utc.iso8601(6) if iso8601_timestamps?
|
39
|
+
|
34
40
|
Yajl::Encoder.encode(h) + "\n"
|
35
41
|
end
|
42
|
+
|
43
|
+
def iso8601_timestamps?
|
44
|
+
@iso8601_timestamps
|
45
|
+
end
|
36
46
|
end
|
data/lib/steno/codec.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'steno/codec/base'
|
2
|
+
require 'steno/codec/json'
|
data/lib/steno/config.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require 'yaml'
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require 'steno/codec'
|
4
|
+
require 'steno/context'
|
5
|
+
require 'steno/logger'
|
6
|
+
require 'steno/sink'
|
7
7
|
|
8
8
|
module Steno
|
9
9
|
end
|
@@ -23,7 +23,7 @@ class Steno::Config
|
|
23
23
|
# @return [Steno::Config]
|
24
24
|
def from_file(path, overrides = {})
|
25
25
|
h = YAML.load_file(path)
|
26
|
-
h = h[
|
26
|
+
h = h['logging'] || {}
|
27
27
|
new(to_config_hash(h).merge(overrides))
|
28
28
|
end
|
29
29
|
|
@@ -37,13 +37,15 @@ class Steno::Config
|
|
37
37
|
|
38
38
|
level = hash[:level] || hash[:default_log_level]
|
39
39
|
opts = {
|
40
|
-
:
|
41
|
-
:
|
40
|
+
sinks: [],
|
41
|
+
default_log_level: level.nil? ? :info : level.to_sym
|
42
42
|
}
|
43
43
|
|
44
|
+
opts[:codec] = Steno::Codec::Json.new(iso8601_timestamps: true) if hash[:iso8601_timestamps]
|
45
|
+
|
44
46
|
if hash[:file]
|
45
47
|
max_retries = hash[:max_retries]
|
46
|
-
opts[:sinks] << Steno::Sink::IO.for_file(hash[:file], :
|
48
|
+
opts[:sinks] << Steno::Sink::IO.for_file(hash[:file], max_retries: max_retries)
|
47
49
|
end
|
48
50
|
|
49
51
|
if Steno::Sink::WINDOWS
|
@@ -51,20 +53,14 @@ class Steno::Config
|
|
51
53
|
Steno::Sink::Eventlog.instance.open(hash[:eventlog])
|
52
54
|
opts[:sinks] << Steno::Sink::Eventlog.instance
|
53
55
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
opts[:sinks] << Steno::Sink::Syslog.instance
|
58
|
-
end
|
56
|
+
elsif hash[:syslog]
|
57
|
+
Steno::Sink::Syslog.instance.open(hash[:syslog])
|
58
|
+
opts[:sinks] << Steno::Sink::Syslog.instance
|
59
59
|
end
|
60
60
|
|
61
|
-
if hash[:fluentd]
|
62
|
-
opts[:sinks] << Steno::Sink::Fluentd.new(hash[:fluentd])
|
63
|
-
end
|
61
|
+
opts[:sinks] << Steno::Sink::Fluentd.new(hash[:fluentd]) if hash[:fluentd]
|
64
62
|
|
65
|
-
if opts[:sinks].empty?
|
66
|
-
opts[:sinks] << Steno::Sink::IO.new(STDOUT)
|
67
|
-
end
|
63
|
+
opts[:sinks] << Steno::Sink::IO.new(STDOUT) if opts[:sinks].empty?
|
68
64
|
|
69
65
|
opts
|
70
66
|
end
|
@@ -74,23 +70,20 @@ class Steno::Config
|
|
74
70
|
end
|
75
71
|
end
|
76
72
|
|
77
|
-
attr_reader :sinks
|
78
|
-
attr_reader :codec
|
79
|
-
attr_reader :context
|
80
|
-
attr_reader :default_log_level
|
73
|
+
attr_reader :sinks, :codec, :context, :default_log_level
|
81
74
|
|
82
75
|
def initialize(opts = {})
|
83
76
|
@sinks = opts[:sinks] || []
|
84
77
|
@codec = opts[:codec] || Steno::Codec::Json.new
|
85
|
-
@context = opts[:context] ||Steno::Context::Null.new
|
78
|
+
@context = opts[:context] || Steno::Context::Null.new
|
86
79
|
|
87
80
|
@sinks.each { |sink| sink.codec = @codec }
|
88
81
|
|
89
|
-
if opts[:default_log_level]
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
82
|
+
@default_log_level = if opts[:default_log_level]
|
83
|
+
opts[:default_log_level].to_sym
|
84
|
+
else
|
85
|
+
:info
|
86
|
+
end
|
94
87
|
end
|
95
88
|
|
96
89
|
private_class_method :symbolize_keys
|
data/lib/steno/context.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'fiber'
|
2
|
+
require 'thread'
|
3
3
|
|
4
4
|
class Fiber
|
5
5
|
def __steno_context_data__
|
@@ -36,7 +36,7 @@ module Steno::Context
|
|
36
36
|
end
|
37
37
|
|
38
38
|
class ThreadLocal < Base
|
39
|
-
THREAD_LOCAL_KEY =
|
39
|
+
THREAD_LOCAL_KEY = '__steno_locals__'
|
40
40
|
|
41
41
|
def data
|
42
42
|
Thread.current[THREAD_LOCAL_KEY] ||= {}
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'set'
|
3
|
+
require 'yajl'
|
4
4
|
|
5
5
|
module Steno
|
6
6
|
end
|
@@ -24,7 +24,7 @@ class Steno::JsonPrettifier
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def initialize(excluded_fields = [])
|
27
|
-
@time_format =
|
27
|
+
@time_format = '%Y-%m-%d %H:%M:%S.%6N'
|
28
28
|
@excluded_fields = Set.new(excluded_fields)
|
29
29
|
@max_src_len = MIN_COL_WIDTH
|
30
30
|
end
|
@@ -49,8 +49,8 @@ class Steno::JsonPrettifier
|
|
49
49
|
next if @excluded_fields.include?(field_name)
|
50
50
|
|
51
51
|
exists = nil
|
52
|
-
pred_meth = "check_#{field_name}"
|
53
|
-
if respond_to?(pred_meth)
|
52
|
+
pred_meth = :"check_#{field_name}"
|
53
|
+
if respond_to?(pred_meth, true)
|
54
54
|
exists = send(pred_meth, record)
|
55
55
|
elsif record.respond_to?(:has_key?)
|
56
56
|
exists = record.has_key?(field_name)
|
@@ -59,35 +59,35 @@ class Steno::JsonPrettifier
|
|
59
59
|
raise ParseError, msg
|
60
60
|
end
|
61
61
|
|
62
|
-
if exists
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
fields << if exists
|
63
|
+
send(:"format_#{field_name}", record)
|
64
|
+
else
|
65
|
+
'-'
|
66
|
+
end
|
67
67
|
end
|
68
68
|
|
69
|
-
fields.join(
|
69
|
+
fields.join(' ') + "\n"
|
70
70
|
end
|
71
71
|
|
72
72
|
def format_timestamp(record)
|
73
|
-
Time.at(record[
|
73
|
+
Time.at(record['timestamp']).strftime(@time_format)
|
74
74
|
end
|
75
75
|
|
76
76
|
def format_source(record)
|
77
|
-
@max_src_len = [@max_src_len, record[
|
78
|
-
record[
|
77
|
+
@max_src_len = [@max_src_len, record['source'].length].max
|
78
|
+
record['source'].ljust(@max_src_len)
|
79
79
|
end
|
80
80
|
|
81
81
|
def format_process_id(record)
|
82
|
-
|
82
|
+
format('pid=%-5s', record['process_id'])
|
83
83
|
end
|
84
84
|
|
85
85
|
def format_thread_id(record)
|
86
|
-
|
86
|
+
format('tid=%s', shortid(record['thread_id']))
|
87
87
|
end
|
88
88
|
|
89
89
|
def format_fiber_id(record)
|
90
|
-
|
90
|
+
format('fid=%s', shortid(record['fiber_id']))
|
91
91
|
end
|
92
92
|
|
93
93
|
def check_location(record)
|
@@ -95,36 +95,37 @@ class Steno::JsonPrettifier
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def format_location(record)
|
98
|
-
parts = record[
|
98
|
+
parts = record['file'].split('/')
|
99
99
|
|
100
100
|
trimmed_filename = nil
|
101
|
-
if parts.size == 1
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
101
|
+
trimmed_filename = if parts.size == 1
|
102
|
+
parts[0]
|
103
|
+
else
|
104
|
+
parts.slice(-2, 2).join('/')
|
105
|
+
end
|
106
106
|
|
107
|
-
|
107
|
+
format('%s/%s:%s', trimmed_filename, record['method'], record['lineno'])
|
108
108
|
end
|
109
109
|
|
110
110
|
def check_data(record)
|
111
|
-
record[
|
111
|
+
record['data'].is_a?(Hash)
|
112
112
|
end
|
113
113
|
|
114
114
|
def format_data(record)
|
115
|
-
record[
|
115
|
+
record['data'].map { |k, v| "#{k}=#{v}" }.join(',')
|
116
116
|
end
|
117
117
|
|
118
118
|
def format_log_level(record)
|
119
|
-
|
119
|
+
format('%7s', record['log_level'].upcase)
|
120
120
|
end
|
121
121
|
|
122
122
|
def format_message(record)
|
123
|
-
|
123
|
+
format('-- %s', record['message'])
|
124
124
|
end
|
125
125
|
|
126
126
|
def shortid(data)
|
127
|
-
return
|
127
|
+
return '-' if data.nil?
|
128
|
+
|
128
129
|
digest = Digest::MD5.hexdigest(data.to_s)
|
129
130
|
digest[0, 4]
|
130
131
|
end
|
data/lib/steno/log_level.rb
CHANGED
data/lib/steno/logger.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
require
|
1
|
+
require 'thread'
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'steno/errors'
|
4
|
+
require 'steno/log_level'
|
5
5
|
|
6
6
|
module Steno
|
7
7
|
end
|
8
8
|
|
9
9
|
class Steno::Logger
|
10
10
|
LEVELS = {
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
11
|
+
off: Steno::LogLevel.new(:off, 0),
|
12
|
+
fatal: Steno::LogLevel.new(:fatal, 1),
|
13
|
+
error: Steno::LogLevel.new(:error, 5),
|
14
|
+
warn: Steno::LogLevel.new(:warn, 10),
|
15
|
+
info: Steno::LogLevel.new(:info, 15),
|
16
|
+
debug: Steno::LogLevel.new(:debug, 16),
|
17
|
+
debug1: Steno::LogLevel.new(:debug1, 17),
|
18
|
+
debug2: Steno::LogLevel.new(:debug2, 18),
|
19
|
+
all: Steno::LogLevel.new(:all, 30)
|
20
20
|
}
|
21
21
|
|
22
22
|
class << self
|
@@ -28,19 +28,17 @@ class Steno::Logger
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def define_logf_method(name)
|
31
|
-
define_method(name.to_s +
|
31
|
+
define_method(name.to_s + 'f') { |fmt, *args| log(name, fmt % args) }
|
32
32
|
end
|
33
33
|
|
34
34
|
def define_level_active_predicate(name)
|
35
|
-
define_method(name.to_s +
|
35
|
+
define_method(name.to_s + '?') { level_active?(name) }
|
36
36
|
end
|
37
37
|
|
38
38
|
def lookup_level(name)
|
39
39
|
level = LEVELS[name]
|
40
40
|
|
41
|
-
if level.nil?
|
42
|
-
raise Steno::Error.new("Unknown level: #{name}")
|
43
|
-
end
|
41
|
+
raise Steno::Error.new("Unknown level: #{name}") if level.nil?
|
44
42
|
|
45
43
|
level
|
46
44
|
end
|
@@ -85,8 +83,6 @@ class Steno::Logger
|
|
85
83
|
level = self.class.lookup_level(level_name)
|
86
84
|
|
87
85
|
@min_level_lock.synchronize { @min_level = level }
|
88
|
-
|
89
|
-
nil
|
90
86
|
end
|
91
87
|
|
92
88
|
# Returns the name of the current log level
|
@@ -113,7 +109,7 @@ class Steno::Logger
|
|
113
109
|
|
114
110
|
# @return [nil]
|
115
111
|
def log_exception(ex, user_data = {})
|
116
|
-
warn("Caught exception: #{ex}", user_data.merge(:
|
112
|
+
warn("Caught exception: #{ex}", user_data.merge(backtrace: ex.backtrace))
|
117
113
|
end
|
118
114
|
|
119
115
|
# Adds a record to the configured sinks.
|
@@ -123,7 +119,7 @@ class Steno::Logger
|
|
123
119
|
# @param [Hash] user_data
|
124
120
|
#
|
125
121
|
# @return [nil]
|
126
|
-
def log(level_name, message = nil, user_data = nil
|
122
|
+
def log(level_name, message = nil, user_data = nil)
|
127
123
|
return unless level_active?(level_name)
|
128
124
|
|
129
125
|
message = yield if block_given?
|
@@ -153,18 +149,18 @@ class Steno::Logger
|
|
153
149
|
private
|
154
150
|
|
155
151
|
def parse_record_loc(callstack)
|
156
|
-
file
|
152
|
+
file = nil
|
153
|
+
lineno = nil
|
154
|
+
method = nil
|
157
155
|
|
158
156
|
callstack.each do |frame|
|
159
157
|
next if frame =~ /logger\.rb/
|
160
158
|
|
161
|
-
file, lineno, method = frame.split(
|
159
|
+
file, lineno, method = frame.split(':')
|
162
160
|
|
163
161
|
lineno = lineno.to_i
|
164
162
|
|
165
|
-
if method =~ /in `([^']+)/
|
166
|
-
method = $1
|
167
|
-
end
|
163
|
+
method = ::Regexp.last_match(1) if method =~ /in `([^']+)/
|
168
164
|
|
169
165
|
break
|
170
166
|
end
|
data/lib/steno/record.rb
CHANGED
@@ -1,22 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'thread'
|
3
3
|
|
4
4
|
module Steno
|
5
5
|
end
|
6
6
|
|
7
7
|
class Steno::Record
|
8
|
-
|
9
|
-
|
10
|
-
attr_reader :message
|
11
|
-
attr_reader :log_level
|
12
|
-
attr_reader :source
|
13
|
-
attr_reader :data
|
14
|
-
attr_reader :thread_id
|
15
|
-
attr_reader :fiber_id
|
16
|
-
attr_reader :process_id
|
17
|
-
attr_reader :file
|
18
|
-
attr_reader :lineno
|
19
|
-
attr_reader :method
|
8
|
+
attr_reader :timestamp, :message, :log_level, :source, :data, :thread_id, :fiber_id, :process_id, :file, :lineno,
|
9
|
+
:method
|
20
10
|
|
21
11
|
# @param [String] source Identifies message source.
|
22
12
|
# @param [Symbol] log_level
|
@@ -25,7 +15,7 @@ class Steno::Record
|
|
25
15
|
# Format is [<filename>, <lineno>, <method>].
|
26
16
|
# @param [Hash] data User-supplied data
|
27
17
|
def initialize(source, log_level, message, loc = [], data = {})
|
28
|
-
raise
|
18
|
+
raise 'Log level must be a Symbol' unless log_level.is_a? Symbol
|
29
19
|
|
30
20
|
@timestamp = Time.now
|
31
21
|
@source = source
|
data/lib/steno/sink/base.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'thread'
|
3
3
|
|
4
4
|
module Steno
|
5
5
|
module Sink
|
@@ -10,7 +10,6 @@ end
|
|
10
10
|
# Sinks represent the final destination for log records. They abstract storage
|
11
11
|
# mediums (like files) and transport layers (like sockets).
|
12
12
|
class Steno::Sink::Base
|
13
|
-
|
14
13
|
attr_accessor :codec
|
15
14
|
|
16
15
|
# @param [Steno::Codec::Base] formatter Transforms log records to their
|