diff --git a/docs/technical/how-to-write-middlewares.md b/docs/technical/how-to-write-middlewares.md index 9f3b691309..0960cf91e2 100644 --- a/docs/technical/how-to-write-middlewares.md +++ b/docs/technical/how-to-write-middlewares.md @@ -80,7 +80,6 @@ import { ChunkType } from '@renderer/types' // 调整路径 export const createSimpleLoggingMiddleware = (): CompletionsMiddleware => { return (api: MiddlewareAPI) => { - // console.log(`[LoggingMiddleware] Initialized for provider: ${api.getProviderId()}`); return (next: (context: AiProviderMiddlewareCompletionsContext, params: CompletionsParams) => Promise) => { return async (context: AiProviderMiddlewareCompletionsContext, params: CompletionsParams): Promise => { @@ -88,7 +87,7 @@ export const createSimpleLoggingMiddleware = (): CompletionsMiddleware => { // 从 context 中获取 onChunk (它最初来自 params.onChunk) const onChunk = context.onChunk - console.log( + logger.debug( `[LoggingMiddleware] Request for ${context.methodName} with params:`, params.messages?.[params.messages.length - 1]?.content ) @@ -104,14 +103,14 @@ export const createSimpleLoggingMiddleware = (): CompletionsMiddleware => { // 如果在之前,那么它需要自己处理 rawSdkResponse 或确保下游会处理。 const duration = Date.now() - startTime - console.log(`[LoggingMiddleware] Request for ${context.methodName} completed in ${duration}ms.`) + logger.debug(`[LoggingMiddleware] Request for ${context.methodName} completed in ${duration}ms.`) // 假设下游已经通过 onChunk 发送了所有数据。 // 如果这个中间件是链的末端,并且需要确保 BLOCK_COMPLETE 被发送, // 它可能需要更复杂的逻辑来跟踪何时所有数据都已发送。 } catch (error) { const duration = Date.now() - startTime - console.error(`[LoggingMiddleware] Request for ${context.methodName} failed after ${duration}ms:`, error) + logger.error(`[LoggingMiddleware] Request for ${context.methodName} failed after ${duration}ms:`, error) // 如果 onChunk 可用,可以尝试发送一个错误块 if (onChunk) { @@ -207,7 +206,7 @@ export default middlewareConfig ### 调试技巧 -- 在中间件的关键点使用 `console.log` 或调试器来检查 `params`、`context` 的状态以及 `next` 的返回值。 +- 在中间件的关键点使用 `logger.debug` 或调试器来检查 `params`、`context` 的状态以及 `next` 的返回值。 - 暂时简化中间件链,只保留你正在调试的中间件和最简单的核心逻辑,以隔离问题。 - 编写单元测试来独立验证每个中间件的行为。 diff --git a/src/main/index.ts b/src/main/index.ts index e1e05dbf30..7b5338414f 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -129,8 +129,8 @@ if (!app.requestSingleInstanceLock()) { if (isDev) { installExtension([REDUX_DEVTOOLS, REACT_DEVELOPER_TOOLS]) - .then((name) => console.log(`Added Extension: ${name}`)) - .catch((err) => console.log('An error occurred: ', err)) + .then((name) => logger.info(`Added Extension: ${name}`)) + .catch((err) => logger.error('An error occurred: ', err)) } //start selection assistant service diff --git a/src/main/knowledage/preprocess/MineruPreprocessProvider.ts b/src/main/knowledage/preprocess/MineruPreprocessProvider.ts index 1362ffa521..74fed3de8a 100644 --- a/src/main/knowledage/preprocess/MineruPreprocessProvider.ts +++ b/src/main/knowledage/preprocess/MineruPreprocessProvider.ts @@ -205,9 +205,9 @@ export default class MineruPreprocessProvider extends BasePreprocessProvider { try { // 步骤1: 获取上传URL const { batchId, fileUrls } = await this.getBatchUploadUrls(file) - logger.info(`Got upload URLs for batch: ${batchId}`) + logger.debug(`Got upload URLs for batch: ${batchId}`) - console.log('batchId:', batchId, 'fileurls:', fileUrls) + logger.debug(`batchId: ${batchId}, fileurls: ${fileUrls}`) // 步骤2: 上传文件到获取的URL await this.putFileToUrl(file.path, fileUrls[0]) logger.info(`File uploaded successfully: ${file.path}`) diff --git a/src/main/services/FileStorage.ts b/src/main/services/FileStorage.ts index c3ac8035ad..61e8ed2ced 100644 --- a/src/main/services/FileStorage.ts +++ b/src/main/services/FileStorage.ts @@ -57,7 +57,7 @@ class FileStorage { findDuplicateFile = async (filePath: string): Promise => { const stats = fs.statSync(filePath) - console.log('stats', stats, filePath) + logger.debug('stats', stats, filePath) const fileSize = stats.size const files = await fs.promises.readdir(this.storageDir) diff --git a/src/main/services/KnowledgeService.ts b/src/main/services/KnowledgeService.ts index ef6115afec..0e5858a888 100644 --- a/src/main/services/KnowledgeService.ts +++ b/src/main/services/KnowledgeService.ts @@ -156,7 +156,7 @@ class KnowledgeService { } public delete = async (_: Electron.IpcMainInvokeEvent, id: string): Promise => { - console.log('id', id) + logger.debug('delete id', id) const dbPath = path.join(this.storageDir, id) if (fs.existsSync(dbPath)) { fs.rmSync(dbPath, { recursive: true }) diff --git a/src/main/services/MCPService.ts b/src/main/services/MCPService.ts index 4e93664d7d..1b6e012c5f 100644 --- a/src/main/services/MCPService.ts +++ b/src/main/services/MCPService.ts @@ -622,7 +622,7 @@ class McpService { const client = await this.initClient(server) const result = await client.callTool({ name, arguments: args }, undefined, { onprogress: (process) => { - console.log('[MCP] Progress:', process.progress / (process.total || 1)) + logger.debug(`Progress: ${process.progress / (process.total || 1)}`) window.api.mcp.setProgress(process.progress / (process.total || 1)) }, timeout: server.timeout ? server.timeout * 1000 : 60000, // Default timeout of 1 minute diff --git a/src/preload/index.ts b/src/preload/index.ts index 163631c802..43ec5a255c 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -364,6 +364,7 @@ if (process.contextIsolated) { getFiles: (vaultName: string) => ipcRenderer.invoke(IpcChannel.Obsidian_GetFiles, vaultName) }) } catch (error) { + // eslint-disable-next-line no-restricted-syntax console.error(error) } } else { diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index c8a5d41db4..4c02234305 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -26,7 +26,7 @@ import TranslatePage from './pages/translate/TranslatePage' const logger = loggerService.withContext('App.tsx') function App(): React.ReactElement { - logger.error('App initialized') + logger.info('App initialized') return ( diff --git a/src/renderer/src/aiCore/clients/ApiClientFactory.ts b/src/renderer/src/aiCore/clients/ApiClientFactory.ts index 991bdccf34..b92c6cb9f2 100644 --- a/src/renderer/src/aiCore/clients/ApiClientFactory.ts +++ b/src/renderer/src/aiCore/clients/ApiClientFactory.ts @@ -1,3 +1,4 @@ +import { loggerService } from '@logger' import { Provider } from '@renderer/types' import { AihubmixAPIClient } from './AihubmixAPIClient' @@ -10,6 +11,8 @@ import { OpenAIAPIClient } from './openai/OpenAIApiClient' import { OpenAIResponseAPIClient } from './openai/OpenAIResponseAPIClient' import { PPIOAPIClient } from './ppio/PPIOAPIClient' +const logger = loggerService.withContext('ApiClientFactory') + /** * Factory for creating ApiClient instances based on provider configuration * 根据提供者配置创建ApiClient实例的工厂 @@ -20,7 +23,7 @@ export class ApiClientFactory { * 为给定的提供者创建ApiClient实例 */ static create(provider: Provider): BaseApiClient { - console.log(`[ApiClientFactory] Creating ApiClient for provider:`, { + logger.debug(`Creating ApiClient for provider:`, { id: provider.id, type: provider.type }) @@ -29,17 +32,17 @@ export class ApiClientFactory { // 首先检查特殊的provider id if (provider.id === 'aihubmix') { - console.log(`[ApiClientFactory] Creating AihubmixAPIClient for provider: ${provider.id}`) + logger.debug(`Creating AihubmixAPIClient for provider: ${provider.id}`) instance = new AihubmixAPIClient(provider) as BaseApiClient return instance } if (provider.id === 'new-api') { - console.log(`[ApiClientFactory] Creating NewAPIClient for provider: ${provider.id}`) + logger.debug(`Creating NewAPIClient for provider: ${provider.id}`) instance = new NewAPIClient(provider) as BaseApiClient return instance } if (provider.id === 'ppio') { - console.log(`[ApiClientFactory] Creating PPIOAPIClient for provider: ${provider.id}`) + logger.debug(`Creating PPIOAPIClient for provider: ${provider.id}`) instance = new PPIOAPIClient(provider) as BaseApiClient return instance } @@ -63,7 +66,7 @@ export class ApiClientFactory { instance = new AnthropicAPIClient(provider) as BaseApiClient break default: - console.log(`[ApiClientFactory] Using default OpenAIApiClient for provider: ${provider.id}`) + logger.debug(`Using default OpenAIApiClient for provider: ${provider.id}`) instance = new OpenAIAPIClient(provider) as BaseApiClient break } diff --git a/src/renderer/src/aiCore/middleware/common/ErrorHandlerMiddleware.ts b/src/renderer/src/aiCore/middleware/common/ErrorHandlerMiddleware.ts index 8875a0b627..26d9342ebc 100644 --- a/src/renderer/src/aiCore/middleware/common/ErrorHandlerMiddleware.ts +++ b/src/renderer/src/aiCore/middleware/common/ErrorHandlerMiddleware.ts @@ -1,9 +1,12 @@ +import { loggerService } from '@logger' import { Chunk } from '@renderer/types/chunk' import { CompletionsResult } from '../schemas' import { CompletionsContext } from '../types' import { createErrorChunk } from '../utils' +const logger = loggerService.withContext('ErrorHandlerMiddleware') + export const MIDDLEWARE_NAME = 'ErrorHandlerMiddleware' /** @@ -25,7 +28,7 @@ export const ErrorHandlerMiddleware = // 尝试执行下一个中间件 return await next(ctx, params) } catch (error: any) { - console.log('ErrorHandlerMiddleware_error', error) + logger.error('ErrorHandlerMiddleware_error', error) // 1. 使用通用的工具函数将错误解析为标准格式 const errorChunk = createErrorChunk(error) // 2. 调用从外部传入的 onError 回调 diff --git a/src/renderer/src/aiCore/middleware/core/WebSearchMiddleware.ts b/src/renderer/src/aiCore/middleware/core/WebSearchMiddleware.ts index d4c8f71eff..4c72e877a9 100644 --- a/src/renderer/src/aiCore/middleware/core/WebSearchMiddleware.ts +++ b/src/renderer/src/aiCore/middleware/core/WebSearchMiddleware.ts @@ -1,9 +1,12 @@ +import { loggerService } from '@logger' import { ChunkType } from '@renderer/types/chunk' import { flushLinkConverterBuffer, smartLinkConverter } from '@renderer/utils/linkConverter' import { CompletionsParams, CompletionsResult, GenericChunk } from '../schemas' import { CompletionsContext, CompletionsMiddleware } from '../types' +const logger = loggerService.withContext('WebSearchMiddleware') + export const MIDDLEWARE_NAME = 'WebSearchMiddleware' /** @@ -99,7 +102,7 @@ export const WebSearchMiddleware: CompletionsMiddleware = stream: enhancedStream } } else { - console.log(`[${MIDDLEWARE_NAME}] No stream to process or not a ReadableStream.`) + logger.debug(`No stream to process or not a ReadableStream.`) } } diff --git a/src/renderer/src/components/CodeEditor/hooks.ts b/src/renderer/src/components/CodeEditor/hooks.ts index 5a04b2178d..12117332cc 100644 --- a/src/renderer/src/components/CodeEditor/hooks.ts +++ b/src/renderer/src/components/CodeEditor/hooks.ts @@ -1,9 +1,12 @@ import { linter } from '@codemirror/lint' // statically imported by @uiw/codemirror-extensions-basic-setup import { EditorView } from '@codemirror/view' +import { loggerService } from '@logger' import { useCodeStyle } from '@renderer/context/CodeStyleProvider' import { Extension, keymap } from '@uiw/react-codemirror' import { useEffect, useMemo, useState } from 'react' +const logger = loggerService.withContext('CodeEditorHooks') + // 语言对应的 linter 加载器 const linterLoaders: Record Promise> = { json: async () => { @@ -39,7 +42,7 @@ async function loadLanguageExtension(language: string, languageMap: Record try { return await loader() } catch (error) { - console.debug(`Failed to load linter for ${language}`, error) + logger.debug(`Failed to load linter for ${language}`, error) return null } } @@ -105,7 +108,7 @@ export const useLanguageExtensions = (language: string, lint?: boolean) => { setExtensions(results) } catch (error) { if (!cancelled) { - console.debug('Failed to load language extensions:', error) + logger.debug('Failed to load language extensions:', error) setExtensions([]) } } diff --git a/src/renderer/src/components/MinApp/MinappPopupContainer.tsx b/src/renderer/src/components/MinApp/MinappPopupContainer.tsx index 4ba7badff6..0d4680b7bb 100644 --- a/src/renderer/src/components/MinApp/MinappPopupContainer.tsx +++ b/src/renderer/src/components/MinApp/MinappPopupContainer.tsx @@ -10,6 +10,7 @@ import { PushpinOutlined, ReloadOutlined } from '@ant-design/icons' +import { loggerService } from '@logger' import { isLinux, isMac, isWin } from '@renderer/config/constant' import { DEFAULT_MIN_APPS } from '@renderer/config/minapps' import { useBridge } from '@renderer/hooks/useBridge' @@ -31,6 +32,8 @@ import styled from 'styled-components' import WebviewContainer from './WebviewContainer' +const logger = loggerService.withContext('MinappPopupContainer') + interface AppExtraInfo { canPinned: boolean isPinned: boolean @@ -296,7 +299,7 @@ const MinappPopupContainer: React.FC = () => { const handleWebviewNavigate = (appid: string, url: string) => { // 记录当前URL,用于GoogleLoginTip判断 if (appid === currentMinappId) { - console.log('URL changed:', url) + logger.debug('URL changed:', url) setCurrentUrl(url) } } diff --git a/src/renderer/src/hooks/useAppInit.ts b/src/renderer/src/hooks/useAppInit.ts index ee8096a943..60b8ce448d 100644 --- a/src/renderer/src/hooks/useAppInit.ts +++ b/src/renderer/src/hooks/useAppInit.ts @@ -34,6 +34,7 @@ export function useAppInit() { useEffect(() => { document.getElementById('spinner')?.remove() + // eslint-disable-next-line no-restricted-syntax console.timeEnd('init') // Initialize MemoryService after app is ready diff --git a/src/renderer/src/hooks/useKnowledge.ts b/src/renderer/src/hooks/useKnowledge.ts index 8008930bb3..4dc5f3770f 100644 --- a/src/renderer/src/hooks/useKnowledge.ts +++ b/src/renderer/src/hooks/useKnowledge.ts @@ -1,3 +1,4 @@ +import { loggerService } from '@logger' import { db } from '@renderer/databases' import KnowledgeQueue from '@renderer/queue/KnowledgeQueue' import { getKnowledgeBaseParams } from '@renderer/services/KnowledgeService' @@ -26,6 +27,8 @@ import { v4 as uuidv4 } from 'uuid' import { useAgents } from './useAgents' import { useAssistants } from './useAssistant' +const logger = loggerService.withContext('useKnowledge') + export const useKnowledge = (baseId: string) => { const dispatch = useDispatch() const base = useSelector((state: RootState) => state.knowledge.bases.find((b) => b.id === baseId)) @@ -53,7 +56,7 @@ export const useKnowledge = (baseId: string) => { processingError: '', retryCount: 0 })) - console.log('Adding files:', filesItems) + logger.debug('Adding files:', filesItems) dispatch(addFilesAction({ baseId, items: filesItems })) setTimeout(() => KnowledgeQueue.checkAllBases(), 0) } diff --git a/src/renderer/src/pages/knowledge/KnowledgeContent.tsx b/src/renderer/src/pages/knowledge/KnowledgeContent.tsx index 4d4e702d4e..e1b5464781 100644 --- a/src/renderer/src/pages/knowledge/KnowledgeContent.tsx +++ b/src/renderer/src/pages/knowledge/KnowledgeContent.tsx @@ -1,4 +1,5 @@ import { RedoOutlined } from '@ant-design/icons' +import { loggerService } from '@logger' import CustomTag from '@renderer/components/CustomTag' import { HStack } from '@renderer/components/Layout' import { useKnowledge } from '@renderer/hooks/useKnowledge' @@ -20,6 +21,7 @@ import KnowledgeNotes from './items/KnowledgeNotes' import KnowledgeSitemaps from './items/KnowledgeSitemaps' import KnowledgeUrls from './items/KnowledgeUrls' +const logger = loggerService.withContext('KnowledgeContent') interface KnowledgeContentProps { selectedBase: KnowledgeBase } @@ -52,7 +54,7 @@ const KnowledgeContent: FC = ({ selectedBase }) => { }), window.electron.ipcRenderer.on('directory-processing-percent', (_, { itemId, percent }) => { - console.log('[Progress] Directory:', itemId, percent) + logger.debug('[Progress] Directory:', itemId, percent) setProgressMap((prev) => new Map(prev).set(itemId, percent)) }) ] diff --git a/src/renderer/src/pages/knowledge/components/KnowledgeSettings.tsx b/src/renderer/src/pages/knowledge/components/KnowledgeSettings.tsx index 7af6692abc..482517c1eb 100644 --- a/src/renderer/src/pages/knowledge/components/KnowledgeSettings.tsx +++ b/src/renderer/src/pages/knowledge/components/KnowledgeSettings.tsx @@ -17,6 +17,7 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' +const logger = loggerService.withContext('KnowledgeSettings') interface ShowParams { base: KnowledgeBase } @@ -25,8 +26,6 @@ interface Props extends ShowParams { resolve: (data: any) => void } -const logger = loggerService.withContext('KnowledgeSettings') - const PopupContainer: React.FC = ({ base: _base, resolve }) => { const { preprocessProviders } = usePreprocessProviders() const { ocrProviders } = useOcrProviders() @@ -96,7 +95,7 @@ const PopupContainer: React.FC = ({ base: _base, resolve }) => { const onOk = async () => { try { - console.log('newbase', newBase) + logger.debug('newbase', newBase) updateKnowledgeBase(newBase) setOpen(false) resolve(newBase) diff --git a/src/renderer/src/pages/knowledge/components/StatusIcon.tsx b/src/renderer/src/pages/knowledge/components/StatusIcon.tsx index 465a7cef0f..b9ae3bafc9 100644 --- a/src/renderer/src/pages/knowledge/components/StatusIcon.tsx +++ b/src/renderer/src/pages/knowledge/components/StatusIcon.tsx @@ -1,10 +1,12 @@ import { CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons' +import { loggerService } from '@logger' import { KnowledgeBase, ProcessingStatus } from '@renderer/types' import { Progress, Tooltip } from 'antd' import React, { FC, useMemo } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' +const logger = loggerService.withContext('StatusIcon') interface StatusIconProps { sourceId: string base: KnowledgeBase @@ -26,7 +28,7 @@ const StatusIcon: FC = ({ const status = getProcessingStatus(sourceId) const item = base.items.find((item) => item.id === sourceId) const errorText = item?.processingError - console.log('[StatusIcon] Rendering for item:', item?.id, 'Status:', status, 'Progress:', progress) + logger.debug('[StatusIcon] Rendering for item:', item?.id, 'Status:', status, 'Progress:', progress) return useMemo(() => { if (!status) { diff --git a/src/renderer/src/pages/knowledge/items/KnowledgeFiles.tsx b/src/renderer/src/pages/knowledge/items/KnowledgeFiles.tsx index 8ac29817be..f036ea2ec7 100644 --- a/src/renderer/src/pages/knowledge/items/KnowledgeFiles.tsx +++ b/src/renderer/src/pages/knowledge/items/KnowledgeFiles.tsx @@ -1,4 +1,5 @@ import { DeleteOutlined } from '@ant-design/icons' +import { loggerService } from '@logger' import Ellipsis from '@renderer/components/Ellipsis' import { useKnowledge } from '@renderer/hooks/useKnowledge' import FileItem from '@renderer/pages/files/FileItem' @@ -16,6 +17,8 @@ import { FC, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' +const logger = loggerService.withContext('KnowledgeFiles') + import { ClickableSpan, FlexAlignCenter, @@ -113,7 +116,7 @@ const KnowledgeFiles: FC = ({ selectedBase, progressMap, }) .filter(({ ext }) => fileTypes.includes(ext)) const uploadedFiles = await FileManager.uploadFiles(_files) - console.log('uploadedFiles', uploadedFiles) + logger.debug('uploadedFiles', uploadedFiles) addFiles(uploadedFiles) } } diff --git a/src/renderer/src/pages/memory/index.tsx b/src/renderer/src/pages/memory/index.tsx index eeafcf475b..eb7939884c 100644 --- a/src/renderer/src/pages/memory/index.tsx +++ b/src/renderer/src/pages/memory/index.tsx @@ -338,7 +338,7 @@ const MemoriesPage = () => { const loadMemories = useCallback( async (userId?: string) => { const targetUser = userId || currentUser - console.log('Loading all memories for user:', targetUser) + logger.debug('Loading all memories for user:', targetUser) setLoading(true) try { // First, ensure the memory service is using the correct user @@ -349,7 +349,7 @@ const MemoriesPage = () => { // Get all memories for current user context (load up to 10000) const result = await memoryService.list({ limit: 10000, offset: 0 }) - console.log('Loaded memories for user:', targetUser, 'count:', result.results?.length || 0) + logger.debug('Loaded memories for user:', targetUser, 'count:', result.results?.length || 0) setAllMemories(result.results || []) } catch (error) { logger.error('Failed to load memories:', error) @@ -363,7 +363,7 @@ const MemoriesPage = () => { // Sync memoryService with Redux store on mount and when currentUser changes useEffect(() => { - console.log('useEffect triggered for currentUser:', currentUser) + logger.debug('useEffect triggered for currentUser:', currentUser) // Reset to first page when user changes setCurrentPage(1) loadMemories(currentUser) @@ -453,7 +453,7 @@ const MemoriesPage = () => { } const handleUserSwitch = async (userId: string) => { - console.log('Switching to user:', userId) + logger.debug('Switching to user:', userId) // First update Redux state dispatch(setCurrentUserId(userId)) diff --git a/src/renderer/src/pages/paintings/AihubmixPage.tsx b/src/renderer/src/pages/paintings/AihubmixPage.tsx index eefed99133..9e968dce0c 100644 --- a/src/renderer/src/pages/paintings/AihubmixPage.tsx +++ b/src/renderer/src/pages/paintings/AihubmixPage.tsx @@ -207,7 +207,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => { // 确保渲染速度参数正确传递 const renderSpeed = painting.renderingSpeed || 'DEFAULT' - console.log('使用渲染速度:', renderSpeed) + logger.silly(`使用渲染速度: ${renderSpeed}`) formData.append('rendering_speed', renderSpeed) formData.append('num_images', String(painting.numImages || 1)) @@ -215,7 +215,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => { // Convert aspect ratio format from ASPECT_1_1 to 1x1 for V3 API if (painting.aspectRatio) { const aspectRatioValue = painting.aspectRatio.replace('ASPECT_', '').replace('_', 'x').toLowerCase() - console.log('转换后的宽高比:', aspectRatioValue) + logger.silly(`转换后的宽高比: ${aspectRatioValue}`) formData.append('aspect_ratio', aspectRatioValue) } @@ -223,39 +223,39 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => { // 确保样式类型与API文档一致,保持大写形式 // V3 API支持的样式类型: AUTO, GENERAL, REALISTIC, DESIGN const styleType = painting.styleType - console.log('使用样式类型:', styleType) + logger.silly(`使用样式类型: ${styleType}`) formData.append('style_type', styleType) } else { // 确保明确设置默认样式类型 - console.log('使用默认样式类型: AUTO') + logger.silly('使用默认样式类型: AUTO') formData.append('style_type', 'AUTO') } if (painting.seed) { - console.log('使用随机种子:', painting.seed) + logger.silly(`使用随机种子: ${painting.seed}`) formData.append('seed', painting.seed) } if (painting.negativePrompt) { - console.log('使用负面提示词:', painting.negativePrompt) + logger.silly(`使用负面提示词: ${painting.negativePrompt}`) formData.append('negative_prompt', painting.negativePrompt) } if (painting.magicPromptOption !== undefined) { const magicPrompt = painting.magicPromptOption ? 'ON' : 'OFF' - console.log('使用魔法提示词:', magicPrompt) + logger.silly(`使用魔法提示词: ${magicPrompt}`) formData.append('magic_prompt', magicPrompt) } // 打印所有FormData内容 - console.log('FormData内容:') + logger.silly('FormData内容:') for (const pair of formData.entries()) { - console.log(pair[0] + ': ' + pair[1]) + logger.silly(`${pair[0]}: ${pair[1]}`) } body = formData // For V3 endpoints - 使用模板字符串而不是字符串连接 - console.log('API 端点:', `${aihubmixProvider.apiHost}/ideogram/v1/ideogram-v3/generate`) + logger.silly(`API 端点: ${aihubmixProvider.apiHost}/ideogram/v1/ideogram-v3/generate`) // 调整请求头,可能需要指定multipart/form-data // 注意:FormData会自动设置Content-Type,不应手动设置 @@ -275,7 +275,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => { } const data = await response.json() - console.log('V3 API响应:', data) + logger.silly(`V3 API响应: ${data}`) const urls = data.data.map((item) => item.url) if (urls.length > 0) { @@ -391,7 +391,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => { } const data = await response.json() - console.log('V3 Remix API响应:', data) + logger.silly(`V3 Remix API响应: ${data}`) const urls = data.data.map((item) => item.url) // Handle the downloaded images @@ -461,7 +461,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => { } const data = await response.json() - console.log('通用API响应:', data) + logger.silly(`通用API响应: ${data}`) const urls = data.data.filter((item) => item.url).map((item) => item.url) const base64s = data.data.filter((item) => item.b64_json).map((item) => item.b64_json) diff --git a/src/renderer/src/pages/paintings/PaintingsRoutePage.tsx b/src/renderer/src/pages/paintings/PaintingsRoutePage.tsx index b31085c279..dc92c158c0 100644 --- a/src/renderer/src/pages/paintings/PaintingsRoutePage.tsx +++ b/src/renderer/src/pages/paintings/PaintingsRoutePage.tsx @@ -1,3 +1,4 @@ +import { loggerService } from '@logger' import { useAppDispatch } from '@renderer/store' import { setDefaultPaintingProvider } from '@renderer/store/settings' import { PaintingProvider } from '@renderer/types' @@ -10,6 +11,8 @@ import NewApiPage from './NewApiPage' import SiliconPage from './SiliconPage' import TokenFluxPage from './TokenFluxPage' +const logger = loggerService.withContext('PaintingsRoutePage') + const Options = ['aihubmix', 'silicon', 'dmxapi', 'tokenflux', 'new-api'] const PaintingsRoutePage: FC = () => { @@ -18,7 +21,7 @@ const PaintingsRoutePage: FC = () => { const dispatch = useAppDispatch() useEffect(() => { - console.debug('defaultPaintingProvider', provider) + logger.debug('defaultPaintingProvider', provider) if (provider && Options.includes(provider)) { dispatch(setDefaultPaintingProvider(provider as PaintingProvider)) } diff --git a/src/renderer/src/pages/settings/MCPSettings/providers/lanyun.ts b/src/renderer/src/pages/settings/MCPSettings/providers/lanyun.ts index 67acf6667f..7c773c5505 100644 --- a/src/renderer/src/pages/settings/MCPSettings/providers/lanyun.ts +++ b/src/renderer/src/pages/settings/MCPSettings/providers/lanyun.ts @@ -125,7 +125,7 @@ export const syncTokenLanYunServers = async ( // Transform Token servers to MCP servers format const addedServers: MCPServer[] = [] - console.log('TokenLanYun servers:', servers) + logger.debug('TokenLanYun servers:', servers) for (const server of servers) { try { if (!server.operationalUrls?.[0]?.url) continue diff --git a/src/renderer/src/services/ApiService.ts b/src/renderer/src/services/ApiService.ts index 0f34a95b6b..399fe9111c 100644 --- a/src/renderer/src/services/ApiService.ts +++ b/src/renderer/src/services/ApiService.ts @@ -370,7 +370,7 @@ export async function fetchChatCompletion({ // TODO // onChunkStatus: (status: 'searching' | 'processing' | 'success' | 'error') => void }) { - console.log('fetchChatCompletion', messages, assistant) + logger.debug('fetchChatCompletion', messages, assistant) const provider = getAssistantProvider(assistant) const AI = new AiProvider(provider) @@ -518,12 +518,12 @@ async function processConversationMemory(messages: Message[], assistant: Assista memoryProcessor .processConversation(conversationMessages, processorConfig) .then((result) => { - console.log('Memory processing completed:', result) + logger.debug('Memory processing completed:', result) if (result.facts.length > 0) { - console.log('Extracted facts from conversation:', result.facts) - console.log('Memory operations performed:', result.operations) + logger.debug('Extracted facts from conversation:', result.facts) + logger.debug('Memory operations performed:', result.operations) } else { - console.log('No facts extracted from conversation') + logger.debug('No facts extracted from conversation') } }) .catch((error) => { diff --git a/src/renderer/src/services/KnowledgeService.ts b/src/renderer/src/services/KnowledgeService.ts index 930422e116..6d8b5fd4ec 100644 --- a/src/renderer/src/services/KnowledgeService.ts +++ b/src/renderer/src/services/KnowledgeService.ts @@ -61,7 +61,7 @@ export const getKnowledgeBaseParams = (base: KnowledgeBase): KnowledgeBaseParams } export const getFileFromUrl = async (url: string): Promise => { - console.log('getFileFromUrl', url) + logger.debug('getFileFromUrl', url) let fileName = '' if (url && url.includes('CherryStudio')) { @@ -73,10 +73,10 @@ export const getFileFromUrl = async (url: string): Promise fileName = url.split('\\Data\\Files\\')[1] } } - console.log('fileName', fileName) + logger.debug('fileName', fileName) if (fileName) { const actualFileName = fileName.split(/[/\\]/).pop() || fileName - console.log('actualFileName', actualFileName) + logger.debug('actualFileName', actualFileName) const fileId = actualFileName.split('.')[0] const file = await FileManager.getFile(fileId) if (file) { @@ -135,7 +135,7 @@ export const searchKnowledgeBase = async ( return await Promise.all( limitedResults.map(async (item) => { const file = await getFileFromUrl(item.metadata.source) - console.log('Knowledge search item:', item, 'File:', file) + logger.debug('Knowledge search item:', item, 'File:', file) return { ...item, file } }) ) diff --git a/src/renderer/src/services/MemoryProcessor.ts b/src/renderer/src/services/MemoryProcessor.ts index bbceae0b81..20be0d3b4b 100644 --- a/src/renderer/src/services/MemoryProcessor.ts +++ b/src/renderer/src/services/MemoryProcessor.ts @@ -238,7 +238,7 @@ export class MemoryProcessor { limit }) - console.log( + logger.debug( 'Searching memories with query:', query, 'for user:', diff --git a/src/renderer/src/services/messageStreaming/callbacks/baseCallbacks.ts b/src/renderer/src/services/messageStreaming/callbacks/baseCallbacks.ts index 67a6626f50..0bcfe50592 100644 --- a/src/renderer/src/services/messageStreaming/callbacks/baseCallbacks.ts +++ b/src/renderer/src/services/messageStreaming/callbacks/baseCallbacks.ts @@ -1,3 +1,4 @@ +import { loggerService } from '@logger' import { autoRenameTopic } from '@renderer/hooks/useTopic' import i18n from '@renderer/i18n' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' @@ -21,6 +22,7 @@ import { isFocused, isOnHomePage } from '@renderer/utils/window' import { BlockManager } from '../BlockManager' +const logger = loggerService.withContext('BaseCallbacks') interface BaseCallbacksDependencies { blockManager: BlockManager dispatch: any @@ -68,7 +70,7 @@ export const createBaseCallbacks = (deps: BaseCallbacksDependencies) => { }, onError: async (error: any) => { - console.dir(error, { depth: null }) + logger.debug('onError', error) const isErrorTypeAbort = isAbortError(error) let pauseErrorLanguagePlaceholder = '' if (isErrorTypeAbort) { diff --git a/src/renderer/src/services/messageStreaming/callbacks/citationCallbacks.ts b/src/renderer/src/services/messageStreaming/callbacks/citationCallbacks.ts index cbaef2cb5a..c1ee6f6b05 100644 --- a/src/renderer/src/services/messageStreaming/callbacks/citationCallbacks.ts +++ b/src/renderer/src/services/messageStreaming/callbacks/citationCallbacks.ts @@ -43,9 +43,9 @@ export const createCitationCallbacks = (deps: CitationCallbacksDependencies) => onLLMWebSearchInProgress: async () => { if (blockManager.hasInitialPlaceholder) { // blockManager.lastBlockType = MessageBlockType.CITATION - console.log('blockManager.initialPlaceholderBlockId', blockManager.initialPlaceholderBlockId) + logger.debug('blockManager.initialPlaceholderBlockId', blockManager.initialPlaceholderBlockId) citationBlockId = blockManager.initialPlaceholderBlockId! - console.log('citationBlockId', citationBlockId) + logger.debug('citationBlockId', citationBlockId) const changes = { type: MessageBlockType.CITATION, diff --git a/src/renderer/src/store/knowledge.ts b/src/renderer/src/store/knowledge.ts index dc7c328787..b82e99f471 100644 --- a/src/renderer/src/store/knowledge.ts +++ b/src/renderer/src/store/knowledge.ts @@ -1,7 +1,10 @@ +import { loggerService } from '@logger' import { createSlice, PayloadAction } from '@reduxjs/toolkit' import FileManager from '@renderer/services/FileManager' import { FileMetadata, KnowledgeBase, KnowledgeItem, ProcessingStatus } from '@renderer/types' +const logger = loggerService.withContext('Store:Knowledge') + export interface KnowledgeState { bases: KnowledgeBase[] } @@ -176,7 +179,7 @@ const knowledgeSlice = createSlice({ action: PayloadAction<{ baseId: string; itemId: string; uniqueId: string; uniqueIds: string[] }> ) { const base = state.bases.find((b) => b.id === action.payload.baseId) - console.log('base2', base) + logger.silly('base2', base) if (base) { const item = base.items.find((item) => item.id === action.payload.itemId) if (item) { @@ -191,10 +194,10 @@ const knowledgeSlice = createSlice({ action: PayloadAction<{ baseId: string; itemId: string; isPreprocessed: boolean }> ) { const base = state.bases.find((b) => b.id === action.payload.baseId) - console.log('base', base) + logger.silly('base', base) if (base) { const item = base.items.find((item) => item.id === action.payload.itemId) - console.log('item', item) + logger.silly('item', item) if (item) { item.isPreprocessed = action.payload.isPreprocessed } diff --git a/src/renderer/src/utils/shiki.ts b/src/renderer/src/utils/shiki.ts index 7ad0913ffe..5334a4446a 100644 --- a/src/renderer/src/utils/shiki.ts +++ b/src/renderer/src/utils/shiki.ts @@ -1,3 +1,4 @@ +import { loggerService } from '@logger' import { BundledLanguage, BundledTheme } from 'shiki/bundle/web' import { getTokenStyleObject, type HighlighterGeneric, SpecialLanguage, ThemedToken } from 'shiki/core' @@ -6,6 +7,8 @@ import { AsyncInitializer } from './asyncInitializer' export const DEFAULT_LANGUAGES = ['javascript', 'typescript', 'python', 'java', 'markdown', 'json'] export const DEFAULT_THEMES = ['one-light', 'material-theme-darker'] +const logger = loggerService.withContext('Shiki') + /** * shiki 初始化器,避免并发问题 */ @@ -87,7 +90,7 @@ export async function loadThemeIfNeeded(highlighter: HighlighterGeneric +import { loggerService } from '@logger' + +const logger = loggerService.withContext('PyodideWorker') + // 定义输出结构类型 interface PyodideOutput { result: any @@ -47,7 +51,7 @@ const pyodidePromise = (async () => { }) } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error) - console.error('Failed to load Pyodide:', errorMessage) + logger.error('Failed to load Pyodide:', errorMessage) // 通知主线程初始化错误 self.postMessage({ @@ -77,7 +81,7 @@ function processResult(result: any): any { return result } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error) - console.error('Result processing error:', errorMessage) + logger.error('Result processing error:', errorMessage) return { __error__: 'Result processing failed', details: errorMessage } } } @@ -89,7 +93,7 @@ pyodidePromise }) .catch((error: unknown) => { const errorMessage = error instanceof Error ? error.message : String(error) - console.error('Failed to load Pyodide:', errorMessage) + logger.error('Failed to load Pyodide:', errorMessage) self.postMessage({ type: 'error', error: errorMessage }) }) @@ -141,7 +145,7 @@ self.onmessage = async (event) => { } catch (error: unknown) { // 处理所有其他错误 const errorMessage = error instanceof Error ? error.message : String(error) - console.error('Python processing error:', errorMessage) + logger.error('Python processing error:', errorMessage) if (output.error) { output.error += `\nSystem error:\n${errorMessage}` diff --git a/src/renderer/src/workers/shiki-stream.worker.ts b/src/renderer/src/workers/shiki-stream.worker.ts index 05e40fdd64..2931e2d2f3 100644 --- a/src/renderer/src/workers/shiki-stream.worker.ts +++ b/src/renderer/src/workers/shiki-stream.worker.ts @@ -1,11 +1,14 @@ /// +import { loggerService } from '@logger' import { LRUCache } from 'lru-cache' import type { HighlighterCore, SpecialLanguage, ThemedToken } from 'shiki/core' // 注意保持 ShikiStreamTokenizer 依赖简单,避免打包出问题 import { ShikiStreamTokenizer, ShikiStreamTokenizerOptions } from '../services/ShikiStreamTokenizer' +const logger = loggerService.withContext('ShikiStreamWorker') + // Worker 消息类型 type WorkerMessageType = 'init' | 'highlight' | 'cleanup' | 'dispose' @@ -93,7 +96,7 @@ async function ensureLanguageAndThemeLoaded( await highlighter.loadTheme(themeData) } catch (error) { // 回退到 one-light - console.debug(`Worker: Failed to load theme '${theme}', falling back to 'one-light':`, error) + logger.debug(`Worker: Failed to load theme '${theme}', falling back to 'one-light':`, error) const { bundledThemes } = await import('shiki') const oneLightTheme = await bundledThemes['one-light']() await highlighter.loadTheme(oneLightTheme) @@ -154,7 +157,7 @@ async function highlightCodeChunk( recall: result.recall } } catch (error) { - console.error('Worker failed to highlight code chunk:', error) + logger.error('Worker failed to highlight code chunk:', error) // 提供简单的 fallback const fallbackToken: ThemedToken = { content: chunk || '', color: '#000000', offset: 0 }