Skip to content

Commit

Permalink
Unify logging
Browse files Browse the repository at this point in the history
  • Loading branch information
yoannmoinet committed May 14, 2024
1 parent 50fa436 commit cfad9dc
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 97 deletions.
11 changes: 11 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,5 +386,16 @@ module.exports = {
'import/no-extraneous-dependencies': 0,
},
},
{
files: [
'packages/core/**/*',
'packages/esbuild-plugin/**/*',
'packages/plugins/**/*',
'packages/webpack-plugin/**/*',
],
rules: {
'no-console': 'error',
},
},
],
};
57 changes: 55 additions & 2 deletions packages/plugins/telemetry/src/common/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@

import { defaultTelemetryFilters } from '@datadog/build-plugins-core/helpers';
import type { Metric } from '@datadog/build-plugins-core/types';
import c from 'chalk';

import { CONFIG_KEY } from '../constants';
import type { OptionsWithTelemetryEnabled, OptionsDD, MetricToSend } from '../types';
import { PLUGIN_NAME, CONFIG_KEY } from '../constants';
import type {
OptionsWithTelemetryEnabled,
OptionsDD,
MetricToSend,
LogLevel,
OutputOptions,
} from '../types';

export const getMetric = (metric: Metric, opts: OptionsDD): MetricToSend => ({
type: 'gauge',
Expand All @@ -19,14 +26,60 @@ export const flattened = (arr: any[]) => [].concat(...arr);

export const getType = (name: string) => (name.includes('.') ? name.split('.').pop() : 'unknown');

export const getLogLevel = (output?: OutputOptions) => {
const logLevels: LogLevel[] = ['debug', 'warn', 'error', 'none'];
let logLevel: LogLevel = 'debug';

if (output === false) {
logLevel = 'none';
} else if (typeof output === 'object' && output.level) {
logLevel = output.level;
} else if (typeof output === 'string' && logLevels.includes(output as LogLevel)) {
logLevel = output as LogLevel;
}

return logLevel;
};

export const getOptionsDD = (opt: OptionsWithTelemetryEnabled): OptionsDD => {
const options = opt[CONFIG_KEY];

return {
timestamp: Math.floor((options.datadog?.timestamp || Date.now()) / 1000),
apiKey: opt.auth.apiKey || '',
tags: options.datadog?.tags || [],
endPoint: options.datadog?.endPoint || 'app.datadoghq.com',
prefix: options.datadog?.prefix || '',
filters: options.datadog?.filters || defaultTelemetryFilters,
logLevel: getLogLevel(options.output),
};
};

const log = (text: string, level: LogLevel, type: LogLevel = 'debug') => {
let color = c;
// eslint-disable-next-line no-console
let logFn = console.log;

if (type === 'error') {
color = c.red;
// eslint-disable-next-line no-console
logFn = console.error;
} else if (type === 'warn') {
color = c.yellow;
// eslint-disable-next-line no-console
logFn = console.warn;
}

if (
level === 'debug' ||
(level === 'warn' && ['error', 'warn'].includes(type)) ||
(level === 'error' && type === 'error')
) {
logFn(`[${c.bold(PLUGIN_NAME)}] ${color(text)}`);
}
};

export const getLogFn =
(level: LogLevel) =>
(text: string, type: LogLevel = 'debug') =>
log(text, level, type);
1 change: 0 additions & 1 deletion packages/plugins/telemetry/src/common/metrics/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ export const getIndexed = (stats: StatsJson, cwd: string): WebpackIndexedObject
const entriesPerChunkId: { [key: string]: Entry } = {};

const addModule = (module: Module) => {
// console.log('Add Module', module.name);
// No internals.
if (/^webpack\/runtime/.test(module.name)) {
return;
Expand Down
14 changes: 8 additions & 6 deletions packages/plugins/telemetry/src/common/output/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import path from 'path';

import { CONFIG_KEY } from '../../constants';
import type { Context, OptionsWithTelemetryEnabled } from '../../types';
import { getLogFn, getLogLevel } from '../helpers';

type Files = 'timings' | 'dependencies' | 'bundler' | 'metrics';

Expand Down Expand Up @@ -43,6 +44,7 @@ export const outputFiles = async (context: Context, options: OptionsWithTelemetr
}

const outputPath = path.resolve(options.cwd, destination);
const log = getLogFn(getLogLevel(opts));

try {
const errors: { [key: string]: Error } = {};
Expand Down Expand Up @@ -83,14 +85,14 @@ export const outputFiles = async (context: Context, options: OptionsWithTelemetr

const proms = (Object.keys(filesToWrite) as Files[]).map((file) => {
const start = Date.now();
console.log(`Start writing ${file}.json.`);
log(`Start writing ${file}.json.`);

return writeFile(path.join(outputPath, `${file}.json`), filesToWrite[file]!.content)
.then(() => {
console.log(`Wrote ${file}.json in ${formatDuration(Date.now() - start)}`);
log(`Wrote ${file}.json in ${formatDuration(Date.now() - start)}`);
})
.catch((e) => {
console.log(
log(
`Failed to write ${file}.json in ${formatDuration(Date.now() - start)}`,
'error',
);
Expand All @@ -100,18 +102,18 @@ export const outputFiles = async (context: Context, options: OptionsWithTelemetr

// We can't use Promise.allSettled because we want to support NodeJS 10+
await Promise.all(proms);
console.log(`Wrote files in ${formatDuration(Date.now() - startWriting)}.`);
log(`Wrote files in ${formatDuration(Date.now() - startWriting)}.`);
// If we had some errors.
const fileErrored = Object.keys(errors);
if (fileErrored.length) {
console.log(
log(
`Couldn't write files.\n${fileErrored.map(
(file) => ` - ${file}: ${errors[file].toString()}`,
)}`,
'error',
);
}
} catch (e) {
console.log(`Couldn't write files. ${e}`, 'error');
log(`Couldn't write files. ${e}`, 'error');
}
};
21 changes: 10 additions & 11 deletions packages/plugins/telemetry/src/common/output/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,30 @@
import { formatDuration } from '@datadog/build-plugins-core/helpers';
import c from 'chalk';

import { PLUGIN_NAME } from '../../constants';
import { CONFIG_KEY, PLUGIN_NAME } from '../../constants';
import type { Context, OptionsWithTelemetryEnabled } from '../../types';
import { getMetrics } from '../aggregator';
import { getMetric, getOptionsDD } from '../helpers';
import { getLogFn, getLogLevel, getMetric, getOptionsDD } from '../helpers';
import { sendMetrics } from '../sender';

export const addMetrics = (context: Context, options: OptionsWithTelemetryEnabled) => {
const { report, bundler } = context;
const log = getLogFn(getLogLevel(options[CONFIG_KEY].output));

context.metrics = context.metrics || [];
try {
context.metrics = getMetrics(options, report, bundler);
} catch (e) {
const stack = e instanceof Error ? e.stack : e;
console.log(`Couldn't aggregate metrics: ${stack}`, 'error');
log(`Couldn't aggregate metrics: ${stack}`, 'error');
}
};

export const processMetrics = async (context: Context, options: OptionsWithTelemetryEnabled) => {
const { start } = context;
const duration = Date.now() - start;
const optionsDD = getOptionsDD(options);
const log = getLogFn(optionsDD.logLevel);
context.metrics = context.metrics || [];
// We're missing the duration of this hook for our plugin.
context.metrics.push(
Expand All @@ -41,21 +43,18 @@ export const processMetrics = async (context: Context, options: OptionsWithTelem
),
);

console.log(`Took ${formatDuration(duration)}.`);
log(`Took ${formatDuration(duration)}.`);

// Send everything only if we have the key.
if (!optionsDD.apiKey) {
console.log(`Won't send metrics to ${c.bold('Datadog')}: missing API Key.`, 'warn');
log(`Won't send metrics to ${c.bold('Datadog')}: missing API Key.`, 'warn');
return;
}
try {
const startSending = Date.now();
await sendMetrics(context.metrics, {
apiKey: optionsDD.apiKey,
endPoint: optionsDD.endPoint,
});
console.log(`Sent metrics in ${formatDuration(Date.now() - startSending)}.`);
await sendMetrics(context.metrics, optionsDD);
log(`Sent metrics in ${formatDuration(Date.now() - startSending)}.`);
} catch (e) {
console.log(`Error sending metrics ${e}`, 'error');
log(`Error sending metrics ${e}`, 'error');
}
};
Loading

0 comments on commit cfad9dc

Please sign in to comment.