mongodb_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.
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