Socket
Socket
Sign inDemoInstall

@stencila/logga

Package Overview
Dependencies
Maintainers
3
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@stencila/logga - npm Package Compare versions

Comparing version 2.2.0 to 3.0.0

12

CHANGELOG.md

@@ -0,1 +1,13 @@

# [3.0.0](https://github.com/stencila/logga/compare/v2.2.0...v3.0.0) (2020-09-01)
### Features
* **defaultHandler:** Exit on error option ([d5447a0](https://github.com/stencila/logga/commit/d5447a098f085df625f1b523402891aa7dffef3b))
### BREAKING CHANGES
* **defaultHandler:** Changes the default behaviour to exit the process on the first error logged.
# [2.2.0](https://github.com/stencila/logga/compare/v2.1.0...v2.2.0) (2020-04-21)

@@ -2,0 +14,0 @@

2

dist/browser/logga.umd.js

@@ -1,2 +0,2 @@

!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e=e||self).logga={})}(this,function(e){function n(){return(n=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e}).apply(this,arguments)}var r,o;if("undefined"!=typeof process&&(r={emit:process.emit,listeners:process.listeners,addListener:process.addListener,removeListener:process.removeListener,removeAllListeners:process.removeAllListeners}),"undefined"!=typeof window){var t=new Map;r={emit:function(e,n){window.dispatchEvent(new CustomEvent(e,{detail:n}))},listeners:function(){return Array.from(t.keys())},addListener:function(e,n){var r=function(e){return n(e.detail)};window.addEventListener(e,r),t.set(n,r)},removeListener:function(e,n){var r=t.get(n);void 0!==r&&(window.removeEventListener(e,r),t.delete(n))},removeAllListeners:function(e){Array.from(t.values()).map(function(n){window.removeEventListener(e,n)}),t.clear()}}}function i(n,o,t){var i="";"object"==typeof n&&void 0!==n.message?i=n.message:"string"==typeof n&&(i=n);var s={tag:o,level:t,message:i};if("object"==typeof n&&void 0!==n.stack)s.stack=n.stack;else if(t<=e.LogLevel.error){var a=new Error;if(void 0!==a.stack){var d=a.stack.split("\n");s.stack=[d[0]].concat(d.slice(3)).join("\n")}}r.emit("stencila:logga",s)}function s(){return r.listeners("stencila:logga")}function a(e,n){void 0===n&&(n={});var o=e,t=n.tags,i=n.maxLevel,s=n.messageRegex,a=n.func;return void 0===t&&void 0===i&&void 0===s&&void 0===a||(o=function(n){(void 0===t||t.includes(n.tag))&&(void 0!==i&&n.level>i||(void 0===s||s.test(n.message))&&(void 0===a||a(n))&&e(n))}),r.addListener("stencila:logga",o),o}function d(){r.removeAllListeners("stencila:logga")}(o=e.LogLevel||(e.LogLevel={}))[o.error=0]="error",o[o.warn=1]="warn",o[o.info=2]="info",o[o.debug=3]="debug";var v=new Map;function l(r,o){void 0===o&&(o={});var t=r.tag,i=r.level,s=r.message,a=r.stack,d=o.maxLevel;if(!(i>(void 0===d?e.LogLevel.info:d))){var l=o.throttle;if(void 0!==l){var c=(void 0!==l.signature?l.signature:"").replace(/\${tag}/,t).replace(/\${level}/,i.toString()).replace(/\${message}/,s),f=v.get(c);if(void 0!==f){var g=void 0!==l.duration?l.duration:1e3;if(Date.now()-f<g)return}v.set(c,Date.now())}var u="";if("undefined"!=typeof process&&void 0!==process.stderr&&!0!==process.stderr.isTTY)u=JSON.stringify(n({time:(new Date).toISOString()},r));else{var m=i<0?0:i>3?3:i,p=e.LogLevel[m].toUpperCase().padEnd(5," ");u="undefined"!=typeof window?p+" "+t+" "+s:["🚨","⚠","🛈","🐛"][m]+" "+["","","",""][m]+p+" "+t+" "+s;var L=o.showStack;void 0!==L&&L&&void 0!==a&&(u+="\n "+a)}console.error(u)}}0===s().length&&a(l),e.addHandler=a,e.defaultHandler=l,e.getLogger=function(n){return{error:function(r){i(r,n,e.LogLevel.error)},warn:function(r){i(r,n,e.LogLevel.warn)},info:function(r){i(r,n,e.LogLevel.info)},debug:function(r){i(r,n,e.LogLevel.debug)}}},e.handlers=s,e.removeHandler=function(e){r.removeListener("stencila:logga",e)},e.removeHandlers=d,e.replaceHandlers=function(e){d(),a(e)}});
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e=e||self).logga={})}(this,function(e){function n(){return(n=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e}).apply(this,arguments)}var r,o;if("undefined"!=typeof process&&(r={emit:process.emit,listeners:process.listeners,addListener:process.addListener,removeListener:process.removeListener,removeAllListeners:process.removeAllListeners}),"undefined"!=typeof window){var t=new Map;r={emit:function(e,n){window.dispatchEvent(new CustomEvent(e,{detail:n}))},listeners:function(){return Array.from(t.keys())},addListener:function(e,n){var r=function(e){return n(e.detail)};window.addEventListener(e,r),t.set(n,r)},removeListener:function(e,n){var r=t.get(n);void 0!==r&&(window.removeEventListener(e,r),t.delete(n))},removeAllListeners:function(e){Array.from(t.values()).map(function(n){window.removeEventListener(e,n)}),t.clear()}}}function i(n,o,t){var i="";"object"==typeof n&&void 0!==n.message?i=n.message:"string"==typeof n&&(i=n);var s={tag:o,level:t,message:i};if("object"==typeof n&&void 0!==n.stack)s.stack=n.stack;else if(t<=e.LogLevel.error){var a=new Error;if(void 0!==a.stack){var d=a.stack.split("\n");s.stack=[d[0]].concat(d.slice(3)).join("\n")}}r.emit("stencila:logga",s)}function s(){return r.listeners("stencila:logga")}function a(e,n){void 0===n&&(n={});var o=e,t=n.tags,i=n.maxLevel,s=n.messageRegex,a=n.func;return void 0===t&&void 0===i&&void 0===s&&void 0===a||(o=function(n){(void 0===t||t.includes(n.tag))&&(void 0!==i&&n.level>i||(void 0===s||s.test(n.message))&&(void 0===a||a(n))&&e(n))}),r.addListener("stencila:logga",o),o}function d(){r.removeAllListeners("stencila:logga")}(o=e.LogLevel||(e.LogLevel={}))[o.error=0]="error",o[o.warn=1]="warn",o[o.info=2]="info",o[o.debug=3]="debug";var v=new Map;function l(r,o){void 0===o&&(o={});var t=r.tag,i=r.level,s=r.message,a=r.stack,d=o.maxLevel;if(!(i>(void 0===d?e.LogLevel.info:d))){var l=o.throttle;if(void 0!==l){var c=(void 0!==l.signature?l.signature:"").replace(/\${tag}/,t).replace(/\${level}/,i.toString()).replace(/\${message}/,s),f=v.get(c);if(void 0!==f){var g=void 0!==l.duration?l.duration:1e3;if(Date.now()-f<g)return}v.set(c,Date.now())}var u="";if("undefined"!=typeof process&&void 0!==process.stderr&&!0!==process.stderr.isTTY)u=JSON.stringify(n({time:(new Date).toISOString()},r));else{var p=i<0?0:i>3?3:i,m=e.LogLevel[p].toUpperCase().padEnd(5," ");u="undefined"!=typeof window?m+" "+t+" "+s:["🚨","⚠","🛈","🐛"][p]+" "+["","","",""][p]+m+" "+t+" "+s;var L=o.showStack;void 0!==L&&L&&void 0!==a&&(u+="\n "+a)}console.error(u);var w=o.exitOnError;"undefined"!=typeof process&&(void 0===w||w)&&i===e.LogLevel.error&&process.exit(1)}}0===s().length&&a(l),e.addHandler=a,e.defaultHandler=l,e.getLogger=function(n){return{error:function(r){i(r,n,e.LogLevel.error)},warn:function(r){i(r,n,e.LogLevel.warn)},info:function(r){i(r,n,e.LogLevel.info)},debug:function(r){i(r,n,e.LogLevel.debug)}}},e.handlers=s,e.removeHandler=function(e){r.removeListener("stencila:logga",e)},e.removeHandlers=d,e.replaceHandlers=function(e){d(),a(e)}});
//# sourceMappingURL=logga.umd.js.map

