Skip to main content
Glama
get-daily-metrics.tsβ€’4.04 kB
import { z } from 'zod'; import { LangfuseAnalyticsClient } from '../langfuse-client.js'; import { DailyMetrics } from '../types.js'; export const getDailyMetricsSchema = z.object({ from: z.string().datetime(), to: z.string().datetime(), environment: z.string().optional(), fillMissingDays: z.boolean().default(true), }); export async function getDailyMetrics( client: LangfuseAnalyticsClient, args: z.infer<typeof getDailyMetricsSchema> ) { try { // Use the working getDailyMetrics API directly (same approach as cost_analysis) const dailyResponse = await client.getDailyMetrics({ tags: args.environment ? [`environment:${args.environment}`] : undefined, }); const dailyData: any[] = []; if (dailyResponse.data && Array.isArray(dailyResponse.data)) { // Filter by date range const fromDate = new Date(args.from); const toDate = new Date(args.to); const filteredData = dailyResponse.data.filter((day: any) => { const dayDate = new Date(day.date); return dayDate >= fromDate && dayDate <= toDate; }); // Process each day's data filteredData.forEach((day: any) => { // Calculate total tokens from usage breakdown let totalTokens = 0; let totalObservations = 0; if (day.usage && Array.isArray(day.usage)) { totalTokens = day.usage.reduce((sum: number, usage: any) => { return sum + (usage.totalUsage || usage.inputUsage + usage.outputUsage || 0); }, 0); totalObservations = day.usage.reduce((sum: number, usage: any) => { return sum + (usage.countObservations || 0); }, 0); } dailyData.push({ date: day.date, totalCost: day.totalCost || 0, totalTokens: totalTokens, totalTraces: day.countTraces || 0, totalObservations: totalObservations || day.countObservations || 0, avgCostPerTrace: (day.countTraces || 0) > 0 ? Math.round(((day.totalCost || 0) / (day.countTraces || 0)) * 10000) / 10000 : 0, avgTokensPerTrace: (day.countTraces || 0) > 0 ? Math.round((totalTokens / (day.countTraces || 0)) * 100) / 100 : 0, }); }); // Fill in missing days if requested if (args.fillMissingDays) { const startDate = new Date(args.from); const endDate = new Date(args.to); const dataMap = new Map(dailyData.map(d => [d.date, d])); dailyData.length = 0; // Clear array for (let date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) { const dateStr = date.toISOString().split('T')[0]; const existingData = dataMap.get(dateStr); if (existingData) { dailyData.push(existingData); } else { // Fill missing day with zeros dailyData.push({ date: dateStr, totalCost: 0, totalTokens: 0, totalTraces: 0, totalObservations: 0, avgCostPerTrace: 0, avgTokensPerTrace: 0, }); } } } // Sort by date dailyData.sort((a, b) => a.date.localeCompare(b.date)); } // Return the successful result const result: DailyMetrics = { projectId: client.getProjectId(), from: args.from, to: args.to, dailyData, }; return { content: [ { type: 'text' as const, text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text' as const, text: JSON.stringify({ error: 'Failed to get daily metrics', message: error instanceof Error ? error.message : 'Unknown error', projectId: client.getProjectId(), from: args.from, to: args.to, }, null, 2), }, ], isError: true, }; } }

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/therealsachin/langfuse-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server