Files
laravel-llm-gateway/laravel-app/app/Services/StatisticsService.php
Wilfried Trinkl 602fe582b0 Refactor: Align system with gateway_users architecture
- Fixed database relationships: LlmRequest now properly uses gateway_user_id instead of user_id
- Updated Models: GatewayUser and LlmRequest relationships corrected
- Removed User->llmRequests relationship (admin users don't have LLM requests)
- Simplified Dashboard: Now shows Gateway User statistics instead of admin users
- Removed obsolete Budgets management pages (budgets handled directly in gateway_users)
- Removed User Budgets admin section (redundant with gateway_users management)
- Fixed view errors: Added null-checks for user_id in keys views
- Updated navigation: Removed Budget and User Budget links
- Updated routes: Cleaned up unused BudgetController and UserManagementController routes
- Simplified StatisticsService: Focus on gateway_users and basic metrics only
2025-11-19 21:13:59 +01:00

183 lines
6.2 KiB
PHP

<?php
namespace App\Services;
use App\Models\LlmRequest;
use App\Models\GatewayUser;
use App\Models\UserProviderCredential;
use Illuminate\Support\Facades\DB;
class StatisticsService
{
/**
* Get dashboard overview statistics
*/
public function getDashboardStats(): array
{
return [
'total_gateway_users' => GatewayUser::count(),
'active_gateway_users' => GatewayUser::where('blocked', false)->count(),
'blocked_gateway_users' => GatewayUser::where('blocked', true)->count(),
'total_requests_today' => LlmRequest::whereDate('created_at', today())->count(),
'total_spend_today' => LlmRequest::whereDate('created_at', today())->sum('total_cost') ?? 0,
'total_tokens_today' => LlmRequest::whereDate('created_at', today())->sum('total_tokens') ?? 0,
'total_spend_month' => LlmRequest::whereMonth('created_at', now()->month)
->whereYear('created_at', now()->year)
->sum('total_cost') ?? 0,
'total_requests_month' => LlmRequest::whereMonth('created_at', now()->month)
->whereYear('created_at', now()->year)
->count(),
'avg_cost_per_request' => LlmRequest::whereMonth('created_at', now()->month)
->whereYear('created_at', now()->year)
->avg('total_cost') ?? 0,
];
}
/**
* Get usage breakdown by provider
*/
public function getUsageByProvider(int $days = 30)
{
return LlmRequest::selectRaw('provider, COUNT(*) as count, SUM(total_cost) as total_cost, SUM(total_tokens) as total_tokens')
->where('created_at', '>=', now()->subDays($days))
->where('status', 'success')
->groupBy('provider')
->orderByDesc('count')
->get();
}
/**
* Get usage breakdown by model
*/
public function getUsageByModel(int $days = 30)
{
return LlmRequest::selectRaw('model, provider, COUNT(*) as count, SUM(total_tokens) as tokens, SUM(total_cost) as total_cost')
->where('created_at', '>=', now()->subDays($days))
->where('status', 'success')
->groupBy('model', 'provider')
->orderByDesc('count')
->limit(10)
->get();
}
/**
* Get daily usage chart data
*/
public function getDailyUsageChart(int $days = 30)
{
return LlmRequest::selectRaw('DATE(created_at) as date, COUNT(*) as requests, SUM(total_cost) as cost, SUM(total_tokens) as tokens')
->where('created_at', '>=', now()->subDays($days))
->where('status', 'success')
->groupBy('date')
->orderBy('date')
->get();
}
/**
* Get top gateway users by spend
*/
public function getTopUsers(int $limit = 10)
{
return GatewayUser::select('gateway_users.*')
->withCount('llmRequests')
->withSum('llmRequests as total_cost', 'total_cost')
->withSum('llmRequests as total_tokens', 'total_tokens')
->orderByDesc('total_cost')
->limit($limit)
->get();
}
/**
* Get recent activity
*/
public function getRecentActivity(int $limit = 20)
{
return LlmRequest::with('gatewayUser')
->orderByDesc('created_at')
->limit($limit)
->get();
}
/**
* Get gateway user statistics
*/
public function getGatewayUserStatistics(string $gatewayUserId, int $days = 30)
{
return LlmRequest::where('gateway_user_id', $gatewayUserId)
->where('created_at', '>=', now()->subDays($days))
->where('status', 'success')
->selectRaw('
COUNT(*) as total_requests,
SUM(prompt_tokens) as total_prompt_tokens,
SUM(completion_tokens) as total_completion_tokens,
SUM(total_tokens) as total_tokens,
SUM(total_cost) as total_cost,
AVG(total_tokens) as avg_tokens_per_request,
AVG(total_cost) as avg_cost_per_request,
AVG(response_time_ms) as avg_response_time_ms
')
->first();
}
/**
* Get provider usage over time
*/
public function getProviderUsageOverTime(int $days = 30)
{
return LlmRequest::selectRaw('DATE(created_at) as date, provider, COUNT(*) as count, SUM(total_cost) as cost')
->where('created_at', '>=', now()->subDays($days))
->where('status', 'success')
->groupBy('date', 'provider')
->orderBy('date')
->get()
->groupBy('provider');
}
/**
* Get cost trends
*/
public function getCostTrends(int $days = 30)
{
$data = LlmRequest::selectRaw('
DATE(created_at) as date,
SUM(total_cost) as daily_cost,
AVG(total_cost) as avg_request_cost,
COUNT(*) as request_count
')
->where('created_at', '>=', now()->subDays($days))
->where('status', 'success')
->groupBy('date')
->orderBy('date')
->get();
return [
'daily_data' => $data,
'total_cost' => $data->sum('daily_cost'),
'avg_daily_cost' => $data->avg('daily_cost'),
'total_requests' => $data->sum('request_count'),
];
}
/**
* Get error statistics
*/
public function getErrorStats(int $days = 30)
{
return [
'total_errors' => LlmRequest::where('created_at', '>=', now()->subDays($days))
->where('status', '!=', 'success')
->count(),
'errors_by_status' => LlmRequest::selectRaw('status, COUNT(*) as count')
->where('created_at', '>=', now()->subDays($days))
->where('status', '!=', 'success')
->groupBy('status')
->get(),
'errors_by_provider' => LlmRequest::selectRaw('provider, COUNT(*) as count')
->where('created_at', '>=', now()->subDays($days))
->where('status', '!=', 'success')
->groupBy('provider')
->get(),
];
}
}