1- import url from './url'
21import path = require( 'path' )
3- import { app } from 'electron'
42import fs = require( 'fs-extra' )
5- export import log = require ( 'electron-log' )
3+
4+ type ElectronAppLike = {
5+ isPackaged ?: boolean
6+ getVersion ?: ( ) => string
7+ getPath ?: ( name : string ) => string
8+ }
9+
10+ type LogTransportFileLike = {
11+ level ?: string
12+ format ?: string
13+ maxSize ?: number
14+ resolvePathFn ?: ( ) => string
15+ }
16+
17+ type LoggerLike = {
18+ debug : ( ...args : unknown [ ] ) => void
19+ info : ( ...args : unknown [ ] ) => void
20+ warn : ( ...args : unknown [ ] ) => void
21+ error : ( ...args : unknown [ ] ) => void
22+ transports : {
23+ file : LogTransportFileLike
24+ }
25+ }
26+
27+ const safeRequire = ( id : string ) : unknown => {
28+ try {
29+ const dynamicRequire = Function ( 'return require' ) ( ) as NodeRequire
30+ return dynamicRequire ( id )
31+ } catch {
32+ return null
33+ }
34+ }
35+
36+ const electronModule =
37+ ( safeRequire ( 'electron' ) as {
38+ app ?: ElectronAppLike
39+ } | null ) || null
40+ const electronApp = electronModule ?. app || null
41+
42+ const createConsoleLogger = ( ) : LoggerLike => ( {
43+ debug : ( ...args : unknown [ ] ) => console . debug ( ...args ) ,
44+ info : ( ...args : unknown [ ] ) => console . info ( ...args ) ,
45+ warn : ( ...args : unknown [ ] ) => console . warn ( ...args ) ,
46+ error : ( ...args : unknown [ ] ) => console . error ( ...args ) ,
47+ transports : {
48+ file : { }
49+ }
50+ } )
51+
52+ const loadedElectronLog =
53+ ( safeRequire ( 'electron-log' ) as Partial < LoggerLike > | null | undefined ) || null
54+
55+ export const log : LoggerLike =
56+ loadedElectronLog &&
57+ typeof loadedElectronLog . debug === 'function' &&
58+ typeof loadedElectronLog . info === 'function' &&
59+ typeof loadedElectronLog . warn === 'function' &&
60+ typeof loadedElectronLog . error === 'function'
61+ ? ( {
62+ ...loadedElectronLog ,
63+ transports : {
64+ file : loadedElectronLog . transports ?. file || { }
65+ }
66+ } as LoggerLike )
67+ : createConsoleLogger ( )
668
769const isPackagedRuntime = ( ( ) => {
870 try {
9- return ! ! ( app && typeof app . isPackaged === 'boolean' && app . isPackaged )
71+ return ! ! ( electronApp && typeof electronApp . isPackaged === 'boolean' && electronApp . isPackaged )
1072 } catch {
1173 return false
1274 }
@@ -18,35 +80,40 @@ const isDevRuntime = (() => {
1880 return ! isPackagedRuntime
1981} ) ( )
2082
21- log . transports . file . level = 'debug' // 设置日志级别
83+ const resolveUserDataDir = ( ) => {
84+ if ( ! isPackagedRuntime ) return __dirname
85+ try {
86+ const resolved = electronApp ?. getPath ?.( 'userData' )
87+ return typeof resolved === 'string' && resolved . trim ( ) ? resolved : __dirname
88+ } catch {
89+ return __dirname
90+ }
91+ }
92+
2293const appVersion = ( ( ) => {
2394 try {
24- return app . getVersion ( )
25- } catch ( _e ) {
95+ const resolved = electronApp ?. getVersion ?.( )
96+ return typeof resolved === 'string' && resolved . trim ( ) ? resolved : 'unknown'
97+ } catch {
2698 return 'unknown'
2799 }
28100} ) ( )
29- log . transports . file . format = `{y}-{m}-{d} {h}:{i}:{s}.{ms} [v${ appVersion } ] {text}` // 自定义日志格式,带版本号
30- log . transports . file . maxSize = 20 * 1024 * 1024 // 提高上限,避免长时间追踪时日志过快轮转
31101
32- // dev 模式下日志保存在项目根目录,生产模式下保存在用户数据目录
102+ log . transports . file . level = 'debug'
103+ log . transports . file . format = `{y}-{m}-{d} {h}:{i}:{s}.{ms} [v${ appVersion } ] {text}`
104+ log . transports . file . maxSize = 20 * 1024 * 1024
33105log . transports . file . resolvePathFn = ( ) => {
34106 if ( isDevRuntime ) {
35- // dev 模式:保存到项目根目录
36107 return path . join ( process . cwd ( ) , 'log.txt' )
37- } else {
38- // 生产模式:保存到用户数据目录
39- return path . join ( url . userDataDir , 'log.txt' )
40108 }
109+ return path . join ( resolveUserDataDir ( ) , 'log.txt' )
41110}
42111
43- // 导出获取日志路径的函数,供其他模块使用
44112export function getLogPath ( ) : string {
45113 if ( isDevRuntime ) {
46114 return path . join ( process . cwd ( ) , 'log.txt' )
47- } else {
48- return path . join ( url . userDataDir , 'log.txt' )
49115 }
116+ return path . join ( resolveUserDataDir ( ) , 'log.txt' )
50117}
51118
52119export function clearLogFileSync ( ) : void {
@@ -68,7 +135,6 @@ type ErrorLike = {
68135 message ?: unknown
69136}
70137
71- // 预期内错误规则集中定义,后续可在此追加
72138const expectedErrorRules : ExpectedErrorRule [ ] = [
73139 { code : 'ENOSPC' } ,
74140 { messageIncludes : / n o s p a c e l e f t o n d e v i c e / i }
@@ -84,10 +150,11 @@ export function isExpectedError(error: unknown): boolean {
84150 if ( rule . messageIncludes && rule . messageIncludes . test ( message ) ) return true
85151 }
86152 return false
87- } catch ( _e ) {
153+ } catch {
88154 return false
89155 }
90156}
157+
91158process . on ( 'uncaughtException' , ( error ) => {
92159 if ( isExpectedError ( error ) ) return
93160 log . error ( error )
0 commit comments