• This repository has been archived on 04/Dec/2021
  • Stars
    star
    141
  • Rank 259,971 (Top 6 %)
  • Language
    Ruby
  • License
    MIT License
  • Created about 13 years ago
  • Updated almost 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

MongoDB logger for Rails

MongodbLogger

Build Status Code Climate

MongodbLogger is a alternative logger for Rails or Rack based app, which log all requests of you application into MongoDB database. It:

  • simple to integrate into existing Rails application;
  • allow to store all logs from web cluster into one scalable storage - MongoDB;
  • flexible schema of MongoDB allow to store and search any information from logs;
  • web panel allow filter logs, build graphs using MapReduce by information from logs;

Rails support

Please note the latest version is compatible with rails 3.1.x or newer.

For rails 3.0.x latest version 0.2.8.

Doesn't support the Rails version below 3.

Installation

  1. Add the following to your Gemfile then refresh your dependencies by executing "bundle install" (or just simple "bundle"):

     gem "mongodb_logger"
    
  2. Add adapter in Gemfile. Supported mongo and moped (mongoid). For example:

     gem "mongo"
     gem "bson_ext"
    

or

    gem "moped"
  1. Add the following line to your ApplicationController:

     include MongodbLogger::Base
    
  2. For use with Heroku you need to prevent the rails_log_stdout plugin from being added by Heroku for rails 3:

     mkdir vendor/plugins/rails_log_stdout
     touch vendor/plugins/rails_log_stdout/.gitkeep
    

    For Rails 4 just remove from Gemfile "rails_12factor" gem.

  3. Add MongodbLogger settings to database.yml for each environment in which you want to use the MongodbLogger. The MongodbLogger will also look for a separate mongodb_logger.yml or mongoid.yml (if you are using mongoid) before looking in database.yml. In the mongodb_logger.yml and mongoid.yml case, the settings should be defined without the 'mongodb_logger' subkey.

    database.yml:

     development:
       adapter: postgresql
       database: my_app_development
       username: postgres
       mongodb_logger:
         database: my_app               # required (the only required setting)
         capped: true                   # default: true  - warning: uncapped collections introduce the vulnerability that the size of the collection grows too high, exceeding all avaialble disk space
         capsize: <%= 10.megabytes %>   # default: 250MB - ignored if capped is set to false
         host: localhost                # default: localhost
         port: 27017                    # default: 27017
         username: null                 # default: null, username for MongoDB Auth
         password: null                 # default: null, password for MongoDB Auth
         replica_set: true              # default: false - Adds retries for ConnectionFailure during voting for replica set master
         write_options:                 # default: {w: 0, wtimeout: 200} - write options for inserts (w - wait for insert to propagate to "w" numbers of nodes)
           w: 0
           wtimeout: 200
         application_name: my_app       # default: Rails.application
         disable_file_logging: false    # default: false - disable logging into filesystem (only in MongoDB)
         collection: some_name          # default: Rails.env + "_log" - name of MongoDB collection
    

    mongodb_logger.yml:

     development:
       database: my_app
       capsize: <%= 10.megabytes %>
       host: localhost
       port: 27017
       replica_set: true
    

    Also you can use "url" parameter for setup connection to mongodb:

     development:
       url: mongodb://username:password@localhost:27017/my_app
       capsize: <%= 10.megabytes %>
    
  4. For using with MongoDB Replica Set (more info you can read by this link http://www.mongodb.org/display/DOCS/Replica+Sets). In config set list of [host, port] in key "hosts":

     development:
       database: my_app
       capsize: <%= 10.megabytes %>
       host: localhost
       port: 27017
       hosts:
         - - 127.0.0.1
           - 27018
         - - 127.0.0.1
           - 27019
    
  5. For assets pipeline you can generate all js/css file into folder by rake task:

     rake mongodb_logger:assets:compile[public/assets]
    

Assets pipeline

For capistrano possible compile assets by receipt. Add this to config/deploy.rb:

require 'mongodb_logger/capistrano'
set :mongodb_logger_assets_dir, "public/assets" # where to put mongodb assets
after 'deploy:update_code', 'mongodb_logger:precompile'

Also you can serve assets from rails app. You need just mount it separately:

mount MongodbLogger::Server.new, :at => "/mongodb", :as => :mongodb
mount MongodbLogger::Assets.instance, :at => "/mongodb/assets", :as => :mongodb_assets # assets

Usage

After success instalation of gem, a new MongoDB document (record) will be created for each request on your application, by default will record the following information: Runtime, IP Address, Request Time, Controller, Method, Action, Params, Application Name and All messages sent to the logger. The structure of the MongoDB document looks like this:

{
  'action'           : action_name,
  'application_name' : application_name (rails root),
  'controller'       : controller_name,
  'ip'               : ip_address,
  'messages'         : {
                         'info'  : [ ],
                         'debug' : [ ],
                         'error' : [ ],
                         'warn'  : [ ],
                         'fatal' : [ ]
                       },
  'params'           : { },
  'path'             : path,
  'request_time'     : date_of_request,
  'runtime'          : elapsed_execution_time_in_milliseconds,
  'url'              : full_url,
  'method'           : request method (GET, POST, OPTIONS),
  'session'          : information from session,
  'is_exception'     : true only for exceptions (in other cases this field miss)
}

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), you can just call the Rails.logger.add_metadata method on your logger like so (for example from a before_filter):

