mongo_request_logger 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (296) hide show
  1. data/.gitignore +17 -0
  2. data/.travis.yml +11 -0
  3. data/Gemfile +10 -0
  4. data/LICENSE.txt +28 -0
  5. data/README.md +90 -0
  6. data/Rakefile +1 -0
  7. data/config.ru +11 -0
  8. data/lib/mongo_request_logger/adapters/base.rb +51 -0
  9. data/lib/mongo_request_logger/adapters/mongo.rb +89 -0
  10. data/lib/mongo_request_logger/adapters/moped.rb +94 -0
  11. data/lib/mongo_request_logger/backtrace_cleaner.rb +11 -0
  12. data/lib/mongo_request_logger/config.rb +109 -0
  13. data/lib/mongo_request_logger/ext/buffered_logger.rb +6 -0
  14. data/lib/mongo_request_logger/ext/logger.rb +6 -0
  15. data/lib/mongo_request_logger/log_message.rb +170 -0
  16. data/lib/mongo_request_logger/logged_job.rb +63 -0
  17. data/lib/mongo_request_logger/logger.rb +122 -0
  18. data/lib/mongo_request_logger/logger_extensions.rb +34 -0
  19. data/lib/mongo_request_logger/rack.rb +63 -0
  20. data/lib/mongo_request_logger/railtie.rb +57 -0
  21. data/lib/mongo_request_logger/search_terms.rb +59 -0
  22. data/lib/mongo_request_logger/version.rb +3 -0
  23. data/lib/mongo_request_logger/viewer.rb +212 -0
  24. data/lib/mongo_request_logger.rb +16 -0
  25. data/mongo_request_logger.gemspec +24 -0
  26. data/public/css/bootstrap-responsive.css +815 -0
  27. data/public/css/bootstrap-responsive.min.css +9 -0
  28. data/public/css/bootstrap.css +4983 -0
  29. data/public/css/bootstrap.min.css +9 -0
  30. data/public/img/flags/ad.png +0 -0
  31. data/public/img/flags/ae.png +0 -0
  32. data/public/img/flags/af.png +0 -0
  33. data/public/img/flags/ag.png +0 -0
  34. data/public/img/flags/ai.png +0 -0
  35. data/public/img/flags/al.png +0 -0
  36. data/public/img/flags/am.png +0 -0
  37. data/public/img/flags/an.png +0 -0
  38. data/public/img/flags/ao.png +0 -0
  39. data/public/img/flags/ar.png +0 -0
  40. data/public/img/flags/as.png +0 -0
  41. data/public/img/flags/at.png +0 -0
  42. data/public/img/flags/au.png +0 -0
  43. data/public/img/flags/aw.png +0 -0
  44. data/public/img/flags/ax.png +0 -0
  45. data/public/img/flags/az.png +0 -0
  46. data/public/img/flags/ba.png +0 -0
  47. data/public/img/flags/bb.png +0 -0
  48. data/public/img/flags/bd.png +0 -0
  49. data/public/img/flags/be.png +0 -0
  50. data/public/img/flags/bf.png +0 -0
  51. data/public/img/flags/bg.png +0 -0
  52. data/public/img/flags/bh.png +0 -0
  53. data/public/img/flags/bi.png +0 -0
  54. data/public/img/flags/bj.png +0 -0
  55. data/public/img/flags/bm.png +0 -0
  56. data/public/img/flags/bn.png +0 -0
  57. data/public/img/flags/bo.png +0 -0
  58. data/public/img/flags/br.png +0 -0
  59. data/public/img/flags/bs.png +0 -0
  60. data/public/img/flags/bt.png +0 -0
  61. data/public/img/flags/bv.png +0 -0
  62. data/public/img/flags/bw.png +0 -0
  63. data/public/img/flags/by.png +0 -0
  64. data/public/img/flags/bz.png +0 -0
  65. data/public/img/flags/ca.png +0 -0
  66. data/public/img/flags/catalonia.png +0 -0
  67. data/public/img/flags/cc.png +0 -0
  68. data/public/img/flags/cd.png +0 -0
  69. data/public/img/flags/cf.png +0 -0
  70. data/public/img/flags/cg.png +0 -0
  71. data/public/img/flags/ch.png +0 -0
  72. data/public/img/flags/ci.png +0 -0
  73. data/public/img/flags/ck.png +0 -0
  74. data/public/img/flags/cl.png +0 -0
  75. data/public/img/flags/cm.png +0 -0
  76. data/public/img/flags/cn.png +0 -0
  77. data/public/img/flags/co.png +0 -0
  78. data/public/img/flags/cr.png +0 -0
  79. data/public/img/flags/cs.png +0 -0
  80. data/public/img/flags/cu.png +0 -0
  81. data/public/img/flags/cv.png +0 -0
  82. data/public/img/flags/cx.png +0 -0
  83. data/public/img/flags/cy.png +0 -0
  84. data/public/img/flags/cz.png +0 -0
  85. data/public/img/flags/de.png +0 -0
  86. data/public/img/flags/dj.png +0 -0
  87. data/public/img/flags/dk.png +0 -0
  88. data/public/img/flags/dm.png +0 -0
  89. data/public/img/flags/do.png +0 -0
  90. data/public/img/flags/dz.png +0 -0
  91. data/public/img/flags/ec.png +0 -0
  92. data/public/img/flags/ee.png +0 -0
  93. data/public/img/flags/eg.png +0 -0
  94. data/public/img/flags/eh.png +0 -0
  95. data/public/img/flags/england.png +0 -0
  96. data/public/img/flags/er.png +0 -0
  97. data/public/img/flags/es.png +0 -0
  98. data/public/img/flags/et.png +0 -0
  99. data/public/img/flags/europeanunion.png +0 -0
  100. data/public/img/flags/fam.png +0 -0
  101. data/public/img/flags/fi.png +0 -0
  102. data/public/img/flags/fj.png +0 -0
  103. data/public/img/flags/fk.png +0 -0
  104. data/public/img/flags/fm.png +0 -0
  105. data/public/img/flags/fo.png +0 -0
  106. data/public/img/flags/fr.png +0 -0
  107. data/public/img/flags/ga.png +0 -0
  108. data/public/img/flags/gb.png +0 -0
  109. data/public/img/flags/gd.png +0 -0
  110. data/public/img/flags/ge.png +0 -0
  111. data/public/img/flags/gf.png +0 -0
  112. data/public/img/flags/gh.png +0 -0
  113. data/public/img/flags/gi.png +0 -0
  114. data/public/img/flags/gl.png +0 -0
  115. data/public/img/flags/gm.png +0 -0
  116. data/public/img/flags/gn.png +0 -0
  117. data/public/img/flags/gp.png +0 -0
  118. data/public/img/flags/gq.png +0 -0
  119. data/public/img/flags/gr.png +0 -0
  120. data/public/img/flags/gs.png +0 -0
  121. data/public/img/flags/gt.png +0 -0
  122. data/public/img/flags/gu.png +0 -0
  123. data/public/img/flags/gw.png +0 -0
  124. data/public/img/flags/gy.png +0 -0
  125. data/public/img/flags/hk.png +0 -0
  126. data/public/img/flags/hm.png +0 -0
  127. data/public/img/flags/hn.png +0 -0
  128. data/public/img/flags/hr.png +0 -0
  129. data/public/img/flags/ht.png +0 -0
  130. data/public/img/flags/hu.png +0 -0
  131. data/public/img/flags/id.png +0 -0
  132. data/public/img/flags/ie.png +0 -0
  133. data/public/img/flags/il.png +0 -0
  134. data/public/img/flags/in.png +0 -0
  135. data/public/img/flags/io.png +0 -0
  136. data/public/img/flags/iq.png +0 -0
  137. data/public/img/flags/ir.png +0 -0
  138. data/public/img/flags/is.png +0 -0
  139. data/public/img/flags/it.png +0 -0
  140. data/public/img/flags/jm.png +0 -0
  141. data/public/img/flags/jo.png +0 -0
  142. data/public/img/flags/jp.png +0 -0
  143. data/public/img/flags/ke.png +0 -0
  144. data/public/img/flags/kg.png +0 -0
  145. data/public/img/flags/kh.png +0 -0
  146. data/public/img/flags/ki.png +0 -0
  147. data/public/img/flags/km.png +0 -0
  148. data/public/img/flags/kn.png +0 -0
  149. data/public/img/flags/kp.png +0 -0
  150. data/public/img/flags/kr.png +0 -0
  151. data/public/img/flags/kw.png +0 -0
  152. data/public/img/flags/ky.png +0 -0
  153. data/public/img/flags/kz.png +0 -0
  154. data/public/img/flags/la.png +0 -0
  155. data/public/img/flags/lb.png +0 -0
  156. data/public/img/flags/lc.png +0 -0
  157. data/public/img/flags/li.png +0 -0
  158. data/public/img/flags/lk.png +0 -0
  159. data/public/img/flags/lr.png +0 -0
  160. data/public/img/flags/ls.png +0 -0
  161. data/public/img/flags/lt.png +0 -0
  162. data/public/img/flags/lu.png +0 -0
  163. data/public/img/flags/lv.png +0 -0
  164. data/public/img/flags/ly.png +0 -0
  165. data/public/img/flags/ma.png +0 -0
  166. data/public/img/flags/mc.png +0 -0
  167. data/public/img/flags/md.png +0 -0
  168. data/public/img/flags/me.png +0 -0
  169. data/public/img/flags/mg.png +0 -0
  170. data/public/img/flags/mh.png +0 -0
  171. data/public/img/flags/mk.png +0 -0
  172. data/public/img/flags/ml.png +0 -0
  173. data/public/img/flags/mm.png +0 -0
  174. data/public/img/flags/mn.png +0 -0
  175. data/public/img/flags/mo.png +0 -0
  176. data/public/img/flags/mp.png +0 -0
  177. data/public/img/flags/mq.png +0 -0
  178. data/public/img/flags/mr.png +0 -0
  179. data/public/img/flags/ms.png +0 -0
  180. data/public/img/flags/mt.png +0 -0
  181. data/public/img/flags/mu.png +0 -0
  182. data/public/img/flags/mv.png +0 -0
  183. data/public/img/flags/mw.png +0 -0
  184. data/public/img/flags/mx.png +0 -0
  185. data/public/img/flags/my.png +0 -0
  186. data/public/img/flags/mz.png +0 -0
  187. data/public/img/flags/na.png +0 -0
  188. data/public/img/flags/nc.png +0 -0
  189. data/public/img/flags/ne.png +0 -0
  190. data/public/img/flags/nf.png +0 -0
  191. data/public/img/flags/ng.png +0 -0
  192. data/public/img/flags/ni.png +0 -0
  193. data/public/img/flags/nl.png +0 -0
  194. data/public/img/flags/no.png +0 -0
  195. data/public/img/flags/np.png +0 -0
  196. data/public/img/flags/nr.png +0 -0
  197. data/public/img/flags/nu.png +0 -0
  198. data/public/img/flags/nz.png +0 -0
  199. data/public/img/flags/om.png +0 -0
  200. data/public/img/flags/pa.png +0 -0
  201. data/public/img/flags/pe.png +0 -0
  202. data/public/img/flags/pf.png +0 -0
  203. data/public/img/flags/pg.png +0 -0
  204. data/public/img/flags/ph.png +0 -0
  205. data/public/img/flags/pk.png +0 -0
  206. data/public/img/flags/pl.png +0 -0
  207. data/public/img/flags/pm.png +0 -0
  208. data/public/img/flags/pn.png +0 -0
  209. data/public/img/flags/pr.png +0 -0
  210. data/public/img/flags/ps.png +0 -0
  211. data/public/img/flags/pt.png +0 -0
  212. data/public/img/flags/pw.png +0 -0
  213. data/public/img/flags/py.png +0 -0
  214. data/public/img/flags/qa.png +0 -0
  215. data/public/img/flags/re.png +0 -0
  216. data/public/img/flags/ro.png +0 -0
  217. data/public/img/flags/rs.png +0 -0
  218. data/public/img/flags/ru.png +0 -0
  219. data/public/img/flags/rw.png +0 -0
  220. data/public/img/flags/sa.png +0 -0
  221. data/public/img/flags/sb.png +0 -0
  222. data/public/img/flags/sc.png +0 -0
  223. data/public/img/flags/scotland.png +0 -0
  224. data/public/img/flags/sd.png +0 -0
  225. data/public/img/flags/se.png +0 -0
  226. data/public/img/flags/sg.png +0 -0
  227. data/public/img/flags/sh.png +0 -0
  228. data/public/img/flags/si.png +0 -0
  229. data/public/img/flags/sj.png +0 -0
  230. data/public/img/flags/sk.png +0 -0
  231. data/public/img/flags/sl.png +0 -0
  232. data/public/img/flags/sm.png +0 -0
  233. data/public/img/flags/sn.png +0 -0
  234. data/public/img/flags/so.png +0 -0
  235. data/public/img/flags/sr.png +0 -0
  236. data/public/img/flags/st.png +0 -0
  237. data/public/img/flags/sv.png +0 -0
  238. data/public/img/flags/sy.png +0 -0
  239. data/public/img/flags/sz.png +0 -0
  240. data/public/img/flags/tc.png +0 -0
  241. data/public/img/flags/td.png +0 -0
  242. data/public/img/flags/tf.png +0 -0
  243. data/public/img/flags/tg.png +0 -0
  244. data/public/img/flags/th.png +0 -0
  245. data/public/img/flags/tj.png +0 -0
  246. data/public/img/flags/tk.png +0 -0
  247. data/public/img/flags/tl.png +0 -0
  248. data/public/img/flags/tm.png +0 -0
  249. data/public/img/flags/tn.png +0 -0
  250. data/public/img/flags/to.png +0 -0
  251. data/public/img/flags/tr.png +0 -0
  252. data/public/img/flags/tt.png +0 -0
  253. data/public/img/flags/tv.png +0 -0
  254. data/public/img/flags/tw.png +0 -0
  255. data/public/img/flags/tz.png +0 -0
  256. data/public/img/flags/ua.png +0 -0
  257. data/public/img/flags/ug.png +0 -0
  258. data/public/img/flags/uk.png +0 -0
  259. data/public/img/flags/um.png +0 -0
  260. data/public/img/flags/us.png +0 -0
  261. data/public/img/flags/uy.png +0 -0
  262. data/public/img/flags/uz.png +0 -0
  263. data/public/img/flags/va.png +0 -0
  264. data/public/img/flags/vc.png +0 -0
  265. data/public/img/flags/ve.png +0 -0
  266. data/public/img/flags/vg.png +0 -0
  267. data/public/img/flags/vi.png +0 -0
  268. data/public/img/flags/vn.png +0 -0
  269. data/public/img/flags/vu.png +0 -0
  270. data/public/img/flags/wales.png +0 -0
  271. data/public/img/flags/wf.png +0 -0
  272. data/public/img/flags/ws.png +0 -0
  273. data/public/img/flags/ye.png +0 -0
  274. data/public/img/flags/yt.png +0 -0
  275. data/public/img/flags/za.png +0 -0
  276. data/public/img/flags/zm.png +0 -0
  277. data/public/img/flags/zw.png +0 -0
  278. data/public/img/glyphicons-halflings-white.png +0 -0
  279. data/public/img/glyphicons-halflings.png +0 -0
  280. data/public/js/bootstrap.js +1825 -0
  281. data/public/js/bootstrap.min.js +6 -0
  282. data/public/js/jquery-1.7.2.min.js +4 -0
  283. data/public/js/logs.js +194 -0
  284. data/spec/mongo_logger_spec.rb +33 -0
  285. data/spec/moped_logger_spec.rb +39 -0
  286. data/spec/query_spec.rb +80 -0
  287. data/spec/railtie_spec.rb +21 -0
  288. data/spec/shared_examples.rb +111 -0
  289. data/spec/spec_helper.rb +17 -0
  290. data/spec/testapp/config/logger.yml +6 -0
  291. data/spec/testapp/log/.gitkeep +0 -0
  292. data/views/index.erb +0 -0
  293. data/views/layout.erb +61 -0
  294. data/views/log_page.erb +22 -0
  295. data/views/logs.erb +76 -0
  296. metadata +402 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ script: "bundle exec rspec"
