flogger-log
Advanced tools
Comparing version 1.0.4 to 1.1.0
@@ -13,2 +13,6 @@ 'use strict'; | ||
var _path = require('path'); | ||
var _path2 = _interopRequireDefault(_path); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -18,2 +22,62 @@ | ||
var MAX_ARCHIVES = 10000; | ||
function getArchiveName(filePath, archiveNamesSorting) { | ||
var dir = _path2.default.dirname(filePath); | ||
var ext = _path2.default.extname(filePath); | ||
var name = _path2.default.basename(filePath, ext); | ||
// Checks if last archive name was used | ||
var lastArchiveNameAvail = false; | ||
var lastArchive = _path2.default.resolve(dir, name + '_' + MAX_ARCHIVES + ext); | ||
try { | ||
_fs2.default.openSync(lastArchive, 'r'); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
// Last archive file name is available | ||
lastArchiveNameAvail = true; | ||
} else { | ||
throw err; | ||
} | ||
} | ||
if (!lastArchiveNameAvail) throw new Error('No usable archive file name found. Please consider removing older logs.'); | ||
// Descending order (newer archives gets higher suffix number) | ||
if (archiveNamesSorting === 'descending') { | ||
for (var i = 1; i <= MAX_ARCHIVES; i += 1) { | ||
var candidate = _path2.default.resolve(dir, name + '_' + i + ext); | ||
try { | ||
_fs2.default.openSync(candidate, 'r'); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
// Available archive file name found | ||
return candidate; | ||
} | ||
throw err; | ||
} | ||
} | ||
throw new Error('No usable archive file name found. Please consider removing older logs.'); | ||
} else { | ||
// AscendingOrder order (newer archives get lower suffix number) | ||
// Rename all archives | ||
for (var _i = MAX_ARCHIVES - 1; _i >= 1; _i -= 1) { | ||
var oldName = _path2.default.resolve(dir, name + '_' + _i + ext); | ||
var newName = _path2.default.resolve(dir, name + '_' + (_i + 1) + ext); | ||
// Renames file if exists | ||
try { | ||
_fs2.default.renameSync(oldName, newName); | ||
} catch (err) { | ||
if (err.code !== 'ENOENT') { | ||
// Unexpected error | ||
throw err; | ||
} | ||
} | ||
} | ||
// Return new archive name | ||
return _path2.default.resolve(dir, name + '_' + 1 + ext); | ||
} | ||
} | ||
var FileRenderer = function () { | ||
@@ -23,6 +87,40 @@ function FileRenderer(options) { | ||
this.path = null; | ||
this.fileSizeLimit = 0; | ||
this.fileSizeOverflowPolicy = 'archive'; | ||
if (options) { | ||
// File path | ||
if (options.path) { | ||
this.file = options.path; | ||
if (typeof options.path !== 'string') throw new Error('options.path must be a string'); | ||
this.path = options.path; | ||
} | ||
// File size limit | ||
if (options.fileSizeLimit) { | ||
if (!Number.isInteger(options.fileSizeLimit) || options.fileSizeLimit < 0) { | ||
throw new Error('options.fileSizeLimit must be a integer >= 0'); | ||
} | ||
this.fileSizeLimit = options.fileSizeLimit; | ||
} | ||
// File size overflow policy | ||
if (options.fileSizeOverflowPolicy) { | ||
if (typeof options.fileSizeOverflowPolicy !== 'string') throw new Error('options.fileSizeOverflowPolicy must be a string'); | ||
if (options.fileSizeOverflowPolicy === 'archive' || options.fileSizeOverflowPolicy === 'overwrite') { | ||
this.fileSizeOverflowPolicy = options.fileSizeOverflowPolicy; | ||
} else { | ||
throw new Error('"' + options.fileSizeOverflowPolicy + '" is not a legal options.fileSizeOverflowPolicy value'); | ||
} | ||
} | ||
// Archive names sorting | ||
if (options.archiveNamesSorting) { | ||
if (typeof options.archiveNamesSorting !== 'string') throw new Error('options.archiveNamesSorting must be a string'); | ||
if (options.archiveNamesSorting === 'ascending' || options.archiveNamesSorting === 'descending') { | ||
this.archiveNamesSorting = options.archiveNamesSorting; | ||
} else { | ||
throw new Error('"' + options.archiveNamesSorting + '" is not a legal options.archiveNamesSorting value'); | ||
} | ||
} | ||
} | ||
@@ -34,8 +132,49 @@ } | ||
value: function render(level, origin, message) { | ||
var timeDate = new Date().toUTCString(); | ||
var log = timeDate + ' - [' + level + '] ' + origin + ':\n' + message + '\n\n'; | ||
try { | ||
_fs2.default.appendFileSync(this.file, log); | ||
} catch (err) { | ||
console.error(err); | ||
var append = true; | ||
if (this.path) { | ||
var filePath = this.path; | ||
// If a file size limit is set | ||
if (this.fileSizeLimit > 0) { | ||
var fileSizeInBytes = 0; | ||
try { | ||
var stats = _fs2.default.statSync(filePath); | ||
fileSizeInBytes = stats.size; | ||
} catch (err) {} | ||
// ok, file does not exists | ||
// Checks if log file is too big | ||
if (fileSizeInBytes > this.fileSizeLimit) { | ||
if (this.fileSizeOverflowPolicy === 'archive') { | ||
try { | ||
// Rename log file to archive it | ||
var archiveName = getArchiveName(filePath, this.archiveNamesSorting); | ||
_fs2.default.renameSync(filePath, archiveName); | ||
} catch (err) { | ||
console.error(err); | ||
filePath = null; | ||
} | ||
} else { | ||
// Overwriting file | ||
append = false; | ||
} | ||
} | ||
} | ||
// Write or append the log entry to file | ||
if (filePath) { | ||
var timeDate = new Date().toUTCString(); | ||
var log = timeDate + ' - [' + level + '] ' + origin + ':\n' + message + '\n\n'; | ||
try { | ||
if (append) { | ||
_fs2.default.appendFileSync(filePath, log); | ||
} else { | ||
_fs2.default.writeFileSync(filePath, log); | ||
} | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
} | ||
@@ -42,0 +181,0 @@ } |
@@ -91,14 +91,2 @@ 'use strict'; | ||
} | ||
/* | ||
setLevel(level) { | ||
if (!Number.isInteger(level) || level < 0 || level > Object.keys(this.levels).length) { | ||
throw new Error(`${level} is not a valid log level`); | ||
} | ||
this.level = level; | ||
} | ||
*/ | ||
// setLevelName(name) { | ||
}, { | ||
@@ -114,11 +102,2 @@ key: 'setLevel', | ||
} | ||
/* | ||
getLevel() { | ||
return this.level; | ||
} | ||
*/ | ||
// getLevelName() { | ||
}, { | ||
@@ -125,0 +104,0 @@ key: 'getLevel', |
{ | ||
"name": "flogger-log", | ||
"version": "1.0.4", | ||
"version": "1.1.0", | ||
"description": "A ready to use - zero conf - logger", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"build": "eslint --fix src/**/*.js && rimraf lib && babel src -d lib" | ||
"prebuild": "eslint --fix src/**/*.js", | ||
"build": "rimraf lib && babel src -d lib", | ||
"postbuild": "npm run test", | ||
"test": "node ./test/flogger-test.js | tap-spec" | ||
}, | ||
@@ -32,3 +35,7 @@ "repository": { | ||
"eslint-plugin-import": "^2.8.0", | ||
"rimraf": "^2.6.2" | ||
"rimraf": "^2.6.2", | ||
"shelljs": "^0.8.1", | ||
"tap-spec": "^4.1.1", | ||
"tape": "^4.9.0", | ||
"tmp": "0.0.33" | ||
}, | ||
@@ -35,0 +42,0 @@ "dependencies": { |
@@ -8,5 +8,7 @@ # Flogger | ||
### *New in 1.1.0:* | ||
Support for archiving log files when their size gets over a threshold was added to [FileRenderer](#FileRenderer). | ||
### Basic usage | ||
```javascript | ||
@@ -85,2 +87,51 @@ import Flogger from 'flogger-log'; | ||
## <a name="FileRenderer"></a>File renderer | ||
The FileRenderer is a renderer for writing classic log files and it is shipped with this package. | ||
```javascript | ||
import { Flogger, FileRenderer } from 'flogger-log'; | ||
const flog = new Flogger({ | ||
renderer: new FileRenderer(options) | ||
}); | ||
``` | ||
The file renderer constructor accepts this options argument: | ||
```javascript | ||
{ | ||
path, | ||
fileSizeLimit, | ||
fileSizeOverflowPolicy, | ||
archiveNamesSorting, | ||
} | ||
``` | ||
### path: `String` | ||
The log file path. | ||
### fileSizeLimit: `Integer >= 0, default: 0` | ||
The file size threshold limit in bytes. | ||
When a log file size gets over this limit, on the next log function | ||
call the policy associated to the `fileSizeOverflowPolicy` option will | ||
be applied. | ||
Set to 0 for "no limit". | ||
### fileSizeOverflowPolicy: `'archive' or 'overwrite', default: 'archive'` | ||
Policy to be applied when the log file gets over the value of | ||
fileSizeLimit option. | ||
Set to `overwrite` for writing over the existing log file. | ||
Set to `archive` to make archive copies of the log file. | ||
When `archive` is used, the archived filename will be: | ||
`<log_filename_without_extension>_<suffix>.<log_filename_extension>` | ||
Where `suffix` is an integer between 1 and 10000. | ||
By default newer archive files gets higher suffix number (descending order). You can change this behaviour with the `archiveNamesSorting` option. | ||
### archiveNamesSorting: `'descending' or 'ascending', default: 'descending'` | ||
The archiveNamesSorting change the way suffixes are assigned to archive file names. | ||
Set to `descending` to assign higher suffix numbers to newer archive files. | ||
Set to `ascending` to assign lower suffix numbers to newer archive files. | ||
## License | ||
@@ -87,0 +138,0 @@ |
51920
277
159
10