mongo_request_logger 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 +17 -0
- data/.travis.yml +11 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +28 -0
- data/README.md +90 -0
- data/Rakefile +1 -0
- data/config.ru +11 -0
- data/lib/mongo_request_logger/adapters/base.rb +51 -0
- data/lib/mongo_request_logger/adapters/mongo.rb +89 -0
- data/lib/mongo_request_logger/adapters/moped.rb +94 -0
- data/lib/mongo_request_logger/backtrace_cleaner.rb +11 -0
- data/lib/mongo_request_logger/config.rb +109 -0
- data/lib/mongo_request_logger/ext/buffered_logger.rb +6 -0
- data/lib/mongo_request_logger/ext/logger.rb +6 -0
- data/lib/mongo_request_logger/log_message.rb +170 -0
- data/lib/mongo_request_logger/logged_job.rb +63 -0
- data/lib/mongo_request_logger/logger.rb +122 -0
- data/lib/mongo_request_logger/logger_extensions.rb +34 -0
- data/lib/mongo_request_logger/rack.rb +63 -0
- data/lib/mongo_request_logger/railtie.rb +57 -0
- data/lib/mongo_request_logger/search_terms.rb +59 -0
- data/lib/mongo_request_logger/version.rb +3 -0
- data/lib/mongo_request_logger/viewer.rb +212 -0
- data/lib/mongo_request_logger.rb +16 -0
- data/mongo_request_logger.gemspec +24 -0
- data/public/css/bootstrap-responsive.css +815 -0
- data/public/css/bootstrap-responsive.min.css +9 -0
- data/public/css/bootstrap.css +4983 -0
- data/public/css/bootstrap.min.css +9 -0
- data/public/img/flags/ad.png +0 -0
- data/public/img/flags/ae.png +0 -0
- data/public/img/flags/af.png +0 -0
- data/public/img/flags/ag.png +0 -0
- data/public/img/flags/ai.png +0 -0
- data/public/img/flags/al.png +0 -0
- data/public/img/flags/am.png +0 -0
- data/public/img/flags/an.png +0 -0
- data/public/img/flags/ao.png +0 -0
- data/public/img/flags/ar.png +0 -0
- data/public/img/flags/as.png +0 -0
- data/public/img/flags/at.png +0 -0
- data/public/img/flags/au.png +0 -0
- data/public/img/flags/aw.png +0 -0
- data/public/img/flags/ax.png +0 -0
- data/public/img/flags/az.png +0 -0
- data/public/img/flags/ba.png +0 -0
- data/public/img/flags/bb.png +0 -0
- data/public/img/flags/bd.png +0 -0
- data/public/img/flags/be.png +0 -0
- data/public/img/flags/bf.png +0 -0
- data/public/img/flags/bg.png +0 -0
- data/public/img/flags/bh.png +0 -0
- data/public/img/flags/bi.png +0 -0
- data/public/img/flags/bj.png +0 -0
- data/public/img/flags/bm.png +0 -0
- data/public/img/flags/bn.png +0 -0
- data/public/img/flags/bo.png +0 -0
- data/public/img/flags/br.png +0 -0
- data/public/img/flags/bs.png +0 -0
- data/public/img/flags/bt.png +0 -0
- data/public/img/flags/bv.png +0 -0
- data/public/img/flags/bw.png +0 -0
- data/public/img/flags/by.png +0 -0
- data/public/img/flags/bz.png +0 -0
- data/public/img/flags/ca.png +0 -0
- data/public/img/flags/catalonia.png +0 -0
- data/public/img/flags/cc.png +0 -0
- data/public/img/flags/cd.png +0 -0
- data/public/img/flags/cf.png +0 -0
- data/public/img/flags/cg.png +0 -0
- data/public/img/flags/ch.png +0 -0
- data/public/img/flags/ci.png +0 -0
- data/public/img/flags/ck.png +0 -0
- data/public/img/flags/cl.png +0 -0
- data/public/img/flags/cm.png +0 -0
- data/public/img/flags/cn.png +0 -0
- data/public/img/flags/co.png +0 -0
- data/public/img/flags/cr.png +0 -0
- data/public/img/flags/cs.png +0 -0
- data/public/img/flags/cu.png +0 -0
- data/public/img/flags/cv.png +0 -0
- data/public/img/flags/cx.png +0 -0
- data/public/img/flags/cy.png +0 -0
- data/public/img/flags/cz.png +0 -0
- data/public/img/flags/de.png +0 -0
- data/public/img/flags/dj.png +0 -0
- data/public/img/flags/dk.png +0 -0
- data/public/img/flags/dm.png +0 -0
- data/public/img/flags/do.png +0 -0
- data/public/img/flags/dz.png +0 -0
- data/public/img/flags/ec.png +0 -0
- data/public/img/flags/ee.png +0 -0
- data/public/img/flags/eg.png +0 -0
- data/public/img/flags/eh.png +0 -0
- data/public/img/flags/england.png +0 -0
- data/public/img/flags/er.png +0 -0
- data/public/img/flags/es.png +0 -0
- data/public/img/flags/et.png +0 -0
- data/public/img/flags/europeanunion.png +0 -0
- data/public/img/flags/fam.png +0 -0
- data/public/img/flags/fi.png +0 -0
- data/public/img/flags/fj.png +0 -0
- data/public/img/flags/fk.png +0 -0
- data/public/img/flags/fm.png +0 -0
- data/public/img/flags/fo.png +0 -0
- data/public/img/flags/fr.png +0 -0
- data/public/img/flags/ga.png +0 -0
- data/public/img/flags/gb.png +0 -0
- data/public/img/flags/gd.png +0 -0
- data/public/img/flags/ge.png +0 -0
- data/public/img/flags/gf.png +0 -0
- data/public/img/flags/gh.png +0 -0
- data/public/img/flags/gi.png +0 -0
- data/public/img/flags/gl.png +0 -0
- data/public/img/flags/gm.png +0 -0
- data/public/img/flags/gn.png +0 -0
- data/public/img/flags/gp.png +0 -0
- data/public/img/flags/gq.png +0 -0
- data/public/img/flags/gr.png +0 -0
- data/public/img/flags/gs.png +0 -0
- data/public/img/flags/gt.png +0 -0
- data/public/img/flags/gu.png +0 -0
- data/public/img/flags/gw.png +0 -0
- data/public/img/flags/gy.png +0 -0
- data/public/img/flags/hk.png +0 -0
- data/public/img/flags/hm.png +0 -0
- data/public/img/flags/hn.png +0 -0
- data/public/img/flags/hr.png +0 -0
- data/public/img/flags/ht.png +0 -0
- data/public/img/flags/hu.png +0 -0
- data/public/img/flags/id.png +0 -0
- data/public/img/flags/ie.png +0 -0
- data/public/img/flags/il.png +0 -0
- data/public/img/flags/in.png +0 -0
- data/public/img/flags/io.png +0 -0
- data/public/img/flags/iq.png +0 -0
- data/public/img/flags/ir.png +0 -0
- data/public/img/flags/is.png +0 -0
- data/public/img/flags/it.png +0 -0
- data/public/img/flags/jm.png +0 -0
- data/public/img/flags/jo.png +0 -0
- data/public/img/flags/jp.png +0 -0
- data/public/img/flags/ke.png +0 -0
- data/public/img/flags/kg.png +0 -0
- data/public/img/flags/kh.png +0 -0
- data/public/img/flags/ki.png +0 -0
- data/public/img/flags/km.png +0 -0
- data/public/img/flags/kn.png +0 -0
- data/public/img/flags/kp.png +0 -0
- data/public/img/flags/kr.png +0 -0
- data/public/img/flags/kw.png +0 -0
- data/public/img/flags/ky.png +0 -0
- data/public/img/flags/kz.png +0 -0
- data/public/img/flags/la.png +0 -0
- data/public/img/flags/lb.png +0 -0
- data/public/img/flags/lc.png +0 -0
- data/public/img/flags/li.png +0 -0
- data/public/img/flags/lk.png +0 -0
- data/public/img/flags/lr.png +0 -0
- data/public/img/flags/ls.png +0 -0
- data/public/img/flags/lt.png +0 -0
- data/public/img/flags/lu.png +0 -0
- data/public/img/flags/lv.png +0 -0
- data/public/img/flags/ly.png +0 -0
- data/public/img/flags/ma.png +0 -0
- data/public/img/flags/mc.png +0 -0
- data/public/img/flags/md.png +0 -0
- data/public/img/flags/me.png +0 -0
- data/public/img/flags/mg.png +0 -0
- data/public/img/flags/mh.png +0 -0
- data/public/img/flags/mk.png +0 -0
- data/public/img/flags/ml.png +0 -0
- data/public/img/flags/mm.png +0 -0
- data/public/img/flags/mn.png +0 -0
- data/public/img/flags/mo.png +0 -0
- data/public/img/flags/mp.png +0 -0
- data/public/img/flags/mq.png +0 -0
- data/public/img/flags/mr.png +0 -0
- data/public/img/flags/ms.png +0 -0
- data/public/img/flags/mt.png +0 -0
- data/public/img/flags/mu.png +0 -0
- data/public/img/flags/mv.png +0 -0
- data/public/img/flags/mw.png +0 -0
- data/public/img/flags/mx.png +0 -0
- data/public/img/flags/my.png +0 -0
- data/public/img/flags/mz.png +0 -0
- data/public/img/flags/na.png +0 -0
- data/public/img/flags/nc.png +0 -0
- data/public/img/flags/ne.png +0 -0
- data/public/img/flags/nf.png +0 -0
- data/public/img/flags/ng.png +0 -0
- data/public/img/flags/ni.png +0 -0
- data/public/img/flags/nl.png +0 -0
- data/public/img/flags/no.png +0 -0
- data/public/img/flags/np.png +0 -0
- data/public/img/flags/nr.png +0 -0
- data/public/img/flags/nu.png +0 -0
- data/public/img/flags/nz.png +0 -0
- data/public/img/flags/om.png +0 -0
- data/public/img/flags/pa.png +0 -0
- data/public/img/flags/pe.png +0 -0
- data/public/img/flags/pf.png +0 -0
- data/public/img/flags/pg.png +0 -0
- data/public/img/flags/ph.png +0 -0
- data/public/img/flags/pk.png +0 -0
- data/public/img/flags/pl.png +0 -0
- data/public/img/flags/pm.png +0 -0
- data/public/img/flags/pn.png +0 -0
- data/public/img/flags/pr.png +0 -0
- data/public/img/flags/ps.png +0 -0
- data/public/img/flags/pt.png +0 -0
- data/public/img/flags/pw.png +0 -0
- data/public/img/flags/py.png +0 -0
- data/public/img/flags/qa.png +0 -0
- data/public/img/flags/re.png +0 -0
- data/public/img/flags/ro.png +0 -0
- data/public/img/flags/rs.png +0 -0
- data/public/img/flags/ru.png +0 -0
- data/public/img/flags/rw.png +0 -0
- data/public/img/flags/sa.png +0 -0
- data/public/img/flags/sb.png +0 -0
- data/public/img/flags/sc.png +0 -0
- data/public/img/flags/scotland.png +0 -0
- data/public/img/flags/sd.png +0 -0
- data/public/img/flags/se.png +0 -0
- data/public/img/flags/sg.png +0 -0
- data/public/img/flags/sh.png +0 -0
- data/public/img/flags/si.png +0 -0
- data/public/img/flags/sj.png +0 -0
- data/public/img/flags/sk.png +0 -0
- data/public/img/flags/sl.png +0 -0
- data/public/img/flags/sm.png +0 -0
- data/public/img/flags/sn.png +0 -0
- data/public/img/flags/so.png +0 -0
- data/public/img/flags/sr.png +0 -0
- data/public/img/flags/st.png +0 -0
- data/public/img/flags/sv.png +0 -0
- data/public/img/flags/sy.png +0 -0
- data/public/img/flags/sz.png +0 -0
- data/public/img/flags/tc.png +0 -0
- data/public/img/flags/td.png +0 -0
- data/public/img/flags/tf.png +0 -0
- data/public/img/flags/tg.png +0 -0
- data/public/img/flags/th.png +0 -0
- data/public/img/flags/tj.png +0 -0
- data/public/img/flags/tk.png +0 -0
- data/public/img/flags/tl.png +0 -0
- data/public/img/flags/tm.png +0 -0
- data/public/img/flags/tn.png +0 -0
- data/public/img/flags/to.png +0 -0
- data/public/img/flags/tr.png +0 -0
- data/public/img/flags/tt.png +0 -0
- data/public/img/flags/tv.png +0 -0
- data/public/img/flags/tw.png +0 -0
- data/public/img/flags/tz.png +0 -0
- data/public/img/flags/ua.png +0 -0
- data/public/img/flags/ug.png +0 -0
- data/public/img/flags/uk.png +0 -0
- data/public/img/flags/um.png +0 -0
- data/public/img/flags/us.png +0 -0
- data/public/img/flags/uy.png +0 -0
- data/public/img/flags/uz.png +0 -0
- data/public/img/flags/va.png +0 -0
- data/public/img/flags/vc.png +0 -0
- data/public/img/flags/ve.png +0 -0
- data/public/img/flags/vg.png +0 -0
- data/public/img/flags/vi.png +0 -0
- data/public/img/flags/vn.png +0 -0
- data/public/img/flags/vu.png +0 -0
- data/public/img/flags/wales.png +0 -0
- data/public/img/flags/wf.png +0 -0
- data/public/img/flags/ws.png +0 -0
- data/public/img/flags/ye.png +0 -0
- data/public/img/flags/yt.png +0 -0
- data/public/img/flags/za.png +0 -0
- data/public/img/flags/zm.png +0 -0
- data/public/img/flags/zw.png +0 -0
- data/public/img/glyphicons-halflings-white.png +0 -0
- data/public/img/glyphicons-halflings.png +0 -0
- data/public/js/bootstrap.js +1825 -0
- data/public/js/bootstrap.min.js +6 -0
- data/public/js/jquery-1.7.2.min.js +4 -0
- data/public/js/logs.js +194 -0
- data/spec/mongo_logger_spec.rb +33 -0
- data/spec/moped_logger_spec.rb +39 -0
- data/spec/query_spec.rb +80 -0
- data/spec/railtie_spec.rb +21 -0
- data/spec/shared_examples.rb +111 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/testapp/config/logger.yml +6 -0
- data/spec/testapp/log/.gitkeep +0 -0
- data/views/index.erb +0 -0
- data/views/layout.erb +61 -0
- data/views/log_page.erb +22 -0
- data/views/logs.erb +76 -0
- metadata +402 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Copyright (c) 2013 Embark Mobile
|
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.
|
23
|
+
|
24
|
+
|
25
|
+
Some code was used from the following projects:
|
26
|
+
|
27
|
+
https://github.com/le0pard/mongodb_logger (MIT License)
|
28
|
+
|
data/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# MongoRequestLogger
|
2
|
+
|
3
|
+
Log requests in a structured format to MongoDB.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'mongo_request_logger'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install mongo_request_logger
|
18
|
+
|
19
|
+
## Usage with Rails
|
20
|
+
|
21
|
+
Create config/logger.yml containing something like the following:
|
22
|
+
|
23
|
+
development:
|
24
|
+
host: localhost
|
25
|
+
database: your_app_logs_production_dev
|
26
|
+
capsize: 100
|
27
|
+
|
28
|
+
production:
|
29
|
+
host: localhost
|
30
|
+
database: your_app_logs_production
|
31
|
+
username: your_app_logs_production
|
32
|
+
password: password
|
33
|
+
capsize: 1024
|
34
|
+
|
35
|
+
Routes for log viewer
|
36
|
+
|
37
|
+
mount MongoRequestLogger::Viewer, :at => "log"
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
## Usage with other Rack-based frameworks (Sinatra, etc)
|
42
|
+
|
43
|
+
In config.ru, or where appropriate:
|
44
|
+
|
45
|
+
require 'moped'
|
46
|
+
|
47
|
+
config = {
|
48
|
+
database: 'my_log_db',
|
49
|
+
collection: 'log',
|
50
|
+
capsize: 100 * 1024 * 1024,
|
51
|
+
}
|
52
|
+
|
53
|
+
adapter = MongoRequestLogger::Adapters::Moped.new(config)
|
54
|
+
logger = MongoRequestLogger::Logger.new(adapter, "myapp.log")
|
55
|
+
MongoRequestLogger::Rack.logger = loggger
|
56
|
+
|
57
|
+
use MongoRequestLogger::Rack
|
58
|
+
|
59
|
+
run MyApp
|
60
|
+
|
61
|
+
## Ignoring paths
|
62
|
+
|
63
|
+
Often you want some requests not to be logged, for example assets files. This can be done by specifying the prefixes
|
64
|
+
to be ignored:
|
65
|
+
|
66
|
+
MongoRequestLogger::Rack.ignore_prefixes << '/assets/'
|
67
|
+
|
68
|
+
## Usage with resque
|
69
|
+
|
70
|
+
Extend from MongoRequestLogger::LoggedJob, to have each job logged as if it was a request.
|
71
|
+
|
72
|
+
class MyJob
|
73
|
+
extend MongoRequestLogger::LoggedJob
|
74
|
+
|
75
|
+
def perform(args)
|
76
|
+
# ...
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
## License
|
81
|
+
|
82
|
+
All code is under the MIT licence, see LICENSE.txt.
|
83
|
+
|
84
|
+
## Contributing
|
85
|
+
|
86
|
+
1. Fork it
|
87
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
88
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
89
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
90
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/config.ru
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Sinatra app for viewing logs
|
2
|
+
|
3
|
+
require 'moped'
|
4
|
+
require 'mongo_request_logger/viewer'
|
5
|
+
|
6
|
+
config = {database: 'request_logger_test', collection: 'server_log', capsize: 10*1024*1024}
|
7
|
+
|
8
|
+
MongoRequestLogger::Viewer.adapter = MongoRequestLogger::Adapters::Moped.new(config)
|
9
|
+
|
10
|
+
MongoRequestLogger::Viewer.run!
|
11
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Adapted from https://github.com/le0pard/mongodb_logger
|
2
|
+
|
3
|
+
module MongoRequestLogger
|
4
|
+
module Adapters
|
5
|
+
class Base
|
6
|
+
|
7
|
+
attr_reader :configuration, :connection, :connection_type, :collection, :authenticated
|
8
|
+
|
9
|
+
def collection_name
|
10
|
+
@configuration['collection']
|
11
|
+
end
|
12
|
+
|
13
|
+
def authenticated?
|
14
|
+
@authenticated
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_for_collection
|
18
|
+
# setup the capped collection if it doesn't already exist
|
19
|
+
create_collection unless @connection.collection_names.include?(@configuration['collection'])
|
20
|
+
@collection = @connection[@configuration['collection']]
|
21
|
+
end
|
22
|
+
|
23
|
+
def reset_collection
|
24
|
+
if @connection && @collection
|
25
|
+
@collection.drop
|
26
|
+
create_collection
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def reconnect
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def collection_stats_hash(stats)
|
35
|
+
{
|
36
|
+
:is_capped => (stats["capped"] && ([1, true].include?(stats["capped"]))),
|
37
|
+
:count => stats["count"].to_i,
|
38
|
+
:size => stats["size"].to_f,
|
39
|
+
:storageSize => stats["storageSize"].to_f,
|
40
|
+
:db_name => @configuration["database"],
|
41
|
+
:collection => collection_name
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_collection
|
46
|
+
raise "Not implemented"
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# Adapted from https://github.com/le0pard/mongodb_logger/
|
2
|
+
|
3
|
+
require 'mongo_request_logger/adapters/base'
|
4
|
+
|
5
|
+
module MongoRequestLogger
|
6
|
+
module Adapters
|
7
|
+
class Mongo < Base
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@authenticated = false
|
11
|
+
@configuration = options.with_indifferent_access
|
12
|
+
|
13
|
+
connect
|
14
|
+
|
15
|
+
check_for_collection
|
16
|
+
end
|
17
|
+
|
18
|
+
def connect
|
19
|
+
if @configuration['url']
|
20
|
+
uri = URI.parse(@configuration['url'])
|
21
|
+
@configuration['database'] = uri.path.gsub(/^\//, '')
|
22
|
+
@connection ||= mongo_connection_object.db(@configuration['database'])
|
23
|
+
@authenticated = true
|
24
|
+
else
|
25
|
+
@connection ||= mongo_connection_object.db(@configuration['database'])
|
26
|
+
if @configuration['username'] && @configuration['password']
|
27
|
+
# the driver stores credentials in case reconnection is required
|
28
|
+
@authenticated = @connection.authenticate(@configuration['username'],
|
29
|
+
@configuration['password'])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def reconnect
|
35
|
+
connect
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_collection
|
39
|
+
@connection.create_collection(collection_name,
|
40
|
+
{:capped => true, :size => @configuration['capsize'].to_i})
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_index field
|
44
|
+
@collection.create_index(field)
|
45
|
+
end
|
46
|
+
|
47
|
+
def insert_log_record(record)
|
48
|
+
# TODO: we should make this non-safe?
|
49
|
+
@collection.insert(record)
|
50
|
+
end
|
51
|
+
|
52
|
+
def collection_stats
|
53
|
+
collection_stats_hash(@collection.stats)
|
54
|
+
end
|
55
|
+
|
56
|
+
def query(criteria, options={})
|
57
|
+
q = @collection.find(filter.get_mongo_conditions).sort('timestamp', -1)
|
58
|
+
if options[:limit]
|
59
|
+
q = q.limit(options.limit)
|
60
|
+
end
|
61
|
+
q
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_by_id(id)
|
65
|
+
@collection.find_one(::BSON::ObjectId(id))
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def mongo_connection_object
|
71
|
+
if @configuration['hosts']
|
72
|
+
conn = ::Mongo::ReplSetConnection.new(*(@configuration['hosts'] <<
|
73
|
+
{:connect => true, :pool_timeout => 6}))
|
74
|
+
@configuration['replica_set'] = true
|
75
|
+
elsif @configuration['url']
|
76
|
+
conn = ::Mongo::Connection.from_uri(@configuration['url'])
|
77
|
+
else
|
78
|
+
conn = ::Mongo::Connection.new(@configuration['host'],
|
79
|
+
@configuration['port'],
|
80
|
+
:connect => true,
|
81
|
+
:pool_timeout => 6)
|
82
|
+
end
|
83
|
+
@connection_type = conn.class
|
84
|
+
conn
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# Adapted from https://github.com/le0pard/mongodb_logger/
|
2
|
+
|
3
|
+
require 'mongo_request_logger/adapters/base'
|
4
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
5
|
+
|
6
|
+
module MongoRequestLogger
|
7
|
+
module Adapters
|
8
|
+
class Moped < Base
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@configuration = options.with_indifferent_access
|
12
|
+
@configuration['host'] ||= '127.0.0.1'
|
13
|
+
@configuration['port'] ||= '27017'
|
14
|
+
@configuration['collection'] ||= 'server_log'
|
15
|
+
|
16
|
+
if @configuration['url']
|
17
|
+
uri = URI.parse(@configuration['url'])
|
18
|
+
@configuration['database'] = uri.path.gsub(/^\//, '')
|
19
|
+
@connection ||= mongo_connection_object
|
20
|
+
@connection.use @configuration['database']
|
21
|
+
@authenticated = true
|
22
|
+
else
|
23
|
+
@connection ||= mongo_connection_object
|
24
|
+
@connection.use @configuration['database']
|
25
|
+
|
26
|
+
login
|
27
|
+
end
|
28
|
+
|
29
|
+
check_for_collection
|
30
|
+
end
|
31
|
+
|
32
|
+
def login
|
33
|
+
if @configuration['username'] && @configuration['password']
|
34
|
+
# the driver stores credentials in case reconnection is required
|
35
|
+
@authenticated = @connection.login(@configuration['username'],
|
36
|
+
@configuration['password'])
|
37
|
+
end
|
38
|
+
|
39
|
+
# Allow MongoDB configured both with and without authentication
|
40
|
+
begin
|
41
|
+
@connection.command(ping: 1)
|
42
|
+
rescue ::Moped::Errors::AuthenticationFailure => e
|
43
|
+
@connection.logout
|
44
|
+
@connection.command(ping: 1)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_collection
|
49
|
+
@connection.command(create: collection_name, capped: true, size: @configuration['capsize'].to_i)
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_index field
|
53
|
+
@collection.indexes.create({field => 1})
|
54
|
+
end
|
55
|
+
|
56
|
+
def insert_log_record(record)
|
57
|
+
record[:_id] = ::Moped::BSON::ObjectId.new
|
58
|
+
@connection.with(safe: false)[collection_name].insert(record)
|
59
|
+
end
|
60
|
+
|
61
|
+
def collection_stats
|
62
|
+
collection_stats_hash(@connection.command(collStats: collection_name))
|
63
|
+
end
|
64
|
+
|
65
|
+
def query(criteria, options={})
|
66
|
+
q = @collection.find(criteria).sort({'timestamp' => -1})
|
67
|
+
if options[:limit]
|
68
|
+
q = q.limit(options[:limit])
|
69
|
+
end
|
70
|
+
q
|
71
|
+
end
|
72
|
+
|
73
|
+
def find_by_id(id)
|
74
|
+
@collection.find("_id" => ::Moped::BSON::ObjectId.from_string(id)).first
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def mongo_connection_object
|
80
|
+
if @configuration['hosts']
|
81
|
+
conn = ::Moped::Session.new(@configuration['hosts'].map{|(host,port)| "#{host}:#{port}"}, :timeout => 6)
|
82
|
+
@configuration['replica_set'] = true
|
83
|
+
elsif @configuration['url']
|
84
|
+
conn = ::Moped::Session.connect(@configuration['url'])
|
85
|
+
else
|
86
|
+
conn = ::Moped::Session.new(["#{@configuration['host']}:#{@configuration['port']}"], :timeout => 6)
|
87
|
+
end
|
88
|
+
@connection_type = conn.class
|
89
|
+
conn
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module MongoRequestLogger
|
4
|
+
class Config
|
5
|
+
attr_accessor :raw_config
|
6
|
+
attr_accessor :params
|
7
|
+
attr_accessor :namespace
|
8
|
+
|
9
|
+
def initialize(config=nil)
|
10
|
+
@raw_config = {}
|
11
|
+
@params = {}
|
12
|
+
@namespace = nil
|
13
|
+
load_config(config) unless config.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
def namespaced(namespace)
|
17
|
+
config = deep_merge(@raw_config['common'], @raw_config[namespace])
|
18
|
+
ac = self.class.new(config)
|
19
|
+
ac.namespace = namespace
|
20
|
+
ac
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def namespaces
|
25
|
+
@raw_config.keys - %w(common)
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_file(file)
|
29
|
+
begin
|
30
|
+
hash = YAML::load(IO.read(file))
|
31
|
+
rescue => e
|
32
|
+
hash = nil
|
33
|
+
end
|
34
|
+
load_config(hash) unless hash.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def deep_merge(a, b)
|
38
|
+
if a.is_a? Hash and b.is_a? Hash
|
39
|
+
r = a.dup
|
40
|
+
for k, v in b
|
41
|
+
r[k] = deep_merge(a[k], v)
|
42
|
+
end
|
43
|
+
r
|
44
|
+
elsif b.is_a? Hash
|
45
|
+
b.dup
|
46
|
+
else
|
47
|
+
b
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def load_config(config)
|
52
|
+
@raw_config = deep_merge(@raw_config, config)
|
53
|
+
@params = {}
|
54
|
+
@raw_config.each { |k, v|
|
55
|
+
if v.is_a? Hash
|
56
|
+
@params[k] = self.class.new(v)
|
57
|
+
else
|
58
|
+
@params[k] = v
|
59
|
+
end
|
60
|
+
}
|
61
|
+
|
62
|
+
create_accessors!
|
63
|
+
end
|
64
|
+
|
65
|
+
def has?(param)
|
66
|
+
@params.key?(param.to_s)
|
67
|
+
end
|
68
|
+
|
69
|
+
def get(param)
|
70
|
+
@params[param.to_s]
|
71
|
+
end
|
72
|
+
|
73
|
+
def [](param)
|
74
|
+
get(param)
|
75
|
+
end
|
76
|
+
|
77
|
+
def []=(param, value)
|
78
|
+
@params[param.to_s] = value
|
79
|
+
end
|
80
|
+
|
81
|
+
def with_indifferent_access
|
82
|
+
self
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_accessors!
|
86
|
+
@params.each do |key,val|
|
87
|
+
create_accessor_for(key)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Use instance_eval/class_eval because they're actually more efficient than define_method{}
|
92
|
+
# http://stackoverflow.com/questions/185947/ruby-definemethod-vs-def
|
93
|
+
# http://bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/
|
94
|
+
def create_accessor_for(key)
|
95
|
+
key = key.to_s
|
96
|
+
return unless key =~ /^[\w_]+$/ # could have "some-setting:" which blows up eval
|
97
|
+
|
98
|
+
self.class.class_eval <<-EndEval
|
99
|
+
def #{key}
|
100
|
+
return @params["#{key}"]
|
101
|
+
end
|
102
|
+
|
103
|
+
def #{key}= value
|
104
|
+
@params["#{key}"] = value
|
105
|
+
end
|
106
|
+
EndEval
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|