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); } }