Skip to content

feat(astro): Update @sentry/astro to use OpenTelemetry #10960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"dependencies": {
"@sentry/node-experimental": "latest || *",
"@sentry/node": "latest || *",
"@sentry/sveltekit": "latest || *",
"@sentry/remix": "latest || *",
"@sentry/astro": "latest || *",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,52 @@
import * as SentryAstro from '@sentry/astro';
import * as SentryBun from '@sentry/bun';
import * as SentryNextJs from '@sentry/nextjs';
import * as SentryNode from '@sentry/node-experimental';
import * as SentryNode from '@sentry/node';
import * as SentryNodeExperimental from '@sentry/node-experimental';
import * as SentryRemix from '@sentry/remix';
import * as SentryServerless from '@sentry/serverless';
import * as SentrySvelteKit from '@sentry/sveltekit';

/* List of exports that are safe to ignore / we don't require in any depending package */
const NODE_EXPORTS_IGNORE = [
const NODE_EXPERIMENTAL_EXPORTS_IGNORE = [
'default',
// Probably generated by transpilation, no need to require it
'__esModule',
// These Node exports were only made for type definition fixes (see #10339)
'Undici',
// These are not re-exported where not needed
'Http',
'DebugSession',
'AnrIntegrationOptions',
'LocalVariablesIntegrationOptions',
'Undici',
];

/* List of exports that are safe to ignore / we don't require in any depending package */
const NODE_EXPORTS_IGNORE = [
'default',
// Probably generated by transpilation, no need to require it
'__esModule',
];

/* Sanitized list of node exports */
const nodeExperimentalExports = Object.keys(SentryNodeExperimental).filter(
e => !NODE_EXPERIMENTAL_EXPORTS_IGNORE.includes(e),
);
const nodeExports = Object.keys(SentryNode).filter(e => !NODE_EXPORTS_IGNORE.includes(e));

type Dependent = {
package: string;
exports: string[];
ignoreExports?: string[];
skip?: boolean;
compareWith: string[];
};

const DEPENDENTS: Dependent[] = [
{
package: '@sentry/astro',
compareWith: nodeExports,
exports: Object.keys(SentryAstro),
},
{
package: '@sentry/bun',
compareWith: nodeExperimentalExports,
exports: Object.keys(SentryBun),
ignoreExports: [
// not supported in bun:
Expand All @@ -44,35 +58,36 @@ const DEPENDENTS: Dependent[] = [
},
{
package: '@sentry/nextjs',
compareWith: nodeExperimentalExports,
// Next.js doesn't require explicit exports, so we can just merge top level and `default` exports:
// @ts-expect-error: `default` is not in the type definition but it's defined
exports: Object.keys({ ...SentryNextJs, ...SentryNextJs.default }),
},
{
package: '@sentry/remix',
compareWith: nodeExperimentalExports,
exports: Object.keys(SentryRemix),
},
{
package: '@sentry/serverless',
compareWith: nodeExperimentalExports,
exports: Object.keys(SentryServerless),
ignoreExports: ['cron', 'hapiErrorPlugin'],
},
{
package: '@sentry/sveltekit',
compareWith: nodeExperimentalExports,
exports: Object.keys(SentrySvelteKit),
},
];

/* Sanitized list of node exports */
const nodeExports = Object.keys(SentryNode).filter(e => !NODE_EXPORTS_IGNORE.includes(e));

console.log('🔎 Checking for consistent exports of @sentry/node exports in depending packages');

const missingExports: Record<string, string[]> = {};
const dependentsToCheck = DEPENDENTS.filter(d => !d.skip);

for (const nodeExport of nodeExports) {
for (const dependent of dependentsToCheck) {
for (const dependent of dependentsToCheck) {
for (const nodeExport of dependent.compareWith) {
if (dependent.ignoreExports?.includes(nodeExport)) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"dependencies": {
"@sentry/browser": "8.0.0-alpha.2",
"@sentry/core": "8.0.0-alpha.2",
"@sentry/node-experimental": "8.0.0-alpha.2",
"@sentry/node": "8.0.0-alpha.2",
"@sentry/types": "8.0.0-alpha.2",
"@sentry/utils": "8.0.0-alpha.2",
"@sentry/vite-plugin": "^2.14.2"
Expand Down
23 changes: 17 additions & 6 deletions packages/astro/src/index.server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Node SDK exports
// Unfortunately, we cannot `export * from '@sentry/node-experimental'` because in prod builds,
// Unfortunately, we cannot `export * from '@sentry/node'` because in prod builds,
// Vite puts these exports into a `default` property (Sentry.default) rather than
// on the top - level namespace.

Expand Down Expand Up @@ -37,7 +37,6 @@ export {
setHttpStatus,
withScope,
withIsolationScope,
autoDiscoverNodePerformanceMonitoringIntegrations,
makeNodeTransport,
getDefaultIntegrations,
defaultStackParser,
Expand All @@ -47,7 +46,6 @@ export {
addRequestDataToEvent,
DEFAULT_USER_INCLUDES,
extractRequestData,
Integrations,
consoleIntegration,
onUncaughtExceptionIntegration,
onUnhandledRejectionIntegration,
Expand All @@ -59,7 +57,6 @@ export {
functionToStringIntegration,
inboundFiltersIntegration,
linkedErrorsIntegration,
Handlers,
setMeasurement,
getActiveSpan,
startSpan,
Expand All @@ -74,10 +71,24 @@ export {
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
} from '@sentry/node-experimental';
expressIntegration,
expressErrorHandler,
setupExpressErrorHandler,
fastifyIntegration,
graphqlIntegration,
mongoIntegration,
mongooseIntegration,
mysqlIntegration,
mysql2Integration,
nestIntegration,
postgresIntegration,
prismaIntegration,
hapiIntegration,
setupHapiErrorHandler,
} from '@sentry/node';

// We can still leave this for the carrier init and type exports
export * from '@sentry/node-experimental';
export * from '@sentry/node';

export { init } from './server/sdk';

Expand Down
16 changes: 12 additions & 4 deletions packages/astro/src/index.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ import sentryAstro from './index.server';
/** Initializes Sentry Astro SDK */
export declare function init(options: Options | clientSdk.BrowserOptions | serverSdk.NodeOptions): void;

// We only export server Integrations for now, until the exports are removed from Svelte and Node SDKs.
// Necessary to avoid type collision.
export declare const Integrations: typeof serverSdk.Integrations;

export declare const linkedErrorsIntegration: typeof clientSdk.linkedErrorsIntegration;
export declare const contextLinesIntegration: typeof clientSdk.contextLinesIntegration;

Expand All @@ -26,5 +22,17 @@ export declare const defaultStackParser: StackParser;
export declare function close(timeout?: number | undefined): PromiseLike<boolean>;
export declare function flush(timeout?: number | undefined): PromiseLike<boolean>;

// eslint-disable-next-line deprecation/deprecation
export declare const makeMain: typeof clientSdk.makeMain;
export declare const getActiveSpan: typeof clientSdk.getActiveSpan;
// eslint-disable-next-line deprecation/deprecation
export declare const getCurrentHub: typeof clientSdk.getCurrentHub;
export declare const getClient: typeof clientSdk.getClient;
export declare const startSpan: typeof clientSdk.startSpan;
export declare const startInactiveSpan: typeof clientSdk.startInactiveSpan;
export declare const startSpanManual: typeof clientSdk.startSpanManual;
export declare const withActiveSpan: typeof clientSdk.withActiveSpan;
export declare const Span: clientSdk.Span;

export declare const metrics: typeof clientSdk.metrics & typeof serverSdk.metrics;
export default sentryAstro;
2 changes: 1 addition & 1 deletion packages/astro/src/integration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => {
// @sentry/node is required in case we have 2 different @sentry/node
// packages installed in the same project.
// Ref: https://github.com/getsentry/sentry-javascript/issues/10121
noExternal: ['@sentry/astro', '@sentry/node-experimental', '@sentry/node'],
noExternal: ['@sentry/astro', '@sentry/node'],
},
},
});
Expand Down
6 changes: 4 additions & 2 deletions packages/astro/src/server/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, setHttpStatus } from '@sentry/core';
import {
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
captureException,
continueTrace,
getActiveSpan,
getClient,
getCurrentScope,
setHttpStatus,
startSpan,
withIsolationScope,
} from '@sentry/node-experimental';
} from '@sentry/node';
import type { Client, Scope, Span, SpanAttributes } from '@sentry/types';
import { addNonEnumerableProperty, objectify, stripUrlQueryAndFragment } from '@sentry/utils';
import type { APIContext, MiddlewareResponseHandler } from 'astro';
Expand Down
15 changes: 11 additions & 4 deletions packages/astro/src/server/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import { applySdkMetadata } from '@sentry/core';
import type { NodeOptions } from '@sentry/node-experimental';
import { init as initNodeSdk, setTag } from '@sentry/node-experimental';
import type { NodeOptions } from '@sentry/node';
import { getDefaultIntegrations } from '@sentry/node';
import { init as initNodeSdk, setTag } from '@sentry/node';

/**
*
* @param options
*/
export function init(options: NodeOptions): void {
applySdkMetadata(options, 'astro', ['astro', 'node']);
const opts = {
...options,
// TODO v8: For now, we disable the Prisma integration, because that has weird esm-cjs interop issues
// We should figure these out and fix these before v8 goes stable.
defaultIntegrations: getDefaultIntegrations(options).filter(integration => integration.name !== 'Prisma'),
};
applySdkMetadata(opts, 'astro', ['astro', 'node']);

initNodeSdk(options);
initNodeSdk(opts);

setTag('runtime', 'node');
}
10 changes: 7 additions & 3 deletions packages/astro/test/client/sdk.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import type { BrowserClient } from '@sentry/browser';
import { getActiveSpan } from '@sentry/browser';
import { browserTracingIntegration } from '@sentry/browser';
import {
browserTracingIntegration,
getActiveSpan,
getCurrentScope,
getGlobalScope,
getIsolationScope,
} from '@sentry/browser';
import * as SentryBrowser from '@sentry/browser';
import { SDK_VERSION, getClient } from '@sentry/browser';
import { vi } from 'vitest';

import { getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core';
import { init } from '../../../astro/src/client/sdk';

const browserInit = vi.spyOn(SentryBrowser, 'init');
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/test/server/meta.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { vi } from 'vitest';

import { getTracingMetaTags, isValidBaggageString } from '../../src/server/meta';

const TRACE_FLAG_SAMPLED = 0x1;
const TRACE_FLAG_SAMPLED = 1;

const mockedSpan = new SentrySpan({
traceId: '12345678901234567890123456789012',
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/test/server/middleware.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
import * as SentryNode from '@sentry/node-experimental';
import * as SentryNode from '@sentry/node';
import type { Client, Span } from '@sentry/types';
import { vi } from 'vitest';

Expand Down
4 changes: 2 additions & 2 deletions packages/astro/test/server/sdk.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as SentryNode from '@sentry/node-experimental';
import { SDK_VERSION } from '@sentry/node-experimental';
import * as SentryNode from '@sentry/node';
import { SDK_VERSION } from '@sentry/node';
import { vi } from 'vitest';

import { init } from '../../src/server/sdk';
Expand Down
4 changes: 2 additions & 2 deletions packages/node-experimental/src/proxy/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
*/

/* eslint-disable jsdoc/require-jsdoc */
import * as http from 'http';
import * as https from 'https';
import * as http from 'node:http';
import * as https from 'node:https';
import type { Readable } from 'stream';

export type ThenableRequest = http.ClientRequest & {
Expand Down
4 changes: 2 additions & 2 deletions packages/node-experimental/src/transports/http-module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ClientRequest, IncomingHttpHeaders, RequestOptions as HTTPRequestOptions } from 'http';
import type { RequestOptions as HTTPSRequestOptions } from 'https';
import type { ClientRequest, IncomingHttpHeaders, RequestOptions as HTTPRequestOptions } from 'node:http';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These ones shouldn't matter since they're type imports and wont end up in the output

import type { RequestOptions as HTTPSRequestOptions } from 'node:https';

export type HTTPModuleRequestOptions = HTTPRequestOptions | HTTPSRequestOptions | string | URL;

Expand Down
4 changes: 2 additions & 2 deletions packages/node-experimental/src/transports/http.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as http from 'http';
import * as https from 'https';
import * as http from 'node:http';
import * as https from 'node:https';
import { Readable } from 'stream';
import { createGzip } from 'zlib';
import { createTransport } from '@sentry/core';
Expand Down