mongodb_logger 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/.gitignore +20 -0
  2. data/.rvmrc +1 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +4 -0
  5. data/README.md +177 -0
  6. data/Rakefile +110 -0
  7. data/SUPPORTED_RAILS_VERSIONS +13 -0
  8. data/TESTING.md +24 -0
  9. data/bin/mongodb_logger_web +24 -0
  10. data/config.ru +16 -0
  11. data/examples/server_config.yml +4 -0
  12. data/features/rails.feature +10 -0
  13. data/features/step_definitions/rails_application_steps.rb +48 -0
  14. data/features/support/env.rb +15 -0
  15. data/features/support/rails.rb +91 -0
  16. data/features/support/terminal.rb +94 -0
  17. data/lib/mongodb_logger.rb +31 -0
  18. data/lib/mongodb_logger/initializer_mixin.rb +26 -0
  19. data/lib/mongodb_logger/logger.rb +184 -0
  20. data/lib/mongodb_logger/railtie.rb +12 -0
  21. data/lib/mongodb_logger/replica_set_helper.rb +19 -0
  22. data/lib/mongodb_logger/server.rb +136 -0
  23. data/lib/mongodb_logger/server/model/filter.rb +37 -0
  24. data/lib/mongodb_logger/server/partials.rb +24 -0
  25. data/lib/mongodb_logger/server/public/images/ajax-loader.gif +0 -0
  26. data/lib/mongodb_logger/server/public/images/failure.png +0 -0
  27. data/lib/mongodb_logger/server/public/images/logo.png +0 -0
  28. data/lib/mongodb_logger/server/public/images/play-icon.png +0 -0
  29. data/lib/mongodb_logger/server/public/images/stop-icon.png +0 -0
  30. data/lib/mongodb_logger/server/public/images/success.png +0 -0
  31. data/lib/mongodb_logger/server/public/javascripts/jquery-1.7.min.js +4 -0
  32. data/lib/mongodb_logger/server/public/stylesheets/all.css +9 -0
  33. data/lib/mongodb_logger/server/public/stylesheets/grids.css +18 -0
  34. data/lib/mongodb_logger/server/public/stylesheets/group-buttons.css +83 -0
  35. data/lib/mongodb_logger/server/public/stylesheets/group-forms.css +60 -0
  36. data/lib/mongodb_logger/server/public/stylesheets/group-headers.css +8 -0
  37. data/lib/mongodb_logger/server/public/stylesheets/group-tables.css +42 -0
  38. data/lib/mongodb_logger/server/public/stylesheets/layout.css +168 -0
  39. data/lib/mongodb_logger/server/public/stylesheets/library.css +134 -0
  40. data/lib/mongodb_logger/server/public/stylesheets/reset.css +43 -0
  41. data/lib/mongodb_logger/server/public/stylesheets/spaces.css +42 -0
  42. data/lib/mongodb_logger/server/views/application.coffee +54 -0
  43. data/lib/mongodb_logger/server/views/error.erb +2 -0
  44. data/lib/mongodb_logger/server/views/layout.erb +32 -0
  45. data/lib/mongodb_logger/server/views/overview.erb +94 -0
  46. data/lib/mongodb_logger/server/views/shared/_log.erb +8 -0
  47. data/lib/mongodb_logger/server/views/shared/_log_info.erb +25 -0
  48. data/lib/mongodb_logger/server/views/shared/_tabs.erb +4 -0
  49. data/lib/mongodb_logger/server/views/show_log.erb +85 -0
  50. data/lib/mongodb_logger/server_config.rb +45 -0
  51. data/lib/mongodb_logger/version.rb +3 -0
  52. data/mongodb_logger.gemspec +37 -0
  53. data/test/active_record.rb +13 -0
  54. data/test/config/samples/database.yml +9 -0
  55. data/test/config/samples/database_no_file_logging.yml +10 -0
  56. data/test/config/samples/database_replica_set.yml +8 -0
  57. data/test/config/samples/database_with_auth.yml +9 -0
  58. data/test/config/samples/mongodb_logger.yml +2 -0
  59. data/test/config/samples/mongoid.yml +30 -0
  60. data/test/rails.rb +22 -0
  61. data/test/rails/app/controllers/order_controller.rb +20 -0
  62. data/test/rails/test/functional/order_controller_test.rb +56 -0
  63. data/test/rails/test/test_helper.rb +10 -0
  64. data/test/shoulda_macros/log_macros.rb +13 -0
  65. data/test/test.sh +4 -0
  66. data/test/test_helper.rb +88 -0
  67. data/test/unit/mongodb_logger_replica_test.rb +45 -0
  68. data/test/unit/mongodb_logger_test.rb +252 -0
  69. metadata +300 -0
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .project
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ test/log
19
+ tmp
20
+ .DS_Store
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm ruby-1.9.3-p0@mongodb_logger_gems --create
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ #before_script:
2
+ # - "rake vendor_test_gems"
3
+ script: "sh -c 'test/test.sh'"
4
+ rvm:
5
+ - 1.8.7
6
+ - ree
7
+ - 1.9.2
8
+ - 1.9.3
9
+ - ruby-head
10
+ notifications:
11
+ email: false
12
+ branches:
13
+ only:
14
+ - master
15
+ - development
16
+ - gem
17
+ #bundler_args: --path vendor/bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongodb_logger.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # MongodbLogger [![Build Status](https://secure.travis-ci.org/le0pard/mongodb_logger.png)](http://travis-ci.org/le0pard/mongodb_logger)
2
+
3
+ MongodbLogger is a alternative logger for Rails 3, which log all requests off you application into MongoDB database.
4
+ It:
5
+
6
+ * simple to integrate into existing Rails 3 application;
7
+ * allow to store all logs from web cluster into one scalable storage - MongoDB;
8
+ * flexible schema of MongoDB allow to store and search any information from logs;
9
+ * web panel allow filter logs, build graphs using MapReduce by information from logs;
10
+
11
+ ## Installation
12
+
13
+ 1. Add the following to your Gemfile then refresh your dependencies by executing "bundle install" (or just simple "bundle"):
14
+
15
+ gem "mongodb_logger"
16
+
17
+ 1. Add the following line to your ApplicationController:
18
+
19
+ include MongodbLogger::Base
20
+
21
+ 1. Add MongodbLogger settings to database.yml for each environment in which you want to use the MongodbLogger. The MongodbLogger will also
22
+ look for a separate mongodb\_logger.yml or mongoid.yml (if you are using mongoid) before looking in database.yml.
23
+ In the mongodb\_logger.yml and mongoid.yml case, the settings should be defined without the 'mongodb\_logger' subkey.
24
+
25
+ File: database.yml:
26
+
27
+ development:
28
+ adapter: postgresql
29
+ database: my_app_development
30
+ username: postgres
31
+ mongodb_logger:
32
+ database: my_app # required (the only required setting)
33
+ capsize: <%= 10.megabytes %> # default: 250MB
34
+ host: localhost # default: localhost
35
+ port: 27017 # default: 27017
36
+ replica_set: true # default: false - Adds retries for ConnectionFailure during voting for replica set master
37
+ safe_insert: false # default: false - Enable/Disable safe inserts (wait for insert to propagate to all nodes)
38
+ application_name: my_app # default: Rails.application
39
+ disable_file_logging: false # default: false - disable logging into filesystem (only in MongoDB)
40
+ collection: some_name # default: Rails.env + "_log" - name of MongoDB collection
41
+
42
+ File: mongodb\_logger.yml:
43
+
44
+ development:
45
+ database: my_app
46
+ capsize: <%= 10.megabytes %>
47
+ host: localhost
48
+ port: 27017
49
+ replica_set: true
50
+
51
+
52
+ ## Usage
53
+
54
+ After success instalation of gem, a new MongoDB document (record) will be created for each request on your application,
55
+ by default will record the following information: Runtime, IP Address, Request Time, Controller, Method,
56
+ Action, Params, Application Name and All messages sent to the logger. The structure of the MongoDB document looks like this:
57
+
58
+ {
59
+ 'action' : action_name,
60
+ 'application_name' : application_name (rails root),
61
+ 'controller' : controller_name,
62
+ 'ip' : ip_address,
63
+ 'messages' : {
64
+ 'info' : [ ],
65
+ 'debug' : [ ],
66
+ 'error' : [ ],
67
+ 'warn' : [ ],
68
+ 'fatal' : [ ]
69
+ },
70
+ 'params' : { },
71
+ 'path' : path,
72
+ 'request_time' : date_of_request,
73
+ 'runtime' : elapsed_execution_time_in_milliseconds,
74
+ 'url' : full_url,
75
+ 'method' : request method (GET, POST, PUT, DELETE, OPTIONS)
76
+ }
77
+
78
+ Beyond that, if you want to add extra information to the base of the document (let's say something like user\_id on every request that it's available),
79
+ you can just call the Rails.logger.add\_metadata method on your logger like so (for example from a before\_filter):
80
+
81
+ # make sure we're using the MongodbLogger in this environment
82
+ if Rails.logger.respond_to?(:add_metadata)
83
+ Rails.logger.add_metadata(:user_id => @current_user.id)
84
+ end
85
+
86
+
87
+ ## The Front End
88
+ To setup web interface in you Rails application, first of all create autoload file in you Rails application
89
+
90
+ File: you\_rails\_app/config/initializers/mongodb\_logger.rb (example)
91
+
92
+ require 'mongodb_logger/server' # required
93
+ # this secure you web interface by basic auth, but you can skip this, if you no need this
94
+ MongodbLogger::Server.use Rack::Auth::Basic do |username, password|
95
+ [username, password] == ['admin', 'password']
96
+ end
97
+
98
+ and just mount MongodbLogger::Server in rails routes:
99
+
100
+ File: you\_rails\_app/config/routes.rb
101
+
102
+ mount MongodbLogger::Server.new, :at => "/mongodb"
103
+
104
+ Now you can see web interface by url "http://localhost:3000/mongodb"
105
+
106
+ If you've installed Resque as a gem and want running the front end without Rails application, you can do it by this command:
107
+
108
+ mongodb_logger_web config.yml
109
+
110
+ where config.yml is config, similar to config of Rails apps, but without Rails.env. Example:
111
+
112
+ database: app_logs_dev
113
+ host: localhost
114
+ port: 27017
115
+ collection: development_log # set for see development logs
116
+
117
+ parameter "collection" should be set, if your set custom for your Rails application or start this front end not for production
118
+ enviroment (by default taken "production\_log" collection, in Rails application gem generate "#{Rails.env}\_log" collection,
119
+ if it is not defined in config).
120
+
121
+ It's a thin layer around rackup so it's configurable as well:
122
+
123
+ mongodb_logger_web config.yml -p 8282
124
+
125
+ ### Passenger
126
+
127
+ Using Passenger? MongodbLogger ships with a `config.ru` you can use. See Phusion's guide:
128
+
129
+ * Apache: <http://www.modrails.com/documentation/Users%20guide%20Apache.html#_deploying_a_rack_based_ruby_application>
130
+ * Nginx: <http://www.modrails.com/documentation/Users%20guide%20Nginx.html#deploying_a_rack_app>
131
+
132
+ Don't forget setup MONGODBLOGGERCONFIG env variable, which provide information about MongodbLogger config. Example starting with unicorn:
133
+
134
+ MONGODBLOGGERCONFIG=examples/server_config.yml unicorn
135
+
136
+ ## Querying via the Rails console
137
+
138
+ And now, for a couple quick examples on getting ahold of this log data...
139
+ First, here's how to get a handle on the MongoDB from within a Rails console:
140
+
141
+ >> db = Rails.logger.mongo_connection
142
+ => #<Mongo::DB:0x007fdc7c65adc8 @name="monkey_logs_dev" ... >
143
+
144
+ >> collection = db[Rails.logger.mongo_collection_name]
145
+ => #<Mongo::Collection:0x007fdc7a4d12b0 @name="development_log" .. >
146
+
147
+ Once you've got the collection, you can find all requests for a specific user (with id):
148
+
149
+ >> cursor = collection.find(:user_id => '12355')
150
+ => #<Mongo::Cursor:0x1031a3e30 ... >
151
+ >> cursor.count
152
+ => 5
153
+
154
+ Find all requests that took more that one second to complete:
155
+
156
+ >> collection.find({:runtime => {'$gt' => 1000}}).count
157
+ => 3
158
+
159
+ Find all order#show requests with a particular order id (id=order\_id):
160
+
161
+ >> collection.find({"controller" => "order", "action"=> "show", "params.id" => order_id})
162
+
163
+ Find all requests with an exception that contains "RoutingError" in the message or stack trace:
164
+
165
+ >> collection.find({"messages.error" => /RoutingError/})
166
+
167
+ Find all requests with errors:
168
+
169
+ >> collection.find({"is_exception" => true})
170
+
171
+ Find all requests with a request\_date greater than '11/18/2010 22:59:52 GMT'
172
+
173
+ >> collection.find({:request_time => {'$gt' => Time.utc(2010, 11, 18, 22, 59, 52)}})
174
+
175
+
176
+
177
+ Copyright (c) 2009-2011 Phil Burrows, CustomInk and Leopard released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env rake
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ begin
5
+ require 'cucumber/rake/task'
6
+ rescue LoadError
7
+ $stderr.puts "Please install cucumber: `gem install cucumber`"
8
+ exit 1
9
+ end
10
+
11
+ require "bundler/gem_tasks"
12
+
13
+
14
+ desc 'Default: run unit tests.'
15
+ task :default => [:test]
16
+ #task :default => [:test, "cucumber:rails:all"]
17
+
18
+ desc "Clean out the tmp directory"
19
+ task :clean do
20
+ exec "rm -rf tmp"
21
+ end
22
+
23
+ desc 'Test the airbrake gem.'
24
+ Rake::TestTask.new(:test) do |test|
25
+ test.libs << 'lib' << 'test'
26
+ test.pattern = 'test/unit/mongodb_logger_test.rb'
27
+ test.verbose = true
28
+ end
29
+
30
+ namespace :test do
31
+
32
+ desc "Run replica set tests (not for CI)"
33
+ Rake::TestTask.new(:replica_set) do |test|
34
+ test.libs << 'lib' << 'test'
35
+ test.pattern = 'test/unit/mongodb_logger_replica_test.rb'
36
+ test.verbose = true
37
+ end
38
+
39
+ end
40
+
41
+
42
+ GEM_ROOT = File.dirname(__FILE__).freeze
43
+ LOCAL_GEM_ROOT = File.join(GEM_ROOT, 'tmp', 'local_gems').freeze
44
+ RAILS_VERSIONS = IO.read('SUPPORTED_RAILS_VERSIONS').strip.split("\n")
45
+ LOCAL_GEMS = [['sqlite3', nil], ['shoulda', nil], ["rspec", nil], ["mocha", nil], ["cucumber", nil], ["bundler", "1.0.21"]] +
46
+ RAILS_VERSIONS.collect { |version| ['rails', version] }
47
+
48
+ desc "Vendor test gems: Run this once to prepare your test environment"
49
+ task :vendor_test_gems do
50
+ old_gem_path = ENV['GEM_PATH']
51
+ old_gem_home = ENV['GEM_HOME']
52
+ ENV['GEM_PATH'] = LOCAL_GEM_ROOT
53
+ ENV['GEM_HOME'] = LOCAL_GEM_ROOT
54
+ LOCAL_GEMS.each do |gem_name, version|
55
+ gem_file_pattern = [gem_name, version || '*'].compact.join('-')
56
+ version_option = version ? "-v #{version}" : ''
57
+ pattern = File.join(LOCAL_GEM_ROOT, 'gems', "#{gem_file_pattern}")
58
+ existing = Dir.glob(pattern).first
59
+ unless existing
60
+ command = "gem install -i #{LOCAL_GEM_ROOT} --no-ri --no-rdoc --backtrace #{version_option} #{gem_name}"
61
+ puts "Vendoring #{gem_file_pattern}..."
62
+ unless system("#{command} 2>&1")
63
+ puts "Command failed: #{command}"
64
+ exit(1)
65
+ end
66
+ end
67
+ end
68
+ ENV['GEM_PATH'] = old_gem_path
69
+ ENV['GEM_HOME'] = old_gem_home
70
+ end
71
+
72
+ Cucumber::Rake::Task.new(:cucumber) do |t|
73
+ t.fork = true
74
+ t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'progress')]
75
+ end
76
+
77
+ task :cucumber => [:vendor_test_gems]
78
+
79
+ def run_rails_cucumbr_task(version, additional_cucumber_args)
80
+ puts "Testing Rails #{version}"
81
+ if version.empty?
82
+ raise "No Rails version specified - make sure ENV['RAILS_VERSION'] is set, e.g. with `rake cucumber:rails:all`"
83
+ end
84
+ ENV['RAILS_VERSION'] = version
85
+ system("cucumber --format #{ENV['CUCUMBER_FORMAT'] || 'progress'} #{additional_cucumber_args} features/rails.feature")
86
+ end
87
+
88
+ def define_rails_cucumber_tasks(additional_cucumber_args = '')
89
+ namespace :rails do
90
+ RAILS_VERSIONS.each do |version|
91
+ desc "Test integration of the gem with Rails #{version}"
92
+ task version => [:vendor_test_gems] do
93
+ exit 1 unless run_rails_cucumbr_task(version, additional_cucumber_args)
94
+ end
95
+ end
96
+
97
+ desc "Test integration of the gem with all Rails versions"
98
+ task :all do
99
+ results = RAILS_VERSIONS.map do |version|
100
+ run_rails_cucumbr_task(version, additional_cucumber_args)
101
+ end
102
+
103
+ exit 1 unless results.all?
104
+ end
105
+ end
106
+ end
107
+
108
+ namespace :cucumber do
109
+ define_rails_cucumber_tasks
110
+ end
@@ -0,0 +1,13 @@
1
+ 3.0.0
2
+ 3.0.1
3
+ 3.0.2
4
+ 3.0.3
5
+ 3.0.4
6
+ 3.0.5
7
+ 3.0.6
8
+ 3.0.7
9
+ 3.0.8
10
+ 3.0.9
11
+ 3.0.10
12
+ 3.1.0
13
+ 3.1.1
data/TESTING.md ADDED
@@ -0,0 +1,24 @@
1
+ Running the suite
2
+ =================
3
+
4
+ Since the logger must run on many versions of Rails, running its test suite is slightly different than you may be used to.
5
+
6
+ First execute the following command:
7
+
8
+ rake vendor_test_gems
9
+ # NOT: bundle exec rake vendor_test_gems
10
+
11
+ This command will download the various versions of Rails that the notifier must be tested against.
12
+
13
+ Then, to start the suite, run
14
+
15
+ rake cucumber:rails:all
16
+
17
+ Note: do NOT use 'bundle exec rake cucumber:rails:all'.
18
+
19
+ For help created file test/test.sh, which run all this testing steps + unit tests. Run this file from root of gem:
20
+
21
+ ./test/test.sh
22
+
23
+ Versions of testing Rails you can see in file "SUPPORTED_RAILS_VERSIONS". If some tests is faild, you can see
24
+ more information about fallen tests in file "tmp/terminal.log".
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ begin
5
+ require 'vegas'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'vegas'
9
+ end
10
+ require 'mongodb_logger/server'
11
+
12
+
13
+ Vegas::Runner.new(MongodbLogger::Server, 'mongodb_logger_web', {
14
+ :before_run => lambda {|v|
15
+ config_file = (ENV['MONGODBLOGGERCONFIG'] || v.args.first)
16
+ if config_file
17
+ MongodbLogger::ServerConfig.set_config(config_file)
18
+ else
19
+ raise ArgumentError, "please provide config file"
20
+ end
21
+ }
22
+ }) do |runner, opts, app|
23
+ #
24
+ end
data/config.ru ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ require 'logger'
3
+
4
+ $LOAD_PATH.unshift ::File.expand_path(::File.dirname(__FILE__) + '/lib')
5
+ require 'mongodb_logger/server'
6
+
7
+ # Set the RESQUECONFIG env variable if you've a `resque.rb` or similar
8
+ # config file you want loaded on boot.
9
+ if ENV['MONGODBLOGGERCONFIG'] && ::File.exists?(::File.expand_path(ENV['MONGODBLOGGERCONFIG']))
10
+ MongodbLogger::ServerConfig.set_config(::File.expand_path(ENV['MONGODBLOGGERCONFIG']))
11
+ else
12
+ raise "Please provide config file"
13
+ end
14
+
15
+ use Rack::ShowExceptions
16
+ run MongodbLogger::Server.new
@@ -0,0 +1,4 @@
1
+ database: monkey_logs_dev
2
+ host: localhost
3
+ port: 27017
4
+ collection: development_log
@@ -0,0 +1,10 @@
1
+ Feature: Install the Gem in a Rails application and test it
2
+
3
+ Background:
4
+ Given I have built and installed the "mongodb_logger" gem
5
+
6
+ Scenario: Use the gem without vendoring the gem in a Rails application
7
+ When I generate a new Rails application
8
+ And I configure my application to require the "mongodb_logger" gem
9
+ And I setup mongodb_logger tests
10
+ Then the tests should have run successfully
@@ -0,0 +1,48 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ Given /^I have built and installed the "([^\"]*)" gem$/ do |gem_name|
4
+ @terminal.build_and_install_gem(File.join(PROJECT_ROOT, "#{gem_name}.gemspec"))
5
+ end
6
+
7
+ When /^I generate a new Rails application$/ do
8
+ @terminal.cd(TEMP_DIR)
9
+ version_string = ENV['RAILS_VERSION']
10
+ rails_create_command = 'new'
11
+
12
+ load_rails = <<-RUBY
13
+ gem "rails", "#{version_string}"; \
14
+ load Gem.bin_path("rails", "rails", "#{version_string}")
15
+ RUBY
16
+
17
+ @terminal.run(%{ruby -rrubygems -rthread -e "#{load_rails.gsub("\"", "\\\"").strip!}" #{rails_create_command} rails_root})
18
+ if rails_root_exists?
19
+ @terminal.echo("Generated a Rails #{version_string} application")
20
+ else
21
+ raise "Unable to generate a Rails application:\n#{@terminal.output}"
22
+ end
23
+ require_thread if rails30?
24
+ end
25
+
26
+ When /^I configure my application to require the "([^\"]*)" gem(?: with version "(.+)")?$/ do |gem_name, version|
27
+ bundle_gem(gem_name, version)
28
+ end
29
+
30
+ When /^I setup mongodb_logger tests$/ do
31
+ copy_tests
32
+ add_routes
33
+ end
34
+
35
+ Then /^the tests should have run successfully$/ do
36
+ bundle_gem("therubyracer", nil) if rails31?
37
+ step %{I run "bundle install"}
38
+ @terminal.status.exitstatus.should == 0
39
+ step %{I run "rake db:create db:migrate RAILS_ENV=test --trace"}
40
+ @terminal.status.exitstatus.should == 0
41
+ step %{I run "rake test RAILS_ENV=test --trace"}
42
+ @terminal.status.exitstatus.should == 0
43
+ end
44
+
45
+ When /^I run "([^\"]*)"$/ do |command|
46
+ @terminal.cd(rails_root)
47
+ @terminal.run(command)
48
+ end