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:
claude-code-best
2026-04-11 22:07:38 +08:00
committed by GitHub
parent 6a9da9d546
commit 2fea429dc6
23 changed files with 1242 additions and 6 deletions

View 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' })
}
}