mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 22:35:51 +00:00
feat: 添加对 langfuse 监控的支持 (#242)
* docs: 更新类型检查的 CLAUDE.md * feat: 添加模型 1M 上下文切换 * chore: remove prefetchOfficialMcpUrls call on startup * docs: 添加 git commit 规范 * feat: 第一次接入 langfuse * fix: 修复 generation 的计时的错误 * feat: 添加多 agent 的监控 * feat: 添加 /poor 省流模式,toggle 关闭 extract_memories 和 prompt_suggestion Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: 修复 lock 文件 * chore: 更新类型依赖 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
72
src/services/langfuse/client.ts
Normal file
72
src/services/langfuse/client.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'
|
||||
import { LangfuseSpanProcessor } from '@langfuse/otel'
|
||||
import type { MaskFunction } from '@langfuse/otel'
|
||||
import { setLangfuseTracerProvider } from '@langfuse/tracing'
|
||||
import { sanitizeGlobal } from './sanitize.js'
|
||||
import { logForDebugging } from 'src/utils/debug.js'
|
||||
|
||||
declare const MACRO: { VERSION: string }
|
||||
|
||||
let processor: LangfuseSpanProcessor | null = null
|
||||
let provider: BasicTracerProvider | null = null
|
||||
|
||||
export function isLangfuseEnabled(): boolean {
|
||||
return !!(process.env.LANGFUSE_PUBLIC_KEY && process.env.LANGFUSE_SECRET_KEY)
|
||||
}
|
||||
|
||||
export function getLangfuseProcessor(): LangfuseSpanProcessor | null {
|
||||
return processor
|
||||
}
|
||||
|
||||
export function initLangfuse(): boolean {
|
||||
if (processor !== null) return true
|
||||
if (!isLangfuseEnabled()) {
|
||||
logForDebugging('[langfuse] No keys configured, running in no-op mode')
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
const maskFn: MaskFunction = ({ data }) => sanitizeGlobal(data)
|
||||
|
||||
processor = new LangfuseSpanProcessor({
|
||||
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
||||
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
||||
baseUrl: process.env.LANGFUSE_BASE_URL ?? 'https://cloud.langfuse.com',
|
||||
flushAt: parseInt(process.env.LANGFUSE_FLUSH_AT ?? '20', 10),
|
||||
flushInterval: parseInt(process.env.LANGFUSE_FLUSH_INTERVAL ?? '10', 10),
|
||||
mask: maskFn,
|
||||
environment: process.env.LANGFUSE_TRACING_ENVIRONMENT ?? 'development',
|
||||
release: MACRO.VERSION,
|
||||
exportMode: (process.env.LANGFUSE_EXPORT_MODE as 'batched' | 'immediate' | undefined) ?? 'batched',
|
||||
timeout: parseInt(process.env.LANGFUSE_TIMEOUT ?? '5', 10),
|
||||
})
|
||||
|
||||
provider = new BasicTracerProvider({
|
||||
spanProcessors: [processor],
|
||||
})
|
||||
|
||||
setLangfuseTracerProvider(provider)
|
||||
|
||||
logForDebugging('[langfuse] Initialized with LangfuseSpanProcessor')
|
||||
return true
|
||||
} catch (e) {
|
||||
logForDebugging(`[langfuse] Init failed: ${e}`, { level: 'error' })
|
||||
processor = null
|
||||
provider = null
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export async function shutdownLangfuse(): Promise<void> {
|
||||
try {
|
||||
if (processor) {
|
||||
await processor.forceFlush()
|
||||
await processor.shutdown()
|
||||
}
|
||||
processor = null
|
||||
provider = null
|
||||
logForDebugging('[langfuse] Shutdown complete')
|
||||
} catch (e) {
|
||||
logForDebugging(`[langfuse] Shutdown error: ${e}`, { level: 'error' })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user