Initial commit: Any-LLM Gateway with Laravel Admin Interface
- Any-LLM Gateway setup with Docker Compose - Laravel 11 admin interface with Livewire - Dashboard with usage statistics and charts - Gateway Users management with budget tracking - API Keys management with revocation - Budget templates with assignment - Usage Logs with filtering and CSV export - Model Pricing management with calculator - PostgreSQL database integration - Complete authentication system for admins
This commit is contained in:
187
laravel-app/app/Http/Controllers/UsageLogController.php
Normal file
187
laravel-app/app/Http/Controllers/UsageLogController.php
Normal file
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\UsageLog;
|
||||
use App\Models\GatewayUser;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class UsageLogController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of usage logs with filters
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = UsageLog::with(['gatewayUser', 'apiKey']);
|
||||
|
||||
// Date Range Filter
|
||||
if ($request->filled('date_from')) {
|
||||
$query->where('timestamp', '>=', $request->date_from . ' 00:00:00');
|
||||
}
|
||||
|
||||
if ($request->filled('date_to')) {
|
||||
$query->where('timestamp', '<=', $request->date_to . ' 23:59:59');
|
||||
}
|
||||
|
||||
// User Filter
|
||||
if ($request->filled('user_id')) {
|
||||
$query->where('user_id', $request->user_id);
|
||||
}
|
||||
|
||||
// Provider Filter
|
||||
if ($request->filled('provider')) {
|
||||
$query->where('provider', $request->provider);
|
||||
}
|
||||
|
||||
// Model Filter
|
||||
if ($request->filled('model')) {
|
||||
$query->where('model', $request->model);
|
||||
}
|
||||
|
||||
// Status Filter
|
||||
if ($request->filled('status')) {
|
||||
if ($request->status === 'success') {
|
||||
$query->success();
|
||||
} elseif ($request->status === 'failed') {
|
||||
$query->failed();
|
||||
}
|
||||
}
|
||||
|
||||
// Get filter options for dropdowns
|
||||
$users = GatewayUser::select('user_id', 'alias')
|
||||
->orderBy('alias')
|
||||
->get();
|
||||
|
||||
$providers = UsageLog::select('provider')
|
||||
->distinct()
|
||||
->whereNotNull('provider')
|
||||
->orderBy('provider')
|
||||
->pluck('provider');
|
||||
|
||||
$models = UsageLog::select('model')
|
||||
->distinct()
|
||||
->whereNotNull('model')
|
||||
->orderBy('model')
|
||||
->pluck('model');
|
||||
|
||||
// Get summary statistics for current filter
|
||||
$summary = $query->clone()
|
||||
->selectRaw('
|
||||
COUNT(*) as total_requests,
|
||||
SUM(CASE WHEN status = \'success\' THEN 1 ELSE 0 END) as successful_requests,
|
||||
SUM(prompt_tokens) as total_prompt_tokens,
|
||||
SUM(completion_tokens) as total_completion_tokens,
|
||||
SUM(total_tokens) as total_tokens,
|
||||
SUM(cost) as total_cost
|
||||
')
|
||||
->first();
|
||||
|
||||
// Paginate results
|
||||
$logs = $query->orderByDesc('timestamp')
|
||||
->paginate(50)
|
||||
->withQueryString(); // Preserve query parameters
|
||||
|
||||
return view('usage-logs.index', compact(
|
||||
'logs',
|
||||
'users',
|
||||
'providers',
|
||||
'models',
|
||||
'summary'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Export usage logs to CSV
|
||||
*/
|
||||
public function export(Request $request)
|
||||
{
|
||||
$query = UsageLog::with(['gatewayUser', 'apiKey']);
|
||||
|
||||
// Apply same filters as index
|
||||
if ($request->filled('date_from')) {
|
||||
$query->where('timestamp', '>=', $request->date_from . ' 00:00:00');
|
||||
}
|
||||
|
||||
if ($request->filled('date_to')) {
|
||||
$query->where('timestamp', '<=', $request->date_to . ' 23:59:59');
|
||||
}
|
||||
|
||||
if ($request->filled('user_id')) {
|
||||
$query->where('user_id', $request->user_id);
|
||||
}
|
||||
|
||||
if ($request->filled('provider')) {
|
||||
$query->where('provider', $request->provider);
|
||||
}
|
||||
|
||||
if ($request->filled('model')) {
|
||||
$query->where('model', $request->model);
|
||||
}
|
||||
|
||||
if ($request->filled('status')) {
|
||||
if ($request->status === 'success') {
|
||||
$query->success();
|
||||
} elseif ($request->status === 'failed') {
|
||||
$query->failed();
|
||||
}
|
||||
}
|
||||
|
||||
// Limit export to 10,000 records for performance
|
||||
$logs = $query->orderByDesc('timestamp')
|
||||
->limit(10000)
|
||||
->get();
|
||||
|
||||
$filename = 'usage-logs-' . now()->format('Y-m-d-His') . '.csv';
|
||||
|
||||
$headers = [
|
||||
'Content-Type' => 'text/csv',
|
||||
'Content-Disposition' => "attachment; filename=\"{$filename}\"",
|
||||
];
|
||||
|
||||
$callback = function() use ($logs) {
|
||||
$file = fopen('php://output', 'w');
|
||||
|
||||
// CSV Header
|
||||
fputcsv($file, [
|
||||
'Timestamp',
|
||||
'User ID',
|
||||
'User Alias',
|
||||
'API Key',
|
||||
'Provider',
|
||||
'Model',
|
||||
'Endpoint',
|
||||
'Prompt Tokens',
|
||||
'Completion Tokens',
|
||||
'Total Tokens',
|
||||
'Cost',
|
||||
'Status',
|
||||
'Error Message'
|
||||
]);
|
||||
|
||||
// CSV Rows
|
||||
foreach ($logs as $log) {
|
||||
fputcsv($file, [
|
||||
$log->timestamp->format('Y-m-d H:i:s'),
|
||||
$log->user_id,
|
||||
$log->gatewayUser?->alias ?? 'N/A',
|
||||
$log->api_key_id,
|
||||
$log->provider,
|
||||
$log->model,
|
||||
$log->endpoint,
|
||||
$log->prompt_tokens,
|
||||
$log->completion_tokens,
|
||||
$log->total_tokens,
|
||||
$log->cost,
|
||||
$log->status,
|
||||
$log->error_message ?? ''
|
||||
]);
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
};
|
||||
|
||||
return response()->stream($callback, 200, $headers);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user