@alwatr/logger
Advanced tools
Comparing version 0.30.0 to 0.31.0
@@ -6,2 +6,16 @@ # Change Log | ||
# [0.31.0](https://github.com/AliMD/alwatr/compare/v0.30.0...v0.31.0) (2023-05-08) | ||
### Bug Fixes | ||
- **logger:** logMethod args type ([66338b7](https://github.com/AliMD/alwatr/commit/66338b7ba1d4b15af78f9f604f7be0a7e483413d)) | ||
- **logger:** logMethod args type ([1983b3d](https://github.com/AliMD/alwatr/commit/1983b3d2fe260226ca2660e33b9bd924facdf776)) | ||
- new logger api ([9d83a7d](https://github.com/AliMD/alwatr/commit/9d83a7dc5c103bc3bb4282dacfd85fa998915300)) | ||
### Features | ||
- **logger:** add `duration time` to logger time label ([ef188c4](https://github.com/AliMD/alwatr/commit/ef188c41a02789e1b35ab424bab24a393a03a3b0)) | ||
- **logger:** add `time` & `timeEnd` ([0bd4ec5](https://github.com/AliMD/alwatr/commit/0bd4ec5dbd185b17cfb8656a84a782e848ade138)) | ||
- **logger:** optional devMode per package ([cc1eb87](https://github.com/AliMD/alwatr/commit/cc1eb879832807d55ad4cf268a54b2d5e4346fff)) | ||
# [0.30.0](https://github.com/AliMD/alwatr/compare/v0.29.0...v0.30.0) (2023-03-06) | ||
@@ -8,0 +22,0 @@ |
import { globalAlwatr } from './global-alwatr.js'; | ||
import type { AlwatrLogger } from './type.js'; | ||
export { type AlwatrLogger, globalAlwatr }; | ||
export declare const isBrowser: boolean; | ||
export declare const style: { | ||
scope: string; | ||
reset: string; | ||
}; | ||
export declare const NODE_MODE: boolean; | ||
export declare const DEV_MODE: boolean; | ||
/** | ||
@@ -22,3 +19,3 @@ * Create a logger function for fancy console debug with custom scope. | ||
*/ | ||
export declare const createLogger: (scope: string, color?: string | null, debug?: boolean) => AlwatrLogger; | ||
export declare const createLogger: (domain: string, devMode?: boolean) => AlwatrLogger; | ||
//# sourceMappingURL=logger.d.ts.map |
131
logger.js
@@ -1,5 +0,4 @@ | ||
var _a, _b, _c, _d; | ||
var _a; | ||
import { globalAlwatr } from './global-alwatr.js'; | ||
export { globalAlwatr }; | ||
export const isBrowser = typeof process === 'undefined'; | ||
globalAlwatr.registeredList.push({ | ||
@@ -9,8 +8,12 @@ name: '@alwatr/logger', | ||
}); | ||
export const NODE_MODE = typeof process !== 'undefined'; | ||
export const DEV_MODE = NODE_MODE | ||
? process.env.ALWATR_DEBUG === '1' | ||
: ((_a = globalThis.localStorage) === null || _a === void 0 ? void 0 : _a.getItem('ALWATR_DEBUG')) === '1'; | ||
/** | ||
* Color list storage for logger. | ||
*/ | ||
let colorIndex = 0; | ||
const colorList = isBrowser | ||
? [ | ||
const colorList = NODE_MODE | ||
? ['0;36', '0;35', '0;34', '0;33', '0;32'] // red and white omitted | ||
: [ | ||
'#35b997', | ||
@@ -31,40 +34,25 @@ '#f05561', | ||
'#ee2524', | ||
] | ||
: ['0;36', '0;35', '0;34', '0;33', '0;32']; // red and white omitted | ||
const getNextColor = () => { | ||
const color = colorList[colorIndex]; | ||
colorIndex++; | ||
if (colorIndex >= colorList.length) { | ||
colorIndex = 0; | ||
]; | ||
let _colorIndex = 0; | ||
const _getNextColor = () => { | ||
const color = colorList[_colorIndex]; | ||
_colorIndex++; | ||
if (_colorIndex >= colorList.length) { | ||
_colorIndex = 0; | ||
} | ||
return color; | ||
}; | ||
const debugString = isBrowser | ||
? (_b = (_a = globalThis.localStorage) === null || _a === void 0 ? void 0 : _a.getItem('ALWATR_DEBUG')) === null || _b === void 0 ? void 0 : _b.trim() | ||
: (_d = (_c = process === null || process === void 0 ? void 0 : process.env) === null || _c === void 0 ? void 0 : _c.ALWATR_DEBUG) === null || _d === void 0 ? void 0 : _d.trim(); | ||
const getDebugState = (scope) => { | ||
if (debugString == null && isBrowser === false && process.env.NODE_ENV !== 'production') { | ||
return true; | ||
const _style = { | ||
scope: NODE_MODE ? '\x1b[{{color}}m' : 'color: {{color}};', | ||
reset: NODE_MODE ? '\x1b[0m' : 'color: inherit;', | ||
}; | ||
const _keySection = NODE_MODE ? '%s%s%s' : '%c%s%c'; | ||
const _sanitizeDomain = (domain) => { | ||
domain = domain.trim(); | ||
const first = domain.charAt(0); | ||
if (first !== '[' && first !== '{' && first !== '<') { | ||
domain = '[' + domain + ']'; | ||
} | ||
// prettier-ignore | ||
if (debugString == null || | ||
debugString == '') { | ||
return false; | ||
} | ||
// prettier-ignore | ||
if (debugString === scope || | ||
debugString === '*' || | ||
(debugString.indexOf('*') === 0 && // starts with `*` for example: `*alwatr*` | ||
scope.indexOf(debugString.replaceAll('*', '')) !== -1) || | ||
(debugString.indexOf('*') === debugString.length - 1 && // ends with `*` for example: `alwatr/*` | ||
scope.indexOf(debugString.replaceAll('*', '')) === 0)) { | ||
return true; | ||
} | ||
// else | ||
return false; | ||
return domain; | ||
}; | ||
export const style = { | ||
scope: isBrowser ? 'color: {{color}};' : '\x1b[{{color}}m', | ||
reset: isBrowser ? 'color: inherit;' : '\x1b[0m', | ||
}; | ||
/** | ||
@@ -83,52 +71,37 @@ * Create a logger function for fancy console debug with custom scope. | ||
*/ | ||
export const createLogger = (scope, color, debug) => { | ||
scope = scope.trim(); | ||
color !== null && color !== void 0 ? color : (color = getNextColor()); | ||
debug !== null && debug !== void 0 ? debug : (debug = getDebugState(scope)); | ||
const first = scope.charAt(0); | ||
if (first !== '[' && first !== '{' && first !== '(' && first !== '<') { | ||
scope = '[' + scope + ']'; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-empty-function | ||
const empty = () => { }; | ||
const keySection = isBrowser ? '%c%s%c' : '%s%s%s'; | ||
const styleScope = style.scope.replaceAll('{{color}}', color); | ||
export const createLogger = (domain, devMode = DEV_MODE) => { | ||
const color = _getNextColor(); | ||
const styleScope = _style.scope.replaceAll('{{color}}', color); | ||
domain = _sanitizeDomain(domain); | ||
/** | ||
* Required logger object, accident, error always reported even when the debug is false. | ||
* Required logger object, accident, error always reported even when the devMode is false. | ||
*/ | ||
const requiredItems = { | ||
debug, | ||
color, | ||
scope, | ||
accident: isBrowser | ||
? console.warn.bind(console, '%c%s%c.%s() Accident `%s` %s!', styleScope, scope, style.reset) | ||
: console.warn.bind(console, `${styleScope}⚠️\n%s\x1b[33m.%s() Accident \`%s\` %s!${style.reset}`, scope), | ||
error: isBrowser | ||
? console.error.bind(console, '%c%s%c.%s() Error `%s`\n', styleScope, scope, style.reset) | ||
: console.error.bind(console, `${styleScope}❌\n%s\x1b[31m.%s() Error \`%s\`${style.reset}\n`, scope), | ||
devMode, | ||
domain, | ||
accident: NODE_MODE | ||
? console.warn.bind(console, `${styleScope}⚠️\n%s\x1b[33m.%s() Accident \`%s\` %s!${_style.reset}`, domain) | ||
: console.warn.bind(console, '%c%s%c.%s() Accident `%s` %s!', styleScope, domain, _style.reset), | ||
error: NODE_MODE | ||
? console.error.bind(console, `${styleScope}❌\n%s\x1b[31m.%s() Error \`%s\`${_style.reset}\n`, domain) | ||
: console.error.bind(console, '%c%s%c.%s() Error `%s`\n', styleScope, domain, _style.reset), | ||
}; | ||
if (!debug) { | ||
return { | ||
...requiredItems, | ||
logProperty: empty, | ||
logMethod: empty, | ||
logMethodArgs: empty, | ||
logMethodFull: empty, | ||
logOther: empty, | ||
incident: empty, | ||
}; | ||
if (!devMode) { | ||
return requiredItems; | ||
} | ||
// else if debug is true for this scope | ||
// else | ||
return { | ||
...requiredItems, | ||
logProperty: console.debug.bind(console, keySection + '.%s = %o;', styleScope, scope, style.reset), | ||
logMethod: console.debug.bind(console, keySection + '.%s();', styleScope, scope, style.reset), | ||
logMethodArgs: console.debug.bind(console, keySection + '.%s(%o);', styleScope, scope, style.reset), | ||
logMethodFull: console.debug.bind(console, keySection + '.%s(%o) => %o', styleScope, scope, style.reset), | ||
logOther: console.debug.bind(console, keySection, styleScope, scope, style.reset), | ||
incident: isBrowser | ||
? console.log.bind(console, '%c%s%c.%s() Incident `%s` %s!', styleScope, scope, 'color: orange;') | ||
: console.log.bind(console, `${styleScope}🚸\n%s${style.reset}.%s() Incident \`%s\` %s!${style.reset}`, scope), | ||
logProperty: console.debug.bind(console, _keySection + '.%s = %o;', styleScope, domain, _style.reset), | ||
logMethod: console.debug.bind(console, _keySection + '.%s();', styleScope, domain, _style.reset), | ||
logMethodArgs: console.debug.bind(console, _keySection + '.%s(%o);', styleScope, domain, _style.reset), | ||
logMethodFull: console.debug.bind(console, _keySection + '.%s(%o) => %o', styleScope, domain, _style.reset), | ||
logOther: console.debug.bind(console, _keySection, styleScope, domain, _style.reset), | ||
incident: NODE_MODE | ||
? console.log.bind(console, `${styleScope}🚸\n%s${_style.reset}.%s() Incident \`%s\` %s!${_style.reset}`, domain) | ||
: console.log.bind(console, '%c%s%c.%s() Incident `%s` %s!', styleScope, domain, 'color: orange;'), | ||
time: (label) => console.time(domain + '.' + label + ' duration time'), | ||
timeEnd: (label) => console.timeEnd(domain + '.' + label + ' duration time'), | ||
}; | ||
}; | ||
//# sourceMappingURL=logger.js.map |
{ | ||
"name": "@alwatr/logger", | ||
"version": "0.30.0", | ||
"version": "0.31.0", | ||
"description": "Fancy colorful console debugger with custom scope written in tiny TypeScript, ES module.", | ||
@@ -35,6 +35,6 @@ "keywords": [ | ||
"dependencies": { | ||
"@alwatr/type": "^0.30.0", | ||
"@alwatr/type": "^0.31.0", | ||
"tslib": "^2.5.0" | ||
}, | ||
"gitHead": "36f55780ccdcb1acc07400b0cdb3fe7b0df56cca" | ||
"gitHead": "896e64b58eed6e9048e870557ecf399d42705612" | ||
} |
175
README.md
@@ -13,7 +13,7 @@ # Alwatr Logger - `@alwatr/logger` | ||
function sayHello(name: string) { | ||
logger.logMethodArgs('sayHello', {name}); | ||
logger.logMethodArgs?.('sayHello', {name}); | ||
} | ||
``` | ||
### Debug Mode | ||
### Debug/Develope Mode (DEV_MODE) | ||
@@ -23,173 +23,6 @@ Many of the methods in the logger are no-ops when the debug mode is off in the browser. | ||
- Debugging all scopes | ||
```ts | ||
window.localStorage?.setItem('ALWATR_DEBUG', '*'); | ||
``` | ||
- Debugging specific scope | ||
```ts | ||
window.localStorage?.setItem('ALWATR_DEBUG', 'scope_name'); | ||
``` | ||
- Debugging some scopes with pattern | ||
```ts | ||
window.localStorage?.setItem('ALWATR_DEBUG', '*alwatr*'); | ||
``` | ||
> Make sure the [log level](https://developer.chrome.com/docs/devtools/console/log/#browser) in set correctly. | ||
## API | ||
### `createLogger(scope: string, color: string, force = boolean)` | ||
Create a logger function for fancy console debug with custom scope. | ||
- **color** is optional and automatically select from internal fancy color list. | ||
- **debug** is optional and automatically detect from localStorage `ALWATR_DEBUG` item or `process.env.ALWATR_DEBUG` | ||
Example: | ||
```ts | ||
import {createLogger} from 'https://esm.run/@alwatr/logger'; | ||
const logger = createLogger('logger/demo'); | ||
window.localStorage?.setItem('ALWATR_DEBUG', '1'); | ||
``` | ||
### `logger.debug: boolean` | ||
Debug state for current scope base on localStorage `ALWATR_DEBUG` pattern. | ||
### `logger.color: string` | ||
Debug state for current scope base on localStorage `ALWATR_DEBUG` pattern. | ||
### `logger.scope: string` | ||
Debug state for current scope base on localStorage `ALWATR_DEBUG` pattern. | ||
### `logger.logProperty(property, value)` | ||
`console.debug` property change. | ||
Example: | ||
```ts | ||
logger.logProperty('name', 'ali'); | ||
``` | ||
### `logger.logMethod(method)` | ||
`console.debug` function or method calls. | ||
Example: | ||
```ts | ||
function myMethod() { | ||
logger.logMethod('myMethod'); | ||
} | ||
``` | ||
### `logger.logMethodArgs(method, args)` | ||
`console.debug` function or method calls with arguments. | ||
Example: | ||
```ts | ||
function myMethod(a: number, b: number) { | ||
logger.logMethodArgs('myMethod', {a, b}); | ||
} | ||
``` | ||
### `logger.logMethodFull(method, args, result)` | ||
`console.debug` function or method calls with arguments. | ||
Example: | ||
```ts | ||
function add(a: number, b: number): number { | ||
const result = a + b; | ||
logger.logMethodFull('add', {a, b}, result); | ||
return result; | ||
} | ||
``` | ||
### `logger.incident(method, code, description, ...args)` | ||
`console.log` an event or expected accident. (not warn or error) | ||
Example: | ||
```ts | ||
logger.incident('fetch', 'abort_signal', 'aborted signal received', {url: '/test.json'}); | ||
``` | ||
### `logger.accident(method, code, description, ...args)` | ||
`console.warn` an unexpected accident or error that you handled. | ||
Example: | ||
```ts | ||
logger.accident('fetch', 'file_not_found', 'url requested return 404 not found', { | ||
url: '/test.json', | ||
}); | ||
``` | ||
### `logger.error(method, code, errorStack, ...args)` | ||
`console.error` an unexpected error. | ||
Example: | ||
```ts | ||
try { | ||
... | ||
} | ||
catch (err) { | ||
logger.error('myMethod', 'error_code', err, {a: 1, b: 2}); | ||
} | ||
``` | ||
### `logger.logOther(...args)` | ||
Simple `console.debug` with styled scope. | ||
Example: | ||
```ts | ||
logger.logOther('foo:', 'bar', {a: 1}); | ||
``` | ||
### How to handle promises? | ||
For example with a promise function with error: | ||
```ts | ||
const failPromiseTest = (): Promise<never> => new Promise((_, reject) => reject(new Error('my_error_code'))); | ||
``` | ||
Best practices to catch the error and log it: | ||
```ts | ||
// Unhandled promise rejection (just log it) | ||
failPromiseTest().catch((err) => | ||
logger.error('myMethod', (err as Error).message || 'error_code', err) | ||
); | ||
// Handled promise rejection | ||
try { | ||
await failPromiseTest(); | ||
} catch (err) { | ||
logger.accident( | ||
'myMethod', | ||
'error_code', | ||
'failPromiseTest failed!, ' + (err as Error).message, | ||
err | ||
); | ||
// do something to handle the error... | ||
} | ||
``` | ||
> Make sure the [log level](https://developer.chrome.com/docs/devtools/console/log/#browser) in set correctly. |
@@ -5,12 +5,8 @@ export interface AlwatrLogger { | ||
*/ | ||
readonly debug: boolean; | ||
readonly devMode: boolean; | ||
/** | ||
* Color picked for current scope. | ||
* Domain scope defined for this logger. | ||
*/ | ||
readonly color: string; | ||
readonly domain: string; | ||
/** | ||
* Scope defined for this logger. | ||
*/ | ||
readonly scope: string; | ||
/** | ||
* `console.debug` property change. | ||
@@ -21,6 +17,6 @@ * | ||
* ```ts | ||
* logger.logProperty('name', 'ali'); | ||
* logger.logProperty?.('name', 'ali'); | ||
* ``` | ||
*/ | ||
logProperty(property: string, value: unknown): void; | ||
logProperty?(property: string, value: unknown): void; | ||
/** | ||
@@ -33,7 +29,7 @@ * `console.debug` function or method calls. | ||
* function myMethod () { | ||
* logger.logMethod('myMethod'); | ||
* logger.logMethod?.('myMethod'); | ||
* } | ||
* ``` | ||
*/ | ||
logMethod(method: string): void; | ||
logMethod?(method: string): void; | ||
/** | ||
@@ -46,7 +42,7 @@ * `console.debug` function or method calls with arguments. | ||
* function myMethod (a: number, b: number) { | ||
* logger.logMethodArgs('myMethod', {a, b}); | ||
* logger.logMethodArgs?.('myMethod', {a, b}); | ||
* } | ||
* ``` | ||
*/ | ||
logMethodArgs(method: string, args: Record<string, unknown> | string | number | boolean): void; | ||
logMethodArgs?(method: string, args: unknown): void; | ||
/** | ||
@@ -60,3 +56,3 @@ * `console.debug` function or method calls with arguments. | ||
* const result = a + b; | ||
* logger.logMethodFull('add', {a, b}, result); | ||
* logger.logMethodFull?.('add', {a, b}, result); | ||
* return result; | ||
@@ -66,3 +62,3 @@ * } | ||
*/ | ||
logMethodFull(method: string, args: Record<string, unknown> | string | number | boolean, result: unknown): void; | ||
logMethodFull?(method: string, args: unknown, result: unknown): void; | ||
/** | ||
@@ -75,6 +71,6 @@ * `console.log` an event or expected accident. | ||
* ```ts | ||
* logger.incident('fetch', 'abort_signal', 'aborted signal received', {url: '/test.json'}); | ||
* logger.incident?.('fetch', 'abort_signal', 'aborted signal received', {url: '/test.json'}); | ||
* ``` | ||
*/ | ||
incident(method: string, code: string, desc: string, ...args: unknown[]): void; | ||
incident?(method: string, code: string, desc: string, ...args: unknown[]): void; | ||
/** | ||
@@ -111,7 +107,27 @@ * `console.warn` an unexpected accident or error that you handled like warning. | ||
* ```ts | ||
* logger.logOther('foo:', 'bar', {a: 1}); | ||
* logger.logOther?.('foo:', 'bar', {a: 1}); | ||
* ``` | ||
*/ | ||
logOther(...args: unknown[]): void; | ||
logOther?(...args: unknown[]): void; | ||
/** | ||
* Simple `console.time` with scope. | ||
* | ||
* Example: | ||
* | ||
* ```ts | ||
* logger.time?.('foo'); | ||
* ``` | ||
*/ | ||
time?(label: string): void; | ||
/** | ||
* Simple `console.timeEnd` with scope. | ||
* | ||
* Example: | ||
* | ||
* ```ts | ||
* logger.timeEnd?.('foo'); | ||
* ``` | ||
*/ | ||
timeEnd?(label: string): void; | ||
} | ||
//# sourceMappingURL=type.d.ts.map |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
1
33817
264
27
+ Added@alwatr/type@0.31.0(transitive)
- Removed@alwatr/type@0.30.0(transitive)
Updated@alwatr/type@^0.31.0