Object
Mongo adapter. Stores mole info to a mongo database.
Initializes the mongo db store. MongoDb can be used as a persitent store for mole information. This is a preferred store for the mole as it will allow you to gather up reports based on application usage, perf or faults...
Setup rackamole to use the mongodb store as follows:
config.middleware.use Rack::Mole, {
:store => Rackamole::Store::MongoDb.new(
:db_name => 'mole_blee_development_mdb',
:username => 'fernand',
:password => 'letmein',
)
}
To use in conjunction with Wackamole your db_name must follow the convention “mole_[app_name]_[environment]_mdb”.
| :host | The name of the host running the mongo server. Default: localhost |
| :port | The port for the mongo server instance. Default: 27017 |
| :db_name | The name of the mole databaase. Default: mole_mdb |
| :username | username if the mongo db has auth setup. optional |
| :password | password if the mongo db has auth required. optional |
# File lib/rackamole/store/mongo_db.rb, line 39
39: def initialize( options={} )
40: opts = default_options.merge( options )
41: validate_options( opts )
42: init_mongo( opts )
43: end
Normalize all accessors to 3 chars.
# File lib/rackamole/store/mongo_db.rb, line 213
213: def self.field_map
214: @field_map ||= {
215: :env => :env,
216: :app_name => :app,
217: :context => :ctx,
218: :controller => :ctl,
219: :action => :act,
220: :type => :typ,
221: :feature_id => :fid,
222: :date_id => :did,
223: :time_id => :tid,
224: :user_id => :uid,
225: :user_name => :una,
226: :browser => :bro,
227: :machine => :mac,
228: :host => :hos,
229: :software => :sof,
230: :request_time => :rti,
231: :performance => :per,
232: :method => :met,
233: :path => :pat,
234: :session => :ses,
235: :params => :par,
236: :ruby_version => :ver,
237: :fault => :msg,
238: :stack => :sta,
239: :created_at => :cro,
240: :status => :sts,
241: :headers => :hdr,
242: :body => :bod
243: }
244: end
Dump mole info to a mongo database. There are actually 2 collections for mole information. Namely features and logs. The features collection hold application and feature information and is referenced in the mole log. The logs collections holds all information that was gathered during the request such as user, params, session, request time, etc...
# File lib/rackamole/store/mongo_db.rb, line 60
60: def mole( arguments )
61: return if arguments.empty?
62:
63: unless @connection
64: init_mongo( :host => host, :port => port, :db_name => db_name )
65: end
66:
67: # get a dup of the args since will mock with the original
68: args = arguments.clone
69:
70: # dump request info to mongo
71: save_log( save_user( args ), save_feature( args ), args )
72: rescue => mole_boom
73: $stderr.puts "MOLE STORE CRAPPED OUT -- #{mole_boom}"
74: $stderr.puts mole_boom.backtrace.join( "\n " )
75: end
# File lib/rackamole/store/mongo_db.rb, line 45
45: def to_yaml( opts={} )
46: YAML::quick_emit( object_id, opts ) do |out|
47: out.map( taguri, to_yaml_style ) do |map|
48: map.add( :host , host )
49: map.add( :port , port )
50: map.add( :db_name , db_name )
51: end
52: end
53: end
Check
# File lib/rackamole/store/mongo_db.rb, line 202
202: def check_hash( value )
203: return value unless value.is_a?( Hash )
204: value.keys.inject({}){ |h,k| h[ensure_valid_key(k)] = value[k];h }
205: end
Set up mongo default options ie localhost host, default mongo port and the database being mole_mdb
# File lib/rackamole/store/mongo_db.rb, line 124
124: def default_options
125: {
126: :host => 'localhost',
127: :port => Mongo::Connection::DEFAULT_PORT
128: }
129: end
Check for invalid key format - ie something that will choke mongo case a.b.c => a_b_c
# File lib/rackamole/store/mongo_db.rb, line 197
197: def ensure_valid_key( key )
198: key.to_s.index( /\./ ) ? key.to_s.gsub( /\./, '_' ) : key
199: end
# File lib/rackamole/store/mongo_db.rb, line 87
87: def init_mongo( opts )
88: @host = opts[:host]
89: @port = opts[:port]
90: @db_name = opts[:db_name]
91:
92: @connection = Mongo::Connection.new( @host, @port, :logger => opts[:logger] )
93: @database = @connection.db( @db_name )
94:
95: if opts[:username] and opts[:password]
96: authenticated = @database.authenticate( opts[:username], opts[:password] )
97: raise "Authentication failed for database #{@db_name}. Please check your credentials and try again" unless authenticated
98: end
99:
100: @features = database.collection( 'features' )
101: @logs = database.collection( 'logs' )
102: @users = database.collection( 'users' )
103: end
For storage reason minify the json to save space...
# File lib/rackamole/store/mongo_db.rb, line 208
208: def min_field( field )
209: Rackamole::Store::MongoDb.field_map[field] || field
210: end
Clear out mole database content ( Careful there - testing only! )
# File lib/rackamole/store/mongo_db.rb, line 81
81: def reset!
82: logs.remove
83: features.remove
84: users.remove
85: end
Find or create a mole feature...
# File lib/rackamole/store/mongo_db.rb, line 154
154: def save_feature( args )
155: app_name = args.delete( :app_name )
156: route_info = args.delete( :route_info )
157: environment = args.delete( :environment )
158:
159: row = { min_field(:app_name) => app_name, min_field(:env) => environment.to_s }
160: if route_info
161: row[min_field(:controller)] = route_info[:controller]
162: row[min_field(:action)] = route_info[:action]
163: else
164: row[min_field(:context)] = args.delete( :path )
165: end
166:
167: feature = features.find_one( row, :fields => ['_id'] )
168: return feature['_id'] if feature
169:
170: now = args[:created_at]
171: row[min_field(:date_id)] = "%4d%02d%02d" %[now.year, now.month, now.day]
172:
173: features.save( row )
174: end
Insert a new feature in the db NOTE : Using min key to reduce storage needs. I know not that great for higher level api’s :-( also saving date and time as ints. same deal...
# File lib/rackamole/store/mongo_db.rb, line 179
179: def save_log( user_id, feature_id, args )
180: now = args.delete( :created_at )
181: row = {
182: min_field( :type ) => args[:type],
183: min_field( :feature_id ) => feature_id,
184: min_field( :user_id ) => user_id,
185: min_field( :date_id ) => "%4d%02d%02d" %[now.year, now.month, now.day],
186: min_field( :time_id ) => "%02d%02d%02d" %[now.hour, now.min, now.sec]
187: }
188:
189: args.each do |k,v|
190: row[min_field(k)] = check_hash( v ) if v
191: end
192: logs.save( row )
193: end
Find or create a moled user... BOZO !! What to do if user name changed ?
# File lib/rackamole/store/mongo_db.rb, line 133
133: def save_user( args )
134: user_id = args.delete( :user_id ) if args.has_key?( :user_id )
135: user_name = args.delete( :user_name ) if args.has_key?( :user_name )
136:
137: row = {}
138: if user_id and user_name
139: row = { min_field( :user_id ) => user_id, min_field( :user_name ) => user_name }
140: else
141: row = { min_field( :user_name ) => user_name }
142: end
143:
144: user = users.find_one( row, :fields => ['_id'] )
145: return user['_id'] if user
146:
147: now = args[:created_at]
148: row[min_field(:date_id)] = "%4d%02d%02d" % [now.year, now.month, now.day]
149:
150: users.save( row )
151: end
Validates option hash.
# File lib/rackamole/store/mongo_db.rb, line 106
106: def validate_options( opts )
107: ]host port db_name].each do |option|
108: unless opts[option.to_sym]
109: raise "[MOle] Mongo store configuration error -- You must specify a value for option `:#{option}"
110: end
111: end
112: # check for auth
113: if opts[:username]
114: %(username password).each do |option|
115: unless opts[option.to_sym]
116: raise "[MOle] Mongo store configuration error -- You must specify a value for auth option `:#{option}"
117: end
118: end
119: end
120: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.