Skip to content

Commit

Permalink
Merge pull request #110 from DataDog/yoann/simpler-logger-instantiation
Browse files Browse the repository at this point in the history
[Logger] Simplify how we instantiate the logger in plugins
  • Loading branch information
yoannmoinet authored Nov 26, 2024
2 parents 819da60 + 83d6955 commit 2f71b18
Show file tree
Hide file tree
Showing 16 changed files with 175 additions and 95 deletions.
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

0 comments on commit 2f71b18

Please sign in to comment.