steno-capi 1.3.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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +7136 -0
  3. data/README.md +78 -0
  4. data/Rakefile +15 -0
  5. data/bin/steno-prettify +99 -0
  6. data/lib/steno.rb +133 -0
  7. data/lib/steno/codec.rb +2 -0
  8. data/lib/steno/codec/base.rb +34 -0
  9. data/lib/steno/codec/json.rb +49 -0
  10. data/lib/steno/config.rb +101 -0
  11. data/lib/steno/context.rb +59 -0
  12. data/lib/steno/core_ext.rb +11 -0
  13. data/lib/steno/errors.rb +3 -0
  14. data/lib/steno/json_prettifier.rb +131 -0
  15. data/lib/steno/log_level.rb +24 -0
  16. data/lib/steno/logger.rb +174 -0
  17. data/lib/steno/record.rb +41 -0
  18. data/lib/steno/sink.rb +6 -0
  19. data/lib/steno/sink/base.rb +38 -0
  20. data/lib/steno/sink/counter.rb +44 -0
  21. data/lib/steno/sink/eventlog.rb +46 -0
  22. data/lib/steno/sink/fluentd.rb +31 -0
  23. data/lib/steno/sink/io.rb +72 -0
  24. data/lib/steno/sink/syslog.rb +62 -0
  25. data/lib/steno/tagged_logger.rb +59 -0
  26. data/lib/steno/version.rb +3 -0
  27. data/spec/spec_helper.rb +6 -0
  28. data/spec/support/barrier.rb +22 -0
  29. data/spec/support/null_sink.rb +17 -0
  30. data/spec/support/shared_context_specs.rb +7 -0
  31. data/spec/unit/config_spec.rb +229 -0
  32. data/spec/unit/context_spec.rb +62 -0
  33. data/spec/unit/core_ext_spec.rb +38 -0
  34. data/spec/unit/json_codec_spec.rb +68 -0
  35. data/spec/unit/json_prettifier_spec.rb +84 -0
  36. data/spec/unit/log_level_spec.rb +19 -0
  37. data/spec/unit/logger_spec.rb +101 -0
  38. data/spec/unit/record_spec.rb +30 -0
  39. data/spec/unit/sink/counter_spec.rb +27 -0
  40. data/spec/unit/sink/eventlog_spec.rb +41 -0
  41. data/spec/unit/sink/fluentd_spec.rb +46 -0
  42. data/spec/unit/sink/io_spec.rb +111 -0
  43. data/spec/unit/sink/syslog_spec.rb +75 -0
  44. data/spec/unit/steno_spec.rb +86 -0
  45. data/spec/unit/tagged_logger_spec.rb +35 -0
  46. data/steno-capi.gemspec +39 -0
  47. metadata +179 -0
