Skip to content

Commit

Permalink
Add internal reporting plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
yoannmoinet committed Feb 21, 2025
1 parent 6db2c83 commit 026c8fd
Show file tree
Hide file tree
Showing 14 changed files with 224 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ packages/tests/src/plugins/telemetry @DataDog/f
# Error Tracking
packages/plugins/error-tracking @yoannmoinet
packages/tests/src/plugins/error-tracking @yoannmoinet

# Analytics
packages/plugins/analytics @yoannmoinet
packages/tests/src/plugins/analytics @yoannmoinet
1 change: 1 addition & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export type GlobalContext = {
getLogger: GetLogger;
git?: RepositoryData;
pluginNames: string[];
sendLog: (message: string, ctx?: any) => Promise<void>;
start: number;
version: string;
};
Expand Down
8 changes: 8 additions & 0 deletions packages/factory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This is used to aggregate all the plugins and expose them to the bundler.

<!-- #toc -->
- [Internal Plugins](#internal-plugins)
- [Analytics](#analytics)
- [Build Report](#build-report)
- [Bundler Report](#bundler-report)
- [Git](#git)
Expand All @@ -23,6 +24,13 @@ These are the plugins that are used internally by the factory.
Most of the time they will interact via the global context.

<!-- #internal-plugins-list -->
### Analytics

> Send some analytics data to Datadog internally.
#### [📝 Full documentation ➡️](/packages/plugins/analytics#readme)


### Build Report

> This will populate `context.build` with a bunch of data coming from the build.
Expand Down
1 change: 1 addition & 0 deletions packages/factory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"dependencies": {
"@dd/core": "workspace:*",
"@dd/error-tracking-plugin": "workspace:*",
"@dd/internal-analytics-plugin": "workspace:*",
"@dd/internal-build-report-plugin": "workspace:*",
"@dd/internal-bundler-report-plugin": "workspace:*",
"@dd/internal-git-plugin": "workspace:*",
Expand Down
3 changes: 3 additions & 0 deletions packages/factory/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ export const getContext = ({
inject: () => {
throw new Error('Inject function called before it was initialized.');
},
sendLog: () => {
throw new Error('SendLog function called before it was initialized.');
},
start: Date.now(),
version,
};
Expand Down
2 changes: 2 additions & 0 deletions packages/factory/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import type { OptionsWithErrorTracking } from '@dd/error-tracking-plugin/types';
import * as errorTracking from '@dd/error-tracking-plugin';
import type { OptionsWithTelemetry } from '@dd/telemetry-plugin/types';
import * as telemetry from '@dd/telemetry-plugin';
import { getAnalyticsPlugins } from '@dd/internal-analytics-plugin';
import { getBuildReportPlugins } from '@dd/internal-build-report-plugin';
import { getBundlerReportPlugins } from '@dd/internal-bundler-report-plugin';
import { getGitPlugins } from '@dd/internal-git-plugin';
Expand Down Expand Up @@ -81,6 +82,7 @@ export const buildPluginFactory = ({
const plugins: (PluginOptions | UnpluginOptions)[] = [
// Prefill with our internal plugins.
// #internal-plugins-injection-marker
...getAnalyticsPlugins(context),
...getBuildReportPlugins(context),
...getBundlerReportPlugins(context),
...getGitPlugins(options, context),
Expand Down
30 changes: 30 additions & 0 deletions packages/plugins/analytics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Analytics Plugin <!-- #omit in toc -->

Send some analytics data to Datadog internally.

It gives you acces to the `context.sendLog()` function.

```typescript
// Send a basic log.
context.sendLog('My basic log');

// Send some context with the log.
context.sendLog('My contextual log', { some: 'context' });
```

Every log already has some context to it:

```typescript
{
ddsource: string; // Name of the bundler plugin (e.g. `@datadog/webpack-plugin`).
env: Env; // Environment (e.g. `production`).
message; // The log message.
service: 'build-plugins';
bundler: {
name: string; // Name of the bundler (e.g. `webpack`).
version: string; // Version of the bundler.
};
plugins: PluginName[]; // List of the plugins/features enabled.
version: string; // Version of the plugin.
}
```
24 changes: 24 additions & 0 deletions packages/plugins/analytics/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@dd/internal-analytics-plugin",
"packageManager": "[email protected]",
"license": "MIT",
"private": true,
"author": "Datadog",
"description": "Send some analytics data to Datadog internally.",
"homepage": "https://github.com/DataDog/build-plugins/tree/main/packages/plugins/analytics#readme",
"repository": {
"type": "git",
"url": "https://github.com/DataDog/build-plugins",
"directory": "packages/plugins/analytics"
},
"exports": {
".": "./src/index.ts",
"./*": "./src/*.ts"
},
"scripts": {
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@dd/core": "workspace:*"
}
}
9 changes: 9 additions & 0 deletions packages/plugins/analytics/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the MIT License.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2019-Present Datadog, Inc.

import type { PluginName } from '@dd/core/types';

export const PLUGIN_NAME: PluginName = 'datadog-analytics-plugin' as const;
export const INTAKE_PATH = 'v1/input/pub44d5f4eb86e1392037b7501f7adc540e';
export const INTAKE_HOST = 'browser-http-intake.logs.datadoghq.com';
69 changes: 69 additions & 0 deletions packages/plugins/analytics/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the MIT License.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2019-Present Datadog, Inc.

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

import { INTAKE_HOST, INTAKE_PATH, PLUGIN_NAME } from './constants';

export { PLUGIN_NAME } from './constants';

export const getAnalyticsPlugins = (context: GlobalContext): PluginOptions[] => {
const log = context.getLogger(PLUGIN_NAME);

context.sendLog = async (message: string, ctx: any = {}) => {
// Only send logs in production.
if (context.env !== 'production') {
return;
}

try {
const bundler = {
name: context.bundler.name,
version: context.bundler.version,
};

await doRequest({
// Don't delay the build too much on error.
retries: 2,
minTimeout: 100,
url: `https://${INTAKE_HOST}/${INTAKE_PATH}`,
method: 'POST',
type: 'json',
getData: async () => {
const data = {
ddsource: `@datadog/${bundler.name}-plugin`,
env: context.env,
message,
service: 'build-plugins',
bundler,
plugins: context.pluginNames,
version: context.version,
team: 'yoann',
...ctx,
};
return {
data: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
},
};
},
});
} catch (e: any) {
// We don't want to break anything in case of error.
log.debug(`Could not submit data to Datadog: ${e.message}`);
}
};

return [
{
name: PLUGIN_NAME,
async buildStart() {
// Send a log.
await context.sendLog('Build started');
},
},
];
};
10 changes: 10 additions & 0 deletions packages/plugins/analytics/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"baseUrl": "./",
"rootDir": "./",
"outDir": "./dist"
},
"include": ["**/*"],
"exclude": ["dist", "node_modules"]
}
1 change: 1 addition & 0 deletions packages/tests/src/_jest/helpers/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export const getContextMock = (overrides: Partial<GlobalContext> = {}): GlobalCo
getLogger: jest.fn(),
inject: jest.fn(),
pluginNames: [],
sendLog: jest.fn(),
start: Date.now(),
version: 'FAKE_VERSION',
...overrides,
Expand Down
53 changes: 53 additions & 0 deletions packages/tests/src/unit/plugins/analytics/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the MIT License.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2019-Present Datadog, Inc.

import { INTAKE_HOST, INTAKE_PATH } from '@dd/internal-analytics-plugin/constants';
import { BUNDLERS, runBundlers } from '@dd/tests/_jest/helpers/runBundlers';
import nock from 'nock';

describe('Analytics Plugin', () => {
describe('Without network error.', () => {
test('Should submit the data.', async () => {
const replyMock = jest.fn(() => ({}));

nock(`https://${INTAKE_HOST}`)
// Intercept logs submissions.
.post(`/${INTAKE_PATH}`)
.times(BUNDLERS.length)
.reply(200, replyMock);

await runBundlers({
customPlugins: (options, context) => {
// Change the env so we DO send the logs.
context.env = 'production';
return [];
},
});

expect(replyMock).toHaveBeenCalledTimes(BUNDLERS.length);

nock.cleanAll();
});
});

describe('With a network error.', () => {
beforeAll(async () => {
nock(`https://${INTAKE_HOST}`)
// Intercept logs submissions.
.post(`/${INTAKE_PATH}`)
// Reply with an error.
.reply(500, 'Network error.')
.persist();
});

afterAll(async () => {
nock.cleanAll();
});

test('Should not throw.', async () => {
const { errors } = await runBundlers();
expect(errors).toHaveLength(0);
});
});
});
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1652,6 +1652,7 @@ __metadata:
dependencies:
"@dd/core": "workspace:*"
"@dd/error-tracking-plugin": "workspace:*"
"@dd/internal-analytics-plugin": "workspace:*"
"@dd/internal-build-report-plugin": "workspace:*"
"@dd/internal-bundler-report-plugin": "workspace:*"
"@dd/internal-git-plugin": "workspace:*"
Expand All @@ -1662,6 +1663,14 @@ __metadata:
languageName: unknown
linkType: soft

"@dd/internal-analytics-plugin@workspace:*, @dd/internal-analytics-plugin@workspace:packages/plugins/analytics":
version: 0.0.0-use.local
resolution: "@dd/internal-analytics-plugin@workspace:packages/plugins/analytics"
dependencies:
"@dd/core": "workspace:*"
languageName: unknown
linkType: soft

"@dd/internal-build-report-plugin@workspace:*, @dd/internal-build-report-plugin@workspace:packages/plugins/build-report":
version: 0.0.0-use.local
resolution: "@dd/internal-build-report-plugin@workspace:packages/plugins/build-report"
Expand Down

0 comments on commit 026c8fd

Please sign in to comment.