3
+ env:
4
+ - CI=true
5
+ rvm:
6
+ - 1.9.3
7
+ services:
8
+ - mongodb
9
+ notifications:
10
+ recipients:
11
+ - ralf@embarkmobile.com
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'mongo'
4
+ gem 'bson_ext'
5
+ gem 'moped'
6
+ gem 'rspec'
7
+ gem 'rails', '~> 3.2.10'
8
+
9
+ # Specify your gem's dependencies in mongo_request_logger.gemspec
10
+ gemspec
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,11 @@
1
+ module MongoRequestLogger
2
+ module BacktraceCleaner
3
+ def self.clean backtrace
4
+ if defined? Rails and Rails.respond_to? :backtrace_cleaner
5
+ Rails.backtrace_cleaner.clean(backtrace)
6
+ else
7
+ backtrace
8
+ end
9
+ end
10
+ end
11
+ 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
@@ -0,0 +1,6 @@
1
+ require 'active_support/buffered_logger'
2
+ require 'mongo_request_logger/logger_extensions'
3
+
4
+ class ActiveSupport::BufferedLogger
5
+ include MongoRequestLogger::LoggerExtensions
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'logger'
2
+ require 'mongo_request_logger/logger_extensions'
3
+
4
+ class Logger
5
+ include MongoRequestLogger::LoggerExtensions
6
+ end