steno-capi 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
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