remexify 1.2.0 → 1.3.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.
data/README.md CHANGED
@@ -1,30 +1,27 @@
1
1
  # Remexify
2
2
 
3
- Remexify is the world's simplest Rails-only ActiveRecord gem to write/retrieve logs written into your database's table.
4
- Its philosophy is not to be a dictator gem, so you have your control over what to log, the log level, and et cetera.
5
- Remexify is happy to be no fluff, and to-the-point!
3
+ Remexify is the simplest way to log anything into your database, build for Rails. It supports ActiveRecord and Mongoid::Document. Remexify is happy to be no fluff, and to-the-point!
6
4
 
7
5
  ## Behind the scene
8
6
 
9
7
  > Roses are red violets are blue, a log is not a poem it should be accessible to you.
10
8
 
11
- Remexify is always by my side whenever I need to log something into the database. I am tired of managing different logger,
12
- or duplicatings codes accross multitude of projects I am working on only to have this kind of ability that I wanted.
13
- Therefore, I refactor it and made it into a gem available to all projects a bundle away not only for mine, but also for yours.
14
- I wish it will help you somehow.
9
+ I always used Remexify whenever I need to log something into the database. I am tired of managing different logger,
10
+ or duplicating codes across projects for getting the simple functionality that I had always wanted to have.
11
+ Therefore, I refactor it, and made it into a gem, so that it become available to all projects a bundle away.
15
12
 
16
13
  ## Why should you use Remexify?
17
14
 
18
15
  Remexify...
19
16
 
20
- 1. Help you log to your own database, by giving you the control and ease on when/where to do that.
21
- 2. Let you log not only an error, but also info, log, etc. Actually, "error" is just a numeric constant.
22
- 3. Gives you the flexible means of accessing your logged error.
23
- 4. Let you *censor* specific error classes which you don't want it to appear in the backtrace.
24
- 5. Let you define acceptable/unacceptable classes of error which you can use to control what instance of exception class you want to dismiss, or to keep.
25
- 6. Logs similar error once, but will record the frequency if similar error occurred again.
26
- 7. Can associate your logs to certain user, object, or anything.
27
- 7. Is free and open source for all the People of Earth.
17
+ 1. Help you log to your own database, giving you the control and ease on when/where to do that.
18
+ 2. Let you log not only an error, but also info, log, etc. (Those info/log/etc definition is just a numeric constant.)
19
+ 3. Give you the easy, and flexible mean of accessing your log.
20
+ 4. Let you *censor* string in the backtrace so it won't pollute your backtrace from noisy, unnecessary information.
21
+ 5. Let you define acceptable/unacceptable classes to be logged.
22
+ 6. Logs error once, and increase its occurence frequency so no 2 similar logs are duplicate of each other.
23
+ 7. Can associate your logs to certain user, object, or anything in order to trace who trigger the error.
24
+ 7. It is free, 100% I contribute it as an open source for all the People of Earth to use it.
28
25
 
29
26
  ## Installation
30
27
 
@@ -40,30 +37,30 @@ Or install it yourself as:
40
37
 
41
38
  $ gem install remexify
42
39
 
40
+ Then, you need to generate some models that the gem needs, here we give our model name of `System::Loggers`:
41
+
42
+ rails g remexify System::Loggers
43
+
44
+ You can name your log class anything, such as `System::Loggers`. After that, you have to migrate it:
45
+
46
+ rake db:migrate
47
+
43
48
  ## Design Decision
44
49
 
45
- This gem monkey patch attribute already_logged(?) in two standard ruby error classes:
50
+ By using this gem, it will monkey patch `already_logged` into these two classes:
46
51
 
47
52
  1. RuntimeError
48
53
  2. StandardError
49
54
 
50
- `already_logged` (or `already_logged?`) will return nil if the exception is not yet logged.
51
-
52
- Additionally, there is new error class `DisplayableError`. DisplayableError will be quite handy if you want to raise an enduser-visible error. In your controller, you may only allow an instance of DisplayableError to be displayed. DisplayableError
53
- is nothing but a StandardError subclassed.
54
-
55
- If Remexify caught exceptions any of the above class, it will mark `already_logged` to `true`. Remexify won't log it again when parent/calling method rescue the error.
55
+ `already_logged` (or `already_logged?`) will return nil if the exception is not yet logged. Additionally, there is new error class
56
+ `DisplayableError`. You can set apart user-visible error for system-only administrative-level error through the use of
57
+ `DisplayableError`. Thus, in your controller, you may allow only an instance of DisplayableError to be displayed. DisplayableError
58
+ is nothing but a sub-classed StandardError.
56
59
 
