1
- import {
2
- HandlerOptions ,
3
- handlers ,
4
- LevelName ,
5
- Logger ,
6
- LogMode ,
7
- LogRecord ,
8
- } from "std/log/mod.ts" ;
1
+ import { handlers , LevelName , Logger , LogRecord } from "std/log/mod.ts" ;
9
2
import { format } from "std/datetime/mod.ts" ;
10
3
import { join } from "std/path/mod.ts" ;
11
4
import dirs from "dirs/mod.ts" ;
12
5
import { isTesting , mbToBytes } from "./_utils.ts" ;
13
6
import { ErgomaticError } from "./error.ts" ;
14
- import { existsSync } from "std/fs/exists.ts" ;
15
- import { BufWriterSync } from "std/io/buf_writer.ts" ;
16
7
17
8
function formatter ( { loggerName, levelName, msg } : LogRecord ) {
18
9
const datetime = format ( new Date ( ) , "yyyy-MM-dd HH:mm:ss" ) ;
@@ -36,107 +27,11 @@ function logsDir() {
36
27
return ensureDir ( join ( dataDir , "ergomatic" ) ) ;
37
28
}
38
29
39
- interface RotatingFileHandlerOptions extends HandlerOptions {
40
- filename : string ;
41
- mode ?: LogMode ;
42
- maxBytes : number ;
43
- maxBackupCount : number ;
44
- }
45
-
46
- /**
47
- * `RotatingFileHandler` provided by deno has async `setup()` method
48
- * which appears to be a bug: https://github.com/denoland/deno_std/issues/3538#issuecomment-1676942783
49
- * If this is addressed in deno maybe one day we can remove this class.
50
- *
51
- * Create a sync version of `RotatingFileHandler` and use that instead.
52
- * This is basically just `RotatingFileHandler` but using `Deno.*Sync` methods instead.
53
- */
54
- class SyncRotatingFileHandler extends handlers . FileHandler {
55
- #maxBytes: number ;
56
- #maxBackupCount: number ;
57
- #currentFileSize = 0 ;
58
-
59
- constructor ( levelName : LevelName , options : RotatingFileHandlerOptions ) {
60
- super ( levelName , options ) ;
61
- this . #maxBytes = options . maxBytes ;
62
- this . #maxBackupCount = options . maxBackupCount ;
63
- }
64
-
65
- override setup ( ) {
66
- if ( this . #maxBytes < 1 ) {
67
- this . destroy ( ) ;
68
- throw new Error ( "maxBytes cannot be less than 1" ) ;
69
- }
70
- if ( this . #maxBackupCount < 1 ) {
71
- this . destroy ( ) ;
72
- throw new Error ( "maxBackupCount cannot be less than 1" ) ;
73
- }
74
- super . setup ( ) ;
75
-
76
- if ( this . _mode === "w" ) {
77
- // Remove old backups too as it doesn't make sense to start with a clean
78
- // log file, but old backups
79
- for ( let i = 1 ; i <= this . #maxBackupCount; i ++ ) {
80
- try {
81
- Deno . removeSync ( this . _filename + "." + i ) ;
82
- } catch ( error ) {
83
- if ( ! ( error instanceof Deno . errors . NotFound ) ) {
84
- throw error ;
85
- }
86
- }
87
- }
88
- } else if ( this . _mode === "x" ) {
89
- // Throw if any backups also exist
90
- for ( let i = 1 ; i <= this . #maxBackupCount; i ++ ) {
91
- if ( existsSync ( this . _filename + "." + i ) ) {
92
- this . destroy ( ) ;
93
- throw new Deno . errors . AlreadyExists (
94
- "Backup log file " + this . _filename + "." + i + " already exists" ,
95
- ) ;
96
- }
97
- }
98
- } else {
99
- this . #currentFileSize = Deno . statSync ( this . _filename ) . size ;
100
- }
101
- }
102
-
103
- override log ( msg : string ) {
104
- const msgByteLength = this . _encoder . encode ( msg ) . byteLength + 1 ;
105
-
106
- if ( this . #currentFileSize + msgByteLength > this . #maxBytes) {
107
- this . rotateLogFiles ( ) ;
108
- this . #currentFileSize = 0 ;
109
- }
110
-
111
- super . log ( msg ) ;
112
-
113
- this . #currentFileSize += msgByteLength ;
114
- }
115
-
116
- rotateLogFiles ( ) {
117
- this . _buf . flush ( ) ;
118
- this . _file ! . close ( ) ;
119
-
120
- for ( let i = this . #maxBackupCount - 1 ; i >= 0 ; i -- ) {
121
- const source = this . _filename + ( i === 0 ? "" : "." + i ) ;
122
- const dest = this . _filename + "." + ( i + 1 ) ;
123
-
124
- if ( existsSync ( source ) ) {
125
- Deno . renameSync ( source , dest ) ;
126
- }
127
- }
128
-
129
- this . _file = Deno . openSync ( this . _filename , this . _openOptions ) ;
130
- this . _writer = this . _file ;
131
- this . _buf = new BufWriterSync ( this . _file ) ;
132
- }
133
- }
134
-
135
30
export function createLogger ( name : string , level : LevelName ) {
136
31
const logHandlers = [ ] ;
137
32
138
33
if ( ! isTesting ( ) ) {
139
- const fileHandler = new SyncRotatingFileHandler ( level , {
34
+ const fileHandler = new handlers . RotatingFileHandler ( level , {
140
35
formatter,
141
36
filename : join ( logsDir ( ) , "ergomatic.log" ) ,
142
37
maxBackupCount : 3 ,
0 commit comments