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 ADDED
@@ -0,0 +1 @@
1
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ gem 'mongo', '>= 0.19'
2
+ gem 'mongo_ext', '>= 0.19'
3
+
4
+ group :test do
5
+ gem 'rspec', '>= 1.3.0'
6
+ gem 'ZenTest'
7
+ gem 'autotest-growl'
8
+ gem 'autotest-fsevent'
9
+ end
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
+ ![](http://img2.timeinc.net/ew/dynamic/imgs/080612/Paul-Bunyan-Blue-Ox_l.jpg)
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
@@ -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
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format
3
+ s
4
+ --loadby mtime
5
+ --reverse
@@ -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