Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@boost/log

Package Overview
Dependencies
Maintainers
1
Versions
55
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@boost/log - npm Package Compare versions

Comparing version 2.2.4 to 2.2.5

lib/constants.js

12

CHANGELOG.md

@@ -6,2 +6,14 @@ # Change Log

### 2.2.5 - 2021-03-26
#### 📦 Dependencies
- **[packemon]** Update to v0.14. (#145) ([9897e2a](https://github.com/milesj/boost/commit/9897e2a)), closes [#145](https://github.com/milesj/boost/issues/145)
**Note:** Version bump only for package @boost/log
### 2.2.4 - 2021-02-21

@@ -8,0 +20,0 @@

600

lib/index.js

@@ -9,597 +9,31 @@ // Generated with Packemon: https://packemon.dev

var common = require('@boost/common');
var createLogger = require('./createLogger.js');
var chalk = require('chalk');
var formats = require('./formats.js');
var path = require('path');
var Logger = require('./Logger.js');
var translate = require('@boost/translate');
var Transport = require('./Transport.js');
var os = require('os');
var ConsoleTransport = require('./transports/ConsoleTransport.js');
var util = require('util');
var FileTransport = require('./transports/FileTransport.js');
var internal = require('@boost/internal');
var RotatingFileTransport = require('./transports/RotatingFileTransport.js');
var fs = require('fs');
var StreamTransport = require('./transports/StreamTransport.js');
var zlib = require('zlib');
var constants = require('./constants.js');
function _interopDefaultLegacy(e) {
return e && typeof e === 'object' && 'default' in e ? e : {
'default': e
};
}
var chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk);
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
var util__default = /*#__PURE__*/_interopDefaultLegacy(util);
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
var msg = translate.createTranslator('log', path__default['default'].join(__dirname, '../res')); // In order of priority!
const LOG_LEVELS = ['log', 'trace', 'debug', 'info', 'warn', 'error'];
const DEFAULT_LABELS = {
debug: chalk__default['default'].gray(msg('log:levelDebug')),
error: chalk__default['default'].red(msg('log:levelError')),
info: chalk__default['default'].cyan(msg('log:levelInfo')),
log: chalk__default['default'].yellow(msg('log:levelLog')),
trace: chalk__default['default'].magenta(msg('log:levelTrace')),
warn: chalk__default['default'].yellow(msg('log:levelWarn'))
};
const MAX_LOG_SIZE = 10485760;
var debug = internal.createInternalDebugger('log');
function formatMetadata(metadata) {
const items = [];
const keys = Object.keys(metadata).sort();
keys.forEach(key => {
items.push(`${key}=${metadata[key]}`);
});
return `(${items.join(', ')})`;
}
function console$1(item) {
let output = item.message;
if (item.level !== 'log') {
output = `${item.label} ${output}`;
}
return output;
}
function debug$1(item) {
return `[${item.time.toISOString()}] ${item.level.toUpperCase()} ${item.message} ${formatMetadata({ ...item.metadata,
host: item.host,
name: item.name,
pid: item.pid
})}`;
}
function json(item) {
return JSON.stringify(item);
}
function message(item) {
return item.message;
}
var formats = /*#__PURE__*/Object.freeze({
__proto__: null,
console: console$1,
debug: debug$1,
json: json,
message: message
});
class Transport extends common.Contract {
constructor(options) {
super(options);
this.levels = [];
this.levels = this.options.levels;
}
blueprint({
array,
func,
string
}) {
return {
eol: string(os__default['default'].EOL),
format: func().nullable(),
levels: array(string().oneOf(LOG_LEVELS))
};
}
/**
* Format the log item into a message string, and append a trailing newline if missing.
*/
format(item) {
const {
eol,
format
} = this.options;
let output = typeof format === 'function' ? format(item) : debug$1(item);
if (!output.endsWith(eol)) {
output += eol;
}
return output;
}
/**
* Write the formatted message according to the transport.
*/
}
class ConsoleTransport extends Transport {
constructor(options) {
super({
format: console$1,
levels: LOG_LEVELS,
...options
});
}
write(message, {
level
}) {
// eslint-disable-next-line no-console
console[level](message.trim());
}
}
class Logger extends common.Contract {
constructor(options) {
super(options);
this.silent = false;
const defaultLevel = internal.env('LOG_DEFAULT_LEVEL');
const maxLevel = internal.env('LOG_MAX_LEVEL');
debug('New logger "%s" created: %s %s', this.options.name, defaultLevel ? `${defaultLevel} level` : 'all levels', maxLevel ? `(max ${maxLevel})` : '');
}
blueprint({
array,
func,
instance,
object,
shape,
string
}) {
return {
labels: object(string()),
metadata: object(),
name: string().required().notEmpty(),
transports: array(instance(Transport).notNullable(), [new ConsoleTransport()])
};
}
disable() {
debug('Logger %s disabled', this.options.name);
this.silent = true;
}
enable() {
debug('Logger %s enabled', this.options.name);
this.silent = false;
}
isAllowed(level, maxLevel) {
if (!maxLevel) {
return true;
} // eslint-disable-next-line no-restricted-syntax
for (const currentLevel of LOG_LEVELS) {
if (currentLevel === level) {
return true;
}
if (currentLevel === maxLevel) {
break;
}
}
return false;
}
log({
args = [],
level,
message,
metadata = {}
}) {
const logLevel = level || internal.env('LOG_DEFAULT_LEVEL') || 'log';
if (this.silent || !this.isAllowed(logLevel, internal.env('LOG_MAX_LEVEL'))) {
return;
}
const item = {
host: os__default['default'].hostname(),
label: this.options.labels[logLevel] || DEFAULT_LABELS[logLevel] || '',
level: logLevel,
message: util__default['default'].format(message, ...args),
metadata: { ...this.options.metadata,
...metadata
},
name: this.options.name,
pid: process.pid,
time: new Date()
};
this.options.transports.forEach(transport => {
if (transport.levels.includes(item.level)) {
void transport.write(transport.format(item), item);
}
});
}
}
function pipeLog(logger, level) {
return (...args) => {
let metadata = {};
let message = '';
if (common.isObject(args[0])) {
metadata = args.shift();
}
message = args.shift();
logger.log({
args,
level,
message,
metadata
});
};
}
function createLogger(options) {
const logger = new Logger(options);
const log = pipeLog(logger);
LOG_LEVELS.forEach(level => {
Object.defineProperty(log, level, {
value: pipeLog(logger, level)
});
});
Object.defineProperty(log, 'disable', {
value: () => {
logger.disable();
}
});
Object.defineProperty(log, 'enable', {
value: () => {
logger.enable();
}
});
return log;
}
class FileTransport extends Transport {
constructor(options) {
super(options);
this.path = void 0;
this.stream = void 0;
this.buffer = '';
this.draining = false;
this.lastSize = 0;
this.rotating = false;
this.path = common.Path.resolve(this.options.path);
this.checkFolderRequirements();
}
blueprint(preds) {
const {
bool,
instance,
union,
number,
string
} = preds;
return { ...super.blueprint(preds),
gzip: bool(),
maxSize: number(MAX_LOG_SIZE).positive(),
path: union([string(), instance(common.Path)], '').required()
};
}
/**
* Close the file stream and trigger the callback when finished.
*/
close(cb) {
const onClose = () => {
if (cb) {
cb();
}
this.stream = undefined;
};
if (this.stream) {
this.stream.once('finish', onClose).end();
} else {
onClose();
}
}
/**
* Open the file stream for writing.
*/
open() {
if (this.stream) {
return this.stream;
}
this.stream = this.createStream();
if (this.path.exists()) {
this.lastSize = fs__default['default'].statSync(this.path.path()).size;
}
if (this.buffer) {
const message = this.buffer;
this.buffer = '';
this.write(message);
}
return this.stream;
}
/**
* Write a message to the file stream, and rotate files once written if necessary.
*/
write(message) {
if (this.rotating) {
this.buffer += message;
return;
}
const stream = this.open();
const written = stream.write(message, 'utf8', () => {
this.lastSize += Buffer.byteLength(message);
this.checkIfNeedsRotation();
}); // istanbul ignore next
if (!written) {
this.draining = true;
stream.once('drain', () => {
this.draining = false;
});
}
}
/**
* Check that the parent folder exists and has the correct permissions.
*/
checkFolderRequirements() {
fs__default['default'].mkdirSync(this.path.parent().path(), {
recursive: true
});
}
/**
* Check if we should change and rotate files because of max size.
*/
checkIfNeedsRotation() {
if (this.lastSize > this.options.maxSize) {
this.closeStreamAndRotateFile();
}
}
/**
* Open and create a file stream for the defined path.
* Apply file size and gzip checks.
*/
createStream() {
const stream = fs__default['default'].createWriteStream(this.path.path(), {
encoding: 'utf8',
flags: 'a'
}); // Apply gzip compression to the stream
if (this.options.gzip) {
const gzip = zlib__default['default'].createGzip();
gzip.pipe(stream);
return gzip;
}
return stream;
}
/**
* Return the file name with extension, of the newly rotated file.
*/
getRotatedFileName() {
return this.path.name();
}
/**
* Count the number of files within path directory that matches the given file name.
*/
getNextIncrementCount(name) {
const files = fs__default['default'].readdirSync(this.path.parent().path()); // eslint-disable-next-line security/detect-non-literal-regexp
const pattern = new RegExp(`^${name}.\\d+$`, 'u');
let count = 0;
files.forEach(file => {
if (file.match(pattern)) {
count += 1;
}
});
return count;
}
/**
* Close the open stream and attempt to rotate the file.
*/
closeStreamAndRotateFile() {
// istanbul ignore next
if (this.draining || this.rotating) {
return;
}
this.rotating = true;
this.close(() => {
this.rotateFile();
this.rotating = false;
});
}
/**
* Rotate the current file into a new file with an incremented name.
*/
rotateFile() {
let fileName = this.getRotatedFileName();
if (this.options.gzip) {
fileName += '.gz';
}
fileName += `.${this.getNextIncrementCount(fileName)}`;
fs__default['default'].renameSync(this.path.path(), this.path.parent().append(fileName).path());
this.lastSize = 0;
}
}
const DAYS_IN_WEEK = 7;
class RotatingFileTransport extends FileTransport {
constructor(...args) {
super(...args);
this.lastTimestamp = this.formatTimestamp(Date.now());
}
blueprint(preds) {
const {
string
} = preds;
return { ...super.blueprint(preds),
rotation: string().oneOf(['hourly', 'daily', 'weekly', 'monthly'])
};
}
/**
* Format a `Date` object into a format used within the log file name.
*/
formatTimestamp(ms) {
const {
rotation
} = this.options;
const date = new Date(ms);
let timestamp = `${date.getFullYear()}${String(date.getMonth() + 1).padStart(2, '0')}`;
if (rotation === 'monthly') {
return timestamp;
} // Special case, calculate the week manually and return,
// but do not append so other rotations inherit!
if (rotation === 'weekly') {
const firstDay = new Date(date.getFullYear(), date.getMonth(), 1).getDay();
const offsetDate = date.getDate() + firstDay - 1;
timestamp += `.W${Math.floor(offsetDate / DAYS_IN_WEEK) + 1}`;
return timestamp;
}
timestamp += String(date.getDate()).padStart(2, '0');
if (rotation === 'daily') {
return timestamp;
}
timestamp += `.${String(date.getHours()).padStart(2, '0')}`;
return timestamp;
}
/**
* @inheritdoc
*/
checkIfNeedsRotation() {
if (this.lastSize > this.options.maxSize || this.formatTimestamp(Date.now()) !== this.lastTimestamp) {
this.closeStreamAndRotateFile();
}
}
/**
* @inheritdoc
*/
getRotatedFileName() {
const name = this.path.name(true);
const ext = this.path.ext(true);
return `${name}-${this.lastTimestamp}.${ext}`;
}
/**
* @inheritdoc
*/
rotateFile() {
super.rotateFile(); // Update timestamp to the new format
this.lastTimestamp = this.formatTimestamp(Date.now());
}
}
class StreamTransport extends Transport {
constructor(options) {
super(options);
this.stream = void 0;
this.stream = options.stream;
}
blueprint(preds) {
const {
func,
shape
} = preds;
return { ...super.blueprint(preds),
stream: shape({
write: func().required().notNullable()
})
};
}
write(message) {
this.stream.write(message);
}
}
exports.createLogger = createLogger;
exports.formats = formats;
exports.Logger = Logger;
exports.Transport = Transport;
exports.ConsoleTransport = ConsoleTransport;
exports.DEFAULT_LABELS = DEFAULT_LABELS;
exports.FileTransport = FileTransport;
exports.LOG_LEVELS = LOG_LEVELS;
exports.Logger = Logger;
exports.MAX_LOG_SIZE = MAX_LOG_SIZE;
exports.RotatingFileTransport = RotatingFileTransport;
exports.StreamTransport = StreamTransport;
exports.Transport = Transport;
exports.createLogger = createLogger;
exports.formats = formats;
exports.DEFAULT_LABELS = constants.DEFAULT_LABELS;
exports.LOG_LEVELS = constants.LOG_LEVELS;
exports.MAX_LOG_SIZE = constants.MAX_LOG_SIZE;
//# sourceMappingURL=index.js.map

@@ -24,1 +24,2 @@ // Generated with Packemon: https://packemon.dev

exports.mockLogger = mockLogger;
//# sourceMappingURL=test.js.map
{
"name": "@boost/log",
"version": "2.2.4",
"version": "2.2.5",
"release": "1594765247526",

@@ -15,2 +15,10 @@ "description": "Lightweight level based logging system.",

"types": "./dts/index.d.ts",
"files": [
"dts/**/*.d.ts",
"lib/**/*.{js,map}",
"res/",
"src/**/*.{ts,tsx,json}",
"test.d.ts",
"test.js"
],
"engines": {

@@ -31,5 +39,5 @@ "node": ">=10.3.0",

"dependencies": {
"@boost/common": "^2.7.1",
"@boost/internal": "^2.2.1",
"@boost/translate": "^2.2.4",
"@boost/common": "^2.7.2",
"@boost/internal": "^2.2.2",
"@boost/translate": "^2.2.5",
"chalk": "^4.1.0"

@@ -48,3 +56,3 @@ },

},
"gitHead": "85109c6c9f196f4374e13519cb52f88dc4860310"
"gitHead": "f9eb83de54fa41334f1a1e487216004a03caf662"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc