Class: Sixty::Exporter
- Inherits:
-
Object
- Object
- Sixty::Exporter
- Defined in:
- lib/sixty/exporter.rb
Overview
Transport. Ships aggregate windows and exemplar traces to the collector.
Rules this obeys, because an observability agent that harms the host is worse than no agent at all:
- never block the request path (the flush runs on the agent's own thread)
- never grow without bound (the exemplar queue is capped and drops oldest)
- never keep the process alive (the thread is not joined at exit; the
final flush is bounded by its own timeout)
- never raise into user code (every failure is swallowed and counted)
Constant Summary collapse
- MAX_QUEUED_EXEMPLARS =
200- TIMEOUT_SECONDS =
10
Instance Attribute Summary collapse
-
#failures ⇒ Object
readonly
Returns the value of attribute failures.
Instance Method Summary collapse
- #flush(metrics, sections: {}, timeout: TIMEOUT_SECONDS) ⇒ Object
-
#initialize(endpoint:, api_key:, service:, environment:, release:, repo_url: '', path: '/v1/ingest', on_warn: ->(_msg) {}) ⇒ Exporter
constructor
A new instance of Exporter.
- #queue_exemplar(trace) ⇒ Object
Constructor Details
#initialize(endpoint:, api_key:, service:, environment:, release:, repo_url: '', path: '/v1/ingest', on_warn: ->(_msg) {}) ⇒ Exporter
Returns a new instance of Exporter.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/sixty/exporter.rb', line 23 def initialize(endpoint:, api_key:, service:, environment:, release:, repo_url: '', path: '/v1/ingest', on_warn: ->(_msg) {}) @endpoint = endpoint.to_s.sub(%r{/\z}, '') # The collector's receive path, appended to the endpoint — and overridable # because not every endpoint is the collector. A service reporting through # a proxy mounted on its own origin is given the exact URL that proxy # lives at, and appending anything to it produces a route the application # never registered. That failure is unusually quiet: the request 404s, the # agent swallows it like any other transport error, and the only symptom # is an absence of data. @path = path @api_key = api_key @resource = { service: service, environment: environment, release: release, repoUrl: repo_url.to_s } @on_warn = on_warn @exemplars = [] @mutex = Mutex.new @failures = 0 @warned_at = 0.0 @last_attempt = nil end |
Instance Attribute Details
#failures ⇒ Object (readonly)
Returns the value of attribute failures.
21 22 23 |
# File 'lib/sixty/exporter.rb', line 21 def failures @failures end |
Instance Method Details
#flush(metrics, sections: {}, timeout: TIMEOUT_SECONDS) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/sixty/exporter.rb', line 62 def flush(metrics, sections: {}, timeout: TIMEOUT_SECONDS) exemplars = @mutex.synchronize do taken = @exemplars @exemplars = [] taken end has_sections = sections.any? { |_k, v| !v.nil? } return if metrics.nil? && exemplars.empty? && !has_sections # A collector that is down stops being contacted for a while, rather than # being dialled on every interval for as long as the outage lasts. The # window that would have been sent is dropped here, deliberately: an agent # that retained data through an outage would be an agent whose memory # footprint is decided by somebody else's uptime. return if backing_off? body = JSON.generate( { resource: @resource, metrics: metrics, exemplars: exemplars, sentAt: (Time.now.to_f * 1000).round }.merge(sections.reject { |_k, v| v.nil? }) ) post(body, timeout) end |
#queue_exemplar(trace) ⇒ Object
49 50 51 52 53 54 |
# File 'lib/sixty/exporter.rb', line 49 def queue_exemplar(trace) @mutex.synchronize do @exemplars.shift if @exemplars.length >= MAX_QUEUED_EXEMPLARS @exemplars << trace end end |