bunyan 0.1.0
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/.gitignore +1 -0
- data/Gemfile +9 -0
- data/README.md +60 -0
- data/Rakefile +17 -0
- data/VERSION +1 -0
- data/bunyan.gemspec +56 -0
- data/lib/bunyan.rb +90 -0
- data/spec/bunyan_spec.rb +137 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +33 -0
- metadata +97 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.bundle
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
Bunyan
|
2
|
+
======
|
3
|
+
Bunyan is a thin ruby wrapper around a MongoDB [capped collection](http://www.mongodb.org/display/DOCS/Capped+Collections),
|
4
|
+
created with high-performance, flexible logging in mind.
|
5
|
+
|
6
|
+

|
7
|
+
|
8
|
+
Install
|
9
|
+
=======
|
10
|
+
gem install bunyan
|
11
|
+
|
12
|
+
Configure
|
13
|
+
=========
|
14
|
+
The only configuration options required are the database and collection name.
|
15
|
+
|
16
|
+
For rails apps, puts the config block in an initializer.
|
17
|
+
|
18
|
+
# config/initializers/bunyan.rb
|
19
|
+
Bunyan::Logger.configure do |config|
|
20
|
+
# required options
|
21
|
+
config.database 'bunyan_logger'
|
22
|
+
config.collection 'development_log'
|
23
|
+
|
24
|
+
# optional
|
25
|
+
config.disabled true
|
26
|
+
end
|
27
|
+
|
28
|
+
Usage
|
29
|
+
=====
|
30
|
+
You can access the bunyan logger anywhere is your app via Bunyan::Logger.
|
31
|
+
The Logger class is implemented as a singleton, and you can call any instance
|
32
|
+
method on the Logger class. This is implemented with some method_missing magic,
|
33
|
+
which is explained in a bit more detail below.
|
34
|
+
|
35
|
+
Internals
|
36
|
+
=========
|
37
|
+
Bunyan makes heavy usage of method\_missing both at the class and instance level.
|
38
|
+
At the class level, this is purely for convenience to pass missing class methods
|
39
|
+
to the singleton instance, which precludes us from needing to use Logger.instance
|
40
|
+
directly. At the instance level, method\_missing is used to provide a very thin
|
41
|
+
layer around MongoDB, via the Mongo driver.
|
42
|
+
|
43
|
+
The net effect of this is that there is no reason to muck around with
|
44
|
+
calling methods directly on Bunyan::Logger.instance, because all methods that
|
45
|
+
don't already exist at the class level will be sent to Bunyan::Logger.instance.
|
46
|
+
|
47
|
+
Bunyan::Logger.count == Bunyan::Logger.instance.count # => true
|
48
|
+
|
49
|
+
Also, you can call any instance methods Bunyan::Logger that you would otherwise
|
50
|
+
call on a Mongo collection object.
|
51
|
+
|
52
|
+
More
|
53
|
+
====
|
54
|
+
* [MongoDB Capped Collections](http://www.mongodb.org/display/DOCS/Capped+Collections)
|
55
|
+
* [Mongo Ruby Driver](http://github.com/mongodb/mongo-ruby-driver)
|
56
|
+
|
57
|
+
TODO
|
58
|
+
====
|
59
|
+
* Ability to limit bunyan to only run in certain environments
|
60
|
+
* Add middleware client for easy drop-in to rails/rack apps
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "bunyan"
|
5
|
+
gemspec.summary = "A MongoDB-based logging solution."
|
6
|
+
gemspec.description = "Bunyan is a thin ruby wrapper around a MongoDB capped collection, created with high-performance, flexible logging in mind."
|
7
|
+
gemspec.email = "ajsharp@gmail.com"
|
8
|
+
gemspec.homepage = "http://github.com/ajsharp/bunyan"
|
9
|
+
gemspec.authors = ["Alex Sharp"]
|
10
|
+
gemspec.add_dependency 'mongo', '>= 0.19'
|
11
|
+
gemspec.add_dependency 'mongo_ext', '>= 0.19'
|
12
|
+
end
|
13
|
+
Jeweler::GemcutterTasks.new
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
16
|
+
end
|
17
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bunyan.gemspec
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{bunyan}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Alex Sharp"]
|
12
|
+
s.date = %q{2010-03-17}
|
13
|
+
s.description = %q{Bunyan is a thin ruby wrapper around a MongoDB capped collection, created with high-performance, flexible logging in mind.}
|
14
|
+
s.email = %q{ajsharp@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"Gemfile",
|
21
|
+
"README.md",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"bunyan.gemspec",
|
25
|
+
"lib/bunyan.rb",
|
26
|
+
"spec/bunyan_spec.rb",
|
27
|
+
"spec/spec.opts",
|
28
|
+
"spec/spec_helper.rb"
|
29
|
+
]
|
30
|
+
s.homepage = %q{http://github.com/ajsharp/bunyan}
|
31
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.rubygems_version = %q{1.3.6}
|
34
|
+
s.summary = %q{A MongoDB-based logging solution.}
|
35
|
+
s.test_files = [
|
36
|
+
"spec/bunyan_spec.rb",
|
37
|
+
"spec/spec_helper.rb"
|
38
|
+
]
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
|
+
s.specification_version = 3
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
45
|
+
s.add_runtime_dependency(%q<mongo>, [">= 0.19"])
|
46
|
+
s.add_runtime_dependency(%q<mongo_ext>, [">= 0.19"])
|
47
|
+
else
|
48
|
+
s.add_dependency(%q<mongo>, [">= 0.19"])
|
49
|
+
s.add_dependency(%q<mongo_ext>, [">= 0.19"])
|
50
|
+
end
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<mongo>, [">= 0.19"])
|
53
|
+
s.add_dependency(%q<mongo_ext>, [">= 0.19"])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
data/lib/bunyan.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
#gem 'mongo_ext'
|
4
|
+
|
5
|
+
require 'mongo'
|
6
|
+
require 'singleton'
|
7
|
+
|
8
|
+
module Bunyan
|
9
|
+
class Logger
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
class InvalidConfigurationError < RuntimeError; end
|
13
|
+
|
14
|
+
attr_reader :db, :connection, :config
|
15
|
+
|
16
|
+
# Bunyan::Logger.configure do |config|
|
17
|
+
# # required options
|
18
|
+
# config.database 'bunyan_logger'
|
19
|
+
# config.collection 'development_log'
|
20
|
+
# end
|
21
|
+
def configure(&block)
|
22
|
+
@config = {}
|
23
|
+
|
24
|
+
yield self
|
25
|
+
|
26
|
+
ensure_required_options_exist
|
27
|
+
initialize_connection unless disabled?
|
28
|
+
end
|
29
|
+
|
30
|
+
# First time called sets the database name.
|
31
|
+
# Otherwise, returns the database name.
|
32
|
+
def database(db_name = nil)
|
33
|
+
@config[:database] ||= db_name
|
34
|
+
end
|
35
|
+
alias_method :database=, :database
|
36
|
+
|
37
|
+
# First time called sets the collection name.
|
38
|
+
# Otherwise, returns the collection name.
|
39
|
+
# For the actual collection object returned by Mongo, see #db.
|
40
|
+
def collection(coll = nil)
|
41
|
+
@config[:collection] ||= coll
|
42
|
+
end
|
43
|
+
alias_method :collection=, :collection
|
44
|
+
|
45
|
+
def disabled(dis = nil)
|
46
|
+
@config[:disabled] ||= dis
|
47
|
+
end
|
48
|
+
alias_method :disabled=, :disabled
|
49
|
+
|
50
|
+
def disabled?
|
51
|
+
!!disabled
|
52
|
+
end
|
53
|
+
|
54
|
+
def method_missing(method, *args, &block)
|
55
|
+
begin
|
56
|
+
db.send(method, *args)
|
57
|
+
rescue
|
58
|
+
super(method, *args, &block)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Pass all missing class methods to the singleton instance
|
63
|
+
def self.method_missing(method, *args, &block)
|
64
|
+
Logger.instance.send(method, *args, &block)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def initialize_connection
|
69
|
+
@connection = Mongo::Connection.new.db(database)
|
70
|
+
@db = retrieve_or_initialize_collection(collection)
|
71
|
+
end
|
72
|
+
|
73
|
+
def ensure_required_options_exist
|
74
|
+
raise InvalidConfigurationError, 'Error! Please provide a database name.' unless database
|
75
|
+
raise InvalidConfigurationError, 'Error! Please provide a collection name.' unless collection
|
76
|
+
end
|
77
|
+
|
78
|
+
def retrieve_or_initialize_collection(collection_name)
|
79
|
+
if collection_exists?(collection_name)
|
80
|
+
connection.collection(collection_name)
|
81
|
+
else
|
82
|
+
connection.create_collection(collection_name, :capped => true)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def collection_exists?(collection_name)
|
87
|
+
connection.collection_names.include? collection_name
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/spec/bunyan_spec.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bunyan::Logger do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@conn = mock_mongo_connection
|
7
|
+
@logger = Bunyan::Logger.instance
|
8
|
+
@logger.stub!(:connection).and_return(@conn)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should have a connection' do
|
12
|
+
@logger.should respond_to :connection
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should have a collection' do
|
16
|
+
@logger.should respond_to :collection
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should have a config hash' do
|
20
|
+
@logger.config.should be_a Hash
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should create a new capped collection if the collection does not already exist' do
|
24
|
+
@conn.should_receive(:create_collection).with('collection_1', :capped => true)
|
25
|
+
@conn.stub!(:collection_names).and_return([])
|
26
|
+
Bunyan::Logger.configure do |config|
|
27
|
+
config.database 'database_1'
|
28
|
+
config.collection 'collection_1'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should not create a new collection if one already exists by that name' do
|
33
|
+
@conn.should_not_receive(:create_collection)
|
34
|
+
@conn.collection_names.should_receive(:include?).with('collection_1').and_return(true)
|
35
|
+
Bunyan::Logger.configure do |config|
|
36
|
+
config.database 'database_1'
|
37
|
+
config.collection 'collection_1'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'the required config options' do
|
44
|
+
it 'should raise an error if a db name is not provided' do
|
45
|
+
lambda {
|
46
|
+
Bunyan::Logger.configure do |c|
|
47
|
+
c.collection 'collection_without_database'
|
48
|
+
end
|
49
|
+
}.should raise_exception(Bunyan::Logger::InvalidConfigurationError, 'Error! Please provide a database name.')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should raise an error if a db collection is not provided' do
|
53
|
+
lambda {
|
54
|
+
Bunyan::Logger.configure do |c|
|
55
|
+
c.database 'db_without_collection'
|
56
|
+
end
|
57
|
+
}.should raise_exception(Bunyan::Logger::InvalidConfigurationError, 'Error! Please provide a collection name.')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'bunyan logger configuration' do
|
62
|
+
describe 'setting config values' do
|
63
|
+
before do
|
64
|
+
Bunyan::Logger.configure do |c|
|
65
|
+
c.database 'database2'
|
66
|
+
c.collection 'collection2'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should allow setting of the database' do
|
71
|
+
Bunyan::Logger.database.should == 'database2'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'shoudl allow setting of the collection name' do
|
75
|
+
Bunyan::Logger.collection.should == 'collection2'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'the optional config options' do
|
80
|
+
it 'should allow the user to mark bunyan as disabled' do
|
81
|
+
Bunyan::Logger.configure do |c|
|
82
|
+
c.database 'test_db'
|
83
|
+
c.collection 'test_collection'
|
84
|
+
c.disabled true
|
85
|
+
end
|
86
|
+
Bunyan::Logger.should be_disabled
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "when the disabled flag is set" do
|
91
|
+
it 'should not create a new logger instance' do
|
92
|
+
Bunyan::Logger.should_not_receive(:initialize_connection)
|
93
|
+
Bunyan::Logger.configure do |c|
|
94
|
+
c.database 'test_db'
|
95
|
+
c.collection 'test_collection'
|
96
|
+
c.disabled true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe Bunyan::Logger, "#disabled?" do
|
103
|
+
it "should return false if nothing is set" do
|
104
|
+
Bunyan::Logger.configure do |config|
|
105
|
+
config.database 'my_database'
|
106
|
+
config.collection 'my_collection'
|
107
|
+
end
|
108
|
+
Bunyan::Logger.disabled?.should == false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe 'the database getter' do
|
113
|
+
it 'should allow setting of the database' do
|
114
|
+
Bunyan::Logger.configure do |config|
|
115
|
+
config.database 'my_database'
|
116
|
+
config.collection 'my_collection'
|
117
|
+
end
|
118
|
+
Bunyan::Logger.instance.database.should == 'my_database'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe 'mongodb instance methods passed to a logger instance' do
|
123
|
+
it 'should be passed through to the collection' do
|
124
|
+
Bunyan::Logger.db.should_receive(:count)
|
125
|
+
Bunyan::Logger.count
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe 'alternate configuration syntax' do
|
130
|
+
it 'should allow a user to set config options with traditional setters' do
|
131
|
+
Bunyan::Logger.configure do |config|
|
132
|
+
config.database = 'some_database'
|
133
|
+
config.collection = 'some_collection'
|
134
|
+
end
|
135
|
+
Bunyan::Logger.config[:database].should == 'some_database'
|
136
|
+
end
|
137
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
Bundler.setup
|
2
|
+
Bundler.require :default, :test
|
3
|
+
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/bunyan')
|
5
|
+
$LOAD_PATH.unshift File.expand_path(__FILE__)
|
6
|
+
|
7
|
+
Spec::Runner.configure do |config|
|
8
|
+
|
9
|
+
config.after :each do
|
10
|
+
cleanup_bunyan_config
|
11
|
+
end
|
12
|
+
|
13
|
+
config.before :each do
|
14
|
+
mock_mongo_connection
|
15
|
+
end
|
16
|
+
|
17
|
+
def mock_mongo_connection
|
18
|
+
@mock_collection = mock("Mongo Collection")
|
19
|
+
@mock_database = mock("Mongo Database",
|
20
|
+
:collection => @mock_collection,
|
21
|
+
:create_collection => @mock_collection,
|
22
|
+
:collection_names => ['name 1'])
|
23
|
+
@mock_connection = mock("Mongo Connection", :db => @mock_database)
|
24
|
+
Mongo::Connection.stub!(:new).and_return(@mock_connection)
|
25
|
+
@mock_database
|
26
|
+
end
|
27
|
+
|
28
|
+
def cleanup_bunyan_config
|
29
|
+
Bunyan::Logger.instance_variable_set(:@database, nil)
|
30
|
+
Bunyan::Logger.instance_variable_set(:@collection, nil)
|
31
|
+
Bunyan::Logger.instance_variable_set(:@db, nil)
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bunyan
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Alex Sharp
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-17 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: mongo
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 19
|
30
|
+
version: "0.19"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: mongo_ext
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
segments:
|
41
|
+
- 0
|
42
|
+
- 19
|
43
|
+
version: "0.19"
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
46
|
+
description: Bunyan is a thin ruby wrapper around a MongoDB capped collection, created with high-performance, flexible logging in mind.
|
47
|
+
email: ajsharp@gmail.com
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files:
|
53
|
+
- README.md
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- Gemfile
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- VERSION
|
60
|
+
- bunyan.gemspec
|
61
|
+
- lib/bunyan.rb
|
62
|
+
- spec/bunyan_spec.rb
|
63
|
+
- spec/spec.opts
|
64
|
+
- spec/spec_helper.rb
|
65
|
+
has_rdoc: true
|
66
|
+
homepage: http://github.com/ajsharp/bunyan
|
67
|
+
licenses: []
|
68
|
+
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options:
|
71
|
+
- --charset=UTF-8
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.3.6
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: A MongoDB-based logging solution.
|
95
|
+
test_files:
|
96
|
+
- spec/bunyan_spec.rb
|
97
|
+
- spec/spec_helper.rb
|