source: trip-planner-front/node_modules/log4js/lib/appenders/fileSync.js@ 6a80231

Last change on this file since 6a80231 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[6a3a178]1const debug = require('debug')('log4js:fileSync');
2const path = require('path');
3const fs = require('fs');
4const os = require('os');
5
6const eol = os.EOL || '\n';
7
8function touchFile(file, options) {
9 // if the file exists, nothing to do
10 if (fs.existsSync(file)) {
11 return;
12 }
13
14 // touch the file to apply flags (like w to truncate the file)
15 const id = fs.openSync(file, options.flags, options.mode);
16 fs.closeSync(id);
17}
18
19class RollingFileSync {
20 constructor(filename, size, backups, options) {
21 debug('In RollingFileStream');
22
23 function throwErrorIfArgumentsAreNotValid() {
24 if (!filename || !size || size <= 0) {
25 throw new Error('You must specify a filename and file size');
26 }
27 }
28
29 throwErrorIfArgumentsAreNotValid();
30
31 this.filename = filename;
32 this.size = size;
33 this.backups = backups || 1;
34 this.options = options;
35 this.currentSize = 0;
36
37 function currentFileSize(file) {
38 let fileSize = 0;
39
40 try {
41 fileSize = fs.statSync(file).size;
42 } catch (e) {
43 // file does not exist
44 touchFile(file, options);
45 }
46 return fileSize;
47 }
48
49 this.currentSize = currentFileSize(this.filename);
50 }
51
52 shouldRoll() {
53 debug('should roll with current size %d, and max size %d', this.currentSize, this.size);
54 return this.currentSize >= this.size;
55 }
56
57 roll(filename) {
58 const that = this;
59 const nameMatcher = new RegExp(`^${path.basename(filename)}`);
60
61 function justTheseFiles(item) {
62 return nameMatcher.test(item);
63 }
64
65 function index(filename_) {
66 return parseInt(filename_.substring((`${path.basename(filename)}.`).length), 10) || 0;
67 }
68
69 function byIndex(a, b) {
70 if (index(a) > index(b)) {
71 return 1;
72 }
73 if (index(a) < index(b)) {
74 return -1;
75 }
76
77 return 0;
78 }
79
80 function increaseFileIndex(fileToRename) {
81 const idx = index(fileToRename);
82 debug(`Index of ${fileToRename} is ${idx}`);
83 if (idx < that.backups) {
84 // on windows, you can get a EEXIST error if you rename a file to an existing file
85 // so, we'll try to delete the file we're renaming to first
86 try {
87 fs.unlinkSync(`${filename}.${idx + 1}`);
88 } catch (e) {
89 // ignore err: if we could not delete, it's most likely that it doesn't exist
90 }
91
92 debug(`Renaming ${fileToRename} -> ${filename}.${idx + 1}`);
93 fs.renameSync(path.join(path.dirname(filename), fileToRename), `${filename}.${idx + 1}`);
94 }
95 }
96
97 function renameTheFiles() {
98 // roll the backups (rename file.n to file.n+1, where n <= numBackups)
99 debug('Renaming the old files');
100
101 const files = fs.readdirSync(path.dirname(filename));
102 files.filter(justTheseFiles).sort(byIndex).reverse().forEach(increaseFileIndex);
103 }
104
105 debug('Rolling, rolling, rolling');
106 renameTheFiles();
107 }
108
109 /* eslint no-unused-vars:0 */
110 write(chunk, encoding) {
111 const that = this;
112
113
114 function writeTheChunk() {
115 debug('writing the chunk to the file');
116 that.currentSize += chunk.length;
117 fs.appendFileSync(that.filename, chunk);
118 }
119
120 debug('in write');
121
122
123 if (this.shouldRoll()) {
124 this.currentSize = 0;
125 this.roll(this.filename);
126 }
127
128 writeTheChunk();
129 }
130}
131
132/**
133 * File Appender writing the logs to a text file. Supports rolling of logs by size.
134 *
135 * @param file file log messages will be written to
136 * @param layout a function that takes a logevent and returns a string
137 * (defaults to basicLayout).
138 * @param logSize - the maximum size (in bytes) for a log file,
139 * if not provided then logs won't be rotated.
140 * @param numBackups - the number of log files to keep after logSize
141 * has been reached (default 5)
142 * @param timezoneOffset - optional timezone offset in minutes
143 * (default system local)
144 * @param options - passed as is to fs options
145 */
146function fileAppender(file, layout, logSize, numBackups, timezoneOffset, options) {
147 debug('fileSync appender created');
148 file = path.normalize(file);
149 numBackups = numBackups === undefined ? 5 : numBackups;
150 // there has to be at least one backup if logSize has been specified
151 numBackups = numBackups === 0 ? 1 : numBackups;
152
153 function openTheStream(filePath, fileSize, numFiles) {
154 let stream;
155
156 if (fileSize) {
157 stream = new RollingFileSync(
158 filePath,
159 fileSize,
160 numFiles,
161 options
162 );
163 } else {
164 stream = (((f) => {
165 // touch the file to apply flags (like w to truncate the file)
166 touchFile(f, options);
167
168 return {
169 write(data) {
170 fs.appendFileSync(f, data);
171 }
172 };
173 }))(filePath);
174 }
175
176 return stream;
177 }
178
179 const logFile = openTheStream(file, logSize, numBackups);
180
181 return (loggingEvent) => {
182 logFile.write(layout(loggingEvent, timezoneOffset) + eol);
183 };
184}
185
186function configure(config, layouts) {
187 let layout = layouts.basicLayout;
188 if (config.layout) {
189 layout = layouts.layout(config.layout.type, config.layout);
190 }
191
192 const options = {
193 flags: config.flags || 'a',
194 encoding: config.encoding || 'utf8',
195 mode: config.mode || 0o644
196 };
197
198 return fileAppender(
199 config.filename,
200 layout,
201 config.maxLogSize,
202 config.backups,
203 config.timezoneOffset,
204 options
205 );
206}
207
208module.exports.configure = configure;
Note: See TracBrowser for help on using the repository browser.