class SemanticLogger::Formatters::Signalfx
Attributes
counter_name[RW]
dimensions[RW]
gauge_name[RW]
hash[RW]
token[RW]
Public Class Methods
new(token:, dimensions: nil, gauge_name: "Application.average", counter_name: "Application.counter", time_format: :ms, **args)
click to toggle source
Calls superclass method
SemanticLogger::Formatters::Base::new
# File lib/semantic_logger/formatters/signalfx.rb, line 7 def initialize(token:, dimensions: nil, gauge_name: "Application.average", counter_name: "Application.counter", time_format: :ms, **args) @token = token @dimensions = dimensions.map(&:to_sym) if dimensions @gauge_name = gauge_name @counter_name = counter_name super(time_format: time_format, **args) end
Public Instance Methods
batch(logs, logger)
click to toggle source
Returns [Hash] a batch of log messages. Signalfx
has a minimum resolution of 1 second. Metrics of the same type, time (second), and dimensions can be aggregated together.
# File lib/semantic_logger/formatters/signalfx.rb, line 108 def batch(logs, logger) self.logger = logger data = {} logs.each do |log| self.hash = {} self.log = log metric; time; value; format_dimensions if log.duration gauges = (data[:gauge] ||= []) add_gauge(gauges, hash) # Also send a count metric whenever it is a gauge so that it can be counted. unless log.dimensions count_hash = hash.dup count_hash[:value] = log.metric_amount || 1 count_hash[:metric] = counter_name counters = (data[:counter] ||= []) add_counter(counters, count_hash) end else counters = (data[:counter] ||= []) add_counter(counters, hash) end end data.to_json end
call(log, logger)
click to toggle source
Returns [Hash] log message in Signalfx
format.
# File lib/semantic_logger/formatters/signalfx.rb, line 80 def call(log, logger) self.hash = {} self.log = log self.logger = logger metric; time; value; format_dimensions # gauge, counter, or cumulative_counter data = {} if log.duration data[:gauge] = [hash] # Also send a count metric whenever it is a gauge so that it can be counted. unless log.dimensions count_hash = hash.dup count_hash[:value] = log.metric_amount || 1 count_hash[:metric] = counter_name data[:counter] = [count_hash] end else data[:counter] = [hash] end data.to_json end
format_dimensions()
click to toggle source
Dimensions for this metric
# File lib/semantic_logger/formatters/signalfx.rb, line 58 def format_dimensions h = (hash[:dimensions] ||= {}) if log.dimensions log.dimensions.each_pair do |name, value| value = value.to_s h[name] = value unless value.empty? end else log.named_tags.each_pair do |name, value| name = name.to_sym value = value.to_s next if value.empty? h[name] = value if dimensions&.include?(name) end end h[:host] = logger.host if log_host && logger.host h[:application] = logger.application if log_application && logger.application h[:environment] = logger.environment if log_environment && logger.environment end
metric()
click to toggle source
Create SignalFx friendly metric.
Strip leading '/' Convert remaining '/' to '.'
# File lib/semantic_logger/formatters/signalfx.rb, line 25 def metric name = log.metric.to_s.sub(%r{\A/+}, "") if log.dimensions name.tr!("/", ".") hash[:metric] = name else # Extract class and action from metric name names = name.split("/") h = (hash[:dimensions] ||= {}) if names.size > 1 h[:action] = names.pop h[:class] = names.join("::") else h[:class] = "Unknown" h[:action] = names.first || log.metric end hash[:metric] = log.duration ? gauge_name : counter_name end end
time()
click to toggle source
Date & time
# File lib/semantic_logger/formatters/signalfx.rb, line 47 def time # 1 second resolution, represented as ms. hash[:timestamp] = log.time.to_i * 1000 end
value()
click to toggle source
Value of this metric
# File lib/semantic_logger/formatters/signalfx.rb, line 53 def value hash[:value] = log.metric_amount || log.duration || 1 end
Private Instance Methods
add_counter(counters, metric)
click to toggle source
Sum counters with the same time (second), name, and dimensions.
# File lib/semantic_logger/formatters/signalfx.rb, line 146 def add_counter(counters, metric) existing = find_match(counters, metric) existing ? existing[:value] += metric[:value] : counters << metric end
add_gauge(gauges, metric)
click to toggle source
# File lib/semantic_logger/formatters/signalfx.rb, line 141 def add_gauge(gauges, metric) gauges << metric end
find_match(list, metric)
click to toggle source
Find Metrics with the same timestamp, metric name, and dimensions.
# File lib/semantic_logger/formatters/signalfx.rb, line 152 def find_match(list, metric) list.find do |item| (item[:timestamp] == metric[:timestamp]) && (item[:metric] == metric[:metric]) && (item[:dimensions] == metric[:dimensions]) end end