Skip to content

Commit

Permalink
Better integrate logger into the ecosystem
Browse files Browse the repository at this point in the history
  • Loading branch information
yoannmoinet committed Nov 14, 2024
1 parent 82ed7f6 commit 9757247
Show file tree
Hide file tree
Showing 36 changed files with 206 additions and 137 deletions.
3 changes: 1 addition & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ stateDiagram-v2
}
state core {
getLogger()
sharedHelpers
sharedConstants
types
Expand Down Expand Up @@ -163,7 +162,7 @@ Bootstrapping all the files you'll need to start coding.
yarn cli create-plugin
```

Then learn more about what you can use from [the ecosystem](/packages/core).
Then learn more about what you can use from [the ecosystem](/packages/factory).

## Tests

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ type GlobalContext = {
writeDuration?: number;
};
cwd: string;
getLogger: (name: string) => [Logger](/packages/factory/src/helpers.ts);
// Added in `buildStart`.
git?: {
hash: string;
Expand Down
45 changes: 0 additions & 45 deletions packages/core/src/log.ts

This file was deleted.

17 changes: 15 additions & 2 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export type SerializedOutput = Assign<Output, { inputs: string[] }>;
export type BuildReport = {
errors: string[];
warnings: string[];
logs: { pluginName: string; type: LogLevel; message: string; time: number }[];
entries?: Entry[];
inputs?: Input[];
outputs?: Output[];
Expand Down Expand Up @@ -73,12 +74,21 @@ export type BundlerReport = {

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

export type Logger = {
(text: any, type?: LogLevel): void;
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,13 +113,13 @@ export type AuthOptions = {
apiKey?: string;
};

export interface GetPluginsOptions {
export interface BaseOptions {
auth?: AuthOptions;
disableGit?: boolean;
logLevel?: LogLevel;
}

export interface Options extends GetPluginsOptions {
export interface Options extends BaseOptions {
// Each product should have a unique entry.
// #types-injection-marker
[rum.CONFIG_KEY]?: RumOptions;
Expand All @@ -118,6 +128,9 @@ export interface Options extends GetPluginsOptions {
customPlugins?: GetCustomPlugins;
}

export type GetPluginsOptions = Required<BaseOptions>;
export type OptionsWithDefaults = Assign<Options, GetPluginsOptions>;

export type PluginName = `datadog-${Lowercase<string>}-plugin`;

type Data = { data: BodyInit; headers?: Record<string, string> };
Expand Down
27 changes: 27 additions & 0 deletions packages/factory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,32 @@ Most of the time they will interact via the global context.
<kbd>[📝 Full documentation ➡️](/packages/plugins/injection#readme)</kbd>
<!-- #internal-plugins-list -->

## 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.

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

export const getMyPlugins = (context: GlobalContext) => {
const logger = context.getLogger('my-plugin');
};
```

Then you can either use one of the helpers or programmatically use a specific level:

```typescript
const logLevel = 'warn';
logger('This will be a warning', logLevel);

logger.warn('This is also a warning');
logger.error('This is an error');
logger.info('This is an info');
logger.debug('This is a debug message');
```

## Global Context

A global, shared context within the build plugins ecosystem.<br/>
Expand Down Expand Up @@ -107,6 +133,7 @@ type GlobalContext = {
writeDuration?: number;
};
cwd: string;
getLogger: (name: string) => [Logger](/packages/factory/src/helpers.ts);
// Added in `buildStart`.
git?: {
hash: string;
Expand Down
1 change: 1 addition & 0 deletions packages/factory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@dd/internal-injection-plugin": "workspace:*",
"@dd/rum-plugin": "workspace:*",
"@dd/telemetry-plugin": "workspace:*",
"chalk": "2.3.1",
"unplugin": "1.14.1"
}
}
83 changes: 74 additions & 9 deletions packages/factory/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,99 @@
// Copyright 2019-Present Datadog, Inc.

import type {
BuildReport,
BundlerFullName,
BundlerName,
FactoryMeta,
GetLogger,
GlobalContext,
LogLevel,
Options,
OptionsWithDefaults,
ToInjectItem,
} from '@dd/core/types';
import c from 'chalk';

const logPriority: Record<LogLevel, number> = {
debug: 0,
info: 1,
warn: 2,
error: 3,
none: 4,
};

const getLoggerFactory =
(build: BuildReport, logLevel: LogLevel = 'warn'): GetLogger =>
(name) => {
const log = (text: any, type: LogLevel = 'debug') => {
// By default (debug) we print dimmed.
let color = c.dim;
let logFn = console.log;

if (type === 'error') {
color = c.red;
logFn = console.error;
} else if (type === 'warn') {
color = c.yellow;
logFn = console.warn;
} else if (type === 'info') {
color = c.cyan;
logFn = console.log;
}

const prefix = `[${type}|${name}]`;

// Keep a trace of the log in the build report.
const content = typeof text === 'string' ? text : JSON.stringify(text, null, 2);
build.logs.push({ pluginName: name, type, message: content, time: Date.now() });
if (type === 'error') {
build.errors.push(content);
}
if (type === 'warn') {
build.warnings.push(content);
}

// Only log if the log level is high enough.
if (logPriority[type] >= logPriority[logLevel]) {
logFn(`${color(prefix)} ${content}`);
}
};

const logFn = (text: any, type: LogLevel = 'debug') => {
log(text, type);
};

// Add shortcuts for the other log levels.
logFn.error = (text: any) => log(text, 'error');
logFn.warn = (text: any) => log(text, 'warn');
logFn.info = (text: any) => log(text, 'info');
logFn.debug = (text: any) => log(text, 'debug');

return logFn;
};

