Module: RubyLLM::Agents::Tenant::Trackable

Extended by:
ActiveSupport::Concern
Included in:
RubyLLM::Agents::Tenant
Defined in:
app/models/ruby_llm/agents/tenant/trackable.rb

Overview

Tracks LLM usage for a tenant including costs, tokens, and execution counts.

Provides methods for querying usage data with various time periods:

  • :today, :yesterday, :this_week, :last_week

  • :this_month, :last_month

  • Custom date ranges

Examples:

Querying costs

tenant.cost                    # Total cost all time
tenant.cost_today              # Today's cost
tenant.cost_this_month         # This month's cost
tenant.cost(period: 1.week.ago..Time.current)

Usage summary

tenant.usage_summary
# => { tenant_id: "acme", cost: 123.45, tokens: 50000, executions: 100 }

Usage breakdown

tenant.usage_by_agent
# => { "ChatAgent" => { cost: 50.0, tokens: 20000, count: 40 } }

See Also:

Instance Method Summary collapse

Instance Method Details

#cost(period: nil) ⇒ Float

Returns total cost for the given period

Parameters:

  • period (Symbol, Range, nil) (defaults to: nil)

    Time period (:today, :this_month, etc.) or date range

Returns:

  • (Float)

    Total cost in USD



47
48
49
50
51
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 47

def cost(period: nil)
  scope = executions
  scope = apply_period_scope(scope, period) if period
  scope.sum(:total_cost) || 0
end

#cost_last_monthFloat

Returns last month’s cost

Returns:

  • (Float)


93
94
95
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 93

def cost_last_month
  cost(period: :last_month)
end

#cost_last_weekFloat

Returns last week’s cost

Returns:

  • (Float)


78
79
80
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 78

def cost_last_week
  cost(period: :last_week)
end

#cost_this_monthFloat

Returns this month’s cost from counter columns

Returns:

  • (Float)


85
86
87
88
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 85

def cost_this_month
  ensure_monthly_reset!
  monthly_cost_spent
end

#cost_this_weekFloat

Returns this week’s cost

Returns:

  • (Float)


71
72
73
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 71

def cost_this_week
  cost(period: :this_week)
end

#cost_todayFloat

Returns today’s cost from counter columns

Returns:

  • (Float)


56
57
58
59
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 56

def cost_today
  ensure_daily_reset!
  daily_cost_spent
end

#cost_yesterdayFloat

Returns yesterday’s cost

Returns:

  • (Float)


64
65
66
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 64

def cost_yesterday
  cost(period: :yesterday)
end

#errors_this_monthInteger

Returns this month’s error count from counter columns

Returns:

  • (Integer)


208
209
210
211
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 208

def errors_this_month
  ensure_monthly_reset!
  monthly_error_count
end

#errors_todayInteger

Returns today’s error count from counter columns

Returns:

  • (Integer)


200
201
202
203
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 200

def errors_today
  ensure_daily_reset!
  daily_error_count
end

#execution_count(period: nil) ⇒ Integer

Returns execution count for the given period

Parameters:

  • period (Symbol, Range, nil) (defaults to: nil)

    Time period or date range

Returns:

  • (Integer)

    Execution count



152
153
154
155
156
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 152

def execution_count(period: nil)
  scope = executions
  scope = apply_period_scope(scope, period) if period
  scope.count
end

#executions_last_monthInteger

Returns last month’s execution count

Returns:

  • (Integer)


191
192
193
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 191

def executions_last_month
  execution_count(period: :last_month)
end

#executions_this_monthInteger

Returns this month’s execution count from counter columns

Returns:

  • (Integer)


183
184
185
186
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 183

def executions_this_month
  ensure_monthly_reset!
  monthly_executions_count
end

#executions_this_weekInteger

Returns this week’s execution count

Returns:

  • (Integer)


176
177
178
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 176

def executions_this_week
  execution_count(period: :this_week)
end

#executions_todayInteger

Returns today’s execution count from counter columns

Returns:

  • (Integer)


161
162
163
164
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 161

def executions_today
  ensure_daily_reset!
  daily_executions_count
end

#executions_yesterdayInteger

Returns yesterday’s execution count

Returns:

  • (Integer)


169
170
171
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 169

def executions_yesterday
  execution_count(period: :yesterday)
end

#failed_executions(period: nil, limit: nil) ⇒ ActiveRecord::Relation

Returns failed executions for this tenant

Parameters:

  • period (Symbol, Range, nil) (defaults to: nil)

    Time period

  • limit (Integer, nil) (defaults to: nil)

    Optional limit

Returns:

  • (ActiveRecord::Relation)


307
308
309
310
311
312
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 307

def failed_executions(period: nil, limit: nil)
  scope = executions.where(status: "error")
  scope = apply_period_scope(scope, period) if period
  scope = scope.limit(limit) if limit
  scope.order(created_at: :desc)
end

#recent_executions(limit: 10) ⇒ Array<Execution>

Returns the most recent executions for this tenant

