Skip to content

Commit

Permalink
wip: Provide YARD documentation for gem
Browse files Browse the repository at this point in the history
  • Loading branch information
dickdavis committed Aug 10, 2024
1 parent f39817c commit 36ac021
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 3 deletions.
36 changes: 34 additions & 2 deletions lib/event_logger_rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,58 @@
require 'event_logger_rails/output'
require 'event_logger_rails/version'

##
# Namespace for EventLoggerRails gem
# Provides configurable state and public API for EventLoggerRails.
# Also serves as the namespace for the gem.
module EventLoggerRails
# @!attribute [r] default_level
# @return [Symbol] The default level of the events logged by EventLoggerRails.
mattr_accessor :default_level

# @!attribute [r] logdev
# @return [IO, #write] The log device used by EventLoggerRails.
mattr_accessor :logdev

# @!attribute [r] registered_events
# @return [Array<Hash>] The events registry defined in the config/event_logger_rails.yml file.
mattr_accessor :registered_events

# @!attribute [r] sensitive_fields
# @return [Array<Symbol>] The fields which may contain sensitive data that EventLoggerRails should filter.
mattr_accessor :sensitive_fields

# Provides a method for configuring EventLoggerRails.
#
# @yield [self] Gives the class itself to the block for configuration.
# @example
# EventLoggerRails.setup do |config|
# config.default_level = :info
# end
# @return [void]
def self.setup
yield self
end

# Returns or initializes the Emitter instance for EventLoggerRails.
#
# @note The emitter is initialized with the configured log device.
# @return [Emitter] The Emitter instance used for logging events.
def self.emitter
@emitter ||= Emitter.new(logdev:)
end

# Forwards the arguments to the Emitter's log method.
#
# @example
# EventLoggerRails.log('foo.bar.baz', level: :info, data: { foo: 'bar' })
# @param (see Emitter#log)
# @return [void]
def self.log(...)
emitter.log(...)
end

# Resets the Emitter instance.
#
# @return [void]
def self.reset
@emitter = nil
end
Expand Down
13 changes: 13 additions & 0 deletions lib/event_logger_rails/current_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ module EventLoggerRails
##
# Provides global state with request details
class CurrentRequest < ActiveSupport::CurrentAttributes
# @note Defines the attributes for the current request object.
# @!attribute [rw] id
# @return [String] The ID of the request.
# @!attribute [rw] format
# @return [Symbol] The format of the request.
# @!attribute [rw] method
# @return [String] The HTTP method of the request.
# @!attribute [rw] parameters
# @return [Hash] The parameters of the request.
# @!attribute [rw] path
# @return [String] The path of the request.
# @!attribute [rw] remote_ip
# @return [String] The remote IP of the request.
attribute :id, :format, :method, :parameters, :path, :remote_ip
end
end
18 changes: 18 additions & 0 deletions lib/event_logger_rails/emitter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@ module EventLoggerRails
##
# Processes events, sending data to logger.
class Emitter
## Initializes the emitter using the given log device for log output.
#
# @param logdev [IO, #write] The log device for log output.
def initialize(logdev:)
@logger = JsonLogger.new(logdev)
end

# Validates and logs an event with the given level and data.
# If an error is raised, it recursively calls itself with the error's event.
#
# @param event [EventLoggerRails::Event, String] The event to log. Can be a string or an Event object.
# @param level [Symbol] The level of the event.
# @param data [Hash] Additional data to log.
# @return [Integer] The number of bytes written to the log.
def log(event, level:, data: {})
Event.new(event).validate! do |validated_event|
message = Message.new(event: validated_event, data:)
Expand All @@ -20,8 +30,16 @@ def log(event, level:, data: {})

private

# @!attribute [r] logger
# @return [JsonLogger] The logger instance used for log output.
attr_reader :logger

