steno 1.0.3 → 1.0.4
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.
- data/README.md +54 -6
- data/Rakefile +2 -0
- data/lib/steno/config.rb +4 -0
- data/lib/steno/http_handler.rb +0 -1
- data/lib/steno/logger.rb +0 -3
- data/lib/steno/sink.rb +2 -0
- data/lib/steno/sink/counter.rb +44 -0
- data/lib/steno/sink/fluentd.rb +31 -0
- data/lib/steno/version.rb +1 -1
- data/spec/unit/log_level_spec.rb +1 -0
- data/spec/unit/sink/counter_spec.rb +27 -0
- data/spec/unit/sink/fluentd_spec.rb +46 -0
- data/steno.gemspec +1 -0
- metadata +24 -2
data/README.md
CHANGED
@@ -11,19 +11,67 @@ ultimate destination for log records. They transform a structured record into
|
|
11
11
|
a string via a formatter and then typically write the transformed string to
|
12
12
|
another transport.
|
13
13
|
|
14
|
-
##
|
14
|
+
## Configuration
|
15
|
+
|
16
|
+
To use steno, you must configure one or more 'sinks', a 'codec' and a 'context'.
|
17
|
+
If you don't provide a codec, steno will encode your logs as JSON.
|
18
|
+
|
19
|
+
For example:
|
20
|
+
|
15
21
|
config = Steno::Config.new(
|
16
22
|
:sinks => [Steno::Sink::IO.new(STDOUT)],
|
17
23
|
:codec => Steno::Codec::Json.new,
|
18
24
|
:context => Steno::Context::ThreadLocal.new)
|
19
25
|
|
20
|
-
|
26
|
+
### from YAML file
|
27
|
+
|
28
|
+
Alternatively, Steno can read its configuration from a YAML file in the following format:
|
29
|
+
|
30
|
+
```yaml
|
31
|
+
# config.yml
|
32
|
+
---
|
33
|
+
logging:
|
34
|
+
file: /some/path # Optional - path a log file
|
35
|
+
max_retries: 3 # Optional - number of times to retry if a file write fails.
|
36
|
+
syslog: some_syslog.id # Optional
|
37
|
+
fluentd: # Optional
|
38
|
+
host: fluentd.host
|
39
|
+
port: 9999
|
40
|
+
level: debug # Optional - Minimum log level that will be written.
|
41
|
+
# Defaults to 'info'
|
42
|
+
```
|
43
|
+
Then, in your code:
|
44
|
+
```ruby
|
45
|
+
config = Steno::Config.from_file("path/to/config.yml")
|
46
|
+
```
|
21
47
|
|
22
|
-
|
48
|
+
With this configuration method, if neither `file`, `syslog` or `fluentd` are provided,
|
49
|
+
steno will use its stdout as its sink. Also, note that the top-level field `logging` is required.
|
23
50
|
|
51
|
+
### from Hash
|
52
|
+
|
53
|
+
As a third option, steno can be configured using a hash with the same structure as the above
|
54
|
+
YAML file (without the top-level `logging` key):
|
55
|
+
```ruby
|
56
|
+
config = Steno::Config.from_hash(config_hash)
|
57
|
+
```
|
58
|
+
|
59
|
+
## Usage
|
60
|
+
|
61
|
+
Steno.init(config)
|
62
|
+
logger = Steno.logger("test")
|
24
63
|
logger.info("Hello world!")
|
25
64
|
|
26
|
-
|
65
|
+
### Log levels
|
66
|
+
|
67
|
+
LEVEL NUMERIC RANKING
|
68
|
+
off 0
|
69
|
+
fatal 1
|
70
|
+
error 5
|
71
|
+
warn 10
|
72
|
+
info 15
|
73
|
+
debug 16
|
74
|
+
debug1 17
|
75
|
+
debug2 18
|
76
|
+
all 30
|
27
77
|
|
28
|
-
To file a bug against Cloud Foundry Open Source and its components, sign up and use our
|
29
|
-
bug tracking system: [http://cloudfoundry.atlassian.net](http://cloudfoundry.atlassian.net)
|
data/Rakefile
CHANGED
data/lib/steno/config.rb
CHANGED
data/lib/steno/http_handler.rb
CHANGED
data/lib/steno/logger.rb
CHANGED
@@ -104,7 +104,6 @@ class Steno::Logger
|
|
104
104
|
# @return [true || false]
|
105
105
|
def level_active?(level_name)
|
106
106
|
level = self.class.lookup_level(level_name)
|
107
|
-
|
108
107
|
@min_level_lock.synchronize { level <= @min_level }
|
109
108
|
end
|
110
109
|
|
@@ -127,8 +126,6 @@ class Steno::Logger
|
|
127
126
|
def log(level_name, message = nil, user_data = nil, &blk)
|
128
127
|
return unless level_active?(level_name)
|
129
128
|
|
130
|
-
level = self.class.lookup_level(level_name)
|
131
|
-
|
132
129
|
message = yield if block_given?
|
133
130
|
|
134
131
|
callstack = caller
|
data/lib/steno/sink.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
require "steno/sink/base"
|
2
|
+
|
3
|
+
module Steno
|
4
|
+
module Sink
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Steno::Sink::Counter < Steno::Sink::Base
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
# Map of String -> numeric count
|
12
|
+
@counts = {}
|
13
|
+
@mutex = Mutex.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_record(record)
|
17
|
+
level = record.log_level.name.to_s
|
18
|
+
|
19
|
+
@mutex.synchronize do
|
20
|
+
unless @counts[level]
|
21
|
+
@counts[level] = 0
|
22
|
+
end
|
23
|
+
@counts[level] += 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def flush
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_json
|
31
|
+
hash = {}
|
32
|
+
@mutex.synchronize do
|
33
|
+
Steno::Logger::LEVELS.keys.each do |level_name|
|
34
|
+
hash[level_name] = @counts.fetch(level_name.to_s, 0)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
Yajl::Encoder.encode(hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Provide a map of string level -> count. This is thread-safe, the return value is a copy.
|
41
|
+
def counts
|
42
|
+
@mutex.synchronize { @counts.dup }
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'fluent-logger'
|
2
|
+
#
|
3
|
+
# Steno sink implementation for Fluentd
|
4
|
+
#
|
5
|
+
# See fluentd at http://fluentd.org/
|
6
|
+
# and fluent-logger at https://github.com/fluent/fluent-logger-ruby
|
7
|
+
#
|
8
|
+
class Steno::Sink::Fluentd < Steno::Sink::Base
|
9
|
+
|
10
|
+
# @param [Hash] opts Key :tag_prefix tag prefix of fluent logs (default: steno)
|
11
|
+
# Key :host fluentd host (default: 127.0.0.1)
|
12
|
+
# Key :port fluentd port (deafult: 24224)
|
13
|
+
# Key :buffer_limit buffer limit of fluent-logger
|
14
|
+
def initialize(opts = {})
|
15
|
+
super
|
16
|
+
|
17
|
+
@fluentd = Fluent::Logger::FluentLogger.new(opts[:tag_prefix] || "steno",
|
18
|
+
:host => opts[:host] || "127.0.0.1",
|
19
|
+
:port => opts[:port] || 24224,
|
20
|
+
:buffer_limit => opts[:buffer_limit] || Fluent::Logger::FluentLogger::BUFFER_LIMIT)
|
21
|
+
@io_lock = Mutex.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_record(record)
|
25
|
+
@fluentd.post(record.source, record)
|
26
|
+
end
|
27
|
+
|
28
|
+
def flush
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
end
|
data/lib/steno/version.rb
CHANGED
data/spec/unit/log_level_spec.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Steno::Sink::Counter do
|
4
|
+
let(:level) do
|
5
|
+
Steno::Logger.lookup_level(:info)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:record) do
|
9
|
+
Steno::Record.new("source", level, "message")
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "add_record" do
|
13
|
+
it "counts added records" do
|
14
|
+
expect(subject.counts).to be_empty
|
15
|
+
subject.add_record(record)
|
16
|
+
expect(subject.counts.size).to eq 1
|
17
|
+
expect(subject.counts['info']).to eq 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "to_json" do
|
22
|
+
it "produces a valid json representation" do
|
23
|
+
subject.add_record(record)
|
24
|
+
expect(subject.to_json).to match '"info":1'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Steno::Sink::IO do
|
4
|
+
let(:level) do
|
5
|
+
Steno::Logger.lookup_level(:info)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:record) do
|
9
|
+
Steno::Record.new("source", level, "message")
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#initialize" do
|
13
|
+
it "should initialize FluentLogger with the default option" do
|
14
|
+
Fluent::Logger::FluentLogger.should_receive(:new).with("steno", {
|
15
|
+
:host => "127.0.0.1",
|
16
|
+
:port => 24224,
|
17
|
+
:buffer_limit => Fluent::Logger::FluentLogger::BUFFER_LIMIT,
|
18
|
+
}).and_return()
|
19
|
+
sink = Steno::Sink::Fluentd.new()
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should initialize FliuentLogger with override options" do
|
23
|
+
Fluent::Logger::FluentLogger.should_receive(:new).with("vcap", {
|
24
|
+
:host => "localhost",
|
25
|
+
:port => 8080,
|
26
|
+
:buffer_limit => 1024,
|
27
|
+
}).and_return()
|
28
|
+
sink = Steno::Sink::Fluentd.new({
|
29
|
+
:tag_prefix => "vcap",
|
30
|
+
:host => "localhost",
|
31
|
+
:port => 8080,
|
32
|
+
:buffer_limit => 1024
|
33
|
+
})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#add_record" do
|
38
|
+
it "should post an record with the correct tag" do
|
39
|
+
fluentd = mock("fluentd")
|
40
|
+
Fluent::Logger::FluentLogger.should_receive(:new).and_return(fluentd)
|
41
|
+
fluentd.should_receive(:post).with("source", record)
|
42
|
+
sink = Steno::Sink::Fluentd.new()
|
43
|
+
sink.add_record(record)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/steno.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steno
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: grape
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '1.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: fluent-logger
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: ci_reporter
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,6 +145,8 @@ files:
|
|
129
145
|
- lib/steno/logger.rb
|
130
146
|
- lib/steno/record.rb
|
131
147
|
- lib/steno/sink/base.rb
|
148
|
+
- lib/steno/sink/counter.rb
|
149
|
+
- lib/steno/sink/fluentd.rb
|
132
150
|
- lib/steno/sink/io.rb
|
133
151
|
- lib/steno/sink/syslog.rb
|
134
152
|
- lib/steno/sink.rb
|
@@ -151,6 +169,8 @@ files:
|
|
151
169
|
- spec/unit/log_level_spec.rb
|
152
170
|
- spec/unit/logger_spec.rb
|
153
171
|
- spec/unit/record_spec.rb
|
172
|
+
- spec/unit/sink/counter_spec.rb
|
173
|
+
- spec/unit/sink/fluentd_spec.rb
|
154
174
|
- spec/unit/sink/io_spec.rb
|
155
175
|
- spec/unit/sink/syslog_spec.rb
|
156
176
|
- spec/unit/steno_spec.rb
|
@@ -194,6 +214,8 @@ test_files:
|
|
194
214
|
- spec/unit/log_level_spec.rb
|
195
215
|
- spec/unit/logger_spec.rb
|
196
216
|
- spec/unit/record_spec.rb
|
217
|
+
- spec/unit/sink/counter_spec.rb
|
218
|
+
- spec/unit/sink/fluentd_spec.rb
|
197
219
|
- spec/unit/sink/io_spec.rb
|
198
220
|
- spec/unit/sink/syslog_spec.rb
|
199
221
|
- spec/unit/steno_spec.rb
|