refactor(logger): optimize logging architecture with 6 improvements

1. Extract shared module: consolidate getLogDir() and isProduction()
   into shared.ts, eliminate duplication across logger modules
2. Make retention config effective: delay file transport creation
   until config is loaded, apply appRetention/auditRetention from config.yaml
3. Add before-quit log flush: close logger and audit logger on
   app exit to prevent log loss
4. Unify logError entry point: remove duplicate logError from index.ts,
   re-export from error-utils.ts with richer error context
5. Renderer log level filtering: add client-side level check in preload
   to skip IPC for filtered-out messages
6. Child logger cache + audit cleanup: cache child loggers in IPC
   handler for performance, remove redundant timestamp format in audit logger

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-04-03 20:53:53 +08:00
parent 020bbcdccc
commit 883f98065a
22 changed files with 300 additions and 176 deletions

View File

@@ -221,9 +221,7 @@ export const ExtractorOperationHistoryModal: React.FC<ExtractorOperationHistoryM
const toggleUserFilter = (username: string) => {
setSelectedUsers((prev) =>
prev.includes(username)
? prev.filter((u) => u !== username)
: [...prev, username]
prev.includes(username) ? prev.filter((u) => u !== username) : [...prev, username]
)
}
@@ -274,7 +272,10 @@ export const ExtractorOperationHistoryModal: React.FC<ExtractorOperationHistoryM
<span className="text-sm text-gray-600">
{isAdmin ? (
<span className="text-amber-600 font-medium">
{selectedUsers.length > 0 ? `已选择 ${selectedUsers.length} 个用户` : '显示所有用户记录'}
{selectedUsers.length > 0
? `已选择 ${selectedUsers.length} 个用户`
: '显示所有用户记录'}
</span>
) : (
<span></span>

View File

@@ -47,7 +47,10 @@ export const ComparisonTooltip = React.memo(
{user || '未分配'}:
</span>
<span className="font-medium text-slate-900">
{firstMetric === 'executionTimeSecs' ? Number(userEntry.value).toFixed(1) : userEntry.value} {firstMetric === 'executionTimeSecs' ? '秒' : ''}
{firstMetric === 'executionTimeSecs'
? Number(userEntry.value).toFixed(1)
: userEntry.value}{' '}
{firstMetric === 'executionTimeSecs' ? '秒' : ''}
</span>
</div>
)

View File

@@ -40,7 +40,10 @@ export const CustomTooltip = React.memo(
{entry.name}:
</span>
<span className="font-medium text-slate-900">
{entry.dataKey === 'executionTimeSecs' ? Number(entry.value).toFixed(1) : entry.value} {entry.dataKey === 'executionTimeSecs' ? '秒' : ''}
{entry.dataKey === 'executionTimeSecs'
? Number(entry.value).toFixed(1)
: entry.value}{' '}
{entry.dataKey === 'executionTimeSecs' ? '秒' : ''}
</span>
</div>
))}

View File

@@ -68,6 +68,10 @@ export function useAppBootstrap() {
const initializeAuth = useCallback(async () => {
logger.info('=== Starting initializeAuth ===')
// Fetch log level early so client-side filtering takes effect
await window.electron.logger.fetchLevel()
try {
logger.debug('Getting computer name...')
const computerNameResult = await window.electron.auth.getComputerName()