@@ -82,5 +82,5 @@ /**

/**
* Default log data handler.
* Default log event handler.
*
* Prints the data to stderr:
* Prints the event data to stderr:
*

@@ -90,4 +90,8 @@ * - with cutesy emoji, colours and stack (for errors) if stderr is TTY (for human consumption)

*
* If in Node.js, and the
*
* @param data The log data to handle
* @param options.maxLevel The maximum log level to print. Defaults to `info`
* @param options.maxLevel The maximum log level to print. Defaults to `info`.
* @param options.showStack Whether or not to show any stack traces for errors. Defaults to `false`.
* @param options.exitOnError Whether or not to exit the process on the first error. Defaults to `true`.
* @param options.throttle.signature The log event signature to use for throttling. Defaults to '' (i.e. all events)

@@ -99,2 +103,3 @@ * @param options.throttle.duration The duration for throttling (milliseconds). Defaults to 1000ms

showStack?: boolean;
exitOnError?: boolean;
throttle?: {

@@ -101,0 +106,0 @@ signature?: string;

@@ -19,3 +19,13 @@ function _extends() {

/* global CustomEvent */
const LOG_EVENT_NAME = 'stencila:logga';
/**
* The global log event bus from which all events are emitted
* and handlers are attached.
*
* When in Node, exposes the event API of Node `process`.
* When in a browser, creates adaptor functions to mimic the
* Node API using `window` event handling functions.
*/
let bus;

