Class: Exa::Instrumentation::CostTracker
- Inherits:
-
BaseSubscriber
- Object
- BaseSubscriber
- Exa::Instrumentation::CostTracker
- Defined in:
- lib/exa/instrumentation/cost_tracker.rb
Overview
Built-in subscriber for tracking API costs from actual response data. Thread-safe and works with both sync and async requests.
Instance Attribute Summary collapse
-
#request_count ⇒ Integer
readonly
Number of requests tracked.
-
#requests ⇒ Array<Hash>
readonly
All tracked requests with their costs.
-
#total_cost ⇒ Float
readonly
Total accumulated cost in dollars.
Instance Method Summary collapse
-
#average_cost ⇒ Float
Returns the average cost per request.
-
#initialize ⇒ CostTracker
constructor
A new instance of CostTracker.
-
#report ⇒ String
Returns a formatted report of costs.
-
#reset! ⇒ Object
Reset all tracked data.
-
#subscribe ⇒ Object
Subscribe to request completion events.
-
#summary ⇒ Hash<Endpoint, Float>
Returns a summary of costs grouped by endpoint.
Methods inherited from BaseSubscriber
Constructor Details
#initialize ⇒ CostTracker
Returns a new instance of CostTracker.
29 30 31 32 33 34 35 |
# File 'lib/exa/instrumentation/cost_tracker.rb', line 29 def initialize @total_cost = 0.0 @request_count = 0 @requests = [] @mutex = Mutex.new super() end |
Instance Attribute Details
#request_count ⇒ Integer (readonly)
Returns Number of requests tracked.
24 25 26 |
# File 'lib/exa/instrumentation/cost_tracker.rb', line 24 def request_count @request_count end |
#requests ⇒ Array<Hash> (readonly)
Returns All tracked requests with their costs.
27 28 29 |
# File 'lib/exa/instrumentation/cost_tracker.rb', line 27 def requests @requests end |
#total_cost ⇒ Float (readonly)
Returns Total accumulated cost in dollars.
21 22 23 |
# File 'lib/exa/instrumentation/cost_tracker.rb', line 21 def total_cost @total_cost end |
Instance Method Details
#average_cost ⇒ Float
Returns the average cost per request.
68 69 70 71 72 73 |
# File 'lib/exa/instrumentation/cost_tracker.rb', line 68 def average_cost @mutex.synchronize do return 0.0 if @request_count.zero? @total_cost / @request_count end end |
#report ⇒ String
Returns a formatted report of costs.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/exa/instrumentation/cost_tracker.rb', line 86 def report @mutex.synchronize do lines = ["Exa API Cost Report"] lines << "-" * 40 lines << "Total Cost: $#{format('%.6f', @total_cost)}" lines << "Request Count: #{@request_count}" lines << "Average Cost: $#{format('%.6f', @request_count.zero? ? 0.0 : @total_cost / @request_count)}" lines << "" lines << "By Endpoint:" @requests .group_by { |req| req[:endpoint] } .transform_values { |reqs| reqs.sum { |r| r[:cost] } } .sort_by { |_endpoint, cost| -cost } .each do |endpoint, cost| lines << " #{endpoint.serialize}: $#{format('%.6f', cost)}" end lines.join("\n") end end |
#reset! ⇒ Object
Reset all tracked data.
76 77 78 79 80 81 82 |
# File 'lib/exa/instrumentation/cost_tracker.rb', line 76 def reset! @mutex.synchronize do @total_cost = 0.0 @request_count = 0 @requests.clear end end |
#subscribe ⇒ Object
Subscribe to request completion events. Call this after initialization to start tracking.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/exa/instrumentation/cost_tracker.rb', line 39 def subscribe add_subscription("exa.request.complete") do |_event_name, payload| next unless payload.cost_dollars @mutex.synchronize do @total_cost += payload.cost_dollars @request_count += 1 @requests << { endpoint: payload.endpoint, cost: payload.cost_dollars, request_id: payload.request_id, timestamp: payload. } end end end |
#summary ⇒ Hash<Endpoint, Float>
Returns a summary of costs grouped by endpoint.
58 59 60 61 62 63 64 |
# File 'lib/exa/instrumentation/cost_tracker.rb', line 58 def summary @mutex.synchronize do @requests .group_by { |req| req[:endpoint] } .transform_values { |reqs| reqs.sum { |r| r[:cost] } } end end |