From 6573e70ad4360bb890b785d05cfe8c4a338465f0 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sun, 26 Aug 2018 11:50:33 -0400 Subject: [PATCH] grpc-js-core: implement setLogger() and setLogVerbosity() These were missing from the pure JS implementation. This commit adds them. --- packages/grpc-js-core/src/constants.ts | 6 +++ packages/grpc-js-core/src/index.ts | 12 +++-- packages/grpc-js-core/src/logging.ts | 22 ++++++++ packages/grpc-js-core/test/test-logging.ts | 60 ++++++++++++++++++++++ 4 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 packages/grpc-js-core/src/logging.ts create mode 100644 packages/grpc-js-core/test/test-logging.ts diff --git a/packages/grpc-js-core/src/constants.ts b/packages/grpc-js-core/src/constants.ts index a72f3388..0a0142ec 100644 --- a/packages/grpc-js-core/src/constants.ts +++ b/packages/grpc-js-core/src/constants.ts @@ -17,3 +17,9 @@ export enum Status { DATA_LOSS, UNAUTHENTICATED } + +export enum LogVerbosity { + DEBUG = 0, + INFO, + ERROR +} diff --git a/packages/grpc-js-core/src/index.ts b/packages/grpc-js-core/src/index.ts index 6372f22b..b285c681 100644 --- a/packages/grpc-js-core/src/index.ts +++ b/packages/grpc-js-core/src/index.ts @@ -4,10 +4,11 @@ import {IncomingHttpHeaders} from 'http'; import {CallCredentials} from './call-credentials'; import {ChannelCredentials} from './channel-credentials'; import {Client} from './client'; -import {Status} from './constants'; +import {LogVerbosity, Status} from './constants'; import {loadPackageDefinition, makeClientConstructor} from './make-client'; import {Metadata} from './metadata'; import { Channel } from './channel'; +import * as logging from './logging'; interface IndexedObject { [key: string]: any; @@ -96,6 +97,7 @@ export {Metadata}; /**** Constants ****/ export { + LogVerbosity as logVerbosity, Status as status // TODO: Other constants as well }; @@ -135,12 +137,12 @@ export const load = (filename: any, format: any, options: any) => { 'Not available in this library. Use @grpc/proto-loader and loadPackageDefinition instead'); }; -export const setLogger = (logger: any) => { - throw new Error('Not yet implemented'); +export const setLogger = (logger: Partial): void => { + logging.setLogger(logger); }; -export const setLogVerbosity = (verbosity: any) => { - throw new Error('Not yet implemented'); +export const setLogVerbosity = (verbosity: LogVerbosity): void => { + logging.setLoggerVerbosity(verbosity); }; export const Server = (options: any) => { diff --git a/packages/grpc-js-core/src/logging.ts b/packages/grpc-js-core/src/logging.ts new file mode 100644 index 00000000..b5e151c4 --- /dev/null +++ b/packages/grpc-js-core/src/logging.ts @@ -0,0 +1,22 @@ +import {LogVerbosity} from './constants'; + +let _logger: Partial = console; +let _logVerbosity: LogVerbosity = LogVerbosity.DEBUG; + +export const getLogger = (): Partial => { + return _logger; +}; + +export const setLogger = (logger: Partial): void => { + _logger = logger; +}; + +export const setLoggerVerbosity = (verbosity: LogVerbosity): void => { + _logVerbosity = verbosity; +}; + +export const log = (severity: LogVerbosity, ...args: any[]): void => { + if (severity >= _logVerbosity && typeof _logger.error === 'function') { + _logger.error(...args); + } +}; diff --git a/packages/grpc-js-core/test/test-logging.ts b/packages/grpc-js-core/test/test-logging.ts new file mode 100644 index 00000000..c1c0c25b --- /dev/null +++ b/packages/grpc-js-core/test/test-logging.ts @@ -0,0 +1,60 @@ +import * as assert from 'assert'; + +import * as grpc from '../src'; +import * as logging from '../src/logging'; + +describe('Logging', () => { + afterEach(function() { + // Ensure that the logger is restored to its defaults after each test. + grpc.setLogger(console); + grpc.setLogVerbosity(grpc.logVerbosity.DEBUG); + }); + + it('logger defaults to console', () => { + assert.strictEqual(logging.getLogger(), console); + }); + + it('sets the logger to a new value', () => { + const logger: Partial = {}; + + logging.setLogger(logger); + assert.strictEqual(logging.getLogger(), logger); + }); + + it('gates logging based on severity', () => { + const output: any[] = []; + const logger: Partial = { + error(...args: any[]): void { + output.push(args); + } + }; + + logging.setLogger(logger); + + // The default verbosity (DEBUG) should log everything. + logging.log(grpc.logVerbosity.DEBUG, 'a', 'b', 'c'); + logging.log(grpc.logVerbosity.INFO, 'd', 'e'); + logging.log(grpc.logVerbosity.ERROR, 'f'); + + // The INFO verbosity should not log DEBUG data. + logging.setLoggerVerbosity(grpc.logVerbosity.INFO); + logging.log(grpc.logVerbosity.DEBUG, 1, 2, 3); + logging.log(grpc.logVerbosity.INFO, 'g'); + logging.log(grpc.logVerbosity.ERROR, 'h', 'i'); + + // The ERROR verbosity should not log DEBUG or INFO data. + logging.setLoggerVerbosity(grpc.logVerbosity.ERROR); + logging.log(grpc.logVerbosity.DEBUG, 4, 5, 6); + logging.log(grpc.logVerbosity.INFO, 7, 8); + logging.log(grpc.logVerbosity.ERROR, 'j', 'k'); + + assert.deepStrictEqual(output, [ + ['a', 'b', 'c'], + ['d', 'e'], + ['f'], + ['g'], + ['h', 'i'], + ['j', 'k'] + ]); + }); +});