57
60
  ## Basic Usage
58
61
 
59
- To use this gem, you need to generate some files first. You can let the gem to generate all required files, including migration and initializer, for you. To do so, issue:
60
-
61
- rails g remexify System::Loggers
62
-
63
- You can name your log class anything, such as `System::Loggers`. After that, you have to migrate it.
62
+ ### Logging
64
63
 
65
- rake db:migrate
66
-
67
64
  Finally, you can use the gem!
68
65
 
69
66
  Remexify.log err
@@ -77,16 +74,23 @@ In a rails app, you may invoke the `error()` like this:
77
74
  Remexify.error e, file: __FILE__, class: self.class.name, method: __method__, line: __LINE__
78
75
  raise e
79
76
  end
80
-
81
- Remexify have 4 static functions:
77
+
78
+ Starting from version 1.2.0, you can omit `file`, `method`, and `line` from the hash, which the gem will try to deduct by itself.
79
+
80
+ ```ruby
81
+ Remexify.error e, class: self.class.name
82
+ ```
83
+
84
+ Instead of `error`, Remexify also provide you with other handy method for logging, those are:
82
85
 
83
86
  def write(level, obj, options = {}); end;
84
87
  def info(obj, options = {}); end;
85
88
  def warning(obj, options = {}); end;
86
89
  def error(obj, options = {}); end;
87
-
88
- `write()` is the most basic function, that you will only need to use if you want to define the level yourself.
89
- Some level is predefined:
90
+
91
+ You may define your own level, if you are not satisfied with the already-given `info`, `warning`, and `error`. To do so,
92
+ you will utilise the `write` function. Actually, `write` is the basic function on which the 3 functions above depend on.
93
+ An error, a warning or an info in Remexify is just a constant:
90
94
 
91
95
  INFO = 100
92
96
  WARNING = 200
@@ -94,21 +98,39 @@ Some level is predefined:
94
98
 
95
99
  Thus, if you want to write info log by invoking `info()` then the log will be recorded with level set to 100.
96
100
 
97
- The obj can be any object. You can pass it a(n instance of) `String`, or an `Exception`, `StandardError`, `RuntimeError`, `DisplayableError`.
101
+ ```ruby
102
+ def info(message_object, options = {})
103
+ write INFO, message_object, options
104
+ end
105
+ ```
106
+
107
+ The obj can be any object. You can pass it a `String`, or an `Exception`, `StandardError`, `RuntimeError`, `DisplayableError`.
98
108
 
99
109
  It will **automatically generate the backtrace if the object passed is an exception.**
100
110
 
101
- Options can have:
102
111
 
103
- 1. :method
104
- 2. :line
105
- 3. :file
106
- 4. :parameters
107
- 5. :description
112
+ ### Accepted options for logging
113
+
114
+ Options accepts those parameters:
115
+
116
+ | Option | Optional? | Description |
117
+ |----------------------|-----------|---------------------------------------------------------------------------------------------------------------|
118
+ | :class | N | The class that triggers the error |
119
+ | :method | Y | The method that triggers the error |
120
+ | :line | Y | The line the error is triggered |
121
+ | :file | Y | The file the error is triggered |
122
+ | :params | Y | Additional information (such as query parameters) that may help later on in an effort to replicate the error. |
123
+ | :desc | Y | Description of the error |
124
+ | :extract_params_from | Y | Specify an ActiveRecord model instance, and all of its attributes will be logged as `params` |
125
+ | :owned_by | Y | Associate the error to certain entity |
126
+ | :owned_param1 | Y | Further discrimination of owner |
127
+ | :owned_param2 | Y | Further discrimination of owner |
128
+ | :owned_param3 | Y | Further discrimination of owner |
129
+ | :object | Y | Object of an ActiveRecord model, snatch information about why the error occur if such an information exist. |
108
130
 
109
- All those options are optional, and, if given, will be stored in the database.
131
+ #### Retrieving logs
110
132
 
