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

Implement base browser-side logging system #144107

Merged
merged 21 commits into from
Nov 1, 2022

Conversation

pgayvallet
Copy link
Contributor

@pgayvallet pgayvallet commented Oct 27, 2022

Summary

Part of #33796

Initial browser-side logging system implementation, as described in #33796 (comment)

Create the following packages:

  • @kbn/core-logging-common-internal : extracted common parts of the logging implementation that are now reused by both the server and browser logging systems.
  • @kbn/core-logging-browser-internal : the browser-side logging system implementation
  • @kbn/core-logging-browser-mocks : the associated mocks

@pgayvallet pgayvallet added Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Feature:Logging v8.6.0 labels Oct 27, 2022
Copy link
Contributor Author

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

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

Self review

Comment on lines +10 to +14
export { LoggerConversion } from './logger';
export { LevelConversion } from './level';
export { MessageConversion } from './message';
export { MetaConversion } from './meta';
export { DateConversion } from './date';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved the pattern conversions to the common package. A few notes though:

  • the pid conversion was kept on the server-side, given the concept cannot be used on browser side
  • the level and logger conversion were supporting highlighting using chalk. This only works with for terminal output (and was leaking server-only libraries into core's browser bundle), so I duplicated them and removed the highlight from the common version.

* color highlighting (eg. to make log messages easier to read in the terminal).
* @internal
*/
export class PatternLayout implements Layout {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This base PatternLayout is inherited by the browser and server implementations.

* A basic, abstract logger implementation that delegates the create of log records to the child's createLogRecord function.
* @internal
*/
export abstract class AbstractLogger implements Logger {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same logic here, I created an abstract logger class that is used for the concrete browser/server implementations. The only abstract method to implement on the children is createLogRecord

* color highlighting (eg. to make log messages easier to read in the terminal).
* @internal
*/
export class PatternLayout extends BasePatternLayout {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Inheriting the base PatternLayout. Only the constructor is overridden to manually pass some parameters to it:

  • highlight: false given it's not supported on the browser
  • the browser-side list of supported conversions (excluding the pid one)

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason for renaming the base pattern layout here rather than in the common code?

Comment on lines +55 to +61
private getLoggerConfigByContext(context: string): LoggerConfigType {
return {
level: this.loggingConfig.logLevel,
appenders: [CONSOLE_APPENDER_ID],
name: context,
};
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As planned for the initial version, the browser-side logging configuration is very naive, and preconfigure all loggers to use the global level and a single console appender.

Copy link
Contributor

Choose a reason for hiding this comment

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

As an MVP, this is fine.

Comment on lines +16 to +20
export interface LoggerConfigType {
appenders: string[];
name: string;
level: LogLevelId;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a duplication from the type in the @kbn/core-logging-server package (packages/core/logging/core-logging-server/src/logger.ts).

When we'll eventually want to support full browser-side logging configuration, we will need to move all the logging config types from the @kbn/core-logging-server to a common one, but given this wasn't necessary for the first implementation, I simply copied the single type I'm using.

Copy link
Contributor

Choose a reason for hiding this comment

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

I created #144276 as a way to track enhancements and priority for further work in this area.

Comment on lines +38 to +42
logger: {
get(...contextParts) {
return coreContext.logger.get('plugins', pluginManifest.id, ...contextParts);
},
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

pluginInitConfig.logger.get('...') now available on the browser-side.

Comment on lines +112 to +113
const logLevel: LogLevelId = injectedMetadata.env.mode.dev ? 'all' : 'warn';
this.loggingSystem = new BrowserLoggingSystem({ logLevel });
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using the all level for development and warn level for production.

@pgayvallet pgayvallet marked this pull request as ready for review October 28, 2022 13:54
@pgayvallet pgayvallet requested a review from a team as a code owner October 28, 2022 13:54
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

@pgayvallet pgayvallet added the release_note:skip Skip the PR/issue when compiling release notes label Oct 28, 2022
*/
public append(record: LogRecord) {
// eslint-disable-next-line no-console
console.log(this.layout.format(record));
Copy link
Contributor

Choose a reason for hiding this comment

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

The MVP implements .log by default, which is fine to start with.

In #144276 we'd have a bit more flexibility in how we approach a fuller feature set. Assuming we'd expand on wrapping the console and, since the specifics of how the console object depends on the browser, we should at least implement a subset of the de facto methods that log to std out:
.error, .debug, .warn,.info

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea. I didn't want to go into browser implementation details in the first version. I'll add a bullet point in #144276 to look at how it would be possible to have a proper browser console delegation using more methods

protected readonly factory: LoggerFactory
) {}

protected abstract createLogRecord<Meta extends LogMeta>(
Copy link
Contributor

Choose a reason for hiding this comment

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

TIL (again): protected vs private. I had to read up on protected vs private class methods. The difference is subtle.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea. I almost never use protected in typescript, but for abstract class, the abstract method definitions must be declared as protected, else typescript complains.

@@ -7,7 +7,7 @@
*/

import { schema } from '@kbn/config-schema';
import { Layout, LogRecord, DisposableAppender } from '@kbn/logging';
import type { Layout, LogRecord, DisposableAppender } from '@kbn/logging';
Copy link
Contributor

Choose a reason for hiding this comment

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

Nicely spotted!

@@ -50,10 +52,12 @@ TYPES_DEPS = [
"@npm//rxjs",
"@npm//@types/moment-timezone",
"@npm//elastic-apm-node",
"@npm//chalk",
Copy link
Contributor

@TinaHeiligers TinaHeiligers Oct 31, 2022

Choose a reason for hiding this comment

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

How did we migrate the logging service to packages without specifying @npm//chalk in the BUILD.bazel config? Even on main right now, there aren't any errors. 😕 Are you sure we're not inheriting the dependency from elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, I asked myself the same question... No idea to be honest.

Copy link
Contributor

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

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

I left a few comments and one about an apparent 'missing' dependency regarding chalk that's a bit puzzling.

As an MVP for browser-side logging for dev, we don't need anything more than listed in #33796 (comment).

We can handle further enhancements at a later stage.

LGTM!

@pgayvallet
Copy link
Contributor Author

@elasticmachine merge upstream

@pgayvallet pgayvallet enabled auto-merge (squash) November 1, 2022 07:18
@pgayvallet pgayvallet merged commit 2fb12fb into elastic:main Nov 1, 2022
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Nov 1, 2022
@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
core 391 413 +22

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/core-logging-browser-mocks - 4 +4
@kbn/core-logging-common-internal - 31 +31
@kbn/core-plugins-browser 10 11 +1
core 1201 1202 +1
total +37

Public APIs missing exports

Total count of every type that is part of your API that should be exported but is not. This will cause broken links in the API documentation system. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats exports for more detailed information.

id before after diff
@kbn/core-logging-browser-internal - 1 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
core 369.4KB 376.8KB +7.4KB
Unknown metric groups

API count

id before after diff
@kbn/core-logging-browser-mocks - 4 +4
@kbn/core-logging-common-internal - 38 +38
@kbn/core-plugins-browser 14 15 +1
core 2703 2704 +1
total +44

ESLint disabled in files

id before after diff
osquery 1 2 +1

ESLint disabled line counts

id before after diff
@kbn/core-logging-browser-internal - 3 +3
enterpriseSearch 19 21 +2
fleet 57 63 +6
osquery 103 108 +5
securitySolution 439 443 +4
total +20

Total ESLint disabled count

id before after diff
@kbn/core-logging-browser-internal - 3 +3
enterpriseSearch 20 22 +2
fleet 65 71 +6
osquery 104 110 +6
securitySolution 516 520 +4
total +21

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

jloleysens added a commit to jloleysens/kibana that referenced this pull request Nov 1, 2022
* main: (43 commits)
  [Synthetics] Step details page screenshot (elastic#143452)
  [Lens] Datatable expression types improvement. (elastic#144173)
  [packages/kbn-journeys] start apm after browser start and stop after browser is closed (elastic#144267)
  [Files] Make files namespace agnostic (elastic#144019)
  Implement base browser-side logging system (elastic#144107)
  Correct wrong multiplier for byte conversion (elastic#143751)
  [Monaco] Add JSON syntax support to the Monaco editor (elastic#143739)
  CCS Smoke Test for Remote Clusters and Index Management  (elastic#142423)
  [api-docs] Daily api_docs build (elastic#144294)
  chore(NA): include progress on Bazel tasks (elastic#144275)
  [RAM] Allow users to see event logs from all spaces they have access to (elastic#140449)
  [APM] Show recommended minimum size when going below 5 minutes (elastic#144170)
  [typecheck] delete temporary target_types dirs in packages (elastic#144271)
  [Security Solution][Endpoint] adds new alert loading utility and un-skip FTR test for endpoint (elastic#144133)
  [performance/journeys] revert data_stress_test_lens.ts journey step (elastic#144261)
  [TIP] Use search strategies in Threat Intelligence (elastic#143267)
  Optimize react-query dependencies (elastic#144206)
  [babel/node] invalidate cache when synth pkg map is updated (elastic#144258)
  [APM] AWS lambda estimated cost (elastic#143986)
  [Maps] layer group wizard (elastic#144129)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:Logging release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v8.6.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants