-
-
Notifications
You must be signed in to change notification settings - Fork 197
feat: improve logger #4592
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
Merged
Merged
feat: improve logger #4592
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
test cli-smoke cli-create cli-plugin cli-preview cli-misc |
test cli-smoke cli-misc |
1 similar comment
test cli-smoke cli-misc |
Fatme
approved these changes
May 8, 2019
KristianDD
reviewed
May 8, 2019
Rename `initService` to `projectInitService` as the new name has more sense.
Expose `$logger` for using when CLI is required as a library. Also introduce `initialize` method in it, that allows full configuration of the log4js instance. Implement a new `emit-appender` logger, that emits `logData` event with information for the logging instead of printing it to the stdout. This emitter can be used with the following code: ```JavaScript const tns = require("nativescript"); const { LoggerAppenders } = tns.constants; const { EventEmitter } = require("events"); const emitter = new EventEmitter(); // IMPORTANT: Due to current log4js behavior, you must set the event handler BEFORE calling initialize of the logger. emitter.on("logData", logData => { // logData contains two properties: loggingEvent and formattedMessage // loggingEvent contains information about the level of the message and the raw message itself // formattedMessage is the message with specified layout (i.e. it is string). Default layout is `messagePassThrough`. }); tns.logger.initialize({ appenderOptions: { type: LoggerAppenders.emitAppender, emitter }); ``` This is the easiest way to use the new appender. You can also use LoggerLevel from constants and specify different logging levels. You can pass whatever layout you need for the message.
Introduce initializeService which can be used to setup some specifics of CLI (currently the logger) and to print all required warnings. At the moment, whenever we want to introduce new warnings, we need to introduce new methods that we call from CLI and when it is used as a library. With the new solution all such warnings can be placed in the initialize method and it will automatically show those warnings.
Refactor the logic in CLI's logger to use log4js methods only - currently we have some methods that use `console.log`, others use `process.stdout`, `process.stderr`, etc. Also, there are some methods that apply console colorization for the message, but in fact CLI may be used as a library or in CI, where these colorization does not make sense. To resolve this, introduce a new appender and new layout that CLI will pass to `log4js`. The appender (called `cli-appender`) will control if the message will be shown on `stdout` or `stderr`. The layout (called `cli-layout`) will control the presentation of the message on the terminal, i.e. if we should add new line at the end of the message, if we should wrap it in borders (with `*` symbols, etc.) and the colorization of the message. The layout will be applied on all methods, so you can use it with any log4js method, i.e. you can do: ```TypeScript this.$logger.warn("This is my message", { useStderr: true }); this.$logger.info("This is my message", { useStderr: true }); ``` Before passing the data to `log4js`, CLI will set required properties in the context of the logging event, so the appender and the layout can read them. This way, in case CLI is used as a library, the custom properties and CLI specific layout, will not be shown. Also delete some methods from logger API, so it is streamlined. Also change logger.error to print on stderr instead of stdout. Move logger.ts to logger directory, so all logger logic will be on a single place.
There are several changes in logger API that need to be changed in the code - they are mostly renaming of methods.
Improve initialization service, so it can be used to initialize all settings required at the beginning of CLI process.
cb08737
to
194106c
Compare
test cli-smoke cli-create cli-plugin |
test cli-smoke cli-misc |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Currently CLI's logger uses different ways to print messages on stdout and stderr:
log4js
in some casesconsole.log
process.stdout.write
process.stderr.write
Also, whenever we want to colorize the message, we include the colorization of the message in the message itself, before passing it to one of the methods above. This is a problem when CLI is used as a library, when it might not be used in a terminal environment - the messages contain terminal colorization. Also, in order to get the messages, you need to parse stdout and stderr of the process in which you've required CLI as a library.
To resolve the above, streamline the logger ways for handling messages - use
log4js
everywhere. This allows using different logging mechanism when CLI is used as a command line and when it is used as a library.log4js
has the concept of usingappenders
andlayout
when printing messages.appenders
are responsible for output of log events. They may write events to files, send emails, store them in a database, or anything. Most appenders use layouts to serialise the events to strings for output.layout
is a function for converting a LogEvent into a string representation.Currently we have the several use cases for logging messages:
stdout
orstderr
- for some of the methods we need to print errors and we want them to be shown onstderr
. This can be handled in the appender, as it is the one which actually prints the message. To handle the case, passuseStderr
property in the context of the LogEvent.skipNewLine
property of the LogEvent context.wrapMessageWithBorders
property of the LogEvent context.Each of the properties can be passed directly to each of the methods exposed from
logger
, i.e.:Full list of the properties that can be set is available in
constants.LoggerConfigData
.When using CLI as a library, it makes sense to skip the colorization and instead of printing to
stdout
/stderr
, to allow the consumer to take care of the messages on its own. In order to handle this, introduce an easy way for initializing the logger with different settings, i.e.appender
,layout
,level
. This can be achieved through thelogger.initialize
method orinitializeService.initialize
method.To make it easy when CLI is used as a library, introduce a custom
emit-appender
that emits the logged data instead of printing it. Its usage is fairly simple:Additional code changes
During the implementation of the logger, several changes in other services were required:
initService
toprojectInitService
- it was required to make it easier to determine if the service is for initializing CLI or the project.progress-indicator
- it was not used anywhereprintMsgWithTimeout
method from logger - it was used only inprogress-indicator
initializeService
- it is used to initialize CLI specific modules (like logger) and show all system warnings (for example for not supported macOS version). This way we no longer need to expose different methods when we want to show some warnings in the command line and when CLI is used as a library. We can just place them in the initialize method.warnWithLabel
method from logger - it has been used on only two places and did not make sense to keep it.out
method from logger - its usage is replaced withlogger.info
write
method from logger - its intention was to print message on stdout, without modifying it (i.e. without adding new line, etc.), so it is replaced withinfo
method and passingskipNewLine
to true:printInfoMessageOnSameLine
method from logger - it was used to print messages on stdout without adding new line and only when log level is info. However, the implementation was incorrect (i.e. it was not checking the log level correctly). Replace the method withlogger.info
calls:logger.error
to print tostderr
instead ofstdout
.printOnStderr
method from logger. This can be achieve with any log level by passinguseStderr: true
. Usage is replaced withlogger.error
.initializeCliLogger
method in logger, so it will be easy to setup CLI's log4js optionslogger
related files in alogger
directory.PR Checklist
What is the current behavior?
What is the new behavior?
Implements #4602