Skip to content

Commit

Permalink
fix: logging (#652)
Browse files Browse the repository at this point in the history
* fix(logger): fix regression #651

* fix(types): better types for logger
  • Loading branch information
H4ad committed May 21, 2023
1 parent d5246a7 commit dfcb71a
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 57 deletions.
121 changes: 116 additions & 5 deletions __tests__/integration.js
Expand Up @@ -522,19 +522,130 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo
// expect(customLogger.debug.mock.calls.length).toBe(0)
})

test('custom levels', () => {
const loggerError = serverlessExpressLogger({ level: 'error' })

loggerError.error('error')
loggerError.info('nocall')
loggerError.warn('nocall')
loggerError.debug('nocall')
loggerError.verbose('nocall')
expect(global.console.warn).not.toHaveBeenCalled()
expect(global.console.debug).not.toHaveBeenCalled()
expect(global.console.info).not.toHaveBeenCalled()
expect(global.console.error).toHaveBeenLastCalledWith({
message: 'error'
})

const loggerWarn = serverlessExpressLogger({ level: 'warn' })

loggerWarn.error('error2')
loggerWarn.warn('warn2')
loggerWarn.info('nocall')
loggerWarn.debug('nocall')
loggerWarn.verbose('nocall')
expect(global.console.debug).not.toHaveBeenCalled()
expect(global.console.info).not.toHaveBeenCalled()
expect(global.console.error).toHaveBeenLastCalledWith({
message: 'error2'
})
expect(global.console.warn).toHaveBeenLastCalledWith({
message: 'warn2'
})

const loggerInfo = serverlessExpressLogger({ level: 'info' })

loggerInfo.error('error3')
loggerInfo.warn('warn3')
loggerInfo.info('info3')
loggerInfo.debug('nocall')
loggerInfo.verbose('nocall')
expect(global.console.debug).not.toHaveBeenCalled()
expect(global.console.error).toHaveBeenLastCalledWith({
message: 'error3'
})
expect(global.console.warn).toHaveBeenLastCalledWith({
message: 'warn3'
})
expect(global.console.info).toHaveBeenLastCalledWith({
message: 'info3'
})

const loggerVerbose = serverlessExpressLogger({ level: 'verbose' })

loggerVerbose.error('error4')
loggerVerbose.warn('warn4')
loggerVerbose.info('info4')
loggerVerbose.verbose('verbose4')
loggerVerbose.debug('nocall')
expect(global.console.error).toHaveBeenLastCalledWith({
message: 'error4'
})
expect(global.console.warn).toHaveBeenLastCalledWith({
message: 'warn4'
})
expect(global.console.info).toHaveBeenLastCalledWith({
message: 'info4'
})
expect(global.console.debug).toHaveBeenLastCalledWith({
message: 'verbose4'
})

const loggerDebug = serverlessExpressLogger({ level: 'debug' })

loggerDebug.error('error5')
loggerDebug.warn('warn5')
loggerDebug.info('info5')
loggerDebug.verbose('verbose5')
loggerDebug.debug('debug5')
expect(global.console.error).toHaveBeenLastCalledWith({
message: 'error5'
})
expect(global.console.warn).toHaveBeenLastCalledWith({
message: 'warn5'
})
expect(global.console.info).toHaveBeenLastCalledWith({
message: 'info5'
})
expect(global.console.debug).toHaveBeenLastCalledWith({
message: 'debug5'
})
})

test('lazy print of logger', async () => {
const logger = serverlessExpressLogger()
const logger = serverlessExpressLogger({ level: 'debug' })

logger.debug('simple message')
logger.debug('debug', () => '=true', ' works')
logger.debug(() => 'debug')
logger.debug('array', ['message'])

expect(global.console.debug).not.toHaveBeenNthCalledWith(
expect(global.console.debug).toHaveBeenNthCalledWith(
1,
'debug=true works'
{
message: 'simple message'
}
)
expect(global.console.debug).not.toHaveBeenNthCalledWith(
expect(global.console.debug).toHaveBeenNthCalledWith(
2,
'debug'
{
message: 'debug',
0: '=true',
1: ' works'
}
)
expect(global.console.debug).toHaveBeenNthCalledWith(
3,
{
message: 'debug'
}
)
expect(global.console.debug).toHaveBeenNthCalledWith(
4,
{
message: 'array',
0: ['message']
}
)
})
})
Expand Down
14 changes: 6 additions & 8 deletions src/configure.d.ts
@@ -1,9 +1,9 @@
import { RequestListener } from "http";
import { Handler } from "aws-lambda";
import Logger from "./logger";
import Framework from "./frameworks";
import { RequestListener } from 'http';
import { Handler } from 'aws-lambda';
import { Logger } from './logger';
import Framework from './frameworks';

