Class: LlmCostTracker::Storage::ActiveRecordStore
- Inherits:
-
Object
- Object
- LlmCostTracker::Storage::ActiveRecordStore
- Defined in:
- lib/llm_cost_tracker/storage/active_record_store.rb
Class Method Summary collapse
- .attributes_for(event, model = LlmCostTracker::LlmApiCall) ⇒ Object
- .daily_total(time: Time.now.utc) ⇒ Object
- .insert_many(events) ⇒ Object
- .monthly_total(time: Time.now.utc) ⇒ Object
- .period_totals(periods, time: Time.now.utc) ⇒ Object
- .prune(cutoff:, batch_size:) ⇒ Object
- .reset! ⇒ Object
- .save(event) ⇒ Object
Class Method Details
.attributes_for(event, model = LlmCostTracker::LlmApiCall) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/llm_cost_tracker/storage/active_record_store.rb', line 41 def attributes_for(event, model = LlmCostTracker::LlmApiCall) = (event. || {}) columns = model.columns_hash attributes = { provider: event.provider, model: event.model, input_tokens: event.input_tokens, output_tokens: event.output_tokens, total_tokens: event.total_tokens, input_cost: event.cost&.input_cost, output_cost: event.cost&.output_cost, total_cost: event.cost&.total_cost, tags: (, model), tracked_at: event.tracked_at } attributes[:event_id] = event.event_id if columns.key?("event_id") optional_attributes(event).each do |name, value| attributes[name] = value if columns.key?(name.to_s) end attributes[:latency_ms] = event.latency_ms if columns.key?("latency_ms") attributes[:stream] = event.stream if columns.key?("stream") attributes[:usage_source] = event.usage_source if columns.key?("usage_source") attributes[:provider_response_id] = event.provider_response_id if columns.key?("provider_response_id") attributes end |
.daily_total(time: Time.now.utc) ⇒ Object
73 74 75 |
# File 'lib/llm_cost_tracker/storage/active_record_store.rb', line 73 def daily_total(time: Time.now.utc) period_totals(%i[daily], time: time).fetch(:daily) end |
.insert_many(events) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/llm_cost_tracker/storage/active_record_store.rb', line 26 def insert_many(events) events = Array(events) return [] if events.empty? model = LlmCostTracker::LlmApiCall insertable = new_events(model, events) if insertable.any? rows = insertable.map { |event| attributes_for(event, model) } model.insert_all!(rows, **) ActiveRecordRollups.increment_many!(insertable) end events end |
.monthly_total(time: Time.now.utc) ⇒ Object
69 70 71 |
# File 'lib/llm_cost_tracker/storage/active_record_store.rb', line 69 def monthly_total(time: Time.now.utc) period_totals(%i[monthly], time: time).fetch(:monthly) end |
.period_totals(periods, time: Time.now.utc) ⇒ Object
77 78 79 |
# File 'lib/llm_cost_tracker/storage/active_record_store.rb', line 77 def period_totals(periods, time: Time.now.utc) ActiveRecordPeriodTotals.call(periods, time: time) end |
.prune(cutoff:, batch_size:) ⇒ Object
81 82 83 84 85 86 87 88 89 |
# File 'lib/llm_cost_tracker/storage/active_record_store.rb', line 81 def prune(cutoff:, batch_size:) deleted = 0 loop do batch = prune_batch(cutoff, batch_size) deleted += batch break if batch < batch_size end deleted end |
.reset! ⇒ Object
11 12 13 |
# File 'lib/llm_cost_tracker/storage/active_record_store.rb', line 11 def reset! ActiveRecordRollups.reset! end |
.save(event) ⇒ Object
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/llm_cost_tracker/storage/active_record_store.rb', line 15 def save(event) model = LlmCostTracker::LlmApiCall attributes = attributes_for(event, model) model.transaction do call = model.create!(attributes) ActiveRecordRollups.increment!(event) call end end |