From 210df1de21e159ff1b1c73e326b52f0639c2ee81 Mon Sep 17 00:00:00 2001 From: Peter Somogyvari Date: Thu, 14 May 2020 12:58:32 -0700 Subject: [PATCH] feat(bif-common): adds new pkg with logger It is a universal package by design meaning that it works in the browser and also in NodeJS which allows both the API server and the cockpit to use the logger from the common package. Signed-off-by: Peter Somogyvari --- package.json | 1 + packages/bif-cmd-api-server/package.json | 1 + .../src/main/typescript/api-server.ts | 9 ++- .../main/typescript/config/config-service.ts | 16 ++++- packages/bif-cockpit/package.json | 1 + packages/bif-cockpit/src/app/app.component.ts | 7 +++ packages/bif-common/README.md | 9 +++ packages/bif-common/package-lock.json | 18 ++++++ packages/bif-common/package.json | 52 +++++++++++++++ .../bif-common/src/main/typescript/index.ts | 1 + .../typescript/logging/logger-provider.ts | 15 +++++ .../src/main/typescript/logging/logger.ts | 63 +++++++++++++++++++ .../src/main/typescript/public-api.ts | 2 + .../typescript/integration/api-surface.ts | 11 ++++ .../integration/tap-parallel-not-ok | 0 .../src/test/typescript/unit/api-surface.ts | 11 ++++ packages/bif-common/tsconfig.json | 10 +++ 17 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 packages/bif-common/README.md create mode 100644 packages/bif-common/package-lock.json create mode 100644 packages/bif-common/package.json create mode 100755 packages/bif-common/src/main/typescript/index.ts create mode 100644 packages/bif-common/src/main/typescript/logging/logger-provider.ts create mode 100644 packages/bif-common/src/main/typescript/logging/logger.ts create mode 100755 packages/bif-common/src/main/typescript/public-api.ts create mode 100644 packages/bif-common/src/test/typescript/integration/api-surface.ts create mode 100755 packages/bif-common/src/test/typescript/integration/tap-parallel-not-ok create mode 100644 packages/bif-common/src/test/typescript/unit/api-surface.ts create mode 100644 packages/bif-common/tsconfig.json diff --git a/package.json b/package.json index e6d58cf738..33247beda7 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "private": true, "scripts": { "configure": "lerna clean --yes && lerna bootstrap && npm run build && node ./tools/generate-api-server-config.js", + "start": "node ./packages/bif-cmd-api-server/dist/lib/main/typescript/cmd/bif-api.js --config-file=.config.json", "tsc": "lerna exec --stream --ignore '*/*cockpit' -- tsc --project ./tsconfig.json", "clean": "lerna exec --stream --ignore '*/*cockpit' -- del-cli dist/**", "build": "npm-run-all --parallel build:frontend build:backend", diff --git a/packages/bif-cmd-api-server/package.json b/packages/bif-cmd-api-server/package.json index 6b2c381d3c..b4fbd85642 100755 --- a/packages/bif-cmd-api-server/package.json +++ b/packages/bif-cmd-api-server/package.json @@ -46,6 +46,7 @@ "homepage": "https://github.com/hyperledger-labs/blockchain-integration-framework#readme", "dependencies": { "@hyperledger-labs/bif-cockpit": "0.2.0", + "@hyperledger-labs/bif-common": "0.2.0", "@hyperledger-labs/bif-core-api": "0.2.0", "@hyperledger-labs/bif-plugin-keychain-memory": "0.2.0", "@hyperledger-labs/bif-plugin-kv-storage-memory": "0.2.0", diff --git a/packages/bif-cmd-api-server/src/main/typescript/api-server.ts b/packages/bif-cmd-api-server/src/main/typescript/api-server.ts index 16ad49f822..c9e3883861 100644 --- a/packages/bif-cmd-api-server/src/main/typescript/api-server.ts +++ b/packages/bif-cmd-api-server/src/main/typescript/api-server.ts @@ -8,6 +8,7 @@ import { IPluginKVStorage, PluginFactory } from '@hyperledger-labs/bif-core-api' import { CreateConsortiumEndpointV1 } from './consortium/routes/create-consortium-endpoint-v1'; import { IBifApiServerOptions, ConfigService } from './config/config-service'; import { BIF_OPEN_API_JSON } from './openapi-spec'; +import { Logger, LoggerProvider } from '@hyperledger-labs/bif-common'; export interface IApiServerConstructorOptions { config: Config; @@ -15,6 +16,8 @@ export interface IApiServerConstructorOptions { export class ApiServer { + private readonly log: Logger; + constructor(public readonly options: IApiServerConstructorOptions) { if (!options) { throw new Error(`ApiServer#ctor options was falsy`); @@ -22,6 +25,7 @@ export class ApiServer { if (!options.config) { throw new Error(`ApiServer#ctor options.config was falsy`); } + this.log = LoggerProvider.getOrCreate({ label: 'api-server', level: options.config.get('logLevel') }); } async start(): Promise { @@ -34,7 +38,10 @@ export class ApiServer { const app: Express = express(); const cockpitWwwRoot = this.options.config.get('cockpitWwwRoot'); - app.use(express.static(cockpitWwwRoot)); + this.log.info(`cockpitWwwRoot: ${cockpitWwwRoot}`); + const resolvedWwwRoot = path.resolve(process.cwd(), cockpitWwwRoot); + this.log.info(`resolvedWwwRoot: ${resolvedWwwRoot}`); + app.use(express.static(resolvedWwwRoot)); const cockpitPort: number = this.options.config.get('cockpitPort'); const cockpitHost: string = this.options.config.get('cockpitHost'); diff --git a/packages/bif-cmd-api-server/src/main/typescript/config/config-service.ts b/packages/bif-cmd-api-server/src/main/typescript/config/config-service.ts index 6d111cc48a..ecb3e0922f 100644 --- a/packages/bif-cmd-api-server/src/main/typescript/config/config-service.ts +++ b/packages/bif-cmd-api-server/src/main/typescript/config/config-service.ts @@ -2,10 +2,12 @@ import { randomBytes } from 'crypto'; import convict, { Schema, Config, SchemaObj } from 'convict'; import secp256k1 from 'secp256k1'; import { v4 as uuidV4 } from 'uuid'; +import { LoggerProvider, Logger } from '@hyperledger-labs/bif-common'; export interface IBifApiServerOptions { configFile: string; bifNodeId: string; + logLevel: string; cockpitHost: string; cockpitPort: number; cockpitWwwRoot: string; @@ -64,6 +66,14 @@ export class ConfigService { env: 'BIF_NODE_ID', arg: 'bif-node-id', }, + logLevel: { + doc: 'The level at which loggers should be configured. Supported values include the following: ' + + 'error, warn, info, debug, trace', + format: ConfigService.formatNonBlankString, + default: 'warn', + env: 'LOG_LEVEL', + arg: 'log-level', + }, cockpitHost: { doc: 'The host to bind the Cockpit webserver to. Secure default is: 127.0.0.1. Use 0.0.0.0 to bind for any host.', format: 'ipaddress', @@ -83,7 +93,7 @@ export class ConfigService { format: '*', env: 'COCKPIT_WWW_ROOT', arg: 'cockpit-www-root', - default: 'node_modules/@hyperledger-labs/bif-cockpit/www/', + default: 'packages/bif-cmd-api-server/node_modules/@hyperledger-labs/bif-cockpit/www/', }, apiHost: { doc: 'The host to bind the API to. Secure default is: 127.0.0.1. Use 0.0.0.0 to bind for any host.', @@ -200,6 +210,7 @@ export class ConfigService { return { configFile: '.config.json', bifNodeId: uuidV4(), + logLevel: 'debug', publicKey, privateKey, apiCorsDomainCsv: (schema.apiCorsDomainCsv as SchemaObj).default, @@ -227,6 +238,9 @@ export class ConfigService { } ConfigService.config.validate(); this.validateKeyPairMatch(); + const level = ConfigService.config.get('logLevel'); + const logger: Logger = LoggerProvider.getOrCreate({ label: 'config-service', level }); + logger.info('Configuration validation OK.'); } return ConfigService.config; } diff --git a/packages/bif-cockpit/package.json b/packages/bif-cockpit/package.json index d03e053def..915978291d 100644 --- a/packages/bif-cockpit/package.json +++ b/packages/bif-cockpit/package.json @@ -22,6 +22,7 @@ "@angular/platform-browser-dynamic": "8.2.14", "@angular/router": "8.2.14", "@capacitor/core": "1.5.1", + "@hyperledger-labs/bif-common": "0.2.0", "@ionic-native/core": "5.0.0", "@ionic-native/splash-screen": "5.0.0", "@ionic-native/status-bar": "5.0.0", diff --git a/packages/bif-cockpit/src/app/app.component.ts b/packages/bif-cockpit/src/app/app.component.ts index 433cd5f63d..66ac7432f5 100644 --- a/packages/bif-cockpit/src/app/app.component.ts +++ b/packages/bif-cockpit/src/app/app.component.ts @@ -4,6 +4,8 @@ import { Platform } from '@ionic/angular'; import { SplashScreen } from '@ionic-native/splash-screen/ngx'; import { StatusBar } from '@ionic-native/status-bar/ngx'; +import { LoggerProvider, Logger } from '@hyperledger-labs/bif-common'; + @Component({ selector: 'app-root', templateUrl: 'app.component.html', @@ -45,11 +47,15 @@ export class AppComponent implements OnInit { ]; public labels = ['Family', 'Friends', 'Notes', 'Work', 'Travel', 'Reminders']; + private readonly logger: Logger; + constructor( private platform: Platform, private splashScreen: SplashScreen, private statusBar: StatusBar ) { + this.logger = LoggerProvider.getOrCreate({ label: 'app-component', level: 'debug' }); + this.logger.info('Initializing app...'); this.initializeApp(); } @@ -57,6 +63,7 @@ export class AppComponent implements OnInit { this.platform.ready().then(() => { this.statusBar.styleDefault(); this.splashScreen.hide(); + this.logger.info('App initialized OK. Splashscreen was hidden.'); }); } diff --git a/packages/bif-common/README.md b/packages/bif-common/README.md new file mode 100644 index 0000000000..27af34b73e --- /dev/null +++ b/packages/bif-common/README.md @@ -0,0 +1,9 @@ +# `@hyperledger-labs/bif-common` + +> TODO: description + +## Usage + +``` +// TODO: DEMONSTRATE API +``` diff --git a/packages/bif-common/package-lock.json b/packages/bif-common/package-lock.json new file mode 100644 index 0000000000..2afa224321 --- /dev/null +++ b/packages/bif-common/package-lock.json @@ -0,0 +1,18 @@ +{ + "name": "@hyperledger-labs/bif-common", + "version": "0.2.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "loglevel": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz", + "integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==" + }, + "loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==" + } + } +} diff --git a/packages/bif-common/package.json b/packages/bif-common/package.json new file mode 100644 index 0000000000..353f97ec40 --- /dev/null +++ b/packages/bif-common/package.json @@ -0,0 +1,52 @@ +{ + "name": "@hyperledger-labs/bif-common", + "version": "0.2.0", + "description": "Universal library used by both front end and back end components of BIF. Aims to be a developer swiss army knife.", + "main": "dist/bif-common.node.umd.js", + "mainMinified": "dist/bif-common.node.umd.min.js", + "browser": "dist/bif-common.web.umd.js", + "browserMinified": "dist/bif-common.web.umd.min.js", + "module": "dist/lib/main/typescript/index.js", + "types": "dist/types/main/typescript/index.d.ts", + "files": [ + "dist/*" + ], + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/hyperledger-labs/blockchain-integration-framework.git" + }, + "keywords": [ + "Hyperledger", + "Blockchain", + "Interoperability", + "Integration" + ], + "author": { + "name": "Peter Somogyvari", + "email": "peter.somogyvari@accenture.com", + "url": "https://accenture.com" + }, + "contributors": [ + { + "name": "Please add yourself to the list of contributors", + "email": "your.name@example.com", + "url": "https://example.com" + } + ], + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/hyperledger-labs/blockchain-integration-framework/issues" + }, + "homepage": "https://github.com/hyperledger-labs/blockchain-integration-framework#readme", + "dependencies": { + "loglevel": "1.6.7", + "loglevel-plugin-prefix": "0.8.4" + } +} diff --git a/packages/bif-common/src/main/typescript/index.ts b/packages/bif-common/src/main/typescript/index.ts new file mode 100755 index 0000000000..7e1a213e3e --- /dev/null +++ b/packages/bif-common/src/main/typescript/index.ts @@ -0,0 +1 @@ +export * from './public-api'; diff --git a/packages/bif-common/src/main/typescript/logging/logger-provider.ts b/packages/bif-common/src/main/typescript/logging/logger-provider.ts new file mode 100644 index 0000000000..a55b0305f6 --- /dev/null +++ b/packages/bif-common/src/main/typescript/logging/logger-provider.ts @@ -0,0 +1,15 @@ +import { Logger, ILoggerOptions } from './logger'; + +export class LoggerProvider { + + private static loggers: Map = new Map(); + + public static getOrCreate(loggerOptions: ILoggerOptions) { + let logger: Logger | undefined = LoggerProvider.loggers.get(loggerOptions.label); + if (!logger) { + logger = new Logger(loggerOptions); + LoggerProvider.loggers.set(loggerOptions.label, logger); + } + return logger; + } +} diff --git a/packages/bif-common/src/main/typescript/logging/logger.ts b/packages/bif-common/src/main/typescript/logging/logger.ts new file mode 100644 index 0000000000..d181232fe1 --- /dev/null +++ b/packages/bif-common/src/main/typescript/logging/logger.ts @@ -0,0 +1,63 @@ +import libLogLevel, { Logger as LogLevelLogger, levels } from 'loglevel'; +import prefix from 'loglevel-plugin-prefix'; + +prefix.reg(libLogLevel); + +prefix.apply(libLogLevel, { + template: '[%t] %l (%n):', + levelFormatter(level) { + return level.toUpperCase(); + }, + nameFormatter(name) { + return name || 'global'; + }, + timestampFormatter(date) { + return date.toISOString(); + }, +}); + +export interface ILoggerOptions { + label: string; + level?: string; +} + +/** + * Levels: + * - error: 0, + * - warn: 1, + * - info: 2, + * - debug: 3, + * - trace: 4 + */ +export class Logger { + + private readonly backend: LogLevelLogger; + + constructor(public readonly options: ILoggerOptions) { + const level: string = options.level || 'warn'; + this.backend = libLogLevel.getLogger(options.label); + this.backend.setLevel(level.toUpperCase() as any); + } + + public async shutdown(gracePeriodMillis: number = 60000): Promise { + this.backend.info('Shut down logger OK.'); + } + + public error(...msg: any[]): void { + this.backend.error(...msg); + } + + public warn(...msg: any[]): void { + this.backend.warn(...msg); + } + public info(...msg: any[]): void { + this.backend.info(...msg); + } + public debug(...msg: any[]): void { + this.backend.debug(...msg); + } + public trace(...msg: any[]): void { + this.backend.trace(...msg); + } + +} diff --git a/packages/bif-common/src/main/typescript/public-api.ts b/packages/bif-common/src/main/typescript/public-api.ts new file mode 100755 index 0000000000..d12a72643c --- /dev/null +++ b/packages/bif-common/src/main/typescript/public-api.ts @@ -0,0 +1,2 @@ +export { LoggerProvider } from './logging/logger-provider'; +export { Logger, ILoggerOptions } from './logging/logger'; diff --git a/packages/bif-common/src/test/typescript/integration/api-surface.ts b/packages/bif-common/src/test/typescript/integration/api-surface.ts new file mode 100644 index 0000000000..0546ac7e03 --- /dev/null +++ b/packages/bif-common/src/test/typescript/integration/api-surface.ts @@ -0,0 +1,11 @@ +// tslint:disable-next-line: no-var-requires +const tap = require('tap'); +import { Logger, LoggerProvider } from '../../../main/typescript/public-api'; + +tap.pass('Test file can be executed'); + +tap.test('Library can be loaded', (assert: any) => { + assert.plan(2); + assert.ok(Logger); + assert.ok(LoggerProvider); +}); diff --git a/packages/bif-common/src/test/typescript/integration/tap-parallel-not-ok b/packages/bif-common/src/test/typescript/integration/tap-parallel-not-ok new file mode 100755 index 0000000000..e69de29bb2 diff --git a/packages/bif-common/src/test/typescript/unit/api-surface.ts b/packages/bif-common/src/test/typescript/unit/api-surface.ts new file mode 100644 index 0000000000..0546ac7e03 --- /dev/null +++ b/packages/bif-common/src/test/typescript/unit/api-surface.ts @@ -0,0 +1,11 @@ +// tslint:disable-next-line: no-var-requires +const tap = require('tap'); +import { Logger, LoggerProvider } from '../../../main/typescript/public-api'; + +tap.pass('Test file can be executed'); + +tap.test('Library can be loaded', (assert: any) => { + assert.plan(2); + assert.ok(Logger); + assert.ok(LoggerProvider); +}); diff --git a/packages/bif-common/tsconfig.json b/packages/bif-common/tsconfig.json new file mode 100644 index 0000000000..d90c929ef9 --- /dev/null +++ b/packages/bif-common/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist/lib/", /* Redirect output structure to the directory. */ + "declarationDir": "dist/types", + }, + "include": [ + "./src" + ] +} \ No newline at end of file