diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1128296..14931f9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,19 +7,28 @@ cache: key: "$CI_BUILD_STAGE" stages: -- mirror +- security - test - release - trigger - pages mirror: - stage: mirror + stage: security script: - npmci git mirror tags: - docker +snyk: + stage: security + script: + - npmci command yarn global add snyk + - npmci command yarn install --ignore-scripts + - npmci command snyk test + tags: + - docker + testLEGACY: stage: test script: diff --git a/defaults.yml b/defaults.yml deleted file mode 100644 index 5f158cc..0000000 --- a/defaults.yml +++ /dev/null @@ -1,4 +0,0 @@ -module.name: smartmodule -module.description: a smart description -module.author: Lossless GmbH -module.license: MIT \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 4bb0f09..34141b6 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1 +1 @@ -export declare let standardExport: string; +export * from './logcontext.classes.logger'; diff --git a/dist/index.js b/dist/index.js index 81df592..e768ce0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,4 +1,7 @@ "use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} Object.defineProperty(exports, "__esModule", { value: true }); -exports.standardExport = 'Hi there! :) This is a exported string'; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVXLFFBQUEsY0FBYyxHQUFHLHdDQUF3QyxDQUFBIn0= \ No newline at end of file +__export(require("./logcontext.classes.logger")); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLGlEQUE0QyJ9 \ No newline at end of file diff --git a/dist/logcontext.classes.logger.d.ts b/dist/logcontext.classes.logger.d.ts new file mode 100644 index 0000000..bd9e700 --- /dev/null +++ b/dist/logcontext.classes.logger.d.ts @@ -0,0 +1,60 @@ +import * as plugins from './logcontext.plugins'; +import { LogMap } from './logcontext.classes.logmap'; +export declare class Logger { + namespaceString: string; + clsNameSpace: plugins.smartcls.Namespace; + logmap: LogMap; + thirdPartyLogger: any; + child: any; + settings: { + enableScope: () => void; + disableScope: () => void; + enableAddData: () => void; + disableAddData: () => void; + }; + private settingsParams; + constructor(namespaceArg?: string); + addData(paramNameArg: string, dataArg: any): void; + addThirdPartyLogger(thirdPartyLoggerArg: any): void; + /** + * debug + * @param logMessageArg + */ + debug(logMessageArg: any): void; + /** + * log + * @param logMessageArg + */ + log(logMessageArg: any): void; + /** + * info + * @param logObjectArg + */ + info(logObjectArg: any): void; + /** + * error + * @param logMessageArg + * @param args + */ + error(logMessageArg: any, ...args: any[]): void; + /** + * warn + * @param logMessageArg + * @param args + */ + warn(logMessageArg: any, ...args: any[]): void; + /** + * fatal + * @param logMessageArg + * @param args + */ + fatal(logMessageArg: any, ...args: any[]): void; + scope(funcArg: any): void; + /** + * routes the log according to whats available in the environment + * @param {string} logMethod + * @param {any} message + * @param {any[]} ...args + */ + private routeLog(logMethod, message, ...args); +} diff --git a/dist/logcontext.classes.logger.js b/dist/logcontext.classes.logger.js new file mode 100644 index 0000000..ea91096 --- /dev/null +++ b/dist/logcontext.classes.logger.js @@ -0,0 +1,113 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const plugins = require("./logcontext.plugins"); +const logcontext_classes_logmap_1 = require("./logcontext.classes.logmap"); +class Logger { + constructor(namespaceArg = plugins.shortid()) { + this.settings = { + enableScope: () => { + this.settingsParams.scope = true; + }, + disableScope: () => { + this.settingsParams.scope = false; + }, + enableAddData: () => { + this.settingsParams.addData = true; + }, + disableAddData: () => { + this.settingsParams.addData = false; + } + }; + this.settingsParams = { + scope: true, + addData: true + }; + this.namespaceString = namespaceArg; + this.clsNameSpace = plugins.smartcls.createNamespace(this.namespaceString); + this.logmap = new logcontext_classes_logmap_1.LogMap(this.clsNameSpace); + } + addData(paramNameArg, dataArg) { + if (this.settingsParams.addData) { + this.logmap.addData(paramNameArg, dataArg); + } + } + addThirdPartyLogger(thirdPartyLoggerArg) { + this.thirdPartyLogger = thirdPartyLoggerArg; + } + /** + * debug + * @param logMessageArg + */ + debug(logMessageArg) { + this.routeLog('debug', logMessageArg); + } + /** + * log + * @param logMessageArg + */ + log(logMessageArg) { + this.routeLog('log', logMessageArg); + } + /** + * info + * @param logObjectArg + */ + info(logObjectArg) { + this.routeLog('info', logObjectArg); + } + /** + * error + * @param logMessageArg + * @param args + */ + error(logMessageArg, ...args) { + this.routeLog('error', logMessageArg, ...args); + } + /** + * warn + * @param logMessageArg + * @param args + */ + warn(logMessageArg, ...args) { + this.routeLog('warn', logMessageArg, ...args); + } + /** + * fatal + * @param logMessageArg + * @param args + */ + fatal(logMessageArg, ...args) { + this.routeLog('fatal', logMessageArg, ...args); + } + // creates a new async scope + scope(funcArg) { + // create node continuation scope + if (this.settingsParams.scope) { + this.clsNameSpace.run(funcArg); + } + else { + funcArg(); + } + } + /** + * routes the log according to whats available in the environment + * @param {string} logMethod + * @param {any} message + * @param {any[]} ...args + */ + routeLog(logMethod, message, ...args) { + let logObject = { + message: message, + type: logMethod, + logContext: this.logmap.getAllData() + }; + if (this.thirdPartyLogger && this.thirdPartyLogger[logMethod]) { + this.thirdPartyLogger[logMethod](logObject, ...args); + } + else { + console.log(logObject); + } + } +} +exports.Logger = Logger; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nY29udGV4dC5jbGFzc2VzLmxvZ2dlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2xvZ2NvbnRleHQuY2xhc3Nlcy5sb2dnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxnREFBZ0Q7QUFDaEQsMkVBQXFEO0FBRXJEO0lBeUJFLFlBQVksZUFBdUIsT0FBTyxDQUFDLE9BQU8sRUFBRTtRQW5CcEQsYUFBUSxHQUFHO1lBQ1QsV0FBVyxFQUFFLEdBQUcsRUFBRTtnQkFDaEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBQ25DLENBQUM7WUFDRCxZQUFZLEVBQUUsR0FBRyxFQUFFO2dCQUNqQixJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7WUFDcEMsQ0FBQztZQUNELGFBQWEsRUFBRSxHQUFHLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztZQUNyQyxDQUFDO1lBQ0QsY0FBYyxFQUFFLEdBQUcsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1lBQ3RDLENBQUM7U0FDRixDQUFDO1FBQ00sbUJBQWMsR0FBeUM7WUFDN0QsS0FBSyxFQUFFLElBQUk7WUFDWCxPQUFPLEVBQUUsSUFBSTtTQUNkLENBQUM7UUFHQSxJQUFJLENBQUMsZUFBZSxHQUFHLFlBQVksQ0FBQztRQUNwQyxJQUFJLENBQUMsWUFBWSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksa0NBQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELE9BQU8sQ0FBQyxZQUFvQixFQUFFLE9BQVk7UUFDeEMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FB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 \ No newline at end of file diff --git a/dist/logcontext.classes.logmap.d.ts b/dist/logcontext.classes.logmap.d.ts new file mode 100644 index 0000000..9c4fb9e --- /dev/null +++ b/dist/logcontext.classes.logmap.d.ts @@ -0,0 +1,11 @@ +import * as plugins from './logcontext.plugins'; +import { Namespace } from 'smartcls'; +export declare class LogMap { + clsNamespace: Namespace; + paramMap: plugins.lik.Stringmap; + constructor(clsNamespaceArg: Namespace); + addData(paramName: string, logData: any): void; + deleteData(paramName: string): void; + getData(paramName: string): any; + getAllData(): {}; +} diff --git a/dist/logcontext.classes.logmap.js b/dist/logcontext.classes.logmap.js new file mode 100644 index 0000000..d666e04 --- /dev/null +++ b/dist/logcontext.classes.logmap.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const plugins = require("./logcontext.plugins"); +class LogMap { + constructor(clsNamespaceArg) { + this.paramMap = new plugins.lik.Stringmap(); + this.clsNamespace = clsNamespaceArg; + } + addData(paramName, logData) { + this.paramMap.addString(paramName); + this.clsNamespace.set(paramName, logData); + } + deleteData(paramName) { + this.clsNamespace.set(paramName, null); + } + getData(paramName) { + return this.clsNamespace.get(paramName); + } + getAllData() { + let returnObject = {}; + for (let stringArg of this.paramMap.getStringArray()) { + returnObject[stringArg] = this.clsNamespace.get(stringArg); + } + return returnObject; + } +} +exports.LogMap = LogMap; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nY29udGV4dC5jbGFzc2VzLmxvZ21hcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2xvZ2NvbnRleHQuY2xhc3Nlcy5sb2dtYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxnREFBZ0Q7QUFLaEQ7SUFJRSxZQUFZLGVBQTBCO1FBRnRDLGFBQVEsR0FBRyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUM7UUFHckMsSUFBSSxDQUFDLFlBQVksR0FBRyxlQUFlLENBQUM7SUFDdEMsQ0FBQztJQUVELE9BQU8sQ0FBQyxTQUFpQixFQUFFLE9BQU87UUFDaEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxVQUFVLENBQUMsU0FBaUI7UUFDMUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxPQUFPLENBQUMsU0FBaUI7UUFDdkIsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3RCLEdBQUcsQ0FBQyxDQUFDLElBQUksU0FBUyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3JELFlBQVksQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBQ0QsTUFBTSxDQUFDLFlBQVksQ0FBQztJQUN0QixDQUFDO0NBQ0Y7QUE1QkQsd0JBNEJDIn0= \ No newline at end of file diff --git a/dist/logcontext.plugins.d.ts b/dist/logcontext.plugins.d.ts index 317822d..e8d37e7 100644 --- a/dist/logcontext.plugins.d.ts +++ b/dist/logcontext.plugins.d.ts @@ -1 +1,5 @@ import 'typings-global'; +import * as lik from 'lik'; +import * as smartcls from 'smartcls'; +import * as shortid from 'shortid'; +export { lik, smartcls, shortid }; diff --git a/dist/logcontext.plugins.js b/dist/logcontext.plugins.js index 5900a79..da38297 100644 --- a/dist/logcontext.plugins.js +++ b/dist/logcontext.plugins.js @@ -1,4 +1,10 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); require("typings-global"); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nY29udGV4dC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvbG9nY29udGV4dC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsMEJBQXVCIn0= \ No newline at end of file +const lik = require("lik"); +exports.lik = lik; +const smartcls = require("smartcls"); +exports.smartcls = smartcls; +const shortid = require("shortid"); +exports.shortid = shortid; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nY29udGV4dC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvbG9nY29udGV4dC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsMEJBQXdCO0FBRXhCLDJCQUEyQjtBQUlsQixrQkFBRztBQUhaLHFDQUFxQztBQUd2Qiw0QkFBUTtBQUZ0QixtQ0FBbUM7QUFFWCwwQkFBTyJ9 \ No newline at end of file diff --git a/package.json b/package.json index 40e7e1c..b7f0d19 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "logcontext", - "version": "1.0.3", - "description": "log things contexts in async environments", + "version": "1.0.18", + "description": "enrich logs with context", "main": "dist/index.js", "typings": "dist/index.d.ts", "author": "Lossless GmbH", @@ -10,9 +10,14 @@ "test": "(npmts)" }, "devDependencies": { - "tapbundle": "^1.0.13" + "@types/node": "^9.4.6", + "smartdelay": "^1.0.4", + "tapbundle": "^2.0.0" }, "dependencies": { - "typings-global": "^1.0.16" + "@types/shortid": "^0.0.29", + "lik": "^2.0.5", + "shortid": "^2.2.8", + "smartcls": "^1.0.3" } } diff --git a/readme.md b/readme.md index 8393310..a2ba804 100644 --- a/readme.md +++ b/readme.md @@ -1,29 +1,43 @@ # logcontext -log things contexts in async environments -## Availabililty -[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/logcontext) -[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/logcontext) -[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/logcontext) -[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/logcontext/) +the logconext module exposes an easy to use syntax for nodejs style async logcontexts. -## Status for master -[![build status](https://GitLab.com/pushrocks/logcontext/badges/master/build.svg)](https://GitLab.com/pushrocks/logcontext/commits/master) -[![coverage report](https://GitLab.com/pushrocks/logcontext/badges/master/coverage.svg)](https://GitLab.com/pushrocks/logcontext/commits/master) -[![npm downloads per month](https://img.shields.io/npm/dm/logcontext.svg)](https://www.npmjs.com/package/logcontext) -[![Dependency Status](https://david-dm.org/pushrocks/logcontext.svg)](https://david-dm.org/pushrocks/logcontext) -[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/logcontext/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/logcontext/master/dependencies/npm) -[![bitHound Code](https://www.bithound.io/github/pushrocks/logcontext/badges/code.svg)](https://www.bithound.io/github/pushrocks/logcontext) -[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/) -[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/) -[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) +```typescript +let testLogger = new logcontext.Logger('testNamespace'); -## Usage -Use TypeScript for best in class instellisense. +testLogger.scope(async () => { + testLogger.addData('id1', { + someData: 'someValue' + }); + testLogger.log('hi'); + testLogger.error(new Error('custom error message')); + setTimeout(() => { + outsideFunction(); // log scope will travel through callbacks and promises + }, 2000); +}); -For further information read the linked docs at the top of this README. +let outsideFunction = () => { + sgLogger.log('some message'); +}; +``` -> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh) -| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html) +## class Logger -[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks) +```typescript +import { Logger } from 'logcontext'; + +// instantiate new Logger +// argument optional, if left empty auto generated shortid will be used +let myLogger = new Logger('myNamespace'); + +// create a scope +myLogger.scope(async () => { + // everything that is appended to the call stack from inside here will have all appended context data available + + // add some scoped context information + myLogger.addData('customerId', '12345678'); + + // will log something with priviously appended context of this scope in place + myLoger.log('awesomeText'); +}); +``` diff --git a/test/test.ts b/test/test.ts index ac8ab4f..c1f8743 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,8 +1,54 @@ -import { expect, tap } from 'tapbundle' -import * as logcontext from '../ts/index' +import { expect, tap } from 'tapbundle'; +import * as logcontext from '../ts/index'; +import * as smartdelay from 'smartdelay'; -tap.test('first test', async () => { - console.log(logcontext.standardExport) -}) +let testLogger = new logcontext.Logger('testNamespace'); -tap.start() +tap.test('should log for .error()', async () => { + testLogger.error(new Error('first error message')); +}); + +tap.test('should log for .fatal()', async () => { + testLogger.fatal('this is fatal'); +}); + +// set up independent log context +tap.testParallel('should create an async LogContext', async tools => { + testLogger.scope(async () => { + testLogger.logmap.addData('id1', { + someData: 'someValue' + }); + await tools.delayFor(10).then(async () => { + testLogger.log('hi'); + testLogger.error(new Error('custom error message')); + }); + }); +}); + +tap.testParallel('should create a new scope', async () => { + testLogger.scope(async () => { + testLogger.logmap.addData('id1', { + someData: 'otherValue' + }); + testLogger.info('anything'); + }); +}); + +tap.test('should log within default scope', async tools => { + await tools.delayFor(3000); + testLogger.log('message without context'); +}); + +tap.test('should not expose memory leak', async tools => { + await tools.checkIterationLeak(async () => { + testLogger.scope(() => { + testLogger.addData( + 'someid', + 'wow this is an awesome string with a lot of text, so increases actually matter' + ); + testLogger.log('hi'); + }); + }); +}); + +tap.start(); diff --git a/ts/index.ts b/ts/index.ts index 0ac583b..34141b6 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -1,3 +1 @@ -import * as plugins from './logcontext.plugins' - -export let standardExport = 'Hi there! :) This is a exported string' +export * from './logcontext.classes.logger'; diff --git a/ts/logcontext.classes.logger.ts b/ts/logcontext.classes.logger.ts new file mode 100644 index 0000000..cc676cb --- /dev/null +++ b/ts/logcontext.classes.logger.ts @@ -0,0 +1,124 @@ +import * as plugins from './logcontext.plugins'; +import { LogMap } from './logcontext.classes.logmap'; + +export class Logger { + namespaceString: string; + clsNameSpace: plugins.smartcls.Namespace; + logmap: LogMap; + thirdPartyLogger: any; + child: any; + settings = { + enableScope: () => { + this.settingsParams.scope = true; + }, + disableScope: () => { + this.settingsParams.scope = false; + }, + enableAddData: () => { + this.settingsParams.addData = true; + }, + disableAddData: () => { + this.settingsParams.addData = false; + } + }; + private settingsParams: { scope: boolean; addData: boolean } = { + scope: true, + addData: true + }; + + constructor(namespaceArg: string = plugins.shortid()) { + this.namespaceString = namespaceArg; + this.clsNameSpace = plugins.smartcls.createNamespace(this.namespaceString); + this.logmap = new LogMap(this.clsNameSpace); + } + + addData(paramNameArg: string, dataArg: any) { + if (this.settingsParams.addData) { + this.logmap.addData(paramNameArg, dataArg); + } + } + + addThirdPartyLogger(thirdPartyLoggerArg) { + this.thirdPartyLogger = thirdPartyLoggerArg; + } + + /** + * debug + * @param logMessageArg + */ + debug(logMessageArg) { + this.routeLog('debug', logMessageArg); + } + + /** + * log + * @param logMessageArg + */ + log(logMessageArg) { + this.routeLog('log', logMessageArg); + } + + /** + * info + * @param logObjectArg + */ + info(logObjectArg) { + this.routeLog('info', logObjectArg); + } + + /** + * error + * @param logMessageArg + * @param args + */ + error(logMessageArg, ...args) { + this.routeLog('error', logMessageArg, ...args); + } + + /** + * warn + * @param logMessageArg + * @param args + */ + warn(logMessageArg, ...args) { + this.routeLog('warn', logMessageArg, ...args); + } + + /** + * fatal + * @param logMessageArg + * @param args + */ + fatal(logMessageArg, ...args) { + this.routeLog('fatal', logMessageArg, ...args); + } + + // creates a new async scope + scope(funcArg: any) { + // create node continuation scope + if (this.settingsParams.scope) { + this.clsNameSpace.run(funcArg); + } else { + funcArg(); + } + } + + /** + * routes the log according to whats available in the environment + * @param {string} logMethod + * @param {any} message + * @param {any[]} ...args + */ + private routeLog(logMethod, message, ...args) { + let logObject = { + message: message, + type: logMethod, + logContext: this.logmap.getAllData() + }; + if (this.thirdPartyLogger && this.thirdPartyLogger[logMethod]) { + this.thirdPartyLogger[logMethod](logObject, ...args); + } else { + console.log(logObject); + } + } +} diff --git a/ts/logcontext.classes.logmap.ts b/ts/logcontext.classes.logmap.ts new file mode 100644 index 0000000..9033a40 --- /dev/null +++ b/ts/logcontext.classes.logmap.ts @@ -0,0 +1,34 @@ +import * as plugins from './logcontext.plugins'; + +import { Namespace } from 'smartcls'; +import { Stringmap } from 'lik'; + +export class LogMap { + clsNamespace: Namespace; + paramMap = new plugins.lik.Stringmap(); + + constructor(clsNamespaceArg: Namespace) { + this.clsNamespace = clsNamespaceArg; + } + + addData(paramName: string, logData) { + this.paramMap.addString(paramName); + this.clsNamespace.set(paramName, logData); + } + + deleteData(paramName: string) { + this.clsNamespace.set(paramName, null); + } + + getData(paramName: string) { + return this.clsNamespace.get(paramName); + } + + getAllData() { + let returnObject = {}; + for (let stringArg of this.paramMap.getStringArray()) { + returnObject[stringArg] = this.clsNamespace.get(stringArg); + } + return returnObject; + } +} diff --git a/ts/logcontext.plugins.ts b/ts/logcontext.plugins.ts index 97b63a3..1bcd23c 100644 --- a/ts/logcontext.plugins.ts +++ b/ts/logcontext.plugins.ts @@ -1 +1,7 @@ -import 'typings-global' +import 'typings-global'; + +import * as lik from 'lik'; +import * as smartcls from 'smartcls'; +import * as shortid from 'shortid'; + +export { lik, smartcls, shortid }; diff --git a/yarn.lock b/yarn.lock index cd747c6..67362ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,31 +2,47 @@ # yarn lockfile v1 -"@types/code@^4.0.3": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/code/-/code-4.0.3.tgz#9c4de39f86eb3eba070146d2dab7dbc3f8eac35f" - -"@types/glob@*": - version "5.0.33" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.33.tgz#3dff7c6ce09d65abe919c7961dc3dee016f36ad7" +"@types/chai-as-promised@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz#010b04cde78eacfb6e72bfddb3e58fe23c2e78b9" + dependencies: + "@types/chai" "*" + +"@types/chai-string@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@types/chai-string/-/chai-string-1.4.0.tgz#c8b78deb9ae53e86c05a446c256138faeaff53c1" + dependencies: + "@types/chai" "*" + +"@types/chai@*", "@types/chai@^4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.2.tgz#f1af664769cfb50af805431c407425ed619daa21" + +"@types/continuation-local-storage@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@types/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#a33e0df9dce9b424d1c98fc4fdebd8578dceec7e" dependencies: - "@types/minimatch" "*" "@types/node" "*" -"@types/minimatch@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.1.tgz#b683eb60be358304ef146f5775db4c0e3696a550" +"@types/lodash@^4.14.97": + version "4.14.104" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.104.tgz#53ee2357fa2e6e68379341d92eb2ecea4b11bb80" -"@types/node@*", "@types/node@^8.0.33": - version "8.0.34" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.34.tgz#55f801fa2ddb2a40dd6dfc15ecfe1dde9c129fe9" +"@types/minimatch@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" -"@types/shelljs@^0.7.4": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.4.tgz#137b5f31306eaff4de120ffe5b9d74b297809cfc" - dependencies: - "@types/glob" "*" - "@types/node" "*" +"@types/node@*": + version "8.0.51" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb" + +"@types/node@^9.4.6": + version "9.4.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.6.tgz#d8176d864ee48753d053783e4e463aec86b8d82e" + +"@types/shortid@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/shortid/-/shortid-0.0.29.tgz#8093ee0416a6e2bf2aa6338109114b3fbffa0e9b" "@types/which@^1.0.28": version "1.0.28" @@ -36,6 +52,17 @@ ansi-256-colors@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-256-colors/-/ansi-256-colors-1.1.0.tgz#910de50efcc7c09e3d82f2f87abd6b700c18818a" +assertion-error@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + +async-listener@^0.6.0: + version "0.6.8" + resolved "https://registry.yarnpkg.com/async-listener/-/async-listener-0.6.8.tgz#d3556ef905d5ad77b52e52b37d68b1d8a02481f5" + dependencies: + semver "^5.3.0" + shimmer "^1.1.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -58,16 +85,48 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -code@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/code/-/code-5.1.0.tgz#205e4213536c3cf21b12194384901fadcd81bc1a" +chai-as-promised@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" dependencies: - hoek "4.x.x" + check-error "^1.0.2" + +chai-string@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/chai-string/-/chai-string-1.4.0.tgz#359140c051d36a4e4b1a5fc6b910152f438a8d49" + +chai@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" + dependencies: + assertion-error "^1.0.1" + check-error "^1.0.1" + deep-eql "^3.0.0" + get-func-name "^2.0.0" + pathval "^1.0.0" + type-detect "^4.0.0" + +check-error@^1.0.1, check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" +continuation-local-storage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.0.tgz#e19fc36b597090a5d4e4a3b2ea3ebc5e29694a24" + dependencies: + async-listener "^0.6.0" + emitter-listener "^1.0.1" + +deep-eql@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + dependencies: + type-detect "^4.0.0" + define-properties@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" @@ -83,6 +142,12 @@ early@^2.1.1: smartq "^1.1.1" typings-global "^1.0.16" +emitter-listener@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.0.1.tgz#b2499ea6e58230a52c268d5df261eecd9f10fe97" + dependencies: + shimmer "1.0.0" + es-abstract@^1.5.1: version "1.9.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227" @@ -117,6 +182,10 @@ function-bind@^1.0.2, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + glob@^7.0.0: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" @@ -134,10 +203,6 @@ has@^1.0.1: dependencies: function-bind "^1.0.2" -hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -189,6 +254,21 @@ left-pad@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.1.3.tgz#612f61c033f3a9e08e939f1caebeea41b6f3199a" +lik@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/lik/-/lik-2.0.5.tgz#1338a3201828b557fa91a5b8a6013743ff720e10" + dependencies: + "@types/lodash" "^4.14.97" + "@types/minimatch" "^3.0.3" + lodash "^4.17.4" + minimatch "^3.0.4" + smartq "^1.1.6" + symbol-tree "^3.2.2" + +lodash@^4.17.4: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + memwatch-next@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/memwatch-next/-/memwatch-next-0.3.0.tgz#2111050f9a906e0aa2d72a4ec0f0089c78726f8f" @@ -235,6 +315,10 @@ path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" +pathval@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + pretty-bytes@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" @@ -246,8 +330,8 @@ rechoir@^0.6.2: resolve "^1.1.6" resolve@^1.1.6: - version "1.4.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" dependencies: path-parse "^1.0.5" @@ -263,15 +347,38 @@ shelljs@^0.7.8: interpret "^1.0.0" rechoir "^0.6.2" -smartchai@^1.0.3: - version "1.0.8" - resolved "https://registry.yarnpkg.com/smartchai/-/smartchai-1.0.8.tgz#a074836f4ddd4b98c50f1e7ae9e8e8ad9f6f1902" +shimmer@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.0.0.tgz#49c2d71c678360b802be18b278382d1cbb805c39" + +shimmer@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.1.0.tgz#97d7377137ffbbab425522e429fe0aa89a488b35" + +shortid@^2.2.8: + version "2.2.8" + resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.8.tgz#033b117d6a2e975804f6f0969dbe7d3d0b355131" + +smartchai@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/smartchai/-/smartchai-2.0.1.tgz#d20f17221f0e3c6c3473600b78ddfba0ab0ea762" dependencies: - "@types/code" "^4.0.3" - code "^5.1.0" + "@types/chai" "^4.1.2" + "@types/chai-as-promised" "^7.1.0" + "@types/chai-string" "^1.4.0" + chai "^4.1.2" + chai-as-promised "^7.1.1" + chai-string "^1.4.0" + +smartcls@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/smartcls/-/smartcls-1.0.3.tgz#69875cd8de037f8a05878c9db9b9baac051e81be" + dependencies: + "@types/continuation-local-storage" "^3.2.1" + continuation-local-storage "^3.2.0" typings-global "^1.0.20" -smartdelay@^1.0.3: +smartdelay@^1.0.3, smartdelay@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/smartdelay/-/smartdelay-1.0.4.tgz#791c1a4ee6770494064c10b1d2d2b8e6f3105b82" dependencies: @@ -286,31 +393,36 @@ smartq@^1.1.1, smartq@^1.1.6: util.promisify "^1.0.0" smartshell@^1.0.6: - version "1.0.18" - resolved "https://registry.yarnpkg.com/smartshell/-/smartshell-1.0.18.tgz#b84ccc65cedf3a875bf676cec78ee07f4b4aa9e5" + version "1.0.19" + resolved "https://registry.yarnpkg.com/smartshell/-/smartshell-1.0.19.tgz#459c7a9fab8a25007848ffc711b7a817dd6ffc00" dependencies: - "@types/shelljs" "^0.7.4" "@types/which" "^1.0.28" shelljs "^0.7.8" smartq "^1.1.6" - typings-global "^1.0.20" + typings-global "^1.0.23" which "^1.3.0" -tapbundle@^1.0.13: - version "1.1.8" - resolved "https://registry.yarnpkg.com/tapbundle/-/tapbundle-1.1.8.tgz#e08aee0e100a830d8a26a583a85d37ce53312e02" +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + +tapbundle@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tapbundle/-/tapbundle-2.0.0.tgz#79fce68ff185c786fabaf6eb589a4afc7d2714b7" dependencies: - "@types/node" "^8.0.33" early "^2.1.1" leakage "^0.3.0" - smartchai "^1.0.3" + smartchai "^2.0.0" smartdelay "^1.0.3" smartq "^1.1.1" - typings-global "^1.0.19" -typings-global@^1.0.14, typings-global@^1.0.16, typings-global@^1.0.19, typings-global@^1.0.20: - version "1.0.20" - resolved "https://registry.yarnpkg.com/typings-global/-/typings-global-1.0.20.tgz#3da769c54db538247c5d877d1d9e97eb2ec981ff" +type-detect@^4.0.0: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + +typings-global@^1.0.14, typings-global@^1.0.16, typings-global@^1.0.19, typings-global@^1.0.20, typings-global@^1.0.23: + version "1.0.23" + resolved "https://registry.yarnpkg.com/typings-global/-/typings-global-1.0.23.tgz#cdd085803049dd07d95b2e1475243c6b2db378ab" dependencies: semver "^5.3.0" smartshell "^1.0.6"