There are two existing listeners for the `Audit::Logger`: `:moderator` and `:internal`. (Note: during tests we ignore the :moderator and :internal logs as defined in [config/initializers/audit_events.rb][1].) Using `rg "Audit::Logger\.log\(:internal," --files-with-matches`, the `:internal` listener is found in: - app/controllers/admin/secrets_controller.rb - app/controllers/admin/settings/base_controller.rb - app/controllers/admin/settings/general_settings_controller.rb Using `rg "Audit::Logger\.log\(:moderator," --files-with-matches`, the `:moderator` listener is used in: - app/controllers/rating_votes_controller.rb - app/controllers/comments_controller.rb - app/controllers/stories/pinned_articles_controller.rb - app/controllers/admin/response_templates_controller.rb - app/controllers/admin/tags_controller.rb - app/controllers/admin/articles_controller.rb - app/controllers/admin/users_controller.rb - app/controllers/admin/reactions_controller.rb - app/controllers/admin/tags/moderators_controller.rb - app/controllers/tag_adjustments_controller.rb - app/controllers/reactions_controller.rb The `admin/spaces#update` action is most similar to the `admin#settings` actions, which is why I chose `:internal`. I am looking for further guidance on documenting this little area of the application (in particular providing a data dictionary of :internal and :moderator). Closes forem/forem#16957 [1]:https://github.com/forem/forem/blob/main/config/initializers/audit_events.rb#L9-L11
49 lines
1.6 KiB
Ruby
49 lines
1.6 KiB
Ruby
module Audit
|
|
##
|
|
# Main class for wrapping ActiveSupport Instrumentation API.
|
|
#
|
|
# This class represent main entry point for receiving and notifying custom
|
|
# events, implemented according to
|
|
# https://guides.rubyonrails.org/active_support_instrumentation.html#creating-custom-events
|
|
class Notification
|
|
class << self
|
|
include Audit::Helper
|
|
|
|
##
|
|
# Audit::Notification.notify method, receives listener name, which is registered through
|
|
# Audit::Notification.listen and the event payload, passed as a block.
|
|
#
|
|
# Object of Audit::Event::Payload is send to the block as argument. This way,
|
|
# the payload object follows the rules defined in Audit::Event::Payload
|
|
#
|
|
# Example:
|
|
# Audit::Notification.notify('listener_name') do |payload|
|
|
# payload.user_id = current_user.id
|
|
# payload.roles = current_user.roles.pluck(:name)
|
|
# end
|
|
def notify(listener, &block)
|
|
return unless block
|
|
|
|
ActiveSupport::Notifications.instrument(instrument_name(listener), Audit::Event::Payload.new(&block))
|
|
end
|
|
|
|
##
|
|
# Audit::Notification.listen receives Events sent from ActiveSupport Instrumentation API.
|
|
# Then, this event is serialized and send to background job.
|
|
def listen(*args)
|
|
event = ActiveSupport::Notifications::Event.new(*args)
|
|
AuditLog.create!(params_hash(event))
|
|
end
|
|
|
|
def params_hash(event)
|
|
{
|
|
user_id: event.payload.user_id,
|
|
roles: event.payload.roles,
|
|
slug: event.payload.slug,
|
|
category: event.name,
|
|
data: event.payload.data
|
|
}
|
|
end
|
|
end
|
|
end
|
|
end
|