# Logs a message with the given level.
#
# @param message [String] The message to log.
# @param level [Symbol] The level of the message.
# @return [Integer] The number of bytes written to the log.
# @raise [EventLoggerRails::Exceptions::InvalidLoggerLevel] If the level is invalid.
def log_message(message, level)
logger.send(level) { message }
rescue NoMethodError
Expand Down
79 changes: 78 additions & 1 deletion lib/event_logger_rails/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module EventLoggerRails
##
# Models an event for logging.
class Event
# Contains the default event registration.
DEFAULT_EVENTS = {
'event_logger_rails.logger_level.invalid' => {
description: 'Indicates provided level was invalid.',
Expand All @@ -20,51 +21,127 @@ class Event
}.freeze
private_constant :DEFAULT_EVENTS

attr_reader :identifier, :description, :level
# @!attribute [r] identifier
# @return [String] The identifier of the event.
attr_reader :identifier

# @!attribute [r] description
# @return [String] The description of the event.
attr_reader :description

# @!attribute [r] level
# @return [Symbol] The configured logging level of the event.
attr_reader :level

# Initializes the event using the provided identifier to determine its properties from
# either the default registration (for default events) or the user-defined registry.
#
# @param provided_identifier [EventLoggerRails::Event, String] The event or its identifier.
def initialize(provided_identifier)
@provided_identifier = provided_identifier.to_s

# Attempt to find default registration for event
if (default_event = DEFAULT_EVENTS[@provided_identifier])
default_registration = [@provided_identifier, *default_event&.values]
end

# Fallback to user-defined registration if default not found.
# Deconstruct registration to set identifier, description, and level attributes.
@identifier, @description, @level = default_registration || config_registration
end

# Converts the event into a hash and merges the given hash into it.
#
# @param kwargs [Hash] The hash to merge into the event.
# @return [Hash] The merged hash.
# @example
# event = EventLoggerRails::Event.new('event_logger_rails.event.testing')
# event.merge(foo: 'bar')
# # {
# # event_identifier: 'event_logger_rails.event.testing',
# # event_description: 'Event reserved for testing',
# # foo: 'bar'
# # }
def merge(...)
to_hash.merge(...)
end

# Determines if the event is valid.
#
# @return [Boolean] true if the event is valid, false otherwise.
# @example
# valid_event = EventLoggerRails::Event.new('event_logger_rails.event.testing')
# valid_event.valid? # => true
# invalid_event = EventLoggerRails::Event.new('foo.bar.baz')
# invalid_event.valid? # => false
def valid?
identifier.present?
end

# Validates the event and yields it to the given block.
#
# @yield [self] Yields the event to the given block.
# @raise [EventLoggerRails::Exceptions::UnregisteredEvent] If the event is not registered.
# @example
# event = EventLoggerRails::Event.new('event_logger_rails.event.testing')
# event.validate! do |validated_event|
# puts "Event: #{validated_event}"
# end
def validate!
raise Exceptions::UnregisteredEvent.new(unregistered_event: self) unless valid?

yield(self)
end

# Returns a hash representation of the event.
#
# @return [Hash] The event as a hash.
# @example
# event = EventLoggerRails::Event.new('event_logger_rails.event.testing')
# event.to_hash
# # {
# # event_identifier: 'event_logger_rails.event.testing',
# # event_description: 'Event reserved for testing'
# # }
def to_hash
{
event_identifier: identifier,
event_description: description
}
end

# Returns a string representation of the event.
# The provided identifier is returned if the event is not registered.
#
# @return [String] The event as a string.
# @example
# event = EventLoggerRails::Event.new('event_logger_rails.event.testing')
# event.to_s # => 'event_logger_rails.event.testing'
def to_s
identifier&.to_s || provided_identifier.to_s
end

# Determines if the event is equivalent to the given object through string comparison.
#
# @param other [EventLoggerRails::Event] The event to compare.
# @return [Boolean] true if the event is equal to the given object, false otherwise.
# @example
# event = EventLoggerRails::Event.new('event_logger_rails.event.testing')
# event == 'event_logger_rails.event.testing' # => true
def ==(other)
to_s == other.to_s
end

private

# @!attribute [r] provided_identifier
# @return [String] The identifier provided when the event was initialized.
attr_reader :provided_identifier

# Parses the event identifier and looks up the details from the user-defined registry.
#
# @return [Array<String, String, Symbol>] The identifier, description, and level of the event.
# If the event is not registered, each array element will be nil.
def config_registration
parsed_event = provided_identifier.split('.').map(&:to_sym)
config = EventLoggerRails.registered_events.dig(*parsed_event)
Expand Down

0 comments on commit 36ac021

Please sign in to comment.