Log writer which sends structured messages to an AMQP-based queue via the Alchemy Flux gem. A Hoodoo::Logger::FastWriter subclass, since though talking to the queue might be comparatively slow, Flux uses Event Machine for this so there's no need to add another Thread for this logger.

See also Hoodoo::Logger.

Methods
N
R
Class Public methods
new( alchemy, routing_key = nil )

Create an AMQP logger instance.

alchemy

The Alchemy endpoint to use for sending messages to the AMQP-based queue.

routing_key

The routing key (as a String) to use. Optional. If omitted, reads ENV['AMQ_LOGGING_ENDPOINT'] or if that is unset, defaults to platform.logging.

If you're running with Rack on top of Alchemy, then the call method's env parameter containing the Rack environment MUST have a key of alchemy.service with a value that's the AlchemyFlux::Service instance handling queue communication. This is assigned to the alchemy parameter. The logger will then use this active Alchemy service to send messages to its configured routing key.

If ENV['AMQ_ANALYTICS_LOGGING_ENDPOINT'] is defined then its value is used for a routing key in the case, very specifically, of a message logged with a code of analytics. If the variable is not set, the same routing key is used for all messages regardless of code; else that particular code can be streamed off to another Rabbit queue via the given alternative routing key.

# File lib/hoodoo/services/middleware/amqp_log_writer.rb, line 47
def initialize( alchemy, routing_key = nil )
  routing_key           = routing_key || ENV[ 'AMQ_LOGGING_ENDPOINT' ] || 'platform.logging'
  analytics_routing_key = ENV[ 'AMQ_ANALYTICS_LOGGING_ENDPOINT' ]

  @alchemy      = alchemy
  @routing_keys = Hash.new( routing_key ) # Use "routing_key" as a default value

  @routing_keys[ :analytics ] = analytics_routing_key || routing_key
end
Instance Public methods
report( level, component, code, data )

Custom implementation of the Hoodoo::Logger::WriterMixin#report interface. See that method for parameter details.

The middleware custom logger has expectations about the data payload. It expects these optional but recommended (where the information is available / has been generated) keys/values:

:id

A UUID (via Hoodoo::UUID.generate) to use for this log message - if absent, one is generated automatically.

:session

Description of the current request session when available; a Hoodoo::Services::Session as a Hash (via to_h; keys as Strings). The Caller UUID, identity Participant UUID and identity Outlet UUID are sent as independent, searchable fields in the log payload.

interaction_id

The interaction ID for this client's call. This is also sent as an independent, searchable field in the log payload.

# File lib/hoodoo/services/middleware/amqp_log_writer.rb, line 77
def report( level, component, code, data )
  return if @alchemy.nil?

  # Take care with Symbol keys in 'data' vs string keys in e.g. 'session'.

  session = data[ :session ] || {}
  message = {
    :id                   => data[ :id ],
    :level                => level,
    :component            => component,
    :code                 => code,
    :reported_at          => Time.now.iso8601( 12 ),

    :interaction_id       => data[ :interaction_id ],
    :data                 => data,

    :caller_id            => session[ 'caller_id'            ],
    :caller_identity_name => session[ 'caller_identity_name' ],
    :identity             => ( session[ 'identity' ] || {} ).to_h
  }.to_json()

  @alchemy.send_message_to_service(
    @routing_keys[ code.to_sym ],
    { "body" => message }
  )
end