# make sure we're using the MongodbLogger in this environment
Rails.logger.add_metadata(user_id: @current_user.id) if Rails.logger.respond_to?(:add_metadata)

Callback on exceptions

For send email or do something on exception you can add callback:

MongodbLogger::Base.configure do |config|
  config.on_log_exception do |mongo_record|
    # do something with this data, for example - send email (better - by background job)
  end
end

In this callback send record without "_id", because logger not wait for insert response from MongoDB.

Disable mongodb_logger

To disable MongodbLogger you can use option disable. But this should be set before rails load (for example in Rails app the top of "config/application.rb"):

MongodbLogger::Base.configure do |config|
  config.disable = true
end

or

 MongodbLogger::Base.disable = true

Migrate to another size of capped collection

If you need change capper collection size, you should change the "capsize" key in mongodb_config and run this task for migration:

rake mongodb_logger:migrate

Rack Middleware

If you want use MongodbLogger in Rack app which is mounted to your Rails app, you can try to use rack middleware:

use MongodbLogger::RackMiddleware

Rails::Engine

If you want use MongodbLogger with some of Rails::Engine, you can do this (example for Spree):

Spree::BaseController.send :include, MongodbLogger::Base
Spree::Admin::BaseController.send :include, MongodbLogger::Base # for admin

The Front End

To setup web interface in you Rails application, first of all create autoload file in you Rails application

File: you_rails_app/config/initializers/mongodb_logger.rb (example)

require 'mongodb_logger/server' # required
# this secure you web interface by basic auth, but you can skip this, if you no need this
MongodbLogger::Server.use Rack::Auth::Basic do |username, password|
    [username, password] == ['admin', 'password']
end

and just mount MongodbLogger::Server in rails routes:

File: you_rails_app/config/routes.rb

mount MongodbLogger::Server.new, :at => "/mongodb"

Now you can see web interface by url "http://localhost:3000/mongodb"

If you've installed MongodbLogger as a gem and want running the front end without Rails application, you can do it by this command:

mongodb_logger_web config.yml

where config.yml is config, similar to config of Rails apps, but without Rails.env. Example:

database: app_logs_dev
host: localhost
port: 27017
collection: development_log # set for see development logs

parameter "collection" should be set, if your set custom for your Rails application or start this front end not for production enviroment (by default taken "production_log" collection, in Rails application gem generate "#{Rails.env}_log" collection, if it is not defined in config).

It's a thin layer around rackup so it's configurable as well:

mongodb_logger_web config.yml -p 8282

Passenger, Unicorn, Thin, etc.

Using Passenger, Unicorn, Thin, etc? MongodbLogger ships with a config.ru you can use. See guide:

Don't forget setup MONGODBLOGGERCONFIG env variable, which provide information about MongodbLogger config. Example starting with unicorn:

MONGODBLOGGERCONFIG=examples/server_config.yml unicorn

Demo Application with MongodbLogger

Demo: http://demo-mongodb-logger.catware.org/

Demo Sources: https://github.com/le0pard/mongodb_logger_example_heroku

Querying via the Rails console

And now, for a couple quick examples on getting ahold of this log data... First, here's how to get a handle on the MongoDB from within a Rails console:

>> db = Rails.logger.mongo_adapter.connection
=> #<Mongo::DB:0x007fdc7c65adc8 @name="monkey_logs_dev" ... >
>> collection = Rails.logger.mongo_adapter.collection
=> #<Mongo::Collection:0x007fdc7a4d12b0 @name="development_log" .. >

Once you've got the collection, you can find all requests for a specific user (with id):

>> cursor = collection.find(:user_id => '12355')
=> #<Mongo::Cursor:0x1031a3e30 ... >
>> cursor.count
=> 5

Find all requests that took more that one second to complete:

>> collection.find({:runtime => {'$gt' => 1000}}).count
=> 3

Find all order#show requests with a particular order id (id=order_id):

>> collection.find({"controller" => "order", "action"=> "show", "params.id" => order_id})

Find all requests with an exception that contains "RoutingError" in the message or stack trace:

>> collection.find({"messages.error" => /RoutingError/})

Find all requests with errors:

>> collection.find({"is_exception" => true})

Find all requests with a request_date greater than '11/18/2010 22:59:52 GMT'

>> collection.find({:request_time => {'$gt' => Time.utc(2010, 11, 18, 22, 59, 52)}})