Parameters:

  • limit (Integer) (defaults to: 10)

    Number of executions to return (default: 10)

Returns:



298
299
300
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 298

def recent_executions(limit: 10)
  executions.order(created_at: :desc).limit(limit)
end

#success_rate_todayFloat

Returns today’s success rate from counter columns

Returns:

  • (Float)

    Percentage (0.0-100.0)



216
217
218
219
220
221
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 216

def success_rate_today
  ensure_daily_reset!
  return 100.0 if daily_executions_count.zero?

  ((daily_executions_count - daily_error_count).to_f / daily_executions_count * 100).round(1)
end

#tokens(period: nil) ⇒ Integer

Returns total tokens for the given period

Parameters:

  • period (Symbol, Range, nil) (defaults to: nil)

    Time period or date range

Returns:

  • (Integer)

    Total tokens



103
104
105
106
107
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 103

def tokens(period: nil)
  scope = executions
  scope = apply_period_scope(scope, period) if period
  scope.sum(:total_tokens) || 0
end

#tokens_last_monthInteger

Returns last month’s token usage

Returns:

  • (Integer)


142
143
144
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 142

def tokens_last_month
  tokens(period: :last_month)
end

#tokens_this_monthInteger

Returns this month’s token usage from counter columns

Returns:

  • (Integer)


134
135
136
137
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 134

def tokens_this_month
  ensure_monthly_reset!
  monthly_tokens_used
end

#tokens_this_weekInteger

Returns this week’s token usage

Returns:

  • (Integer)


127
128
129
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 127

def tokens_this_week
  tokens(period: :this_week)
end

#tokens_todayInteger

Returns today’s token usage from counter columns

Returns:

  • (Integer)


112
113
114
115
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 112

def tokens_today
  ensure_daily_reset!
  daily_tokens_used
end

#tokens_yesterdayInteger

Returns yesterday’s token usage

Returns:

  • (Integer)


120
121
122
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 120

def tokens_yesterday
  tokens(period: :yesterday)
end

#usage_by_agent(period: :this_month) ⇒ Hash

Returns usage broken down by agent type

Parameters:

  • period (Symbol, Range) (defaults to: :this_month)

    Time period (default: :this_month)

Returns:

  • (Hash)

    Usage by agent { “AgentName” => { cost:, tokens:, count: } }



244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 244

def usage_by_agent(period: :this_month)
  scope = executions
  scope = apply_period_scope(scope, period) if period

  scope.group(:agent_type).pluck(
    :agent_type,
    Arel.sql("SUM(total_cost)"),
    Arel.sql("SUM(total_tokens)"),
    Arel.sql("COUNT(*)")
  ).to_h do |agent_type, total_cost, total_tokens, count|
    [agent_type, {cost: total_cost || 0, tokens: total_tokens || 0, count: count}]
  end
end

#usage_by_day(period: :this_month) ⇒ Hash

Returns usage broken down by day for a given period

Parameters:

  • period (Symbol, Range) (defaults to: :this_month)

    Time period (default: :this_month)

Returns:

  • (Hash)

    Daily usage { Date => { cost:, tokens:, count: } }



280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 280

def usage_by_day(period: :this_month)
  scope = executions
  scope = apply_period_scope(scope, period) if period

  scope.group("DATE(created_at)").pluck(
    Arel.sql("DATE(created_at)"),
    Arel.sql("SUM(total_cost)"),
    Arel.sql("SUM(total_tokens)"),
    Arel.sql("COUNT(*)")
  ).to_h do |date, total_cost, total_tokens, count|
    [date.to_date, {cost: total_cost || 0, tokens: total_tokens || 0, count: count}]
  end
end

#usage_by_model(period: :this_month) ⇒ Hash

Returns usage broken down by model

Parameters:

  • period (Symbol, Range) (defaults to: :this_month)

    Time period (default: :this_month)

Returns:

  • (Hash)

    Usage by model { “model-id” => { cost:, tokens:, count: } }



262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 262

def usage_by_model(period: :this_month)
  scope = executions
  scope = apply_period_scope(scope, period) if period

  scope.group(:model_id).pluck(
    :model_id,
    Arel.sql("SUM(total_cost)"),
    Arel.sql("SUM(total_tokens)"),
    Arel.sql("COUNT(*)")
  ).to_h do |model_id, total_cost, total_tokens, count|
    [model_id, {cost: total_cost || 0, tokens: total_tokens || 0, count: count}]
  end
end

#usage_summary(period: :this_month) ⇒ Hash

Returns a complete usage summary for the tenant

Parameters:

  • period (Symbol, Range) (defaults to: :this_month)

    Time period (default: :this_month)

Returns:

  • (Hash)

    Usage summary



229
230
231
232
233
234
235
236
237
238
# File 'app/models/ruby_llm/agents/tenant/trackable.rb', line 229

def usage_summary(period: :this_month)
  {
    tenant_id: tenant_id,
    name: display_name,
    period: period,
    cost: cost(period: period),
    tokens: tokens(period: period),
    executions: execution_count(period: period)
  }
end