logstuff 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +101 -0
- data/Rakefile +51 -0
- data/lib/logstuff/version.rb +3 -0
- data/lib/logstuff.rb +115 -0
- data/logstuff.gemspec +27 -0
- data/spec/lib/logstuff_spec.rb +102 -0
- data/spec/spec_helper.rb +37 -0
- metadata +140 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 874141089c82cc738dfed4a5d9911b671a5f0a19
|
|
4
|
+
data.tar.gz: bddd43af5b4283c869a69a9d850df5e316efb62f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: af64bc04db1aabb44b3659db7a44f2d800468fe5db9f6e5a7f63001e5b7e5308b662ea488b9bc6c12ad94bd0d56457af3835a044917154e2fa5a71dfc6bea752
|
|
7
|
+
data.tar.gz: ce26e32e3164061f7853f7d36de9c518ce60e02a556e2076518d79f8e1be3bbad90efdb631d06e1b07711b1a3f93d90b11ac67467c6549dcfbb72dcd85c0e2f4
|
data/.gitignore
ADDED
data/Gemfile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
gemspec
|
|
3
|
+
|
|
4
|
+
group :test do
|
|
5
|
+
gem 'growl'
|
|
6
|
+
gem 'guard'
|
|
7
|
+
gem 'guard-rspec'
|
|
8
|
+
gem 'rails', "~> #{ENV["RAILS_VERSION"] || "3.2.0"}"
|
|
9
|
+
gem 'rb-fsevent', '~> 0.9'
|
|
10
|
+
gem 'rcov', :platforms => :mri_18
|
|
11
|
+
gem 'redis', :require => false
|
|
12
|
+
gem 'simplecov', :platforms => :mri_19, :require => false
|
|
13
|
+
end
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2014 Paul Rhodes
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Logstuff
|
|
2
|
+
|
|
3
|
+
Logstuff is a rubygem for writing application logs in a more structured form.
|
|
4
|
+
|
|
5
|
+
It will output the logs in JSON format to allow collection from logstash/beaver
|
|
6
|
+
or equivalent into a central logging store such as elasticsearch.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
Add this line to your application's Gemfile:
|
|
11
|
+
|
|
12
|
+
gem 'logstuff'
|
|
13
|
+
|
|
14
|
+
And then execute:
|
|
15
|
+
|
|
16
|
+
$ bundle
|
|
17
|
+
|
|
18
|
+
Or install it yourself as:
|
|
19
|
+
|
|
20
|
+
$ gem install logstuff
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
The example IRB session below shows examples of the usage of LogStuff and the associated JSON output generated.
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
# Setup LogStuff to output to STDOUT
|
|
28
|
+
2.1.2 :001 > LogStuff.setup(:logger => LogStuff.new_logger(STDOUT, Logger::INFO))
|
|
29
|
+
=> true
|
|
30
|
+
|
|
31
|
+
# Simple basic logging message
|
|
32
|
+
2.1.2 :002 > LogStuff.info { "Test message" }
|
|
33
|
+
{"@source":"logstuff","@tags":[],"@fields":{},"@severity":"info","message":"Test message","@timestamp":"2014-10-20T08:41:36.950904+00:00"}
|
|
34
|
+
=> 139
|
|
35
|
+
|
|
36
|
+
# Basic logging with additional tags for categorising messages
|
|
37
|
+
2.1.2 :004 > LogStuff.info(:mail,:deliver) { "Test message" }
|
|
38
|
+
{"@source":"logstuff","@tags":["mail","deliver"],"@fields":{},"@severity":"info","message":"Test message","@timestamp":"2014-10-20T08:42:07.589854+00:00"}
|
|
39
|
+
=> 155
|
|
40
|
+
|
|
41
|
+
# Basic logging with additional key/value pairs specified for inclusion in the @fields structure
|
|
42
|
+
2.1.2 :008 > LogStuff.info(:key1 => '1234', :key2 => '5678') { "Test message" }
|
|
43
|
+
{"@source":"logstuff","@tags":[],"@fields":{"key1":"1234","key2":"5678"},"@severity":"info","message":"Test message","@timestamp":"2014-10-20T08:43:04.035798+00:00"}
|
|
44
|
+
=> 166
|
|
45
|
+
|
|
46
|
+
# Using with tag method allows all log messages within the block to inherit those tags
|
|
47
|
+
2.1.2 :009 > LogStuff.tag(:tag1) do
|
|
48
|
+
2.1.2 :010 > LogStuff.info { "A different log message" }
|
|
49
|
+
2.1.2 :011?> end
|
|
50
|
+
{"@source":"logstuff","@tags":["tag1"],"@fields":{},"@severity":"info","message":"A different log message","@timestamp":"2014-10-20T08:44:06.329569+00:00"}
|
|
51
|
+
=> #<Set: {}>
|
|
52
|
+
|
|
53
|
+
# The same can be achieved with the metadata method
|
|
54
|
+
2.1.2 :012 > LogStuff.metadata(:request_id => '345') do
|
|
55
|
+
2.1.2 :013 > LogStuff.info { "A different log message" }
|
|
56
|
+
2.1.2 :014?> end
|
|
57
|
+
{"@source":"logstuff","@tags":[],"@fields":{"request_id":"345"},"@severity":"info","message":"A different log message","@timestamp":"2014-10-20T08:44:47.688320+00:00"}
|
|
58
|
+
=> {}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Configuring for use with Rails
|
|
62
|
+
|
|
63
|
+
To use with Rails first create a new logger and then pass that logger into LogStuff.setup. It is necessary
|
|
64
|
+
to use a wrapping function around to Logger.new to ensure that the autogenerated comment does not appear
|
|
65
|
+
at the top of the generated log file which is non-json and will confuse logstash/beaver.
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
# Custom Logging
|
|
69
|
+
jsonlogger = LogStuff.new_logger("#{Rails.root}/log/output.json", Logger::INFO)
|
|
70
|
+
LogStuff.setup(:logger => jsonlogger)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
Often you might wish to use this library in conjunction with the logstasher gem for encapsulating request
|
|
75
|
+
logs and exceptions. The following block can be used to enable both gems and allow them to reuse a common
|
|
76
|
+
logger.
|
|
77
|
+
|
|
78
|
+
```ruby
|
|
79
|
+
# Custom Logging
|
|
80
|
+
jsonlogger = LogStuff.new_logger("#{Rails.root}/log/output.json", Logger::INFO)
|
|
81
|
+
|
|
82
|
+
config.log_level = :info
|
|
83
|
+
config.logstasher.enabled = true
|
|
84
|
+
config.logstasher.suppress_app_log = false
|
|
85
|
+
config.logstasher.logger = jsonlogger
|
|
86
|
+
# Need to specifically set the logstasher loglevel since it will overwrite the one set earlier
|
|
87
|
+
config.logstasher.log_level = Logger::INFO
|
|
88
|
+
config.logstasher.source = 'logstasher'
|
|
89
|
+
|
|
90
|
+
# Reuse logstasher logger with logstuff
|
|
91
|
+
LogStuff.setup(:logger => jsonlogger)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
## Contributing
|
|
96
|
+
|
|
97
|
+
1. Fork it ( http://github.com/withnale/logstuff/fork )
|
|
98
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
99
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
100
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
101
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
2
|
+
require 'rspec/core/rake_task'
|
|
3
|
+
|
|
4
|
+
# Add default task. When you type just rake command this would run. Travis CI runs this. Making this run spec
|
|
5
|
+
desc 'Default: run specs.'
|
|
6
|
+
task :default => :spec
|
|
7
|
+
|
|
8
|
+
# Defining spec task for running spec
|
|
9
|
+
desc "Run specs"
|
|
10
|
+
RSpec::Core::RakeTask.new('spec') do |spec|
|
|
11
|
+
# Pattern filr for spec files to run. This is default btw.
|
|
12
|
+
spec.pattern = "./spec/**/*_spec.rb"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Run the rdoc task to generate rdocs for this gem
|
|
16
|
+
require 'rdoc/task'
|
|
17
|
+
RDoc::Task.new do |rdoc|
|
|
18
|
+
require "logstuff/version"
|
|
19
|
+
version = Logstuff::VERSION
|
|
20
|
+
|
|
21
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
22
|
+
rdoc.title = "logstuff #{version}"
|
|
23
|
+
rdoc.rdoc_files.include('README*')
|
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Code coverage tasks. Different for Ruby 1.8 vs 1.9
|
|
28
|
+
if RUBY_VERSION =~ /^1\.8/
|
|
29
|
+
# Ruby 1.8 uses rcov for code coverage
|
|
30
|
+
RSpec::Core::RakeTask.new(:coverage) do |spec|
|
|
31
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
|
32
|
+
spec.rcov = true
|
|
33
|
+
spec.rcov_opts = %w{--exclude pkg\/,spec\/,features\/}
|
|
34
|
+
end
|
|
35
|
+
else
|
|
36
|
+
# Ruby 1.9+ using simplecov. Note: Simplecov config defined in spec_helper
|
|
37
|
+
desc "Code coverage detail"
|
|
38
|
+
task :coverage do
|
|
39
|
+
ENV['COVERAGE'] = "true"
|
|
40
|
+
Rake::Task['spec'].execute
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
task :console do
|
|
45
|
+
require 'irb'
|
|
46
|
+
require 'irb/completion'
|
|
47
|
+
require 'logger'
|
|
48
|
+
require 'logstuff'
|
|
49
|
+
ARGV.clear
|
|
50
|
+
IRB.start
|
|
51
|
+
end
|
data/lib/logstuff.rb
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
require "logstuff/version"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
require 'thread'
|
|
5
|
+
|
|
6
|
+
module LogStuff
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
attr_accessor :logger_path
|
|
10
|
+
attr_accessor :logger, :source
|
|
11
|
+
|
|
12
|
+
NAMESPACE = :log
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_thread_current(name)
|
|
16
|
+
Thread.current[NAMESPACE] ||= {
|
|
17
|
+
:current_fields => {},
|
|
18
|
+
:current_tags => Set.new
|
|
19
|
+
}
|
|
20
|
+
Thread.current[NAMESPACE][name].dup
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def set_thread_current(name, value)
|
|
25
|
+
Thread.current[NAMESPACE] ||= {
|
|
26
|
+
:current_fields => {},
|
|
27
|
+
:current_tags => Set.new
|
|
28
|
+
}
|
|
29
|
+
Thread.current[NAMESPACE][name] = value.dup
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def self.log(severity = 'info', *args, &block)
|
|
34
|
+
|
|
35
|
+
return unless block_given?
|
|
36
|
+
|
|
37
|
+
# Ignore if we are not logging this severity
|
|
38
|
+
return unless logger.send("#{severity}?")
|
|
39
|
+
|
|
40
|
+
local_fields = {}
|
|
41
|
+
local_tags = Set.new
|
|
42
|
+
args.each do |arg|
|
|
43
|
+
case arg
|
|
44
|
+
when Hash
|
|
45
|
+
local_fields.merge!(arg)
|
|
46
|
+
when Symbol
|
|
47
|
+
local_tags.add(arg)
|
|
48
|
+
when Array
|
|
49
|
+
local_tags.merge(arg)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
msg = yield
|
|
54
|
+
|
|
55
|
+
event = LogStash::Event.new('@source' => source,
|
|
56
|
+
'@severity' => severity,
|
|
57
|
+
'message' => msg,
|
|
58
|
+
'@tags' => get_thread_current(:current_tags).merge(local_tags).to_a,
|
|
59
|
+
'@fields' => get_thread_current(:current_fields).merge(local_fields)
|
|
60
|
+
)
|
|
61
|
+
logger << event.to_json + "\n"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
%w( fatal error warn info debug ).each do |severity|
|
|
66
|
+
eval <<-EOM, nil, __FILE__, __LINE__ + 1
|
|
67
|
+
def self.#{severity}(*args, &block)
|
|
68
|
+
self.log(:#{severity}, *args, &block )
|
|
69
|
+
end
|
|
70
|
+
EOM
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def tag(*tags, &block)
|
|
75
|
+
original_tags = get_thread_current(:current_tags)
|
|
76
|
+
current_tags = original_tags.dup + tags.flatten
|
|
77
|
+
set_thread_current(:current_tags, current_tags)
|
|
78
|
+
yield
|
|
79
|
+
set_thread_current(:current_tags, original_tags)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def metadata(*pairs, &block)
|
|
84
|
+
original_fields = get_thread_current(:current_fields) || {}
|
|
85
|
+
current_fields = original_fields.dup
|
|
86
|
+
pairs.flatten.each do |pair|
|
|
87
|
+
pair.each do |k, v|
|
|
88
|
+
current_fields[k.to_sym] = v
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
set_thread_current(:current_fields, current_fields)
|
|
92
|
+
yield
|
|
93
|
+
set_thread_current(:current_fields, original_fields)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def setup(params)
|
|
98
|
+
require 'logstash-event'
|
|
99
|
+
self.logger_path = params[:path] || "logstuff.json"
|
|
100
|
+
self.logger = params[:logger] || new_logger(self.logger_path, params[:loglevel])
|
|
101
|
+
self.source = params[:source] || 'logstuff'
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def new_logger(path, loglevel)
|
|
106
|
+
if path.class == String
|
|
107
|
+
FileUtils.touch path # prevent autocreate messages in log
|
|
108
|
+
end
|
|
109
|
+
newlogger = Logger.new path
|
|
110
|
+
newlogger.level = loglevel unless loglevel.nil?
|
|
111
|
+
newlogger
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
end
|
data/logstuff.gemspec
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'logstuff/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "logstuff"
|
|
8
|
+
spec.version = Logstuff::VERSION
|
|
9
|
+
spec.authors = ["Paul Rhodes"]
|
|
10
|
+
spec.email = ["withnale@users.noreply.github.com"]
|
|
11
|
+
spec.summary = %q{Structured Logging for use with Logstash}
|
|
12
|
+
spec.homepage = ""
|
|
13
|
+
spec.license = "MIT"
|
|
14
|
+
|
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
18
|
+
spec.require_paths = ["lib"]
|
|
19
|
+
|
|
20
|
+
spec.add_runtime_dependency 'request_store'
|
|
21
|
+
spec.add_runtime_dependency 'logstash-event', '~> 1.1.0'
|
|
22
|
+
|
|
23
|
+
spec.add_development_dependency('rspec', '>= 2.14')
|
|
24
|
+
spec.add_development_dependency('bundler', '>= 1.0.0')
|
|
25
|
+
spec.add_development_dependency('rails', '>= 3.0')
|
|
26
|
+
spec.add_development_dependency "rake"
|
|
27
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Logstuff do
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
describe '.log' do
|
|
7
|
+
let(:logger) { LogStuff.new_logger('tempfile', Logger::INFO) }
|
|
8
|
+
before do
|
|
9
|
+
LogStuff.setup(:logger => logger)
|
|
10
|
+
allow(LogStash::Time).to receive_messages(:now => 'timestamp')
|
|
11
|
+
allow_message_expectations_on_nil
|
|
12
|
+
end
|
|
13
|
+
it 'adds to log with specified level' do
|
|
14
|
+
#expect(logger).to receive(:send).with('warn?').and_return(true)
|
|
15
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":[],"@fields":{},"@severity":"warn","message":"WARNING","@timestamp":"timestamp"}\n|)
|
|
16
|
+
LogStuff.log('warn') { 'WARNING' }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'adds to log with specified level and tags' do
|
|
20
|
+
#expect(logger).to receive(:send).with('warn?').and_return(true)
|
|
21
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":["tag1","tag2"],"@fields":{},"@severity":"warn","message":"WARNING","@timestamp":"timestamp"}\n|)
|
|
22
|
+
LogStuff.log('warn', :tag1, :tag2) { 'WARNING' }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'adds to log with specified level and hash' do
|
|
26
|
+
#expect(logger).to receive(:send).with('warn?').and_return(true)
|
|
27
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":[],"@fields":{"key1":"value1","key2":"value2"},"@severity":"warn","message":"WARNING","@timestamp":"timestamp"}\n|)
|
|
28
|
+
LogStuff.log('warn', :key1 => 'value1', :key2 => 'value2') { 'WARNING' }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe ".loglevel" do
|
|
34
|
+
%w( fatal error warn info debug ).each do |severity|
|
|
35
|
+
describe ".#{severity}" do
|
|
36
|
+
let(:message) { "This is a #{severity} message" }
|
|
37
|
+
let(:logger) { LogStuff.new_logger('tempfile', Logger::DEBUG) }
|
|
38
|
+
before do
|
|
39
|
+
LogStuff.setup(:logger => logger)
|
|
40
|
+
allow(LogStash::Time).to receive_messages(:now => 'timestamp')
|
|
41
|
+
allow_message_expectations_on_nil
|
|
42
|
+
end
|
|
43
|
+
it 'adds to log with specified level' do
|
|
44
|
+
#expect(logger).to receive(:send).with('warn?').and_return(true)
|
|
45
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":[],"@fields":{},"@severity":"#{severity}","message":"#{message}","@timestamp":"timestamp"}\n|)
|
|
46
|
+
LogStuff.send(severity) { message }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'adds to log with specified level and tags' do
|
|
50
|
+
#expect(logger).to receive(:send).with('warn?').and_return(true)
|
|
51
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":["tag1","tag2"],"@fields":{},"@severity":"#{severity}","message":"#{message}","@timestamp":"timestamp"}\n|)
|
|
52
|
+
LogStuff.send(severity, :tag1, :tag2) { message }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'adds to log with specified level and hash' do
|
|
56
|
+
#expect(logger).to receive(:send).with('warn?').and_return(true)
|
|
57
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":[],"@fields":{"key1":"value1","key2":"value2"},"@severity":"#{severity}","message":"#{message}","@timestamp":"timestamp"}\n|)
|
|
58
|
+
LogStuff.send(severity, :key1 => 'value1', :key2 => 'value2') { message }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "block" do
|
|
65
|
+
let(:severity) { "warn"}
|
|
66
|
+
let(:message1) { "This is a #{severity} message 1" }
|
|
67
|
+
let(:message2) { "This is a #{severity} message 2" }
|
|
68
|
+
|
|
69
|
+
let(:logger) { LogStuff.new_logger('tempfile', Logger::DEBUG) }
|
|
70
|
+
before do
|
|
71
|
+
LogStuff.setup(:logger => logger)
|
|
72
|
+
allow(LogStash::Time).to receive_messages(:now => 'timestamp')
|
|
73
|
+
allow_message_expectations_on_nil
|
|
74
|
+
end
|
|
75
|
+
it 'adds tags only within a block' do
|
|
76
|
+
#expect(logger).to receive(:send).with('warn?').and_return(true)
|
|
77
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":["tag1","tag2"],"@fields":{},"@severity":"#{severity}","message":"#{message1}","@timestamp":"timestamp"}\n|)
|
|
78
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":[],"@fields":{},"@severity":"#{severity}","message":"#{message2}","@timestamp":"timestamp"}\n|)
|
|
79
|
+
|
|
80
|
+
LogStuff.tag(:tag1, :tag2) do
|
|
81
|
+
LogStuff.warn { message1 }
|
|
82
|
+
end
|
|
83
|
+
LogStuff.warn { message2 }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'adds fields only within a block' do
|
|
87
|
+
#expect(logger).to receive(:send).with('warn?').and_return(true)
|
|
88
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":[],"@fields":{"key1":"value1","key2":"value2"},"@severity":"#{severity}","message":"#{message1}","@timestamp":"timestamp"}\n|)
|
|
89
|
+
expect(logger).to receive(:<<).with(%Q|{"@source":"logstuff","@tags":[],"@fields":{},"@severity":"#{severity}","message":"#{message2}","@timestamp":"timestamp"}\n|)
|
|
90
|
+
|
|
91
|
+
LogStuff.metadata(:key1 => 'value1', :key2 => 'value2') do
|
|
92
|
+
LogStuff.warn { message1 }
|
|
93
|
+
end
|
|
94
|
+
LogStuff.warn { message2 }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Notice there is a .rspec file in the root folder. It defines rspec arguments
|
|
2
|
+
|
|
3
|
+
# Ruby 1.9 uses simplecov. The ENV['COVERAGE'] is set when rake coverage is run in ruby 1.9
|
|
4
|
+
if ENV['COVERAGE']
|
|
5
|
+
require 'simplecov'
|
|
6
|
+
SimpleCov.start do
|
|
7
|
+
# Remove the spec folder from coverage. By default all code files are included. For more config options see
|
|
8
|
+
# https://github.com/colszowka/simplecov
|
|
9
|
+
add_filter File.expand_path('../../spec', __FILE__)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Modify load path so you can require 'ogstasher directly.
|
|
14
|
+
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
|
15
|
+
|
|
16
|
+
require 'rubygems'
|
|
17
|
+
# Loads bundler setup tasks. Now if I run spec without installing gems then it would say gem not installed and
|
|
18
|
+
# do bundle install instead of ugly load error on require.
|
|
19
|
+
require 'bundler/setup'
|
|
20
|
+
|
|
21
|
+
# This will require me all the gems automatically for the groups. If I do only .setup then I will have to require gems
|
|
22
|
+
# manually. Note that you have still have to require some gems if they are part of bigger gem like ActiveRecord which is
|
|
23
|
+
# part of Rails. You can say :require => false in gemfile to always use explicit requiring
|
|
24
|
+
Bundler.require(:default, :test)
|
|
25
|
+
|
|
26
|
+
Dir[File.join("./spec/support/**/*.rb")].each { |f| require f }
|
|
27
|
+
|
|
28
|
+
# Set Rails environment as test
|
|
29
|
+
ENV['RAILS_ENV'] = 'test'
|
|
30
|
+
|
|
31
|
+
require 'logger'
|
|
32
|
+
require 'logstash-event'
|
|
33
|
+
|
|
34
|
+
RSpec.configure do |config|
|
|
35
|
+
config.run_all_when_everything_filtered = true
|
|
36
|
+
config.filter_run :focus
|
|
37
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: logstuff
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Paul Rhodes
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-10-20 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: request_store
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: logstash-event
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 1.1.0
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 1.1.0
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '2.14'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '2.14'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: bundler
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 1.0.0
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 1.0.0
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rails
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '3.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.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rake
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
description:
|
|
98
|
+
email:
|
|
99
|
+
- withnale@users.noreply.github.com
|
|
100
|
+
executables: []
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files: []
|
|
103
|
+
files:
|
|
104
|
+
- ".gitignore"
|
|
105
|
+
- Gemfile
|
|
106
|
+
- LICENSE.txt
|
|
107
|
+
- README.md
|
|
108
|
+
- Rakefile
|
|
109
|
+
- lib/logstuff.rb
|
|
110
|
+
- lib/logstuff/version.rb
|
|
111
|
+
- logstuff.gemspec
|
|
112
|
+
- spec/lib/logstuff_spec.rb
|
|
113
|
+
- spec/spec_helper.rb
|
|
114
|
+
homepage: ''
|
|
115
|
+
licenses:
|
|
116
|
+
- MIT
|
|
117
|
+
metadata: {}
|
|
118
|
+
post_install_message:
|
|
119
|
+
rdoc_options: []
|
|
120
|
+
require_paths:
|
|
121
|
+
- lib
|
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
|
+
requirements:
|
|
124
|
+
- - ">="
|
|
125
|
+
- !ruby/object:Gem::Version
|
|
126
|
+
version: '0'
|
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
requirements: []
|
|
133
|
+
rubyforge_project:
|
|
134
|
+
rubygems_version: 2.2.2
|
|
135
|
+
signing_key:
|
|
136
|
+
specification_version: 4
|
|
137
|
+
summary: Structured Logging for use with Logstash
|
|
138
|
+
test_files:
|
|
139
|
+
- spec/lib/logstuff_spec.rb
|
|
140
|
+
- spec/spec_helper.rb
|