winston_mongodb_rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Alastair Brunton
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # Winston Mongodb Rails
2
+
3
+ Initial alpha release, still tied to a rails application config. There are no test, and some tight coupling deep in the code.
4
+ Hopefully this should be improved in later releases.
5
+
6
+
7
+ ## Installation
8
+
9
+ Add the gem to your Gemfile
10
+
11
+ gem 'winston_mongodb_rails'
12
+
13
+ Add `config/initializers/mongo_logger.rb`
14
+
15
+ app_config = Rails.application.config
16
+ Mog = WinstonMongodbRails::MongoLogger.create_logger(app_config, ((app_config.paths.log.to_a rescue nil) || app_config.paths['log']).first)
17
+
18
+ ## Usage
19
+
20
+ Mog.error "This is an error", object_to_inspect
21
+ Mog.debug "Debug message"
22
+ Mog.info "Info message"
23
+
24
+
@@ -0,0 +1,101 @@
1
+ class MongoDatabase
2
+
3
+ attr_reader :connection
4
+
5
+ def initialize(options = {})
6
+
7
+ if ['production', 'staging'].include? Rails.env
8
+
9
+ @connection = Mongo::ReplSetConnection.new(APP_CONFIG['replicaset'], :read => :secondary, :name => APP_CONFIG['replicaset_name'])
10
+ @connection.add_auth(APP_CONFIG['database'], APP_CONFIG['username'], APP_CONFIG['password'])
11
+ @connection.add_auth('admin', APP_CONFIG['username'], APP_CONFIG['password'])
12
+ else
13
+ # if APP_CONFIG['username']
14
+ # url = "mongodb://#{APP_CONFIG['username']}:#{APP_CONFIG['password']}@#{APP_CONFIG['host']}/#{APP_CONFIG['database']}"
15
+ # else
16
+ # url = "mongodb://#{APP_CONFIG['host']}"
17
+ # end
18
+ url = "mongodb://#{APP_CONFIG['host']}"
19
+ @connection = Mongo::Connection.from_uri(url)
20
+ end
21
+
22
+ end
23
+
24
+ def all
25
+ @connection.database_names
26
+ end
27
+
28
+ def collections(database_name)
29
+ db = @connection.db(database_name)
30
+ db.collection_names
31
+ end
32
+
33
+ def distinct(database, collection, field)
34
+ db = @connection.db(database)
35
+ coll = db.collection(collection)
36
+ coll.distinct(field.to_s)
37
+ end
38
+
39
+
40
+ def records(database, collection, last = Time.now)
41
+
42
+ db = @connection.db(database)
43
+ coll = db.collection(collection)
44
+
45
+ if row = coll.find().sort("_id", -1).limit(1).first
46
+ keys = row.keys
47
+ if keys.include?('updated_at')
48
+ find_options = {"updated_at" => {"$lt" => last}}
49
+ sort_options = [['updated_at', 'descending']]
50
+
51
+ elsif keys.include?('created_at')
52
+ find_options = {"created_at" => {"$lt" => last}}
53
+ sort_options = [['created_at', 'descending']]
54
+ else
55
+ find_options = {}
56
+ end
57
+ else
58
+ find_options = {}
59
+ end
60
+
61
+ query = coll.find(find_options).limit(25)
62
+
63
+ if sort_options
64
+ query.sort(sort_options)
65
+ else
66
+ query
67
+ end
68
+ end
69
+
70
+ # Need to do some sort of skip and last chat.
71
+ def capped_records(database, collection, conditions, last = Time.now)
72
+ db = @connection.db(database)
73
+ coll = db.collection(collection)
74
+ conditions = conditions.merge({"timestamp" => {"$lt" => last}})
75
+ coll.find(conditions).sort([["$natural", "-1"]]).limit(50)
76
+ end
77
+
78
+
79
+ # Need to do some sort of first and last chat.
80
+ def range_records(database, collection, conditions, first = Time.now, last = Time.now, limit = 2000)
81
+ db = @connection.db(database)
82
+ coll = db.collection(collection)
83
+ conditions = conditions.merge({"timestamp" => {"$lte" => last, "$gte" => first}})
84
+
85
+ baseQuery = coll.find(conditions).sort([["$natural", "-1"]]).limit(limit)
86
+ end
87
+
88
+ def find(database, collection, id)
89
+ db = @connection.db(database)
90
+ coll = db.collection(collection)
91
+ coll.find_one(:_id => BSON::ObjectId(id))
92
+ end
93
+
94
+ def update(database, collection, id, params)
95
+ db = @connection.db(database)
96
+ coll = db.collection(collection)
97
+ s_params = params.stringify_keys
98
+ coll.update({"_id" => BSON::ObjectId(id)}, {"$set" => s_params}, :safe => true)
99
+ end
100
+
101
+ end
@@ -0,0 +1,94 @@
1
+ module WinstonMongodbRails
2
+ class MongoLogger < ActiveSupport::BufferedLogger
3
+
4
+ # Aim to rely on the mongodb driver for replicaset chat.
5
+
6
+ # Looks for configuration files in this order
7
+ CONFIGURATION_FILES = ["mongoid.yml", "database.yml"]
8
+ LOG_LEVEL_SYM = [:debug, :info, :warn, :error, :fatal, :unknown]
9
+
10
+ def initialize(options={})
11
+ path = options[:path] || File.join(Rails.root, "log/#{Rails.env}-mog.log")
12
+ level = options[:level] || DEBUG
13
+ @db_configuration = resolve_config
14
+ internal_initialize
15
+ super(path, level)
16
+ rescue => e
17
+ # should use a config block for this
18
+ Rails.env.production? ? (raise e) : (puts "Using BufferedLogger due to exception: " + e.message)
19
+ end
20
+
21
+ def add(severity, message = nil, progname = nil, &block)
22
+
23
+ # this writes to mongo
24
+ mongo_record = {
25
+ :level => LOG_LEVEL_SYM[severity].to_s,
26
+ :timestamp => Time.now,
27
+ :message => message,
28
+ :application_name => @application_name,
29
+ :meta => progname
30
+ }
31
+
32
+ insert_log_record(mongo_record, @safe_insert)
33
+ super
34
+ end
35
+
36
+
37
+ private
38
+ # facilitate testing
39
+ def internal_initialize
40
+ configure
41
+ connect
42
+ end
43
+
44
+ def configure
45
+ @mongo_database_name = @db_configuration['database'] || "logs"
46
+ @mongo_collection_name = @db_configuration['collection_name'] || "logs"
47
+ @application_name = @db_configuration['application_name'] || 'default'
48
+ @safe_insert = @db_configuration['safe_insert'] || false
49
+ end
50
+
51
+ def resolve_config
52
+ config = {}
53
+ CONFIGURATION_FILES.each do |filename|
54
+ config_file = Rails.root.join("config", filename)
55
+ if config_file.file?
56
+ config = YAML.load(ERB.new(config_file.read).result)[Rails.env]
57
+ config = config['mongo'] if config.has_key?('mongo')
58
+ break
59
+ end
60
+ end
61
+ config
62
+ end
63
+
64
+ def connect
65
+ @mongo_connection ||= MongoDatabase.new.connection
66
+ @logs_database ||= @mongo_connection.db(@mongo_database_name)
67
+ @logs_collection ||= @logs_database.collection(@mongo_collection_name)
68
+ end
69
+
70
+ # This inserts a log record into mongodb
71
+ def insert_log_record(mongo_record, safe=false)
72
+ @logs_collection.insert(mongo_record, :safe => safe)
73
+ end
74
+
75
+ class << self
76
+ def create_logger(config, path)
77
+ level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase)
78
+ logger = MongoLogger.new(:path => path, :level => level)
79
+ logger.auto_flushing = false if Rails.env.production?
80
+ logger
81
+ rescue StandardError => e
82
+ logger = ActiveSupport::BufferedLogger.new(STDERR)
83
+ logger.level = ActiveSupport::BufferedLogger::WARN
84
+ logger.warn(
85
+ "CentralLogger Initializer Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " +
86
+ "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed." + "\n" +
87
+ e.message + "\n" + e.backtrace.join("\n")
88
+ )
89
+ logger
90
+ end
91
+ end
92
+
93
+ end # class MongoLogger
94
+ end
@@ -0,0 +1,3 @@
1
+ module WinstonMongodbRails
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'mongo'
4
+ require 'winston_mongodb_rails/mongo_database'
5
+ require 'winston_mongodb_rails/mongo_logger'
6
+
data/release_gem.sh ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/zsh
2
+
3
+ rm *.gem
4
+ gem build winston_mongodb_rails.gemspec
5
+ gem push `ls *.gem`
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require 'winston_mongodb_rails/version'
6
+
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = "winston_mongodb_rails"
10
+ s.version = WinstonMongodbRails::VERSION
11
+ s.platform = Gem::Platform::RUBY
12
+ s.authors = ["Alastair Brunton"]
13
+ s.email = ["info@simplyexcited.co.uk"]
14
+ s.homepage = "http://github.com/pyrat/winston_mongodb_rails"
15
+ s.summary = "Port of the winston shared mongodb logger for rails."
16
+ s.description = "This allows many applications to log to a shared mongodb logger. It is useful, if you have many small applications / load balanced applications and you want to treat a log as a first class citizen."
17
+
18
+ s.add_dependency('mongo')
19
+
20
+ s.required_rubygems_version = ">= 1.3.1"
21
+ s.require_path = 'lib'
22
+ s.files = `git ls-files`.split("\n")
23
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: winston_mongodb_rails
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Alastair Brunton
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-09-04 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: mongo
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: This allows many applications to log to a shared mongodb logger. It is useful, if you have many small applications / load balanced applications and you want to treat a log as a first class citizen.
36
+ email:
37
+ - info@simplyexcited.co.uk
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - .gitignore
46
+ - MIT-LICENSE
47
+ - README.md
48
+ - lib/winston_mongodb_rails.rb
49
+ - lib/winston_mongodb_rails/mongo_database.rb
50
+ - lib/winston_mongodb_rails/mongo_logger.rb
51
+ - lib/winston_mongodb_rails/version.rb
52
+ - release_gem.sh
53
+ - winston_mongodb_rails.gemspec
54
+ has_rdoc: true
55
+ homepage: http://github.com/pyrat/winston_mongodb_rails
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 25
78
+ segments:
79
+ - 1
80
+ - 3
81
+ - 1
82
+ version: 1.3.1
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.7
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Port of the winston shared mongodb logger for rails.
90
+ test_files: []
91
+