Using Uncapped Collections as Storage

MongoDB's capped collections are a safe choice for storing logs where expiration happens automatically after exceeding the provided capsize (first in first out expiration).

Capped collections comes with a few limitations, one of them being that you cannot manually delete log entries. Switching to a capped: false configuration will store all log entries in an uncapped collection and remove the constraints of uncapped collections.

Warning: If you choose to deploy mongodb_logger with an uncapped collection configuration, you should implement an alternative way of cleaning up log records (cron job or similar). Uncapped collections can grow indifinely in size and take up more disk space than you anticipated.

Copyright (c) 2009-2014 Phil Burrows, CustomInk (based on https://github.com/customink/central_logger) and Leopard released under the MIT license

More Repositories

1

pgtune

Pgtune - tuning PostgreSQL config by your hardware
JavaScript
1,826
star
2

postgresql_book

Book about PostgreSQL (russian)
TeX
798
star
3

sql-joins-app

SQL JOINS visualizer
Svelte
252
star
4

chef_book

Cooking Infrastructure by Chef
TeX
122
star
5

webp-ffi

Ruby wrapper for libwebp
C
112
star
6

chef-solo-example

Repo with Chef solo example
Ruby
92
star
7

elixir_v8

V8 engine for Elixir with pools
Elixir
67
star
8

rwbox

Vagrant images for Ruby and ROR developers
Ruby
45
star
9

cable-shared-worker

ActionCable and AnyCable Shared Worker support
JavaScript
40
star
10

vmail

VMail - check the markup (HTML, CSS) of HTML email template compatibility with email clients
HTML
23
star
11

webp-wasm

Webp image convertor (webassembly, works offline in browser)
JavaScript
23
star
12

redis_pool

Redis pool for Elixir lang
Elixir
21
star
13

st_rails_example

Demo app for shared templates in rails 3
Ruby
20
star
14

storybook-addon-root-attribute

Storybook addon, which provide ability to change html, body or some element attribute
JavaScript
15
star
15

omniauth-yammer

OmniAuth strategy for Yammer
Ruby
14
star
16

zopfli-ffi

Ruby wrapper for zopfli
Ruby
10
star
17

chef-server-example

Chef server example
Ruby
7
star
18

PsyRadioIOS

PsyRadio app for iOS
Objective-C
6
star
19

my_little_nosql

My Little NoSQL
5
star
20

chef-tdd-monit

Example cookbook with monit
Ruby
5
star
21

le0pard.github.io

My Blog
Sass
5
star
22

sidekiq-crond

Scheduler / Cron for Sidekiq jobs
Ruby
5
star
23

Symfony_films

Films CMS writen on Symfony
PHP
4
star
24

LibreOfficeCSVGenerator

Fill the documents by LibreOffice API and CSV
Java
4
star
25

cv

My Curriculum Vitae
TeX
3
star
26

mpw.js

MPW.js is a JavaScript implementation of the Master Password App algorithm
JavaScript
3
star
27

PsyRadioAndroid

PsyRadio app for Android
Java
3
star
28

ShakeForMute

ShakeForMute for android
Java
3
star
29

mongodb_logger_example_heroku

Example app with mongodb_logger on heroku
CSS
3
star
30

pg_web

PostgreSQL extension which provide web interface for database
C
2
star
31

smartme_backbone_2012

SmartMe Backbone 2012
Ruby
2
star
32

android_coocoo_afisha

Android coocoorooza app
Java
2
star
33

js-api-service

Elixir Web API to execute JavaScript code
CSS
2
star
34

hatakon_16

hakaton android
Objective-C
1
star
35

monkey_pivotal_updater

Monkey update pivotal google docs
JavaScript
1
star
36

catware

catware site
JavaScript
1
star
37

le0pard

Intro
1
star
38

RWProductManager-Android

RWProductManager for android
Java
1
star
39

restauranteers_iphone

Objective-C
1
star
40

browserlist

Browserlist Wasm - display compatible browsers from browserslist string
Svelte
1
star
41

RWProductManager-iOS

RWProductManager
JavaScript
1
star
42

storybook-addon-root-attribute-demo

Demo for storybook-addon-root-attribute
JavaScript
1
star
43

popcornua_web

popcornua web app
Ruby
1
star
44

presentations

my presentations
HTML
1
star
45

Comics-CMS

Comics CMS writen on Ruby (use Sinatra, DataMapper, HAML and SASS)
Ruby
1
star
46

diploma_program_test

diploma_program_test
Ruby
1
star
47

diploma_fileshare

diploma_fileshare
Ruby
1
star
48

iphone_popcornua

popcornua for iphone
Objective-C
1
star
49

whatiswrongwith

whatiswrongwith
Ruby
1
star
50

android_cat_simple

Java
1
star
51

monkey_notification

Monkey Notification Gem
Ruby
1
star