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 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
- ## Getting started
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
- Steno.init(config)
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
- logger = Steno.logger("test")
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
- ## File a Bug
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
@@ -2,6 +2,8 @@
2
2
  require "ci/reporter/rake/rspec"
3
3
  require "rspec/core/rake_task"
4
4
 
5
+ task :default => :spec
6
+
5
7
  desc "Run all specs"
6
8
  RSpec::Core::RakeTask.new("spec") do |t|
7
9
  t.rspec_opts = %w[--color --format documentation]
data/lib/steno/config.rb CHANGED
@@ -52,6 +52,10 @@ class Steno::Config
52
52
  opts[:sinks] << Steno::Sink::Syslog.instance
53
53
  end
54
54
 
55
+ if hash[:fluentd]
56
+ opts[:sinks] << Steno::Sink::Fluentd.new(hash[:fluentd])
57
+ end
58
+
55
59
  if opts[:sinks].empty?
56
60
  opts[:sinks] << Steno::Sink::IO.new(STDOUT)
57
61
  end
@@ -7,7 +7,6 @@ end
7
7
 
8
8
  class Steno::HttpHandler < Grape::API
9
9
  format :json
10
- error_format :json
11
10
 
12
11
  resource :loggers do
13
12
  get :levels do
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
@@ -1,3 +1,5 @@
1
1
  require "steno/sink/base"
2
2
  require "steno/sink/io"
3
3
  require "steno/sink/syslog"
4
+ require "steno/sink/fluentd"
5
+ require "steno/sink/counter"
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Steno
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.4"
3
3
  end
@@ -15,4 +15,5 @@ describe Steno::LogLevel do
15
15
  info_level.to_s.should == "info"
16
16
  end
17
17
  end
18
+
18
19
  end
@@ -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
@@ -27,6 +27,7 @@ Gem::Specification.new do |gem|
27
27
 
28
28
  gem.add_dependency("grape")
29
29
  gem.add_dependency("yajl-ruby", "~> 1.0")
30
+ gem.add_dependency("fluent-logger")
30
31
 
31
32
  gem.add_development_dependency("ci_reporter")
32
33
  gem.add_development_dependency("rack-test")
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.3
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-02-14 00:00:00.000000000 Z
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