@@ -25,2 +35,3 @@

bus = {
/* eslint-disable @typescript-eslint/unbound-method */
emit: process.emit,

@@ -33,3 +44,5 @@ listeners: process.listeners,

}
/* istanbul ignore next */
if (typeof window !== 'undefined') {

@@ -47,4 +60,5 @@ const listeners = new Map();

addListener: (event, handler) => {
const listener = customEvent => handler(customEvent.detail);
const listener = customEvent => handler(customEvent.detail); // @ts-ignore
window.addEventListener(event, listener);

@@ -55,3 +69,4 @@ listeners.set(handler, listener);

const listener = listeners.get(handler);
if (listener === undefined) return;
if (listener === undefined) return; // @ts-ignore
window.removeEventListener(event, listener);

@@ -62,2 +77,3 @@ listeners.delete(handler);

Array.from(listeners.values()).map(listener => {
// @ts-ignore
window.removeEventListener(event, listener);

@@ -76,3 +92,14 @@ });

})(exports.LogLevel || (exports.LogLevel = {}));
/**
* Take a message `string`, or `LogInfo` object,
* and emit an event with a `LogData` object.
*
* For `LogLevel.error`, if `LogInfo` does not have a `stack`,
* one is generated and set on the `LogData`.
*
* @param info
* @param level
*/
function emitLogData(info, tag, level) {

@@ -99,2 +126,4 @@ let message = '';

if (error.stack !== undefined) {
// Remove the first three lines of the stack trace which
// are not useful (see issue #3)
const lines = error.stack.split('\n');

@@ -107,6 +136,22 @@ data.stack = [lines[0], ...lines.slice(3)].join('\n');

}
/**
* Get all handlers.
*/
function handlers() {
return bus.listeners(LOG_EVENT_NAME);
}
/**
* Add a handler.
*
* @param handler A function that handles the log data.
* @param filter Options for filtering log data prior to sending to the handler.
* @param filter.tags A list of tags that the log data should match.
* @param filter.maxLevel The maximum log level.
* @param filter.messageRegex A regex that the log message should match.
* @param filter.func A function that determines if handler is called
* @returns The handler function that was added.
*/
function addHandler(handler, filter = {}) {

@@ -134,8 +179,26 @@ let listener = handler;

}
/**
* Remove a handler.
*
* @param handler The handler function to remove.
*/
function removeHandler(handler) {
bus.removeListener(LOG_EVENT_NAME, handler);
}
/**
* Remove all handlers.
*/
function removeHandlers() {
bus.removeAllListeners(LOG_EVENT_NAME);
}
/**
* Replace all existing handlers with a new handler.
*
* This is a convenience function that can be used to
* replace the default handler with a new one which logs
* to the console.
*/
function replaceHandlers(handler) {

@@ -146,2 +209,20 @@ removeHandlers();

const defaultHandlerHistory = new Map();
/**
* Default log event handler.
*
* Prints the event data to stderr:
*
* - with cutesy emoji, colours and stack (for errors) if stderr is TTY (for human consumption)
* - as JSON if stderr is not TTY (for machine consumption e.g. log files)
*
* If in Node.js, and the
*
* @param data The log data to handle
* @param options.maxLevel The maximum log level to print. Defaults to `info`.
* @param options.showStack Whether or not to show any stack traces for errors. Defaults to `false`.
* @param options.exitOnError Whether or not to exit the process on the first error. Defaults to `true`.
* @param options.throttle.signature The log event signature to use for throttling. Defaults to '' (i.e. all events)
* @param options.throttle.duration The duration for throttling (milliseconds). Defaults to 1000ms
*/
function defaultHandler(data, options = {}) {

@@ -153,7 +234,9 @@ const {

stack
} = data;
} = data; // Skip if greater than desired reporting level
const {
maxLevel = exports.LogLevel.info
} = options;
if (level > maxLevel) return;
if (level > maxLevel) return; // Skip if within throttling duration for the event signature
const {

@@ -174,4 +257,6 @@ throttle

defaultHandlerHistory.set(eventSignature, Date.now());
}
} // Generate a human readable or machine readable log entry based on
// environment
let entry = '';

@@ -186,2 +271,3 @@

const label = exports.LogLevel[index].toUpperCase().padEnd(5, ' ');
/* istanbul ignore next */

@@ -205,4 +291,23 @@ if (typeof window !== 'undefined') {

console.error(entry);
}
const {
exitOnError = true
} = options;
if (typeof process !== 'undefined' && exitOnError && level === exports.LogLevel.error) {
process.exit(1);
}
} // Enable the default handler if there no other handler
// already enabled e.g. by another package using `logga`
if (handlers().length === 0) addHandler(defaultHandler);
/**
* Get a logger for the specific application or package.
*
* Each of the returned logger functions are the public interface for
* posting log messages.
*
* @param tag The unique application or package name
*/
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
function getLogger(tag) {

@@ -209,0 +314,0 @@ return {

{
"name": "@stencila/logga",
"version": "2.2.0",
"version": "3.0.0",
"description": "Unified logging across related Javascript modules",

@@ -42,9 +42,9 @@ "main": "dist/lib/logga.js",

"devDependencies": {
"@stencila/dev-config": "1.4.23",
"@types/jest": "25.2.1",
"jest": "25.2.0",
"microbundle": "^0.12.0-next.8",
"ts-jest": "25.3.1",
"typedoc": "0.17.4",
"typescript": "3.8.3"
"@stencila/dev-config": "1.4.69",
"@types/jest": "26.0.12",
"jest": "26.4.2",
"microbundle": "0.12.3",
"ts-jest": "26.3.0",
"typedoc": "0.19.0",
"typescript": "4.0.2"
},

@@ -51,0 +51,0 @@ "jest": {

@@ -26,2 +26,4 @@ # Logga

### Emitting log events
Create a new logger by calling `getLogger` with a unique tag to identify your app and/or module. Then emit log events using the `debug`, `info`, `warn` and `error` functions. You can pass them a message string or a `LogInfo` object.

@@ -45,3 +47,3 @@

message: 'Woaaah something bad happened! ' + message,
stack
stack,
})

@@ -51,2 +53,14 @@ }

See [this post](https://reflectoring.io/logging-levels/) for advice on when to use the alternative log levels. In summary,
- The `ERROR` level should only be used when the application really is in trouble. Users are being affected without having a way to work around the issue.
- The `WARN` level should be used when something bad happened, but the application still has the chance to heal itself or the issue can wait a day or two to be fixed.
- The `INFO` level should be used to document state changes in the application or some entity within the application.
- The `DEBUG` level should be used to log any information that helps us identify what went wrong.
### Handling log events
The default log handler prints log data to `console.error`. If `stderr` is TTY log data is formatted for human consumption with emoji, colours and stack trace (for errors):

@@ -90,2 +104,10 @@

### Exiting the process
When in Node.js, the `defaultHandler` will exit the process, with code 1, on the first error event. To disable this behavior set the option `exitOnError: false` e.g.
```js
replaceHandlers((data) => defaultHandler(data, { exitOnError: false }))
```
## See also

@@ -92,0 +114,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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