export const getContext = ({
auth,
options,
bundlerName,
bundlerVersion,
injections,
version,
}: {
auth: Options['auth'];
options: OptionsWithDefaults;
bundlerName: BundlerName;
bundlerVersion: string;
injections: ToInjectItem[];
version: FactoryMeta['version'];
}): GlobalContext => {
const cwd = process.cwd();
const variant = bundlerName === 'webpack' ? bundlerVersion.split('.')[0] : '';

const build: BuildReport = {
errors: [],
warnings: [],
logs: [],
};
const context: GlobalContext = {
auth,
auth: options.auth,
pluginNames: [],
bundler: {
name: bundlerName,
Expand All @@ -37,22 +104,20 @@ export const getContext = ({
outDir: cwd,
version: bundlerVersion,
},
build: {
errors: [],
warnings: [],
},
build,
cwd,
inject: (item: ToInjectItem) => {
injections.push(item);
},
getLogger: getLoggerFactory(build, options.logLevel),
start: Date.now(),
version,
};

return context;
};

export const validateOptions = (options: Options = {}): Options => {
export const validateOptions = (options: Options = {}): OptionsWithDefaults => {
return {
auth: {},
disableGit: false,
Expand Down
9 changes: 5 additions & 4 deletions packages/factory/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
FactoryMeta,
GlobalContext,
Options,
OptionsWithDefaults,
PluginOptions,
ToInjectItem,
} from '@dd/core/types';
Expand Down Expand Up @@ -59,7 +60,7 @@ export const buildPluginFactory = ({
// TODO: Validate API Key and endpoint.
// TODO: Inject a metric logger into the global context.

const options = validateOptions(opts);
const options: OptionsWithDefaults = validateOptions(opts);

// Set the host name for the esbuild plugin.
if (unpluginMetaContext.framework === 'esbuild') {
Expand All @@ -69,7 +70,7 @@ export const buildPluginFactory = ({
// Create the global context.
const injections: ToInjectItem[] = [];
const context: GlobalContext = getContext({
auth: options.auth,
options,
bundlerVersion: bundler.version || bundler.VERSION,
bundlerName: unpluginMetaContext.framework as BundlerName,
injections,
Expand All @@ -83,10 +84,10 @@ export const buildPluginFactory = ({
const plugins: (PluginOptions | UnpluginOptions)[] = [
// Prefill with our internal plugins.
// #internal-plugins-injection-marker
...getBuildReportPlugins(options, context),
...getBuildReportPlugins(context),
...getBundlerReportPlugins(context),
...getGitPlugins(options, context),
...getInjectionPlugins(bundler, options, context, injections),
...getInjectionPlugins(bundler, context, injections),
// #internal-plugins-injection-marker
];

Expand Down
7 changes: 3 additions & 4 deletions packages/plugins/build-report/src/esbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
// Copyright 2019-Present Datadog, Inc.

import { getResolvedPath, isInjectionFile } from '@dd/core/helpers';
import type { Logger } from '@dd/core/log';
import type { Entry, GlobalContext, Input, Output, PluginOptions } from '@dd/core/types';
import type { Logger, Entry, GlobalContext, Input, Output, PluginOptions } from '@dd/core/types';
import { glob } from 'glob';

import { cleanName, getAbsolutePath, getType } from './helpers';
Expand Down Expand Up @@ -68,8 +67,8 @@ export const getEsbuildPlugin = (context: GlobalContext, log: Logger): PluginOpt
const entryNames = getEntryNames(entrypoints, context);

build.onEnd((result) => {
context.build.errors = result.errors.map((err) => err.text);
context.build.warnings = result.warnings.map((err) => err.text);
context.build.errors.push(...result.errors.map((err) => err.text));
context.build.warnings.push(...result.warnings.map((err) => err.text));

const warn = (warning: string) => {
context.build.warnings.push(warning);
Expand Down
2 changes: 2 additions & 0 deletions packages/plugins/build-report/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const serializeBuildReport = (report: BuildReport): SerializedBuildReport
const jsonReport: SerializedBuildReport = {
errors: report.errors,
warnings: report.warnings,
logs: report.logs,
start: report.start,
end: report.end,
duration: report.duration,
Expand Down Expand Up @@ -103,6 +104,7 @@ export const unserializeBuildReport = (report: SerializedBuildReport): BuildRepo
const buildReport: BuildReport = {
errors: report.errors,
warnings: report.warnings,
logs: report.logs,
start: report.start,
end: report.end,
duration: report.duration,
Expand Down
Loading

0 comments on commit 9757247

Please sign in to comment.