Raju2024's picture
Upload 1072 files
e3278e4 verified
import type { ColumnDef } from "@tanstack/react-table";
import { getCountryFromIP } from "./ip_lookup";
import moment from "moment";
import React from "react";
import { CountryCell } from "./country_cell";
import { getProviderLogoAndName } from "../provider_info_helpers";
import { Tooltip } from "antd";
import { TimeCell } from "./time_cell";
export type LogEntry = {
request_id: string;
api_key: string;
team_id: string;
model: string;
api_base?: string;
call_type: string;
spend: number;
total_tokens: number;
prompt_tokens: number;
completion_tokens: number;
startTime: string;
endTime: string;
user?: string;
end_user?: string;
custom_llm_provider?: string;
metadata?: Record<string, any>;
cache_hit: string;
cache_key?: string;
request_tags?: Record<string, any>;
requester_ip_address?: string;
messages: string | any[] | Record<string, any>;
response: string | any[] | Record<string, any>;
};
export const columns: ColumnDef<LogEntry>[] = [
{
id: "expander",
header: () => null,
cell: ({ row }) => {
return row.getCanExpand() ? (
<button
{...{
onClick: row.getToggleExpandedHandler(),
style: { cursor: "pointer" },
}}
>
{row.getIsExpanded() ? "▼" : "▶"}
</button>
) : (
"●"
);
},
},
{
header: "Time",
accessorKey: "startTime",
cell: (info: any) => <TimeCell utcTime={info.getValue()} />,
},
{
header: "Request ID",
accessorKey: "request_id",
cell: (info: any) => (
<Tooltip title={String(info.getValue() || "")}>
<span className="font-mono text-xs max-w-[100px] truncate block">
{String(info.getValue() || "")}
</span>
</Tooltip>
),
},
{
header: "Country",
accessorKey: "requester_ip_address",
cell: (info: any) => <CountryCell ipAddress={info.getValue()} />,
},
{
header: "Team",
accessorKey: "metadata.user_api_key_team_alias",
cell: (info: any) => <span>{String(info.getValue() || "-")}</span>,
},
{
header: "Key Name",
accessorKey: "metadata.user_api_key_alias",
cell: (info: any) => <span>{String(info.getValue() || "-")}</span>,
},
{
header: "Request",
accessorKey: "messages",
cell: (info: any) => {
const messages = info.getValue();
try {
const content =
typeof messages === "string" ? JSON.parse(messages) : messages;
let displayText = "";
if (Array.isArray(content)) {
displayText = formatMessage(content[0]?.content);
} else {
displayText = formatMessage(content);
}
return <span className="truncate max-w-md text-sm">{displayText}</span>;
} catch (e) {
return (
<span className="truncate max-w-md text-sm">
{formatMessage(messages)}
</span>
);
}
},
},
{
header: "Model",
accessorKey: "model",
cell: (info: any) => {
const row = info.row.original;
const provider = row.custom_llm_provider;
const modelName = String(info.getValue() || "");
return (
<div className="flex items-center space-x-2">
{provider && (
<img
src={getProviderLogoAndName(provider).logo}
alt=""
className="w-4 h-4"
onError={(e) => {
const target = e.target as HTMLImageElement;
target.style.display = 'none';
}}
/>
)}
<Tooltip title={modelName}>
<span className="max-w-[100px] truncate">
{modelName}
</span>
</Tooltip>
</div>
);
},
},
{
header: "Tokens",
accessorKey: "total_tokens",
cell: (info: any) => {
const row = info.row.original;
return (
<span className="text-sm">
{String(row.total_tokens || "0")}
<span className="text-gray-400 text-xs ml-1">
({String(row.prompt_tokens || "0")}+
{String(row.completion_tokens || "0")})
</span>
</span>
);
},
},
{
header: "Internal User",
accessorKey: "user",
cell: (info: any) => <span>{String(info.getValue() || "-")}</span>,
},
{
header: "End User",
accessorKey: "end_user",
cell: (info: any) => <span>{String(info.getValue() || "-")}</span>,
},
{
header: "Cost",
accessorKey: "spend",
cell: (info: any) => (
<span>${Number(info.getValue() || 0).toFixed(6)}</span>
),
},
{
header: "Tags",
accessorKey: "request_tags",
cell: (info: any) => {
const tags = info.getValue();
if (!tags || Object.keys(tags).length === 0) return "-";
return (
<div className="flex flex-wrap gap-1">
{Object.entries(tags).map(([key, value]) => (
<span
key={key}
className="px-2 py-1 bg-gray-100 rounded-full text-xs"
>
{key}: {String(value)}
</span>
))}
</div>
);
},
},
];
const formatMessage = (message: any): string => {
if (!message) return "N/A";
if (typeof message === "string") return message;
if (typeof message === "object") {
// Handle the {text, type} object specifically
if (message.text) return message.text;
if (message.content) return message.content;
return JSON.stringify(message);
}
return String(message);
};