Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added logger abstraction with default implementation #134

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@
"@babel/runtime": "^7.11.2",
"@jolocom/local-resolver-registrar": "^1.0.1",
"@jolocom/sdk-storage-typeorm": "^4.3.0-rc0",
"@types/app-root-path": "^1.2.4",
"@types/jest": "^26.0.10",
"@types/log4js": "^2.3.5",
"@types/node": "^13.9.8",
"@types/node-fetch": "^2.5.5",
"@types/ramda": "^0.26.8",
"@types/ws": "^7.2.6",
"@typescript-eslint/eslint-plugin": "^2.20.0",
"@typescript-eslint/parser": "^1.5.0",
"@zerollup/ts-transform-paths": "^1.7.17",
"app-root-path": "^3.0.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To define path to the default place to save logs here

"assert": "^2.0.0",
"babel-plugin-inline-import": "^3.0.0",
"babel-plugin-transform-typescript-metadata": "^0.2.2",
Expand All @@ -45,6 +48,7 @@
"fs-extra": "^8.1.0",
"jest": "^26.4.2",
"jolocom-lib": "^5.2.1",
"log4js": "^6.3.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have you compared this against other options for logging libraries? Why did you choose log4js in specific?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I compered with others (with winston specifically) and log4js more lightweight (~x3 times), has standardized log structure out of the box, easier configurable and faster (for example those results)

"mockdate": "^2.0.2",
"node-fetch": "^2.6.0",
"prettier": "^1.18.2",
Expand Down
66 changes: 66 additions & 0 deletions src/logger/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import appRootDir from 'app-root-path'
import { LoggerConfig, LoggerChannel, OutputType, Level } from './types'
import { configure as log4jsConfigure } from 'log4js'

const DEFAULT_MAX_LOG_SIZE = 5242880
const appendersConfigMap = (filePath: string) => ({
file: {
[LoggerChannel.SDK]: {
type: 'file',
filename: filePath + '/sdk.log',
maxLogSize: DEFAULT_MAX_LOG_SIZE,
},
[LoggerChannel.AGENT]: {
type: 'file',
filename: filePath + '/sdk_agent.log',
maxLogSize: DEFAULT_MAX_LOG_SIZE,
},
[LoggerChannel.INTERACTION]: {
type: 'file',
filename: filePath + '/sdk_interaction.log',
maxLogSize: DEFAULT_MAX_LOG_SIZE,
},
},
console: {
[LoggerChannel.SDK]: {
type: 'console',
},
[LoggerChannel.AGENT]: {
type: 'console',
},
[LoggerChannel.INTERACTION]: {
type: 'console',
},
},
})

export const configure = (clientConfig?: LoggerConfig): void => {
const appenders = {}
const categories = {}
let defaultCategoryLevel = Level.INFO

Object.values(LoggerChannel).forEach(channel => {
const channelConfig = clientConfig?.channelsConfig?.[channel] || null
const type = channelConfig?.outputType || OutputType.FILE
const level = channelConfig?.level || Level.INFO
const filePath = clientConfig?.logsDir || appRootDir + '/var/log'

appenders[channel] = appendersConfigMap(filePath)[type][channel]
categories[channel] = { appenders: [channel], level }

if (channel === LoggerChannel.SDK) {
defaultCategoryLevel = level
}
})

log4jsConfigure({
appenders: {
...appenders,
...(clientConfig?.customConfig?.appenders || {}),
},
categories: {
default: { appenders: [LoggerChannel.SDK], level: defaultCategoryLevel },
...{ ...categories, ...(clientConfig?.customConfig?.categories || {}) },
},
})
}
56 changes: 56 additions & 0 deletions src/logger/defaultLogger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { getLogger, Logger as Log4js } from 'log4js'
import { Logger } from './logger'
import { Level } from './types'

