steno 1.2.4 → 1.3.5
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 +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
|