react-app-layout icon indicating copy to clipboard operation
react-app-layout copied to clipboard

blah

Open heswell opened this issue 1 year ago • 0 comments

Let's follow existing conventions as far as possible, whilst keeping thing as simple as possible, we can always add functionality We can take our cures from apache commons logging

log.error log.warn log.info log.debug

In a production build, only error logs will actually log anything, other log statements will be no-ops. In a dev build or a published debug package , the other log statements will log if the configured log level determines that they should, so:

log level === 'debug' all log statements will log

log level === 'info' log.debug statements will not log, all other log statements will be no-ops. This will be default in dev build

log level === "warn" neither log.debug nor log.info statements will log

log level === 'error' only log.error statements log. This is same as prod build

-- Guarding against expensive runtime args The logger implementation will ensure that those log statements that should not log do not do so, according to the configured log level. In some cases, the argument(s) passed to a log statement may themselves be expensive to compute, e.g an expensive JSON stringify or a complex constructed object. To avoid these incurring runtime cost for a log message which will not actually be logged, we will offer a set of guards

  • warnEnabled
  • infoEnabled
  • debugEnabled

so we can code the following

import { logger} from "@finos/vuu-utils"

const log = logger('ServerProxy')

if (log.debugEnabled){
log.debug(`${buildExpensiveDebugObject().toString()}`)
}

whereas if we're just logging a simple string message, we would just use

import { logger} from "@finos/vuu-utils"

// once, at module level
const log = logger('ServerProxy')

// many times, anywhere in code
log.debug("setRange invoked")

Code which is particularly performance sensitive might want to enclose log statements (except for log.error) in a build-time env check

if (process.env.NODE_ENV === 'development'){
log.info('blah blah')
}

Such code will be entirely removed from a prod build, not even incurring the cost of a no-op function call (if such a call even has a cost once the optimising compiler does its thing ?)

configuring the log level

This will be done initially with a cookie. We can set the log level to error, info, warn or debug. Eventually, we will want to allow configuration of category as well, so we can offer fine-grained control of logging. What those categories are will be at the developers discretion. At least each file should create its logger with a context identifier, e.g the example above using 'ServerProxy'. Developers might want to add additional categories that span files. e.g perf, protocol-messages

The worker requires special treatment, as code within the worker has no access to cookies, not can it access any global variables or modules initiated in the UI thread. We will inject a logging configuration object into the worker source code (the source code is loaded a string and Blob Url).

The logger implementation

The utils package should expose a logger factory function that will return a log object with the appropriate guard properties and logging functions.

it might look something like this

// from cookie in ui thread or global config in worker thread
const logLevel = getLogLevel()

const noop = () => undefined;

const debugEnabled = logLevel === 'debug'
const infoEnabled = debugEnabled || logLevel === 'info'
const warnEnabled = infoEnabled || logLevel === 'warn'

return function logger(category){
 return {
debugEnabled,
infoEnabled,
warnEnabled,
info: infoEnabled ? (message)=> console.info('[category] ' + message) : noop
etc
}

Might want to throw a formatted timestamp into the messages too ?

Eventually, we will want to allow the logger factory to be pluggable, probably through React Context (although again the worker will be a special case). Fow now a simple console logger will suffice.

heswell avatar Mar 10 '23 11:03 heswell