class NewRelic::Agent::CustomEventAggregator

Constants

EVENT_TYPE_REGEX
MAX_ATTRIBUTE_COUNT
MAX_ATTRIBUTE_SIZE
MAX_NAME_SIZE
PRIORITY
TIMESTAMP
TYPE

Public Instance Methods

record(type, attributes) click to toggle source
# File lib/new_relic/agent/custom_event_aggregator.rb, line 25
def record(type, attributes)
  unless attributes.is_a?(Hash)
    raise ArgumentError, "Expected Hash but got #{attributes.class}"
  end

  return unless enabled?

  type = @type_strings[type]
  unless EVENT_TYPE_REGEX.match?(type)
    note_dropped_event(type)
    return false
  end

  priority = attributes[:priority] || rand

  stored = @lock.synchronize do
    @buffer.append(priority: priority) do
      create_event(type, priority, attributes)
    end
  end
  stored
end

Private Instance Methods

after_harvest(metadata) click to toggle source
# File lib/new_relic/agent/custom_event_aggregator.rb, line 86
def after_harvest(metadata)
  dropped_count = metadata[:seen] - metadata[:captured]
  note_dropped_events(metadata[:seen], dropped_count)
  record_supportability_metrics(metadata[:seen], metadata[:captured], dropped_count)
end
after_initialize() click to toggle source
# File lib/new_relic/agent/custom_event_aggregator.rb, line 82
def after_initialize
  @type_strings = Hash.new { |hash, key| hash[key] = key.to_s.freeze }
end
create_custom_event_attributes(type, attributes) click to toggle source
# File lib/new_relic/agent/custom_event_aggregator.rb, line 59
def create_custom_event_attributes(type, attributes)
  result = AttributeProcessing.flatten_and_coerce(attributes)

  if result.size > MAX_ATTRIBUTE_COUNT
    NewRelic::Agent.logger.warn("Custom event attributes are limited to #{MAX_ATTRIBUTE_COUNT}. Discarding #{result.size - MAX_ATTRIBUTE_COUNT} attributes")
    result = result.first(MAX_ATTRIBUTE_COUNT)
  end

  result.each_with_object({}) do |(key, val), new_result|
    # name is limited to 255
    if key.is_a?(String) && key.length > MAX_NAME_SIZE
      key = key[0, MAX_NAME_SIZE]
    end

    # value is limited to 4095 except for LLM content-related events
    if val.is_a?(String) && val.length > MAX_ATTRIBUTE_SIZE
      val = val[0, MAX_ATTRIBUTE_SIZE] unless NewRelic::Agent::LLM.exempt_event_attribute?(type, key)
    end

    new_result[key] = val
  end
end
create_event(type, priority, attributes) click to toggle source
# File lib/new_relic/agent/custom_event_aggregator.rb, line 50
def create_event(type, priority, attributes)
  [
    {TYPE => type,
     TIMESTAMP => Process.clock_gettime(Process::CLOCK_REALTIME).to_i,
     PRIORITY => priority},
    create_custom_event_attributes(type, attributes)
  ]
end
note_dropped_event(type) click to toggle source
# File lib/new_relic/agent/custom_event_aggregator.rb, line 105
def note_dropped_event(type)
  ::NewRelic::Agent.logger.log_once(:warn, "dropping_event_of_type:#{type}",
    "Invalid event type name '#{type}', not recording.")
  @buffer.note_dropped
end
note_dropped_events(total_count, dropped_count) click to toggle source
# File lib/new_relic/agent/custom_event_aggregator.rb, line 92
def note_dropped_events(total_count, dropped_count)
  if dropped_count > 0
    NewRelic::Agent.logger.warn("Dropped #{dropped_count} custom events out of #{total_count}.")
  end
end
record_supportability_metrics(total_count, captured_count, dropped_count) click to toggle source
# File lib/new_relic/agent/custom_event_aggregator.rb, line 98
def record_supportability_metrics(total_count, captured_count, dropped_count)
  engine = NewRelic::Agent.instance.stats_engine
  engine.tl_record_supportability_metric_count('Events/Customer/Seen', total_count)
  engine.tl_record_supportability_metric_count('Events/Customer/Sent', captured_count)
  engine.tl_record_supportability_metric_count('Events/Customer/Dropped', dropped_count)
end