Skip to content

Commit 2f71b18

Browse files
authored
Merge pull request #110 from DataDog/yoann/simpler-logger-instantiation
[Logger] Simplify how we instantiate the logger in plugins
2 parents 819da60 + 83d6955 commit 2f71b18

File tree

16 files changed

+175
-95
lines changed

16 files changed

+175
-95
lines changed

README.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ datadogWebpackPlugin({
247247
auth?: {
248248
apiKey?: string;
249249
};
250-
customPlugins?: (options: Options, context: GlobalContext) => UnpluginPlugin[];
250+
customPlugins?: (options: Options, context: GlobalContext, log: Logger) => UnpluginPlugin[];
251251
logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none';
252252
rum?: {
253253
disabled?: boolean;
@@ -305,19 +305,22 @@ Or to prototype some new plugins in the same environment.
305305
306306
```typescript
307307
{
308-
customPlugins: (options, context) => [{
308+
customPlugins: (options, context, log) => [{
309309
name: 'my-custom-plugin',
310310
buildStart() {
311-
console.log('Hello world');
311+
log.info('Hello world');
312312
},
313313
}];
314314
}
315315
```
316316
317-
Your function will receive two arguments:
317+
Your function will receive three arguments:
318318
319319
- `options`: The options you passed to the main plugin (including your custom plugins).
320320
- `context`: The global context shared accross our plugin.
321+
- `log`: A [logger](/packages/factory/README.md#logger) to display messages.
322+
323+
The `context` is a shared object that is mutated during the build process. It contains the following properties:
321324
322325
<!-- #global-context-type -->
323326
```typescript
@@ -372,7 +375,6 @@ type GlobalContext = {
372375
writeDuration?: number;
373376
};
374377
cwd: string;
375-
getLogger: (name: string) => [Logger](/packages/factory/src/helpers.ts);
376378
// Added in `buildStart`.
377379
git?: {
378380
hash: string;

packages/core/src/types.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,20 @@ export type BundlerReport = {
7474

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

77+
export type GetLogger = (name: string) => Logger;
7778
export type Logger = {
79+
getLogger: GetLogger;
7880
error: (text: any) => void;
7981
warn: (text: any) => void;
8082
info: (text: any) => void;
8183
debug: (text: any) => void;
8284
};
83-
export type GetLogger = (name: string) => Logger;
8485
export type GlobalContext = {
8586
auth?: AuthOptions;
8687
inject: (item: ToInjectItem) => void;
8788
bundler: BundlerReport;
8889
build: BuildReport;
8990
cwd: string;
90-
getLogger: GetLogger;
9191
git?: RepositoryData;
9292
pluginNames: string[];
9393
start: number;
@@ -103,8 +103,12 @@ export type PluginOptions = UnpluginOptions & {
103103
name: PluginName;
104104
};
105105

106-
export type GetPlugins<T> = (options: T, context: GlobalContext) => PluginOptions[];
107-
export type GetCustomPlugins = (options: Options, context: GlobalContext) => UnpluginOptions[];
106+
export type GetPlugins<T> = (options: T, context: GlobalContext, log: Logger) => PluginOptions[];
107+
export type GetCustomPlugins = (
108+
options: Options,
109+
context: GlobalContext,
110+
log: Logger,
111+
) => UnpluginOptions[];
108112

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

packages/factory/README.md

+22-4
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,15 @@ Most of the time they will interact via the global context.
5353
## Logger
5454

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

5858
```typescript
5959
// ./packages/plugins/my-plugin/index.ts
6060
[...]
6161

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

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

77+
You can also create a "sub-logger" when you want to individually identify logs from a specific part of your plugin.<br/>
78+
Simply use `log.getLogger('my-plugin')` for this:
79+
80+
```typescript
81+
export const getMyPlugins = (context: GlobalContext, log: Logger) => {
82+
log.debug('Welcome to the root of my plugin');
83+
return [
84+
{
85+
name: 'my-plugin',
86+
setup: (context: PluginContext) => {
87+
const subLog = log.getLogger('my-plugin');
88+
subLog.info('This is a debug message from one of my plugins.');
89+
},
90+
},
91+
];
92+
};
93+
```
94+
7695
## Global Context
7796

7897
A global, shared context within the build plugins ecosystem.<br/>
@@ -130,7 +149,6 @@ type GlobalContext = {
130149
writeDuration?: number;
131150
};
132151
cwd: string;
133-
getLogger: (name: string) => [Logger](/packages/factory/src/helpers.ts);
134152
// Added in `buildStart`.
135153
git?: {
136154
hash: string;

packages/factory/src/helpers.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ export const getLoggerFactory =
6363
};
6464

6565
return {
66+
getLogger: (subName: string) => {
67+
const logger = getLoggerFactory(build, logLevel);
68+
return logger(`${name}:${subName}`);
69+
},
6670
error: (text: any) => log(text, 'error'),
6771
warn: (text: any) => log(text, 'warn'),
6872
info: (text: any) => log(text, 'info'),
@@ -105,7 +109,6 @@ export const getContext = ({
105109
inject: (item: ToInjectItem) => {
106110
injections.push(item);
107111
},
108-
getLogger: getLoggerFactory(build, options.logLevel),
109112
start: Date.now(),
110113
version,
111114
};

packages/factory/src/index.ts

+25-6
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import type {
2323
import type { UnpluginContextMeta, UnpluginInstance, UnpluginOptions } from 'unplugin';
2424
import { createUnplugin } from 'unplugin';
2525

26-
import { getContext, validateOptions } from './helpers';
26+
import { getContext, getLoggerFactory, validateOptions } from './helpers';
2727

2828
/* eslint-disable arca/import-ordering, arca/newline-after-import-section */
2929
// #imports-injection-marker
@@ -77,33 +77,52 @@ export const buildPluginFactory = ({
7777
version,
7878
});
7979

80+
const getLogger = getLoggerFactory(context.build, options.logLevel);
81+
8082
context.pluginNames.push(HOST_NAME);
8183

8284
// List of plugins to be returned.
8385
// We keep the UnpluginOptions type for the custom plugins.
8486
const plugins: (PluginOptions | UnpluginOptions)[] = [
8587
// Prefill with our internal plugins.
8688
// #internal-plugins-injection-marker
87-
...getBuildReportPlugins(context),
89+
...getBuildReportPlugins(context, getLogger('datadog-build-report-plugin')),
8890
...getBundlerReportPlugins(context),
8991
...getGitPlugins(options, context),
90-
...getInjectionPlugins(bundler, context, injections),
92+
...getInjectionPlugins(
93+
bundler,
94+
context,
95+
injections,
96+
getLogger('datadog-injection-plugin'),
97+
),
9198
// #internal-plugins-injection-marker
9299
];
93100

94101
// Add custom, on the fly plugins, if any.
95102
if (options.customPlugins) {
96-
const customPlugins = options.customPlugins(options, context);
103+
const customPlugins = options.customPlugins(
104+
options,
105+
context,
106+
getLogger('datadog-custom-plugins'),
107+
);
97108
plugins.push(...customPlugins);
98109
}
99110

100111
// Based on configuration add corresponding plugin.
101112
// #configs-injection-marker
102113
if (options[rum.CONFIG_KEY] && options[rum.CONFIG_KEY].disabled !== true) {
103-
plugins.push(...rum.getPlugins(options as OptionsWithRum, context));
114+
plugins.push(
115+
...rum.getPlugins(options as OptionsWithRum, context, getLogger(rum.PLUGIN_NAME)),
116+
);
104117
}
105118
if (options[telemetry.CONFIG_KEY] && options[telemetry.CONFIG_KEY].disabled !== true) {
106-
plugins.push(...telemetry.getPlugins(options as OptionsWithTelemetry, context));
119+
plugins.push(
120+
...telemetry.getPlugins(
121+
options as OptionsWithTelemetry,
122+
context,
123+
getLogger(telemetry.PLUGIN_NAME),
124+
),
125+
);
107126
}
108127
// #configs-injection-marker
109128

packages/plugins/build-report/src/index.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@
22
// This product includes software developed at Datadog (https://www.datadoghq.com/).
33
// Copyright 2019-Present Datadog, Inc.
44

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

77
import { getEsbuildPlugin } from './esbuild';
88
import { getRollupPlugin } from './rollup';
99
import { getWebpackPlugin } from './webpack';
1010

11-
const PLUGIN_NAME = 'datadog-build-report-plugin';
11+
export const PLUGIN_NAME = 'datadog-build-report-plugin';
1212

13-
export const getBuildReportPlugins = (context: GlobalContext): PluginOptions[] => {
14-
const log = context.getLogger(PLUGIN_NAME);
13+
export const getBuildReportPlugins = (context: GlobalContext, log: Logger): PluginOptions[] => {
1514
return [
1615
{
1716
name: PLUGIN_NAME,

packages/plugins/bundler-report/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import type { GlobalContext, PluginOptions } from '@dd/core/types';
66
import path from 'path';
77

8-
const PLUGIN_NAME = 'datadog-bundler-report-plugin';
8+
export const PLUGIN_NAME = 'datadog-bundler-report-plugin';
99

1010
const rollupPlugin: (context: GlobalContext) => PluginOptions['rollup'] = (context) => ({
1111
options(options) {

packages/plugins/git/src/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import type { GlobalContext, Options, PluginOptions } from '@dd/core/types';
66

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

9+
export const PLUGIN_NAME = 'datadog-git-plugin';
10+
911
export const getGitPlugins = (options: Options, context: GlobalContext): PluginOptions[] => {
1012
return [
1113
{
12-
name: 'datadog-git-plugin',
14+
name: PLUGIN_NAME,
1315
enforce: 'pre',
1416
async buildStart() {
1517
// Verify that we should get the git information based on the options.

packages/plugins/injection/src/index.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@
44

55
import { INJECTED_FILE } from '@dd/core/constants';
66
import { outputFile, rm } from '@dd/core/helpers';
7-
import type { GlobalContext, PluginOptions, ToInjectItem } from '@dd/core/types';
7+
import type { GlobalContext, Logger, PluginOptions, ToInjectItem } from '@dd/core/types';
88
import fs from 'fs';
99
import path from 'path';
1010

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

14+
export { PLUGIN_NAME } from './constants';
15+
1416
export const getInjectionPlugins = (
1517
bundler: any,
1618
context: GlobalContext,
1719
toInject: ToInjectItem[],
20+
log: Logger,
1821
): PluginOptions[] => {
19-
const log = context.getLogger(PLUGIN_NAME);
2022
const contentToInject: string[] = [];
2123

2224
const getContentToInject = () => {

packages/plugins/rum/src/index.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
// This product includes software developed at Datadog (https://www.datadoghq.com/).
33
// Copyright 2019-Present Datadog, Inc.
44

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

7-
import { PLUGIN_NAME } from './constants';
87
import { uploadSourcemaps } from './sourcemaps';
98
import type { OptionsWithRum, RumOptions, RumOptionsWithSourcemaps } from './types';
109
import { validateOptions } from './validate';
@@ -20,8 +19,8 @@ export type types = {
2019
export const getPlugins: GetPlugins<OptionsWithRum> = (
2120
opts: OptionsWithRum,
2221
context: GlobalContext,
22+
log: Logger,
2323
) => {
24-
const log = context.getLogger(PLUGIN_NAME);
2524
// Verify configuration.
2625
const rumOptions = validateOptions(opts, log);
2726
return [

packages/plugins/telemetry/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// This product includes software developed at Datadog (https://www.datadoghq.com/).
33
// Copyright 2019-Present Datadog, Inc.
44

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

77
import { getMetrics } from './common/aggregator';
88
import { defaultFilters } from './common/filters';
@@ -36,14 +36,14 @@ export type types = {
3636
export const getPlugins: GetPlugins<OptionsWithTelemetry> = (
3737
options: OptionsWithTelemetry,
3838
context: GlobalContext,
39+
logger: Logger,
3940
) => {
4041
let realBuildEnd: number = 0;
4142
const bundlerContext: BundlerContext = {
4243
start: Date.now(),
4344
};
4445

4546
const telemetryOptions = validateOptions(options);
46-
const logger = context.getLogger(PLUGIN_NAME);
4747
const plugins: PluginOptions[] = [];
4848

4949
// Webpack and Esbuild specific plugins.

packages/tests/src/_jest/helpers/mocks.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export const defaultPluginOptions: GetPluginsOptions = {
4848

4949
export const mockLogFn = jest.fn((text: any, level: LogLevel) => {});
5050
const logFn: Logger = {
51+
getLogger: jest.fn(),
5152
error: (text: any) => {
5253
mockLogFn(text, 'error');
5354
},
@@ -79,7 +80,6 @@ export const getContextMock = (options: Partial<GlobalContext> = {}): GlobalCont
7980
},
8081
cwd: '/cwd/path',
8182
inject: jest.fn(),
82-
getLogger: jest.fn(() => mockLogger),
8383
pluginNames: [],
8484
start: Date.now(),
8585
version: 'FAKE_VERSION',

0 commit comments

Comments
 (0)