@@ -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.name, "message")
10
+ end
11
+
12
+ describe "#initialize" do
13
+ it "should initialize FluentLogger with the default option" do
14
+ expect(Fluent::Logger::FluentLogger).to receive(:new).with("steno", {
15
+ :host => "127.0.0.1",
16
+ :port => 24224,
17
+ :buffer_limit => Fluent::Logger::FluentLogger::BUFFER_LIMIT,
18
+ }).and_return(nil)
19
+ sink = Steno::Sink::Fluentd.new()
20
+ end
21
+
22
+ it "should initialize FliuentLogger with override options" do
23
+ expect(Fluent::Logger::FluentLogger).to receive(:new).with("vcap", {
24
+ :host => "localhost",
25
+ :port => 8080,
26
+ :buffer_limit => 1024,
27
+ }).and_return(nil)
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 = double("fluentd")
40
+ expect(Fluent::Logger::FluentLogger).to receive(:new).and_return(fluentd)
41
+ expect(fluentd).to receive(:post).with("source", record)
42
+ sink = Steno::Sink::Fluentd.new()
43
+ sink.add_record(record)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,111 @@
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.name, "message")
10
+ end
11
+
12
+ describe ".for_file" do
13
+ it "should return a new sink configured to append to the file at path with autosync set to true by default" do
14
+ mock_handle = double("file handle")
15
+
16
+ expect(File).to receive(:open).with("path", "a+").and_return(mock_handle)
17
+ expect(mock_handle).to receive(:sync=).with(true)
18
+
19
+ mock_sink = double("sink")
20
+ expect(Steno::Sink::IO).to receive(:new).with(mock_handle,
21
+ :max_retries => 10).
22
+ and_return(mock_sink)
23
+
24
+ returned = Steno::Sink::IO.for_file("path",
25
+ :max_retries => 10)
26
+ expect(returned).to eq(mock_sink)
27
+ end
28
+
29
+ it "should return a new sink configured to append to the file at path with specified options" do
30
+ mock_handle = double("file handle")
31
+
32
+ expect(File).to receive(:open).with("path", "a+").and_return(mock_handle)
33
+ expect(mock_handle).to receive(:sync=).with(false)
34
+
35
+ mock_sink = double("sink")
36
+ expect(Steno::Sink::IO).to receive(:new).with(mock_handle,
37
+ :max_retries => 10).
38
+ and_return(mock_sink)
39
+
40
+ returned = Steno::Sink::IO.for_file("path",
41
+ :autoflush => false,
42
+ :max_retries => 10)
43
+ expect(returned).to eq(mock_sink)
44
+ end
45
+ end
46
+
47
+ describe "#add_record" do
48
+ it "should encode the record and write it to the underlying io object" do
49
+ codec = double("codec")
50
+ expect(codec).to receive(:encode_record).with(record).and_return(record.message)
51
+
52
+ io = double("io")
53
+ expect(io).to receive(:write).with(record.message)
54
+
55
+ Steno::Sink::IO.new(io, :codec => codec).add_record(record)
56
+ end
57
+
58
+ it "should by default not retry on IOError" do
59
+ codec = double("codec")
60
+ expect(codec).to receive(:encode_record).with(record).and_return(record.message)
61
+
62
+ io = double("io")
63
+
64
+ expect(io).to receive(:write).with(record.message).ordered.and_raise(IOError)
65
+
66
+ expect do
67
+ Steno::Sink::IO.new(io, :codec => codec).add_record(record)
68
+ end.to raise_error(IOError)
69
+ end
70
+
71
+ it "should retry not more than specified number of times on IOError" do
72
+ codec = double("codec")
73
+ expect(codec).to receive(:encode_record).with(record).and_return(record.message)
74
+
75
+ io = double("io")
76
+
77
+ expect(io).to receive(:write).exactly(3).times.with(record.message).
78
+ and_raise(IOError)
79
+
80
+ expect do
81
+ Steno::Sink::IO.new(io, :codec => codec, :max_retries => 2).
82
+ add_record(record)
83
+ end.to raise_error(IOError)
84
+ end
85
+
86
+ it "should retry on IOError and succeed" do
87
+ codec = double("codec")
88
+ expect(codec).to receive(:encode_record).with(record).and_return(record.message)
89
+
90
+ io = double("io")
91
+ expect(io).to receive(:write).with(record.message).once.
92
+ and_raise(IOError)
93
+ expect(io).to receive(:write).with(record.message).once.ordered.
94
+ and_return(record.message)
95
+
96
+ expect do
97
+ Steno::Sink::IO.new(io, :codec => codec, :max_retries => 1).
98
+ add_record(record)
99
+ end.to_not raise_error
100
+ end
101
+ end
102
+
103
+ describe "#flush" do
104
+ it "should call flush on the underlying io object" do
105
+ io = double("io")
106
+ expect(io).to receive(:flush)
107
+
108
+ Steno::Sink::IO.new(io).flush
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+ unless Steno::Sink::WINDOWS
3
+ describe Steno::Sink::Syslog do
4
+ let(:level) do
5
+ Steno::Logger.lookup_level(:info)
6
+ end
7
+
8
+ let(:record) do
9
+ Steno::Record.new("source", level.name, "message")
10
+ end
11
+
12
+ let(:record_with_big_message) do
13
+ Steno::Record.new("source", level.name,
14
+ "a" * (Steno::Sink::Syslog::MAX_MESSAGE_SIZE + 1))
15
+ end
16
+
17
+ describe "#add_record" do
18
+ after do
19
+ Syslog::Logger.syslog = nil
20
+ end
21
+
22
+ it "should append an encoded record with the correct priority" do
23
+ identity = "test"
24
+
25
+ syslog = double("syslog", facility: nil)
26
+ expect(Syslog).to receive(:open).and_return(syslog)
27
+
28
+ sink = Steno::Sink::Syslog.instance
29
+ sink.open(identity)
30
+
31
+ codec = double("codec")
32
+ expect(codec).to receive(:encode_record).with(record).and_return(record.message)
33
+ sink.codec = codec
34
+
35
+ expect(syslog).to receive(:log).with(Syslog::LOG_INFO, "%s", record.message)
36
+
37
+ sink.add_record(record)
38
+ end
39
+
40
+ it "should truncate the record message if its greater than than allowed size" do
41
+ identity = "test"
42
+
43
+ syslog = double("syslog", facility: nil)
44
+ expect(Syslog).to receive(:open).and_return(syslog)
45
+
46
+ sink = Steno::Sink::Syslog.instance
47
+ sink.open(identity)
48
+
49
+ truncated = record_with_big_message.message.
50
+ slice(0..(Steno::Sink::Syslog::MAX_MESSAGE_SIZE) - 4)
51
+ truncated << Steno::Sink::Syslog::TRUNCATE_POSTFIX
52
+ codec = double("codec")
53
+ expect(codec).to receive(:encode_record) do |*args|
54
+ expect(args.size).to eq(1)
55
+ expect(args[0].message).to eq(truncated)
56
+ expect(args[0].message.size).to be <= Steno::Sink::Syslog::MAX_MESSAGE_SIZE
57
+
58
+ next args[0].message
59
+ end
60
+
61
+ sink.codec = codec
62
+
63
+ expect(syslog).to receive(:log).with(Syslog::LOG_INFO, "%s", truncated)
64
+
65
+ sink.add_record(record_with_big_message)
66
+ end
67
+ end
68
+
69
+ describe "#flush" do
70
+ it "should do nothing" do
71
+ Steno::Sink::Syslog.instance.flush
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,86 @@
1
+ require "spec_helper"
2
+
3
+ describe Steno do
4
+ let(:config) { Steno::Config.new }
5
+
6
+ before :each do
7
+ Steno.init(config)
8
+ end
9
+
10
+ describe "#logger" do
11
+ it "should return a new Steno::Logger instance" do
12
+ logger = Steno.logger("test")
13
+ expect(logger).to_not be_nil
14
+ expect(logger.name).to eq("test")
15
+ end
16
+
17
+ it "should memoize loggers by name" do
18
+ logger1 = Steno.logger("test")
19
+ logger2 = Steno.logger("test")
20
+
21
+ expect(logger1.object_id).to eq(logger2.object_id)
22
+ end
23
+ end
24
+
25
+ describe "#set_logger_regexp" do
26
+ it "should modify the levels of existing loggers that match the regex" do
27
+ logger = Steno.logger("test")
28
+
29
+ expect(logger.level).to eq(:info)
30
+
31
+ Steno.set_logger_regexp(/te/, :debug)
32
+
33
+ expect(logger.level).to eq(:debug)
34
+ end
35
+
36
+ it "should modify the levels of new loggers after a regexp has been set" do
37
+ Steno.set_logger_regexp(/te/, :debug)
38
+
39
+ expect(Steno.logger("te").level).to eq(:debug)
40
+ end
41
+
42
+ it "should reset the levels of previously matching loggers when changed" do
43
+ Steno.set_logger_regexp(/foo/, :debug)
44
+
45
+ logger = Steno.logger("foo")
46
+ expect(logger.level).to eq(:debug)
47
+
48
+ Steno.set_logger_regexp(/bar/, :debug)
49
+
50
+ expect(logger.level).to eq(:info)
51
+ end
52
+ end
53
+
54
+ describe "#clear_logger_regexp" do
55
+ it "should reset any loggers matching the existing regexp" do
56
+ Steno.set_logger_regexp(/te/, :debug)
57
+
58
+ logger = Steno.logger("test")
59
+ expect(logger.level).to eq(:debug)
60
+
61
+ Steno.clear_logger_regexp
62
+
63
+ expect(logger.level).to eq(:info)
64
+ expect(Steno.logger_regexp).to be_nil
65
+ end
66
+ end
67
+
68
+ describe "#logger_level_snapshot" do
69
+ it "should return a hash mapping logger name to level" do
70
+ loggers = []
71
+
72
+ expected = {
73
+ "foo" => :debug,
74
+ "bar" => :warn,
75
+ }
76
+
77
+ expected.each do |name, level|
78
+ # Prevent GC
79
+ loggers << Steno.logger(name)
80
+ loggers.last.level = level
81
+ end
82
+
83
+ expect(Steno.logger_level_snapshot).to eq(expected)
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Steno::TaggedLogger do
4
+ let(:sink) { NullSink.new }
5
+ let(:logger) { Steno::Logger.new("test", [sink]) }
6
+ let(:user_data) { { "foo" => "bar" } }
7
+ let(:tagged_logger) { Steno::TaggedLogger.new(logger, user_data) }
8
+
9
+ it "should add any user data to each log record" do
10
+ tagged_logger.info("testing", "test" => "data")
11
+ expect(sink.records.size).to eq(1)
12
+ expect(sink.records[0].data).to eq(user_data.merge("test" => "data"))
13
+
14
+ tagged_logger.log_exception(RuntimeError.new("hi"))
15
+ expect(sink.records.size).to eq(2)
16
+ expect(sink.records[1].data).to eq(user_data.merge(:backtrace => nil))
17
+ end
18
+
19
+ it "should forward missing methods to the proxied logger" do
20
+ expect(tagged_logger.level).to eq(:info)
21
+ tagged_logger.level = :warn
22
+
23
+ expect(logger.level).to eq(:warn)
24
+
25
+ expect(tagged_logger.level_active?(:info)).to be_falsey
26
+ end
27
+
28
+ describe "#tag" do
29
+ it "should return a new tagged logger with merged user-data" do
30
+ tl = tagged_logger.tag("bar" => "baz")
31
+ expect(tl.proxied_logger).to eq(logger)
32
+ expect(tl.user_data).to eq(user_data.merge("bar" => "baz"))
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/steno/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["mpage, capi-pivot"]
6
+ gem.email = ["mpage@rbcon.com, zrobinson@pivotal.io"]
7
+ gem.description = "A thread-safe logging library designed to support" \
8
+ + " multiple log destinations. With changes to allow using syslog directly."
9
+ gem.summary = "A logging library."
10
+ gem.homepage = "http://www.cloudfoundry.org"
11
+
12
+ gitignore = File.readlines(".gitignore").grep(/^[^#]/).map { |s| s.chomp }
13
+
14
+ # Ignore Gemfile, this is a library
15
+ gitignore << "Gemfile*"
16
+
17
+ glob = Dir["**/*"].
18
+ reject { |f| File.directory?(f) }.
19
+ reject { |f| gitignore.any? { |i| File.fnmatch(i, f) } }
20
+
21
+ gem.files = glob
22
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
23
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
24
+ gem.name = "steno-capi"
25
+ gem.require_paths = ["lib"]
26
+ gem.version = Steno::VERSION
27
+
28
+ gem.add_dependency("yajl-ruby", "~> 1.0")
29
+ gem.add_dependency("fluent-logger")
30
+
31
+ gem.add_development_dependency("rack-test")
32
+ gem.add_development_dependency("rake")
33
+ gem.add_development_dependency("rspec", "~>3.4.0")
34
+
35
+ if RUBY_PLATFORM=~ /mswin|mingw|cygwin/
36
+ gem.platform = Gem::Platform::CURRENT
37
+ gem.add_dependency("win32-eventlog", "~> 0.6.0")
38
+ end
39
+ end
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: steno-capi
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.4
5
+ platform: ruby
6
+ authors:
7
+ - mpage, capi-pivot
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: yajl-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fluent-logger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack-test
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 3.4.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.4.0
83
+ description: A thread-safe logging library designed to support multiple log destinations.
84
+ With changes to allow using syslog directly.
85
+ email:
86
+ - mpage@rbcon.com, zrobinson@pivotal.io
87
+ executables:
88
+ - steno-prettify
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - LICENSE
93
+ - README.md
94
+ - Rakefile
95
+ - bin/steno-prettify
96
+ - lib/steno.rb
97
+ - lib/steno/codec.rb
98
+ - lib/steno/codec/base.rb
99
+ - lib/steno/codec/json.rb
100
+ - lib/steno/config.rb
101
+ - lib/steno/context.rb
102
+ - lib/steno/core_ext.rb
103
+ - lib/steno/errors.rb
104
+ - lib/steno/json_prettifier.rb
105
+ - lib/steno/log_level.rb
106
+ - lib/steno/logger.rb
107
+ - lib/steno/record.rb
108
+ - lib/steno/sink.rb
109
+ - lib/steno/sink/base.rb
110
+ - lib/steno/sink/counter.rb
111
+ - lib/steno/sink/eventlog.rb
112
+ - lib/steno/sink/fluentd.rb
113
+ - lib/steno/sink/io.rb
114
+ - lib/steno/sink/syslog.rb
115
+ - lib/steno/tagged_logger.rb
116
+ - lib/steno/version.rb
117
+ - spec/spec_helper.rb
118
+ - spec/support/barrier.rb
119
+ - spec/support/null_sink.rb
120
+ - spec/support/shared_context_specs.rb
121
+ - spec/unit/config_spec.rb
122
+ - spec/unit/context_spec.rb
123
+ - spec/unit/core_ext_spec.rb
124
+ - spec/unit/json_codec_spec.rb
125
+ - spec/unit/json_prettifier_spec.rb
126
+ - spec/unit/log_level_spec.rb
127
+ - spec/unit/logger_spec.rb
128
+ - spec/unit/record_spec.rb
129
+ - spec/unit/sink/counter_spec.rb
130
+ - spec/unit/sink/eventlog_spec.rb
131
+ - spec/unit/sink/fluentd_spec.rb
132
+ - spec/unit/sink/io_spec.rb
133
+ - spec/unit/sink/syslog_spec.rb
134
+ - spec/unit/steno_spec.rb
135
+ - spec/unit/tagged_logger_spec.rb
136
+ - steno-capi.gemspec
137
+ homepage: http://www.cloudfoundry.org
138
+ licenses: []
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 2.4.5.1
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: A logging library.
160
+ test_files:
161
+ - spec/spec_helper.rb
162
+ - spec/support/barrier.rb
163
+ - spec/support/null_sink.rb
164
+ - spec/support/shared_context_specs.rb
165
+ - spec/unit/config_spec.rb
166
+ - spec/unit/context_spec.rb
167
+ - spec/unit/core_ext_spec.rb
168
+ - spec/unit/json_codec_spec.rb
169
+ - spec/unit/json_prettifier_spec.rb
170
+ - spec/unit/log_level_spec.rb
171
+ - spec/unit/logger_spec.rb
172
+ - spec/unit/record_spec.rb
173
+ - spec/unit/sink/counter_spec.rb
174
+ - spec/unit/sink/eventlog_spec.rb
175
+ - spec/unit/sink/fluentd_spec.rb
176
+ - spec/unit/sink/io_spec.rb
177
+ - spec/unit/sink/syslog_spec.rb
178
+ - spec/unit/steno_spec.rb
179
+ - spec/unit/tagged_logger_spec.rb