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