type EventSources = "AWS_SNS" | "AWS_DYNAMODB" | "AWS_EVENTBRIDGE" | "AWS_SQS" | "AWS_KINESIS_DATA_STREAM";
type EventSources = 'AWS_SNS' | 'AWS_DYNAMODB' | 'AWS_EVENTBRIDGE' | 'AWS_SQS' | 'AWS_KINESIS_DATA_STREAM';

interface EventSource {
getRequest?: any; // TODO:
Expand Down Expand Up @@ -49,9 +49,7 @@ export interface ConfigureResult<TEvent = any, TResult = any> {
proxy: (proxyParams: ProxyParams) => Promise<Object>;
}

declare function configure<TEvent = any, TResult = any>(
configureParams: ConfigureParams
): Handler<TEvent, TResult> & ConfigureResult<TEvent, TResult>;
declare function configure<TEvent = any, TResult = any>(configureParams: ConfigureParams): Handler<TEvent, TResult> & ConfigureResult<TEvent, TResult>;

// declare function proxy(proxyParams: ProxyParams): Promise<any>

Expand Down
15 changes: 10 additions & 5 deletions src/logger.d.ts
@@ -1,7 +1,12 @@
interface Logger {
info: (message: string, additional: Object) => void
debug: (message: string, additional: Object) => void
error: (message: string, additional: Object) => void
export interface Logger {
info: (message: string, ...additional: Object[]) => void;
debug: (message: string, ...additional: Object[]) => void;
error: (message: string, ...additional: Object[]) => void;
warn: (message: string, ...additional: Object[]) => void;
verbose: (message: string, ...additional: Object[]) => void;
}
interface Options {
level?: 'error' | 'warn' | 'info' | 'verbose' | 'debug' | string;
}

export default Logger
export default function logger(options?: Options): Logger;
93 changes: 54 additions & 39 deletions src/logger.js
@@ -1,49 +1,64 @@
const lazyPrint = (value) => {
if (typeof value === 'function') { return value() }
const lazyPrint = value => {
if (typeof value === 'function') {
return value()
}

return value
}

function logger ({
level = 'error'
} = {}) {
return {
error (message, ...additional) {
if (!level.includes('debug', 'verbose', 'info', 'warn', 'error')) return
console.error({
message: lazyPrint(message),
...additional.map(lazyPrint)
})
},
warn (message, ...additional) {
if (!level.includes('debug', 'verbose', 'info', 'warn')) return
console.warn({
message: lazyPrint(message),
...additional.map(lazyPrint)
})
},
info (message, additional) {
if (!level.includes('debug', 'verbose', 'info')) return
console.info({
message: lazyPrint(message),
...additional.map(lazyPrint)
})
},
verbose (message, additional) {
if (!level.includes('debug', 'verbose')) return
console.debug({
message: lazyPrint(message),
...additional.map(lazyPrint)
})
},
debug (message, additional) {
if (level !== 'debug') return
console.debug({
const logLevels = {
debug: [
['debug', 'debug'],
['verbose', 'debug'],
['info', 'info'],
['error', 'error'],
['warn', 'warn']
],
verbose: [
['verbose', 'debug'],
['info', 'info'],
['error', 'error'],
['warn', 'warn']
],
info: [
['info', 'info'],
['error', 'error'],
['warn', 'warn']
],
warn: [
['warn', 'warn'],
['error', 'error']
],
error: [['error', 'error']],
none: []
}

const print =
fn =>
(message, ...additional) =>
console[fn]({
message: lazyPrint(message),
...additional.map(lazyPrint)
...(Array.isArray(additional) ? additional.map(lazyPrint) : [])
})
}

const NO_OP = () => {}

function logger ({ level = 'error' } = {}) {
const levels = logLevels[level]

const logger = {
error: NO_OP,
debug: NO_OP,
info: NO_OP,
verbose: NO_OP,
warn: NO_OP
}

if (!levels) return logger

for (const [level2, consoleMethod] of levels) logger[level2] = print(consoleMethod)

return logger
}

module.exports = logger

0 comments on commit dfcb71a

Please sign in to comment.