winston_mongodb_rails 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.
- data/.gitignore +1 -0
- data/MIT-LICENSE +20 -0
- data/README.md +24 -0
- data/lib/winston_mongodb_rails/mongo_database.rb +101 -0
- data/lib/winston_mongodb_rails/mongo_logger.rb +94 -0
- data/lib/winston_mongodb_rails/version.rb +3 -0
- data/lib/winston_mongodb_rails.rb +6 -0
- data/release_gem.sh +5 -0
- data/winston_mongodb_rails.gemspec +23 -0
- metadata +91 -0
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
|
data/release_gem.sh
ADDED
@@ -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
|
+
|