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

[Logger] Simplify how we instantiate the logger in plugins #110

Merged
merged 5 commits into from
Nov 26, 2024
Merged
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
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ datadogWebpackPlugin({
auth?: {
apiKey?: string;
};
customPlugins?: (options: Options, context: GlobalContext) => UnpluginPlugin[];
customPlugins?: (options: Options, context: GlobalContext, log: Logger) => UnpluginPlugin[];
logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';
rum?: {
disabled?: boolean;
Expand Down Expand Up @@ -305,19 +305,22 @@ Or to prototype some new plugins in the same environment.

```typescript
{
customPlugins: (options, context) => [{
customPlugins: (options, context, log) => [{
name: 'my-custom-plugin',
buildStart() {
console.log('Hello world');
log.info('Hello world');
},
}];
}
```

Your function will receive two arguments:
Your function will receive three arguments:

- `options`: The options you passed to the main plugin (including your custom plugins).
- `context`: The global context shared accross our plugin.
- `log`: A [logger](/packages/factory/README.md#logger) to display messages.

The `context` is a shared object that is mutated during the build process. It contains the following properties:

<!-- #global-context-type -->
```typescript
Expand Down Expand Up @@ -372,7 +375,6 @@ type GlobalContext = {
writeDuration?: number;
};
cwd: string;
getLogger: (name: string) => [Logger](/packages/factory/src/helpers.ts);
// Added in `buildStart`.
git?: {
hash: string;
Expand Down
12 changes: 8 additions & 4 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,20 @@ export type BundlerReport = {

export type ToInjectItem = { type: 'file' | 'code'; value: string; fallback?: ToInjectItem };

export type GetLogger = (name: string) => Logger;
export type Logger = {
getLogger: GetLogger;
error: (text: any) => void;
warn: (text: any) => void;
info: (text: any) => void;
debug: (text: any) => void;
};
export type GetLogger = (name: string) => Logger;
export type GlobalContext = {
auth?: AuthOptions;
inject: (item: ToInjectItem) => void;
bundler: BundlerReport;
build: BuildReport;
cwd: string;
getLogger: GetLogger;
git?: RepositoryData;
pluginNames: string[];
start: number;
Expand All @@ -103,8 +103,12 @@ export type PluginOptions = UnpluginOptions & {
name: PluginName;
};

export type GetPlugins<T> = (options: T, context: GlobalContext) => PluginOptions[];
export type GetCustomPlugins = (options: Options, context: GlobalContext) => UnpluginOptions[];
export type GetPlugins<T> = (options: T, context: GlobalContext, log: Logger) => PluginOptions[];
export type GetCustomPlugins = (
options: Options,
context: GlobalContext,
log: Logger,
) => UnpluginOptions[];

export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';

Expand Down
26 changes: 22 additions & 4 deletions packages/factory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,15 @@ Most of the time they will interact via the global context.
## Logger

If you need to log anything into the console you'll have to use the global Logger.
Simply instantiate your logger in your plugin's initialization.
Simply add it to your `getMyPlugins` function and run `yarn cli integrity` to update the factory.

```typescript
// ./packages/plugins/my-plugin/index.ts
[...]

export const getMyPlugins = (context: GlobalContext) => {
const logger = context.getLogger('my-plugin');
export const getMyPlugins = (context: GlobalContext, log: Logger) => {
log.debug('Welcome to my plugin');
[...]
};
```

Expand All @@ -73,6 +74,24 @@ logger.info('This is an info');
logger.debug('This is a debug message');
```

You can also create a "sub-logger" when you want to individually identify logs from a specific part of your plugin.<br/>
Simply use `log.getLogger('my-plugin')` for this:

```typescript
export const getMyPlugins = (context: GlobalContext, log: Logger) => {
log.debug('Welcome to the root of my plugin');
return [
{
name: 'my-plugin',
setup: (context: PluginContext) => {
const subLog = log.getLogger('my-plugin');
subLog.info('This is a debug message from one of my plugins.');
},
},
];
};
```

## Global Context

A global, shared context within the build plugins ecosystem.<br/>
Expand Down Expand Up @@ -130,7 +149,6 @@ type GlobalContext = {
writeDuration?: number;
};
cwd: string;
getLogger: (name: string) => [Logger](/packages/factory/src/helpers.ts);
// Added in `buildStart`.
git?: {
hash: string;
Expand Down
5 changes: 4 additions & 1 deletion packages/factory/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ export const getLoggerFactory =
};

return {
getLogger: (subName: string) => {
const logger = getLoggerFactory(build, logLevel);
return logger(`${name}:${subName}`);
},
error: (text: any) => log(text, 'error'),
warn: (text: any) => log(text, 'warn'),
info: (text: any) => log(text, 'info'),
Expand Down Expand Up @@ -105,7 +109,6 @@ export const getContext = ({
inject: (item: ToInjectItem) => {
injections.push(item);
},
getLogger: getLoggerFactory(build, options.logLevel),
start: Date.now(),
version,
};
Expand Down
31 changes: 25 additions & 6 deletions packages/factory/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import type {
import type { UnpluginContextMeta, UnpluginInstance, UnpluginOptions } from 'unplugin';
import { createUnplugin } from 'unplugin';

import { getContext, validateOptions } from './helpers';
import { getContext, getLoggerFactory, validateOptions } from './helpers';

/* eslint-disable arca/import-ordering, arca/newline-after-import-section */
// #imports-injection-marker
Expand Down Expand Up @@ -77,33 +77,52 @@ export const buildPluginFactory = ({
version,
});

const getLogger = getLoggerFactory(context.build, options.logLevel);

context.pluginNames.push(HOST_NAME);

// List of plugins to be returned.
// We keep the UnpluginOptions type for the custom plugins.
const plugins: (PluginOptions | UnpluginOptions)[] = [
// Prefill with our internal plugins.
// #internal-plugins-injection-marker
...getBuildReportPlugins(context),
...getBuildReportPlugins(context, getLogger('datadog-build-report-plugin')),
...getBundlerReportPlugins(context),
...getGitPlugins(options, context),
...getInjectionPlugins(bundler, context, injections),
...getInjectionPlugins(
bundler,
context,
injections,
getLogger('datadog-injection-plugin'),
),
// #internal-plugins-injection-marker
];

// Add custom, on the fly plugins, if any.
if (options.customPlugins) {
const customPlugins = options.customPlugins(options, context);
const customPlugins = options.customPlugins(
options,
context,
getLogger('datadog-custom-plugins'),
);
plugins.push(...customPlugins);
}

// Based on configuration add corresponding plugin.
// #configs-injection-marker
if (options[rum.CONFIG_KEY] && options[rum.CONFIG_KEY].disabled !== true) {
plugins.push(...rum.getPlugins(options as OptionsWithRum, context));
plugins.push(
...rum.getPlugins(options as OptionsWithRum, context, getLogger(rum.PLUGIN_NAME)),
);
}
if (options[telemetry.CONFIG_KEY] && options[telemetry.CONFIG_KEY].disabled !== true) {
plugins.push(...telemetry.getPlugins(options as OptionsWithTelemetry, context));
plugins.push(
...telemetry.getPlugins(
options as OptionsWithTelemetry,
context,
getLogger(telemetry.PLUGIN_NAME),
),
);
}
// #configs-injection-marker

Expand Down
7 changes: 3 additions & 4 deletions packages/plugins/build-report/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2019-Present Datadog, Inc.

import type { GlobalContext, PluginOptions } from '@dd/core/types';
import type { GlobalContext, Logger, PluginOptions } from '@dd/core/types';

import { getEsbuildPlugin } from './esbuild';
import { getRollupPlugin } from './rollup';
import { getWebpackPlugin } from './webpack';

const PLUGIN_NAME = 'datadog-build-report-plugin';
export const PLUGIN_NAME = 'datadog-build-report-plugin';

export const getBuildReportPlugins = (context: GlobalContext): PluginOptions[] => {
const log = context.getLogger(PLUGIN_NAME);
export const getBuildReportPlugins = (context: GlobalContext, log: Logger): PluginOptions[] => {
return [
{
name: PLUGIN_NAME,
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/bundler-report/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import type { GlobalContext, PluginOptions } from '@dd/core/types';
import path from 'path';

const PLUGIN_NAME = 'datadog-bundler-report-plugin';
export const PLUGIN_NAME = 'datadog-bundler-report-plugin';

const rollupPlugin: (context: GlobalContext) => PluginOptions['rollup'] = (context) => ({
options(options) {
Expand Down
4 changes: 3 additions & 1 deletion packages/plugins/git/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import type { GlobalContext, Options, PluginOptions } from '@dd/core/types';

import { getRepositoryData, newSimpleGit } from './helpers';

export const PLUGIN_NAME = 'datadog-git-plugin';

export const getGitPlugins = (options: Options, context: GlobalContext): PluginOptions[] => {
return [
{
name: 'datadog-git-plugin',
name: PLUGIN_NAME,
enforce: 'pre',
async buildStart() {
// Verify that we should get the git information based on the options.
Expand Down
6 changes: 4 additions & 2 deletions packages/plugins/injection/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@

import { INJECTED_FILE } from '@dd/core/constants';
import { outputFile, rm } from '@dd/core/helpers';
import type { GlobalContext, PluginOptions, ToInjectItem } from '@dd/core/types';
import type { GlobalContext, Logger, PluginOptions, ToInjectItem } from '@dd/core/types';
import fs from 'fs';
import path from 'path';

import { PLUGIN_NAME, PREPARATION_PLUGIN_NAME } from './constants';
import { processInjections } from './helpers';

export { PLUGIN_NAME } from './constants';

export const getInjectionPlugins = (
bundler: any,
context: GlobalContext,
toInject: ToInjectItem[],
log: Logger,
): PluginOptions[] => {
const log = context.getLogger(PLUGIN_NAME);
const contentToInject: string[] = [];

const getContentToInject = () => {
Expand Down
5 changes: 2 additions & 3 deletions packages/plugins/rum/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2019-Present Datadog, Inc.

import type { GlobalContext, GetPlugins } from '@dd/core/types';
import type { GlobalContext, GetPlugins, Logger } from '@dd/core/types';

import { PLUGIN_NAME } from './constants';
import { uploadSourcemaps } from './sourcemaps';
import type { OptionsWithRum, RumOptions, RumOptionsWithSourcemaps } from './types';
import { validateOptions } from './validate';
Expand All @@ -20,8 +19,8 @@ export type types = {
export const getPlugins: GetPlugins<OptionsWithRum> = (
opts: OptionsWithRum,
context: GlobalContext,
log: Logger,
) => {
const log = context.getLogger(PLUGIN_NAME);
// Verify configuration.
const rumOptions = validateOptions(opts, log);
return [
Expand Down
4 changes: 2 additions & 2 deletions packages/plugins/telemetry/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2019-Present Datadog, Inc.

import type { GlobalContext, GetPlugins, PluginOptions } from '@dd/core/types';
import type { GlobalContext, GetPlugins, PluginOptions, Logger } from '@dd/core/types';

import { getMetrics } from './common/aggregator';
import { defaultFilters } from './common/filters';
Expand Down Expand Up @@ -36,14 +36,14 @@ export type types = {
export const getPlugins: GetPlugins<OptionsWithTelemetry> = (
options: OptionsWithTelemetry,
context: GlobalContext,
logger: Logger,
) => {
let realBuildEnd: number = 0;
const bundlerContext: BundlerContext = {
start: Date.now(),
};

const telemetryOptions = validateOptions(options);
const logger = context.getLogger(PLUGIN_NAME);
const plugins: PluginOptions[] = [];

// Webpack and Esbuild specific plugins.
Expand Down
2 changes: 1 addition & 1 deletion packages/tests/src/_jest/helpers/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const defaultPluginOptions: GetPluginsOptions = {

export const mockLogFn = jest.fn((text: any, level: LogLevel) => {});
const logFn: Logger = {
getLogger: jest.fn(),
error: (text: any) => {
mockLogFn(text, 'error');
},
Expand Down Expand Up @@ -79,7 +80,6 @@ export const getContextMock = (options: Partial<GlobalContext> = {}): GlobalCont
},
cwd: '/cwd/path',
inject: jest.fn(),
getLogger: jest.fn(() => mockLogger),
pluginNames: [],
start: Date.now(),
version: 'FAKE_VERSION',
Expand Down
Loading