111
- In order to retrieve the recorded logs, you will deal with Remexify's Retrieve module. You may retrieve all logs:
133
+ You will need to deal with an extremely simple Remexify's `Retrieve` module. You may retrieve all logs:
112
134
 
113
135
  Remexify::Retrieve.all
114
136
 
@@ -128,7 +150,7 @@ You may also delete all the logs in your database:
128
150
 
129
151
  Remexify.delete_all_logs
130
152
 
131
- ## What is recorded in the database?
153
+ ### What is recorded in the database?
132
154
 
133
155
  These are the fields that is recorded:
134
156
 
@@ -289,4 +311,7 @@ by Adam Pahlevi Baihaqi
289
311
  - User can configure `accepted_exceptions`
290
312
  - User can configure `discarded_exceptions`
291
313
  - Ability to associate log to specific user
292
- - Ability to retrieve logs that owned by certain identifier_id (like, user's id)
314
+ - Ability to retrieve logs that owned by certain identifier_id (like, user's id)
315
+ - You are no longer required to specify `file`, `class` and `method` as Remexify now is able to deduct such infomation from the calling trace.
316
+ - [v.1.3.0](#)
317
+ - Added support for Mongoid::Document
@@ -1,17 +1,12 @@
1
- require "rails/generators"
1
+ require "rails/generators/active_record"
2
2
  require "rails/generators/migration"
3
- require "rails/generators/named_base"
4
3
 
5
- module Remexify
4
+ module ActiveRecord
6
5
  module Generators
7
- class RemexifyGenerator < Rails::Generators::NamedBase
6
+ class RemexifyGenerator < ActiveRecord::Generators::Base
8
7
  include Rails::Generators::Migration
9
8
  source_root File.expand_path("../templates", __FILE__)
10
9
 
11
- desc "Generates a model with the given NAME for remexify to log error/informations"
12
-
13
- namespace "remexify"
14
-
15
10
  # to avoid next migration numbers having the same exact identity
16
11
  @secondth = 1
17
12
 
@@ -20,11 +15,13 @@ module Remexify
20
15
  (Time.now.utc. + @secondth).strftime("%Y%m%d%H%M%S")
21
16
  end
22
17
 
18
+ # copy the migration
23
19
  def copy_migration
24
20
  migration_template "create_remexify_lognotes.rb", "db/migrate/create_remexify_lognotes.rb"
25
21
  migration_template "create_remexify_logowners.rb", "db/migrate/create_remexify_logowners.rb"
26
22
  end
27
23
 
24
+ # generate appropriate model
28
25
  def generate_model
29
26
  # don't just call invoke without Rails::Generators because Thor task only run once.
30
27
  Rails::Generators.invoke "active_record:model", [name, "--no-migration"]
@@ -4,7 +4,7 @@ class CreateRemexifyLognotes < ActiveRecord::Migration
4
4
  # 0 the more high the level, the more important.
5
5
  t.integer :level, null: false, default: 0
6
6
 
7
- # let your log unique
7
+ # let your log be unique
8
8
  t.string :md5, null: false
9
9
 
10
10
  t.text :message, null: false
@@ -0,0 +1,74 @@
1
+ require "rails/generators/named_base"
2
+
3
+ module Mongoid
4
+ module Generators
5
+ class RemexifyGenerator < Rails::Generators::NamedBase
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ def generate_log_model
9
+ Rails::Generators.invoke "mongoid:model", [name]
10
+ end
11
+
12
+ def generate_logowner_model
13
+ Rails::Generators.invoke "mongoid:model", ["#{name}Owners"]
14
+ end
15
+
16
+ def inject_log_model
17
+ log_data = <<RUBY
18
+ include Mongoid::Timestamps::Short
19
+
20
+ # 0; the more high the level, the more important
21
+ field :level, type: Integer, default: 0
22
+
23
+ # let your log be unique
24
+ field :md5, type: String
25
+
26
+ field :message, type: String
27
+ field :backtrace, type: String
28
+ field :file_name, type: String
29
+
30
+ field :class_name, type: String
31
+ field :method_name, type: String
32
+ field :line, type: String
33
+
34
+ # additional parameters that want to be logged as well
35
+ field :parameters, type: String
36
+
37
+ # additional description that want to be logged as well
38
+ field :description, type: String
39
+
40
+ # how many times the system logging this error?
41
+ field :frequency, type: Integer, default: 1
42
+
43
+ validates_presence_of :level, :md5, :message, :class_name, :frequency
44
+ index({ md5: 1 }, {unique: true})
45
+ RUBY
46
+
47
+ inject_into_file File.join("app", "models", "#{file_path}.rb"), log_data, after: "include Mongoid::Document\n"
48
+ end
49
+
50
+ def inject_logowner_model
51
+ log_data = <<RUBY
52
+ include Mongoid::Timestamps::Short
53
+
54
+ field :log_md5, type: String
55
+ field :identifier_id, type: String
56
+
57
+ field :param1, type: String
58
+ field :param2, type: String
59
+ field :param3, type: String
60
+
61
+ validates_presence_of :log_md5, :identifier_id
62
+
63
+ index({ md5: 1, identifier_id: 1 }, { unique: true })
64
+ RUBY
65
+ inject_into_file File.join("app", "models", "#{file_path}_owners.rb"), log_data, after: "include Mongoid::Document\n"
66
+ end
67
+
68
+ def make_initializer
69
+ template "initialize_remexify.rb", "config/initializers/00_remexify.rb"
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,8 @@
1
+ Remexify.setup do |config|
2
+ config.model = <%= class_name %>
3
+ config.model_owner = <%= class_name %>Owners
4
+
5
+ # uncomment lines bellow if you want to out list mongoid. add other similar lines
6
+ # for other libraries if you wish.
7
+ config.censor_strings << "mongoid"
8
+ end
@@ -0,0 +1,13 @@
1
+ require "rails/generators"
2
+ require "rails/generators/named_base"
3
+
4
+ module Remexify
5
+ module Generators
6
+ class RemexifyGenerator < Rails::Generators::NamedBase
7
+ namespace "remexify"
8
+ desc "Generates a model with the given NAME for remexify to log error/informations"
9
+
10
+ hook_for :orm
11
+ end
12
+ end
13
+ end
data/lib/remexify.rb CHANGED
@@ -36,7 +36,19 @@ module Remexify
36
36
  end
37
37
 
38
38
  # model must exists as ActiveRecord model. model_owner is not necessary to exists at all
39
- raise "Remexify.config.model is not an ActiveRecord model" unless config.model < ActiveRecord::Base
39
+ if defined?(ActiveRecord::Base) && defined?(Mongoid::Document)
40
+ if (config.model < ActiveRecord::Base) || (config.model < Mongoid::Document)
41
+ # good!
42
+ else
43
+ raise "Remexify.config.model is neither an ActiveRecord model or Mongoid::Document"
44
+ end
45
+ elsif defined?(ActiveRecord::Base)
46
+ raise "Remexify.config.model is not an ActiveRecord model" unless config.model < ActiveRecord::Base
47
+ elsif defined?(Mongoid::Document)
48
+ raise "Remexify.config.model is not a Mongoid::Document" unless config.model < Mongoid::Document
49
+ else
50
+ raise "Remexify.config.model is neither an ActiveRecord model or Mongoid::Document"
51
+ end
40
52
  end
41
53
  end
42
54
 
@@ -39,6 +39,8 @@ module Remexify
39
39
  backtrace = ""
40
40
  end
41
41
 
42
+ backtrace = "null" if backtrace.blank?
43
+
42
44
  # standardize into options[:parameters]
43
45
  options[:parameters] = options[:param] if options[:param]
44
46
  options[:parameters] = options[:params] if options[:params]
@@ -48,24 +50,43 @@ module Remexify
48
50
  # will override the options[:parameters] if this block execute successfully
49
51
  if options[:extract_params_from]
50
52
  ar_message_objectect = options[:extract_params_from]
51
- if ar_message_objectect.class < ActiveRecord::Base
52
- if ar_message_objectect.respond_to?(:attribute_names) && ar_message_objectect.respond_to?(:read_attribute)
53
- ar_attributes = ar_message_objectect.attribute_names
54
- attributes = {}
53
+
54
+ def parse_model_fields model
55
+ attributes = {}
56
+ if model.respond_to?(:attribute_names) && model.respond_to?(:read_attribute)
57
+ ar_attributes = model.attribute_names
55
58
  ar_attributes.each do |attr|
56
- attributes[attr.to_s] = ar_message_objectect.read_attribute attr.to_sym
59
+ attributes[attr.to_s] = model.read_attribute attr.to_sym
57
60
  end
58
61
  options[:parameters] = attributes
59
62
  end
63
+ attributes
64
+ end
65
+
66
+ if defined?(ActiveRecord::Base)
67
+ options[:parameters] = parse_model_fields(ar_message_objectect) if ar_message_objectect.class < ActiveRecord::Base
68
+ end
69
+
70
+ if defined?(Mongoid::Document)
71
+ options[:parameters] = parse_model_fields(ar_message_objectect) if ar_message_objectect.class < Mongoid::Document
60
72
  end
61
73
  end
62
74
 
63
75
  # if object is given
64
76
  if options[:object]
65
- # and is an active record
66
- if options[:object].class < ActiveRecord::Base
77
+ parse_error_messages = false
78
+ # and is an active record/mongoid document
79
+ if defined?(ActiveRecord::Base)
80
+ parse_error_messages = true if options[:object].class < ActiveRecord::Base
81
+ end
82
+
83
+ if defined?(Mongoid::Document)
84
+ parse_error_messages = true if options[:object].class < Mongoid::Document
85
+ end
86
+
87
+ if parse_error_messages
67
88
  # append to message
68
- message << "\n\nActiveRecord error messages:\n" << options[:object].errors.full_messages.join("\n")
89
+ message << "\n\nerror messages:\n" << options[:object].errors.full_messages.join("\n")
69
90
  end
70
91
  end
71
92
 
@@ -85,7 +106,7 @@ module Remexify
85
106
  # do not quote md5 directly, it is used to query .where
86
107
  md5 = Digest::MD5.hexdigest hashed
87
108
  # the quoted version of md5, do not replace the original value
88
- qmd5 = config.model.connection.quote md5
109
+ qmd5 = md5
89
110
 
90
111
  # assure md5 is not yet exist, if exist, don't save
91
112
  log = config.model.where(md5: md5).first
@@ -93,9 +114,7 @@ module Remexify
93
114
  log.frequency += 1
94
115
  log.save
95
116
  else
96
- message = config.model.connection.quote message
97
- backtrace = backtrace.blank? ? "null" : config.model.connection.quote(backtrace)
98
- class_name = config.model.connection.quote(class_name)
117
+
99
118
 
100
119
  method = line = file = "null"
101
120
  if Kernel.respond_to? :caller_locations
@@ -109,28 +128,58 @@ module Remexify
109
128
  line = options[:line] unless options[:line].blank?
110
129
  file = options[:file] unless options[:file].blank?
111
130
  end
112
- method = config.model.connection.quote(method)
113
- line = config.model.connection.quote(line)
114
- file = config.model.connection.quote(file)
115
131
 
116
- parameters = options[:parameters].blank? ? "null" : config.model.connection.quote(options[:parameters].inspect)
117
- descriptions = options[:description].blank? ? "null" : config.model.connection.quote(options[:description])
118
- time_now = config.model.connection.quote(Time.now.strftime("%Y-%m-%d %H:%M:%S"))
132
+ parameters = options[:parameters].blank? ? "null" : options[:parameters].inspect
133
+ descriptions = options[:description].blank? ? "null" : options[:description]
134
+ time_now = Time.now.strftime("%Y-%m-%d %H:%M:%S")
135
+
136
+ if defined?(ActiveRecord::Base)
137
+ if config.model < ActiveRecord::Base
138
+ if config.model.connection.transaction_open?
139
+ config.model.connection.rollback_transaction
140
+ end
119
141
 
120
- if config.model.connection.transaction_open?
121
- config.model.connection.rollback_transaction
142
+ qmd5 = config.model.connection.quote md5
143
+ message = config.model.connection.quote message
144
+ backtrace = config.model.connection.quote backtrace
145
+ class_name = config.model.connection.quote class_name
146
+ method = config.model.connection.quote method
147
+ line = config.model.connection.quote line
148
+ file = config.model.connection.quote file
149
+ parameters = config.model.connection.quote parameters
150
+ descriptions = config.model.connection.quote parameters
151
+ time_now = config.model.connection.quote time_now
152
+
153
+ ActiveRecord::Base.transaction do
154
+ config.model.connection.execute <<-SQL
155
+ INSERT INTO #{config.model.table_name} (
156
+ md5, level, message, backtrace,
157
+ class_name, method_name, line, file_name,
158
+ parameters, description, created_at, updated_at)
159
+ VALUES (#{qmd5}, #{Integer level}, #{message}, #{backtrace}, #{class_name},
160
+ #{method}, #{line}, #{file}, #{parameters}, #{descriptions},
161
+ #{time_now}, #{time_now});
162
+ SQL
163
+ end
164
+ end
165
+ elsif defined?(Mongoid::Document)
166
+ if config.model < Mongoid::Document
167
+ new_log = config.model.new
168
+ new_log.md5 = qmd5
169
+ new_log.level = Integer(level)
170
+ new_log.message = message
171
+ new_log.backtrace = backtrace
172
+ new_log.class_name = class_name
173
+ new_log.method_name = method
174
+ new_log.line = line
175
+ new_log.file_name = file
176
+ new_log.parameters = parameters
177
+ new_log.description = descriptions
178
+ new_log.created_at = time_now
179
+ new_log.updated_at = time_now
180
+ new_log.save
181
+ end
122
182
  end
123
- config.model.connection.begin_transaction
124
- config.model.connection.execute <<-SQL
125
- INSERT INTO #{config.model.table_name} (
126
- md5, level, message, backtrace,
127
- class_name, method_name, line, file_name,
128
- parameters, description, created_at, updated_at)
129
- VALUES (#{qmd5}, #{Integer level}, #{message}, #{backtrace}, #{class_name},
130
- #{method}, #{line}, #{file}, #{parameters}, #{descriptions},
131
- #{time_now}, #{time_now});
132
- SQL
133
- config.model.connection.commit_transaction
134
183
  end
135
184
 
136
185
  # mark already logged if DisplayableError
@@ -139,19 +188,38 @@ module Remexify
139
188
  end
140
189
 
141
190
  # if owner_by is given, associate this log to the owned_by user
142
- if !options[:owned_by].blank? && (config.model_owner < ActiveRecord::Base)
143
- owned_by = config.model.connection.quote(options[:owned_by])
144
- owned_param1 = config.model.connection.quote(options[:owned_param1])
145
- owned_param2 = config.model.connection.quote(options[:owned_param2])
146
- owned_param3 = config.model.connection.quote(options[:owned_param3])
147
-
148
- config.model.connection.begin_transaction
149
- config.model.connection.execute <<-SQL
150
- INSERT INTO #{config.model_owner.table_name} (
151
- log_md5, identifier_id, param1, param2, param3)
152
- VALUES (#{qmd5}, #{owned_by}, #{owned_param1}, #{owned_param2}, #{owned_param3})
153
- SQL
154
- config.model.connection.commit_transaction
191
+ unless options[:owned_by].blank?
192
+ owned_by = options[:owned_by]
193
+ owned_param1 = options[:owned_param1]
194
+ owned_param2 = options[:owned_param2]
195
+ owned_param3 = options[:owned_param3]
196
+
197
+ if defined?(ActiveRecord::Base)
198
+ if config.model_owner < ActiveRecord::Base
199
+ owned_by = config.model.connection.quote(owned_by)
200
+ owned_param1 = config.model.connection.quote(owned_param1)
201
+ owned_param2 = config.model.connection.quote(owned_param2)
202
+ owned_param3 = config.model.connection.quote(owned_param3)
203
+
204
+ # config.model.connection.begin_transaction
205
+ ActiveRecord::Base.transaction do
206
+ config.model.connection.execute <<-SQL
207
+ INSERT INTO #{config.model_owner.table_name} (
208
+ log_md5, identifier_id, param1, param2, param3)
209
+ VALUES (#{qmd5}, #{owned_by}, #{owned_param1}, #{owned_param2}, #{owned_param3})
210
+ SQL
211
+ end
212
+ # config.model.connection.commit_transaction
213
+ end
214
+ elsif defined?(Mongoid::Document)
215
+ if config.model_owner < Mongoid::Document
216
+ log_owner = config.model_owner.new
217
+ log_owner.owned_by = owned_by
218
+ log_owner.owned_param1 = owned_param1
219
+ log_owner.owned_param2 = owned_param2
220
+ log_owner.owned_param3 = owned_param3
221
+ end
222
+ end
155
223
  end
156
224
 
157
225
  nil # don't return anything for logging!