export class DefaultLogger implements Logger {
private readonly logger: Log4js
private readonly isEnabled: boolean

constructor(channelName: string, isEnabled = true) {
this.logger = getLogger(channelName)
this.isEnabled = isEnabled
}

/**
* @inheritDoc
*/
public debug(message: string, args: unknown[] = []): void {
this.log(Level.DEBUG, message, args)
}

/**
* @inheritDoc
*/
public info(message: string, args: unknown[] = []): void {
this.log(Level.INFO, message, args)
}

/**
* @inheritDoc
*/
public warn(message: string, args: unknown[] = []): void {
this.log(Level.WARNING, message, args)
}

/**
* @inheritDoc
*/
public error(message: string, args: unknown[] = []): void {
this.log(Level.ERROR, message, args)
}

/**
* @inheritDoc
*/
public fatal(message: string, args: unknown[] = []): void {
this.log(Level.FATAL, message, args)
}

private log(level: Level, message: string, args: unknown[]) {
if (!this.isEnabled) {
return
}

this.logger.log(level, message, ...args)
}
}
4 changes: 4 additions & 0 deletions src/logger/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './config'
export * from './logger'
export * from './defaultLogger'
export * from './types'
49 changes: 49 additions & 0 deletions src/logger/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export interface Logger {
/**
* Adds a log record at the DEBUG level.
* Detailed debug information.
*
* @param message The log message.
* @param args The log context.
*/
debug(message: string, args?: unknown[]): void

/**
* Adds a log record at the INFO level.
* Interesting events.
*
* @param message The log message.
* @param args The log context.
*/
info(message: string, args?: unknown[]): void

/**
* Adds a log record at the WARNING level.
* Exceptional occurrences that are not errors.
*
* Examples: Use of deprecated APIs, poor use of an API,
* undesirable things that are not necessarily wrong.
*
* @param message The log message.
* @param args The log context.
*/
warn(message: string, args?: unknown[]): void

/**
* Adds a log record at the ERROR level.
* Runtime errors.
*
* @param message The log message.
* @param args The log context.
*/
error(message: string, args?: unknown[]): void

/**
* Adds a log record at the FATAL level.
* Critical conditions.
*
* @param message The log message.
* @param args The log context.
*/
fatal(message: string, args?: unknown[]): void
}
54 changes: 54 additions & 0 deletions src/logger/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Configuration } from 'log4js'

export enum OutputType {
CONSOLE = 'console',
FILE = 'file',
}

export enum LoggerChannel {
SDK = 'sdk',
AGENT = 'agent',
INTERACTION = 'interaction',
}

export enum Level {
/**
* Detailed debug information.
*/
DEBUG = 'debug',

/**
* Interesting events.
*/
INFO = 'info',

/**
* Exceptional occurrences that are not errors.
*/
WARNING = 'warn',

/**
* Runtime errors.
*/
ERROR = 'error',

/**
* Critical conditions.
*/
FATAL = 'fatal',
}

export type LoggerChannelConfig = {
[name in LoggerChannel]: {
isEnabled?: boolean
level?: Level
outputType?: OutputType
}
}

export interface LoggerConfig {
isEnabled?: boolean
logsDir?: string
channelsConfig?: LoggerChannelConfig
customConfig?: Configuration
}
49 changes: 48 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,11 @@
dependencies:
"@sinonjs/commons" "^1.7.0"

"@types/app-root-path@^1.2.4":
version "1.2.4"
resolved "https://registry.yarnpkg.com/@types/app-root-path/-/app-root-path-1.2.4.tgz#a78b703282b32ac54de768f5512ecc3569919dc7"
integrity sha1-p4twMoKzKsVN52j1US7MNWmRncc=

"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7":
version "7.1.9"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.9.tgz#77e59d438522a6fb898fa43dc3455c6e72f3963d"
Expand Down Expand Up @@ -1683,6 +1688,13 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=

"@types/log4js@^2.3.5":
version "2.3.5"
resolved "https://registry.yarnpkg.com/@types/log4js/-/log4js-2.3.5.tgz#4d1e56da53d3c1820c08e9cd5092e68c3e1e822f"
integrity sha512-SwF8LkSHqHy9A8GQ67NAYJiGl8zzP4Qtx65Wa+IOxDGdMHxKeoQZjg7m2M1erIT6VK0DYHpu2aTbdLkdkuMHjw==
dependencies:
log4js "*"

"@types/node-fetch@^2.5.5":
version "2.5.7"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c"
Expand Down Expand Up @@ -2778,6 +2790,16 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0"

date-format@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf"
integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==

date-format@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95"
integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==

debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
Expand Down Expand Up @@ -3526,7 +3548,7 @@ flat-cache@^2.0.1:
rimraf "2.6.3"
write "1.0.3"

flatted@^2.0.0:
flatted@^2.0.0, flatted@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
Expand Down Expand Up @@ -5012,6 +5034,17 @@ lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==

log4js@*, log4js@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb"
integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==
dependencies:
date-format "^3.0.0"
debug "^4.1.1"
flatted "^2.0.1"
rfdc "^1.1.4"
streamroller "^2.2.4"

loose-envify@^1.0.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
Expand Down Expand Up @@ -6119,6 +6152,11 @@ rfc4648@^1.4.0:
resolved "https://registry.yarnpkg.com/rfc4648/-/rfc4648-1.4.0.tgz#c75b2856ad2e2d588b6ddb985d556f1f7f2a2abd"
integrity sha512-3qIzGhHlMHA6PoT6+cdPKZ+ZqtxkIvg8DZGKA5z6PQ33/uuhoJ+Ws/D/J9rXW6gXodgH8QYlz2UCl+sdUDmNIg==

rfdc@^1.1.4:
version "1.3.0"
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==

[email protected]:
version "2.6.3"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
Expand Down Expand Up @@ -6518,6 +6556,15 @@ stealthy-require@^1.1.1:
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=

streamroller@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53"
integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==
dependencies:
date-format "^2.1.0"
debug "^4.1.1"
fs-extra "^8.1.0"

string-length@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1"
Expand Down