Module: OneApm::Collector::CollectorService::Helper

Included in:
OneApm::Collector::CollectorService
Defined in:
lib/one_apm/collector/collector/helper.rb

Instance Method Summary collapse

Instance Method Details

#build_metric_data_array(stats_hash) ⇒ Object

The collector wants to recieve metric data in a format that’s different from how we store it internally, so this method handles the translation. It also handles translating metric names to IDs using our metric ID cache.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/one_apm/collector/collector/helper.rb', line 91

def build_metric_data_array(stats_hash)
  metric_data_array = []

  # OneApm::Manager.logger.info "---metric_id_cache--#{metric_id_cache.inspect}"
  stats_hash.each do |metric_spec, stats|
    # Omit empty stats as an optimization
    unless stats.is_reset?
      metric_id = metric_id_cache[metric_spec]
      metric_data = if metric_id
        OneApm::MetricData.new(nil, stats, metric_id)
      else
        OneApm::MetricData.new(metric_spec, stats, nil)
      end
      
      metric_data_array << metric_data #unless metric_spec.name =~ /^Nested/
    end
  end
  # OneApm::Manager.logger.info "--metric_data_array---#{metric_data_array}"
  metric_data_array
end

#fill_metric_id_cache(pairs_of_specs_and_ids) ⇒ Object

Helpers ==========================

takes an array of arrays of spec and id, adds it into the metric cache so we can save the collector some work by sending integers instead of strings the next time around



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/one_apm/collector/collector/helper.rb', line 75

def fill_metric_id_cache(pairs_of_specs_and_ids)
  Array(pairs_of_specs_and_ids).each do |metric_spec_hash, metric_id|
    metric_spec = MetricSpec.new(metric_spec_hash['name'],
                                 metric_spec_hash['scope'])
    metric_id_cache[metric_spec] = metric_id
  end
rescue => e
  # If we've gotten this far, we don't want this error to propagate and
  # make this post appear to have been non-successful, which would trigger
  # re-aggregation of the same metric data into the next post, so just log
  OneApm::Manager.logger.error("Failed to fill metric ID cache from response, error details follow ", e)
end

#handle_serialization_error(method, e) ⇒ Object



6
7
8
9
10
11
12
13
# File 'lib/one_apm/collector/collector/helper.rb', line 6

def handle_serialization_error(method, e)
  OneApm::Manager.increment_metric("Supportability/serialization_failure")
  OneApm::Manager.increment_metric("Supportability/serialization_failure/#{method}")
  msg = "Failed to serialize #{method} data using #{@marshaller.class.to_s}: #{e.inspect}"
  error = SerializationError.new(msg)
  error.set_backtrace(e.backtrace)
  raise error
end

#log_and_return_response(response) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/one_apm/collector/collector/helper.rb', line 44

def log_and_return_response(response)
  OneApm::Manager.logger.debug "Received response, status: #{response.code}, encoding: '#{response['content-encoding']}'"

  case response
  when Net::HTTPSuccess
    true # do nothing
  when Net::HTTPUnauthorized
    raise LicenseException, 'Invalid license key, please visit support.oneapm.com'
  when Net::HTTPServiceUnavailable
    raise ServerConnectionException, "Service unavailable (#{response.code}): #{response.message}"
  when Net::HTTPGatewayTimeOut
    raise ServerConnectionException, "Gateway timeout (#{response.code}): #{response.message}"
  when Net::HTTPRequestEntityTooLarge
    raise UnrecoverableServerException, '413 Request Entity Too Large'
  when Net::HTTPUnsupportedMediaType
    raise UnrecoverableServerException, '415 Unsupported Media Type'
  else
    raise ServerConnectionException, "Unexpected response from server (#{response.code}): #{response.message}"
  end

  response
end

#record_size_supportability_metrics(method, size_bytes, item_count) ⇒ Object

For these metrics, we use the following fields: call_count => number of times this remote method was invoked total_call_time => total size in bytes of payloads across all invocations total_exclusive_time => total size in items (e.g. unique metrics, traces, events, etc) across all invocations

The last field doesn’t make sense for all methods (e.g. get_agent_commands), so we omit it for those methods that don’t really take collections of items as arguments.



34
35
36
37
38
39
40
41
42
# File 'lib/one_apm/collector/collector/helper.rb', line 34

def record_size_supportability_metrics(method, size_bytes, item_count)
  metrics = [
    "Supportability/invoke_remote_size",
    "Supportability/invoke_remote_size/#{method.to_s}"
  ]
  # we may not have an item count, in which case, just record 0 for the exclusive time
  item_count ||= 0
  OneApm::Manager.agent.stats_engine.tl_record_unscoped_metrics(metrics, size_bytes, item_count)
end

#record_timing_supportability_metrics(method, start_ts, serialize_finish_ts) ⇒ Object



15
16
17
18
19
20
21
22
23
24
# File 'lib/one_apm/collector/collector/helper.rb', line 15

def record_timing_supportability_metrics(method, start_ts, serialize_finish_ts)
  serialize_time = serialize_finish_ts && (serialize_finish_ts - start_ts)
  duration = (Time.now - start_ts).to_f
  OneApm::Manager.record_metric("Supportability/invoke_remote", duration)
  OneApm::Manager.record_metric("Supportability/invoke_remote/#{method.to_s}", duration)
  if serialize_time
    OneApm::Manager.record_metric("Supportability/invoke_remote_serialize", serialize_time)
    OneApm::Manager.record_metric("Supportability/invoke_remote_serialize/#{method.to_s}", serialize_time)
  end
end

#reset_metric_id_cacheObject



67
68
69
# File 'lib/one_apm/collector/collector/helper.rb', line 67

def reset_metric_id_cache
  @metric_id_cache = {}
end

#user_agentObject

Sets the user agent for connections to the server, to conform with the HTTP spec and allow for debugging. Includes the ruby version and also zlib version if available since that may cause corrupt compression if there is a problem.



124
125
126
127
128
129
130
131
# File 'lib/one_apm/collector/collector/helper.rb', line 124

def user_agent
  ruby_description = ''
  # note the trailing space!
  ruby_description << "(ruby #{::RUBY_VERSION} #{::RUBY_PLATFORM}) " if defined?(::RUBY_VERSION) && defined?(::RUBY_PLATFORM)
  zlib_version = ''
  zlib_version << "zlib/#{Zlib.zlib_version}" if defined?(::Zlib) && Zlib.respond_to?(:zlib_version)
  "OneApm-RubyAgent/#{OneApm::VERSION::STRING} #{ruby_description}#{zlib_version}"
end

#valid_to_marshal?(data) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
115
116
117
118
# File 'lib/one_apm/collector/collector/helper.rb', line 112

def valid_to_marshal?(data)
  @marshaller.dump(data)
  true
rescue StandardError, SystemStackError => e
  OneApm::Manager.logger.warn("Unable to marshal environment report on connect.", e)
  false
end