diff --git a/backend/open_webui/routers/analytics.py b/backend/open_webui/routers/analytics.py index b6ee4b9f65..5cef680c7a 100644 --- a/backend/open_webui/routers/analytics.py +++ b/backend/open_webui/routers/analytics.py @@ -88,6 +88,7 @@ async def get_user_analytics( end_date: Optional[int] = Query(None, description='End timestamp (epoch)'), group_id: Optional[str] = Query(None, description='Filter by user group ID'), limit: int = Query(50, description='Max users to return'), + metric: Literal['messages', 'tokens'] = Query('messages'), user=Depends(get_admin_user), db: AsyncSession = Depends(get_async_session), ): @@ -99,8 +100,14 @@ async def get_user_analytics( start_date=start_date, end_date=end_date, group_id=group_id, db=db ) - # Get user info for top users - top_user_ids = [uid for uid, _ in sorted(counts.items(), key=lambda x: -x[1])[:limit]] + # Rank by the selected metric before limiting the leaderboard. + top_user_ids = sorted( + counts, + key=lambda uid: ( + -token_usage.get(uid, {}).get('total_tokens', 0) if metric == 'tokens' else -counts[uid], + -counts[uid], + ), + )[:limit] user_info = {u.id: u for u in await Users.get_users_by_user_ids(top_user_ids, db=db)} users = [] diff --git a/src/lib/apis/analytics/index.ts b/src/lib/apis/analytics/index.ts index a6489a62a5..8a5d671c99 100644 --- a/src/lib/apis/analytics/index.ts +++ b/src/lib/apis/analytics/index.ts @@ -43,7 +43,8 @@ export const getUserAnalytics = async ( startDate: number | null = null, endDate: number | null = null, limit: number = 50, - groupId: string | null = null + groupId: string | null = null, + metric: 'messages' | 'tokens' = 'messages' ) => { let error = null; @@ -52,6 +53,7 @@ export const getUserAnalytics = async ( if (endDate) searchParams.append('end_date', endDate.toString()); if (limit) searchParams.append('limit', limit.toString()); if (groupId) searchParams.append('group_id', groupId); + searchParams.append('metric', metric); const res = await fetch(`${WEBUI_API_BASE_URL}/analytics/users?${searchParams.toString()}`, { method: 'GET', diff --git a/src/lib/components/admin/Analytics/Dashboard.svelte b/src/lib/components/admin/Analytics/Dashboard.svelte index 573019d8d3..5e51d6e1c5 100644 --- a/src/lib/components/admin/Analytics/Dashboard.svelte +++ b/src/lib/components/admin/Analytics/Dashboard.svelte @@ -167,7 +167,7 @@ const [summaryRes, modelsRes, usersRes, dailyRes, tokensRes] = await Promise.all([ getSummary(localStorage.token, start, end, selectedGroupId), getModelAnalytics(localStorage.token, start, end, selectedGroupId), - getUserAnalytics(localStorage.token, start, end, 50, selectedGroupId), + getUserAnalytics(localStorage.token, start, end, 50, selectedGroupId, selectedMetric), getDailyStats( localStorage.token, start,