effective_logging 1.9.0 → 1.10.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.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/app/controllers/effective/logs_controller.rb +0 -1
- data/app/helpers/effective_logging_helper.rb +2 -1
- data/app/models/effective/datatables/logs.rb +10 -11
- data/app/models/effective/log.rb +14 -11
- data/app/models/effective_logger.rb +5 -0
- data/config/effective_logging.rb +7 -5
- data/db/migrate/01_create_effective_logging.rb.erb +3 -0
- data/lib/effective_logging/active_record_logger.rb +7 -7
- data/lib/effective_logging/email_logger.rb +3 -3
- data/lib/effective_logging/engine.rb +3 -3
- data/lib/effective_logging/log_page_views.rb +8 -8
- data/lib/effective_logging/user_logger.rb +19 -17
- data/lib/effective_logging/version.rb +1 -1
- data/lib/effective_logging.rb +9 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e724ec2b890ab6af1c5f9a6e5fa573231cf64b8
|
4
|
+
data.tar.gz: dad4e05c79b2eeca0be0434e5aa4987dbb7e6ec0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0227e4b2c520bafc19e5a27a71b7f51964d30302f48a99f1902d51dd87dd6d97d172468fc8938c568c28e00f5a563108e2a42d71a83c03f13e11e7124cba3fc
|
7
|
+
data.tar.gz: e0ba574c10badde2f13e6533ca8d2838c2d2da107abf2d7e05b4da69dce67dea11bf38003ab2d130828bf67b2a588c3d48d787720dc997d7701d2275d53a6d9f
|
data/README.md
CHANGED
@@ -102,7 +102,7 @@ Any email sent by the application will be automatically logged.
|
|
102
102
|
|
103
103
|
This behaviour can be disabled in the config/initializers/effective_logging.rb initializer.
|
104
104
|
|
105
|
-
If the TO email address match a User, the :
|
105
|
+
If the TO email address match a User, the :associated will be set to this user.
|
106
106
|
|
107
107
|
You can specify additional fields to be logged via your mailer:
|
108
108
|
|
@@ -111,7 +111,7 @@ def notify_admin_of_new_post(post)
|
|
111
111
|
mail(
|
112
112
|
to: 'admin@example.com',
|
113
113
|
subject: 'A new post was created',
|
114
|
-
log: { :
|
114
|
+
log: { :post => post, :title => post.title }
|
115
115
|
)
|
116
116
|
end
|
117
117
|
```
|
@@ -229,7 +229,7 @@ And on each create / destroy / update, a full dump of all current attributes is
|
|
229
229
|
|
230
230
|
There is some initial support for passing `only`, `except`, and `additionally` to the mixin to customize what attributes are saved.
|
231
231
|
|
232
|
-
Define your model with `log_changes additionally: [:method1, :method2]` to also log the value of
|
232
|
+
Define your model with `log_changes additionally: [:method1, :method2]` to also _always_ log the value of that method. Even if it's unchanged.
|
233
233
|
|
234
234
|
Apply your own formatting to the logged title of each attribute by creating an instance method on the resource:
|
235
235
|
|
@@ -328,7 +328,7 @@ render_datatable(@datatable)
|
|
328
328
|
|
329
329
|
We can also use a similar method to create a datatable of logs for just one user.
|
330
330
|
|
331
|
-
When initialized with :user_id, the 'User' column is hidden and the Logs are scoped to the User.
|
331
|
+
When initialized with :user_id, the 'User' column is hidden and the Logs are scoped to any logs where this user is the User or Associated column.
|
332
332
|
|
333
333
|
In your controller:
|
334
334
|
|
@@ -8,12 +8,13 @@ module EffectiveLoggingHelper
|
|
8
8
|
when 'info' ; 'info'
|
9
9
|
when 'warning' ; 'warning'
|
10
10
|
when 'error' ; 'danger'
|
11
|
+
when 'change' ; 'info'
|
11
12
|
else 'primary'
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
def render_log(log)
|
16
|
-
render(partial: 'effective/logs/log', locals: {:
|
17
|
+
render(partial: 'effective/logs/log', locals: {log: log})
|
17
18
|
end
|
18
19
|
|
19
20
|
def parents_of_log(log)
|
@@ -15,17 +15,19 @@ if defined?(EffectiveDatatables)
|
|
15
15
|
end
|
16
16
|
|
17
17
|
unless attributes[:status] == false
|
18
|
-
table_column :status, filter: { type: :select, values:
|
18
|
+
table_column :status, filter: { type: :select, values: EffectiveLogging.statuses }
|
19
19
|
end
|
20
20
|
|
21
|
+
table_column :associated_type, visible: false
|
22
|
+
table_column :associated_id, visible: false, label: 'Associated Id'
|
23
|
+
table_column :associated_to_s, label: 'Associated'
|
24
|
+
|
21
25
|
table_column :message do |log|
|
22
26
|
log.message.starts_with?("\t") ? log.message.gsub("\t", " ") : log.message
|
23
27
|
end
|
24
28
|
|
25
29
|
table_column :logs_count, visible: false
|
26
30
|
|
27
|
-
table_column :associated, filter: false, sortable: false, visible: false
|
28
|
-
|
29
31
|
table_column :details, visible: false, sortable: false do |log|
|
30
32
|
tableize_hash(log.details.except(:email), th: true, sub_th: false, width: '100%')
|
31
33
|
end
|
@@ -42,22 +44,19 @@ if defined?(EffectiveDatatables)
|
|
42
44
|
def collection
|
43
45
|
collection = Effective::Log.unscoped.where(parent_id: attributes[:log_id]).includes(:user, :associated)
|
44
46
|
|
45
|
-
if attributes[:
|
46
|
-
collection = collection.where(
|
47
|
+
if attributes[:log_changes]
|
48
|
+
collection = collection.where(status: EffectiveLogging.log_changes_status)
|
47
49
|
end
|
48
50
|
|
49
|
-
if attributes[:user].present?
|
50
|
-
|
51
|
+
if (attributes[:user] || attributes[:user_id]).present?
|
52
|
+
user_id = attributes[:user_id] || (attributes[:user].kind_of?(User) ? attributes[:user].id : attributes[:user].to_i)
|
53
|
+
collection = collection.where('user_id = ? OR (associated_id = ? AND associated_type = ?)', user_id, user_id, 'User')
|
51
54
|
end
|
52
55
|
|
53
56
|
if attributes[:associated_id] && attributes[:associated_type]
|
54
57
|
collection = collection.where(associated_id: attributes[:associated_id], associated_type: attributes[:associated_type])
|
55
58
|
end
|
56
59
|
|
57
|
-
if attributes[:log_changes]
|
58
|
-
collection = collection.where(status: EffectiveLogging.log_changes_status)
|
59
|
-
end
|
60
|
-
|
61
60
|
if attributes[:associated]
|
62
61
|
collection = collection.where(associated: attributes[:associated])
|
63
62
|
end
|
data/app/models/effective/log.rb
CHANGED
@@ -13,21 +13,24 @@ module Effective
|
|
13
13
|
|
14
14
|
# The user this log item is referring to
|
15
15
|
# An associated object, if we wanna add anything extra
|
16
|
-
belongs_to :user
|
17
|
-
belongs_to :associated, polymorphic: true
|
16
|
+
belongs_to :user, optional: true
|
17
|
+
belongs_to :associated, polymorphic: true, optional: true
|
18
18
|
|
19
19
|
serialize :details, Hash
|
20
20
|
|
21
|
-
#
|
22
|
-
#
|
23
|
-
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
21
|
+
# Attributes
|
22
|
+
# logs_count :integer # Rails Counter Cache
|
23
|
+
|
24
|
+
# associated_type :string
|
25
|
+
# associated_id :integer
|
26
|
+
# associated_to_s :string
|
27
|
+
# message :string
|
28
|
+
# details :text
|
29
|
+
# status :string
|
30
|
+
# timestamps
|
28
31
|
|
29
32
|
validates :message, presence: true
|
30
|
-
validates :status, presence: true, inclusion: { in:
|
33
|
+
validates :status, presence: true, inclusion: { in: EffectiveLogging.statuses }
|
31
34
|
|
32
35
|
default_scope -> { order(updated_at: :desc) }
|
33
36
|
|
@@ -39,7 +42,7 @@ module Effective
|
|
39
42
|
end
|
40
43
|
|
41
44
|
def log(message, status = EffectiveLogging.statuses.first, options = {})
|
42
|
-
EffectiveLogger.log(message, status, (options || {}).merge(
|
45
|
+
EffectiveLogger.log(message, status, (options || {}).merge(parent: self))
|
43
46
|
end
|
44
47
|
|
45
48
|
def details
|
@@ -22,6 +22,11 @@ class EffectiveLogger
|
|
22
22
|
log.user = options.delete(:user)
|
23
23
|
log.parent = options.delete(:parent)
|
24
24
|
log.associated = options.delete(:associated)
|
25
|
+
log.associated_to_s = options.delete(:associated_to_s)
|
26
|
+
|
27
|
+
if log.associated.present?
|
28
|
+
log.associated_to_s ||= (log.associated.to_s rescue nil)
|
29
|
+
end
|
25
30
|
|
26
31
|
log.details = options.delete_if { |k, v| v.blank? } if options.kind_of?(Hash)
|
27
32
|
|
data/config/effective_logging.rb
CHANGED
@@ -42,10 +42,12 @@ EffectiveLogging.setup do |config|
|
|
42
42
|
#### Automatic Logging Functionality ####
|
43
43
|
#########################################
|
44
44
|
|
45
|
-
# Log all emails
|
46
|
-
config.
|
45
|
+
# Log all sent emails
|
46
|
+
config.email_enabled = true
|
47
47
|
|
48
|
-
# Log all
|
49
|
-
config.
|
50
|
-
|
48
|
+
# Log all sign ins (successful only)
|
49
|
+
config.sign_in_enabled = true
|
50
|
+
|
51
|
+
# Log all sign outs
|
52
|
+
config.sign_out_enabled = false
|
51
53
|
end
|
@@ -2,10 +2,12 @@ class CreateEffectiveLogging < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
3
3
|
create_table <%= @logs_table_name %> do |t|
|
4
4
|
t.integer :parent_id
|
5
|
+
|
5
6
|
t.integer :user_id
|
6
7
|
|
7
8
|
t.string :associated_type
|
8
9
|
t.integer :associated_id
|
10
|
+
t.string :associated_to_s
|
9
11
|
|
10
12
|
t.integer :logs_count
|
11
13
|
|
@@ -21,6 +23,7 @@ class CreateEffectiveLogging < ActiveRecord::Migration
|
|
21
23
|
add_index <%= @logs_table_name %>, :parent_id
|
22
24
|
add_index <%= @logs_table_name %>, [:associated_type, :associated_id]
|
23
25
|
add_index <%= @logs_table_name %>, :associated_id
|
26
|
+
add_index <%= @logs_table_name %>, :associated_to_s
|
24
27
|
end
|
25
28
|
|
26
29
|
def self.down
|
@@ -53,11 +53,7 @@ module EffectiveLogging
|
|
53
53
|
resource.log_changes_formatted_attribute(attribute)
|
54
54
|
end || attribute.titleize
|
55
55
|
|
56
|
-
|
57
|
-
log("#{attribute} changed from #{before.presence || BLANK} to #{after.presence || BLANK}", details: { attribute: attribute, before: before, after: after })
|
58
|
-
else
|
59
|
-
log("#{attribute} set to #{before || BLANK}", details: { attribute: attribute, value: before })
|
60
|
-
end
|
56
|
+
log("#{attribute}: #{before.presence || BLANK} to #{after.presence || BLANK}", details: { attribute: attribute, before: before, after: after })
|
61
57
|
end
|
62
58
|
|
63
59
|
# Log changes on all accepts_as_nested_parameters has_many associations
|
@@ -75,7 +71,7 @@ module EffectiveLogging
|
|
75
71
|
|
76
72
|
# Collect to_s representations of all belongs_to associations
|
77
73
|
(resource.class.try(:reflect_on_all_associations, :belongs_to) || []).each do |association|
|
78
|
-
attributes[association.name] = resource.send(association.name).to_s.presence
|
74
|
+
attributes[association.name] = resource.send(association.name).to_s.presence
|
79
75
|
end
|
80
76
|
|
81
77
|
# Collect to_s representations for all has_one associations
|
@@ -90,6 +86,8 @@ module EffectiveLogging
|
|
90
86
|
Array(resource.send(association.name)).each_with_index do |child, index|
|
91
87
|
attributes[association.name][index+1] = ActiveRecordLogger.new(child, options.merge(logger: logger)).attributes
|
92
88
|
end
|
89
|
+
|
90
|
+
attributes[association.name].presence
|
93
91
|
end
|
94
92
|
|
95
93
|
attributes
|
@@ -101,7 +99,7 @@ module EffectiveLogging
|
|
101
99
|
# Log to_s changes on all belongs_to associations
|
102
100
|
(resource.class.try(:reflect_on_all_associations, :belongs_to) || []).each do |association|
|
103
101
|
if (change = changes.delete(association.foreign_key)).present?
|
104
|
-
changes[association.name] = [association.klass.find_by_id(change.first), resource.send(association.name)]
|
102
|
+
changes[association.name] = [(association.klass.find_by_id(change.first) if changes.first), resource.send(association.name)]
|
105
103
|
end
|
106
104
|
end
|
107
105
|
|
@@ -115,6 +113,8 @@ module EffectiveLogging
|
|
115
113
|
user: EffectiveLogging.current_user,
|
116
114
|
status: EffectiveLogging.log_changes_status,
|
117
115
|
message: "#{"\t" * depth}#{options[:prefix]}#{message}",
|
116
|
+
associated: resource,
|
117
|
+
associated_to_s: (resource.to_s rescue nil),
|
118
118
|
details: details
|
119
119
|
).tap { |log| log.save }
|
120
120
|
end
|
@@ -7,7 +7,7 @@ module EffectiveLogging
|
|
7
7
|
logged_fields = { from: message.from.join(','), to: message.to, subject: message.subject }
|
8
8
|
|
9
9
|
# Add a log header to your mailer to pass some objects or additional things to EffectiveLogger
|
10
|
-
# mail(to: 'admin@example.com', subject: @post.title, log: {
|
10
|
+
# mail(to: 'admin@example.com', subject: @post.title, log: { post: @post })
|
11
11
|
if message.header['log'].present?
|
12
12
|
# This is a bit sketchy, but gives access to the object in Rails 4.2 anyway
|
13
13
|
logged_fields.merge!(message.header['log'].instance_variable_get(:@value) || {})
|
@@ -22,9 +22,9 @@ module EffectiveLogging
|
|
22
22
|
|
23
23
|
(message.to || []).each do |to|
|
24
24
|
logged_fields[:to] = to
|
25
|
-
logged_fields[:
|
25
|
+
logged_fields[:associated] ||= (User.where(email: to).first rescue nil)
|
26
26
|
|
27
|
-
::EffectiveLogger.
|
27
|
+
::EffectiveLogger.email("#{message.subject} - #{message.to.join(', ')}", logged_fields)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -19,7 +19,7 @@ module EffectiveLogging
|
|
19
19
|
|
20
20
|
# Automatically Log Emails
|
21
21
|
initializer 'effective_logging.emails' do |app|
|
22
|
-
if EffectiveLogging.
|
22
|
+
if EffectiveLogging.email_enabled == true
|
23
23
|
require 'effective_logging/email_logger'
|
24
24
|
ActionMailer::Base.register_interceptor(EffectiveLogging::EmailLogger)
|
25
25
|
end
|
@@ -51,12 +51,12 @@ module EffectiveLogging
|
|
51
51
|
|
52
52
|
# This has to be run after initialization or User hasn't been loaded yet
|
53
53
|
config.after_initialize do
|
54
|
-
if EffectiveLogging.
|
54
|
+
if EffectiveLogging.sign_in_enabled || EffectiveLogging.sign_out_enabled
|
55
55
|
ActiveSupport.on_load :active_record do
|
56
56
|
if defined?(Devise)
|
57
57
|
EffectiveLogging::UserLogger.create_warden_hooks()
|
58
58
|
else
|
59
|
-
raise ArgumentError.new("EffectiveLogging.
|
59
|
+
raise ArgumentError.new("EffectiveLogging.sign_in_enabled only works with Devise")
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
@@ -48,15 +48,15 @@ module EffectiveLogging
|
|
48
48
|
user = (current_user rescue nil)
|
49
49
|
|
50
50
|
if self.class.log_page_views_opts[:details] == false
|
51
|
-
::EffectiveLogger.
|
51
|
+
::EffectiveLogger.view("#{request.request_method} #{request.path}", user: user)
|
52
52
|
else
|
53
|
-
::EffectiveLogger.
|
54
|
-
"
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
53
|
+
::EffectiveLogger.view(
|
54
|
+
"#{request.request_method} #{request.path}",
|
55
|
+
user: user,
|
56
|
+
params: request.filtered_parameters.reject { |k, v| (k == 'controller' || k == 'action') },
|
57
|
+
format: (request.format.to_s == 'text/html' ? nil : request.format.to_s),
|
58
|
+
referrer: request.referrer,
|
59
|
+
user_agent: request.user_agent
|
60
60
|
)
|
61
61
|
end
|
62
62
|
end
|
@@ -2,32 +2,34 @@ module EffectiveLogging
|
|
2
2
|
class UserLogger
|
3
3
|
def self.create_warden_hooks
|
4
4
|
Warden::Manager.after_authentication do |user, warden, opts|
|
5
|
-
if EffectiveLogging.
|
6
|
-
::EffectiveLogger.
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
5
|
+
if EffectiveLogging.sign_in_enabled && !EffectiveLogging.supressed?
|
6
|
+
::EffectiveLogger.sign_in('Sign in',
|
7
|
+
user: user,
|
8
|
+
associated: user,
|
9
|
+
ip: warden.request.ip.presence,
|
10
|
+
referrer: warden.request.referrer,
|
11
|
+
user_agent: warden.request.user_agent
|
11
12
|
)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
Warden::Manager.after_set_user do |user, warden, opts|
|
16
|
-
if EffectiveLogging.
|
17
|
+
if EffectiveLogging.sign_in_enabled && !EffectiveLogging.supressed?
|
17
18
|
if (opts[:event] == :set_user rescue false) # User has just reset their password and signed in
|
18
|
-
::EffectiveLogger.
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
19
|
+
::EffectiveLogger.sign_in('Sign in',
|
20
|
+
user: user,
|
21
|
+
associated: user,
|
22
|
+
ip: warden.request.ip.presence,
|
23
|
+
referrer: warden.request.referrer,
|
24
|
+
user_agent: warden.request.user_agent,
|
25
|
+
notes: 'after password reset'
|
24
26
|
)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
31
|
Warden::Manager.before_logout do |user, warden, opts|
|
30
|
-
if EffectiveLogging.
|
32
|
+
if EffectiveLogging.sign_out_enabled && !EffectiveLogging.supressed?
|
31
33
|
if user.respond_to?(:timedout?) && user.respond_to?(:timeout_in)
|
32
34
|
scope = opts[:scope]
|
33
35
|
last_request_at = (warden.request.session["warden.#{scope}.#{scope}.session"]['last_request_at'] rescue Time.zone.now)
|
@@ -40,12 +42,12 @@ module EffectiveLogging
|
|
40
42
|
end
|
41
43
|
|
42
44
|
if user.timedout?(last_request_at) && !warden.request.env['devise.skip_timeout']
|
43
|
-
::EffectiveLogger.
|
45
|
+
::EffectiveLogger.sign_out('Sign out', user: user, associated: user, timedout: true)
|
44
46
|
else
|
45
|
-
::EffectiveLogger.
|
47
|
+
::EffectiveLogger.sign_out('Sign out', user: user, associated: user)
|
46
48
|
end
|
47
49
|
else # User does not respond to timedout
|
48
|
-
::EffectiveLogger.
|
50
|
+
::EffectiveLogger.sign_out('Sign out', user: user, associated: user)
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
data/lib/effective_logging.rb
CHANGED
@@ -12,9 +12,9 @@ module EffectiveLogging
|
|
12
12
|
mattr_accessor :layout
|
13
13
|
mattr_accessor :additional_statuses
|
14
14
|
|
15
|
-
mattr_accessor :
|
16
|
-
mattr_accessor :
|
17
|
-
mattr_accessor :
|
15
|
+
mattr_accessor :email_enabled
|
16
|
+
mattr_accessor :sign_in_enabled
|
17
|
+
mattr_accessor :sign_out_enabled
|
18
18
|
|
19
19
|
def self.setup
|
20
20
|
yield self
|
@@ -36,11 +36,15 @@ module EffectiveLogging
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def self.statuses
|
39
|
-
@statuses ||= (
|
39
|
+
@statuses ||= (
|
40
|
+
Array(@@additional_statuses).map do |status|
|
41
|
+
status.to_s.downcase
|
42
|
+
end | ['info', 'success', 'error', log_changes_status, ('email' if email_enabled), ('sign_in' if sign_in_enabled), ('sign_out' if sign_out_enabled), 'view'].compact
|
43
|
+
)
|
40
44
|
end
|
41
45
|
|
42
46
|
def self.log_changes_status
|
43
|
-
'
|
47
|
+
'change'.freeze
|
44
48
|
end
|
45
49
|
|
46
50
|
# This is set by the "set_effective_logging_current_user" before_filter.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_logging
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|