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

add logging API #9436

Merged
merged 12 commits into from Jul 23, 2019
Merged

add logging API #9436

merged 12 commits into from Jul 23, 2019

Conversation

sokra
Copy link
Member

@sokra sokra commented Jul 18, 2019

What kind of change does this PR introduce?
feature

Did you add tests for your changes?
yes

Does this PR introduce a breaking change?
no

What needs to be documented once your changes are merged?

  • Plugins should prefer to use compilation.getLogger("PluginName") for logging. This kind of logging is stored to the Stats and formatted in this way. It can be filtered and exported by the user.

  • Plugins may use the compiler.getInfrastructureLogger("PluginName") for logging to, but logging to this is not stored in the Stats and therefore not formatted this way. Instead it's usually logged to the console/dashboard/gui directly. It can be filtered by the user.

  • Loaders should prefer to use this.getLogger(). This is a shortcut to compilation.getLogger() with loader path and processed file.

  • Loaders may use this.getLogger("name") to get an independent logger with a child name. Loader path and processed file is still added.

  • Plugins may use compilation.getLogger ? compilation.getLogger("PluginName") : console to provide a fallback for webpack version not supporting getLogger. Similar for Loaders.

  • Logger API

    • Important hint: Avoid noise in the log! Keep in mind that multiple plugins and loaders are used together. Loader usually process multiple files and are invoked for every file. Choose a log level as low as possible to keep log output informative.
    • Use logger.error(...) for error messages
    • Use logger.warn(...) for warnings
    • Use logger.info(...) for important information messages (they are displayed in the default settings, only use them for things the user really need to know)
    • Use logger.log(...) for unimportant information messages (they are only displayed when opt-in into displaying them)
    • Use logger.debug(...) for debugging information (they are only displayed when opt-in into debug logging for specific modules)
    • Use logger.trace() to display a stack trace (displayed like logger.debug)
    • Use logger.group(...) to group messages together (displayed like logger.log)
    • Use logger.groupEnd() to end a group
    • Use logger.groupCollapsed(...) to group messages together (displayed collapsed like logger.log, displayed expanded when verbose logging or debug logging is enabled)
    • Use logger.clear() to clear the log (it may only print a horizontal line instead) (displayed like logger.log)
    • Use logger.profile(...) and logger.profileEnd(...) to capture a profile (delegated to console.profile when supported)
  • Logging configuration

    • stats.logging: "none"|"error"|"warn"|"info"|"log"|"verbose" to choose displayed log level
      • none: nothing
      • error: only errors
      • warn: errors and warnings
      • info: errors, warnings, and info messages (default)
      • log: errors, warnings, info messages, log messages, groups, clear. Collapsed groups are displayed collapsed.
      • verbose: all except debug and trace. Collapsed groups are displayed expanded
    • stats.logging: false to disable all log output
    • stats.logging: true alias to stats.logging: "log"
    • stats.loggingDebug: true|false|/regexp/|"string"|(name) => true to enable debug output for specific items (intended for plugin/loader developer)
      • When stats.logging: false: stats.loggingDebug is ignored.
    • stats.loggingTrace: true enable stack traces in log output for errors, warnings and traces.
    • infrastructureLogging.level: "none"|"error"|"warn"|"info"|"log"|"verbose"
      • like stats.logging but for infrastructure logging
    • infrastructureLogging.debug: true|false|/regexp/|"string"|(name) => true
      • like stats.loggingDebug but for infrastructure logging
  • Plugins

    • Compiler.hooks.infrastructureLog and Compilation.hooks.log for plugins
    • With webpack 5 there will be plugins for the Stats to modify the log display in stats too
  • Runtime Logger API

    • Only for devtooling. Not intended to be included in production mode.
    • const logging = require("webpack/logging/runtime")
    • logging.getLogger("name")
    • logging.configureDefaultLogger({ level: "log", debug: /something/ })
    • logging.hooks.log to apply plugins to the runtime logger

Plugins:
Compiler.getInfrastructureLogger(name)
Compilation.getLogger(name)

Loader:
this.getLogger([name])

API equal to console API with these methods:
error, warn, info, log, debug,
time, timeLog, timeEnd,
group, groupCollapsed, groupEnd,
profile, profileEnd,
clear
@webpack-bot
Copy link
Contributor

webpack-bot commented Jul 18, 2019

For maintainers only:

  • This need to be documented (issue in webpack/webpack.js.org will be filed when merged)

allow more logging options in schema
collapse groups in non-verbose logging
show number of filtered logging lines
update stats presets for logging
Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

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

Looks good 👍

/cc @hiroppy can you look on this too, it is future logger for webpack-dev-server/webpack-dev-middleare

@hiroppy
Copy link
Member

hiroppy commented Jul 19, 2019

@evilebottnawi If my understanding is correct, this plugin is only Node Side so we use loglevel(or webpack-log) on browsers in webpack-dev-server?

@alexander-akait
Copy link
Member

@hiroppy we can use logger on client side to, just use const { Logger } = require("webpack/logging/Logger");,

@sokra maybe we can add logger as part of exported api to avoid using path to logger (webpack/logging/Logger), because we can move this file to other directories theoretically

@hiroppy
Copy link
Member

hiroppy commented Jul 19, 2019

@evilebottnawi Yep, and we should change the syntax to ES5. sorry, we've already used babel.

@sokra
Copy link
Member Author

sokra commented Jul 20, 2019

You can use this on client side:

const logging = require("webpack/lib/logging/runtime");

// Get a logger
logging.getLogger("Name");

// Apply plugins to the client side logging, i. e. for pretty display or sending log via websocket
new MyLogginPlugin().apply(logging);

By default the logger logs to console.

EDIT by hiroppy: modify webpack/logging/runtime to webpack/lib/logging/runtime.

@sokra
Copy link
Member Author

sokra commented Jul 21, 2019

We should also change the HMR logging to use the new logger in the next major release.

@hiroppy
Copy link
Member

hiroppy commented Jul 21, 2019

You mean we should change the logger of HotModuleReplacement.runtime.js?

@sokra
Copy link
Member Author

sokra commented Jul 21, 2019

The logger of webpack/hot/*. Currently it prints to console, but it probably should use the new runtime logger.

For the runtime logger we also need to add something to set the log level. Maybe like this:

const logging = require("webpack/logging/runtime");

logging.configureDefaultLogger({
  level: "warn",
  debug: /HMR/
})

Similar to the stats options.

@sokra
Copy link
Member Author

sokra commented Jul 21, 2019

I need to look into if this can also implemented in a non-breaking way for webpack 4...

@hiroppy
Copy link
Member

hiroppy commented Jul 21, 2019

Thank you for the explanation!

This was referenced Jun 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants