Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- deps: обновлены пакеты `@sentry/*`, `@opentelemetry/*` (major)
  • Loading branch information
krutoo committed Jul 2, 2024
1 parent 2f3559d commit 1cb5072
Show file tree
Hide file tree
Showing 9 changed files with 1,579 additions and 673 deletions.
2,131 changes: 1,514 additions & 617 deletions package-lock.json

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@
"dependencies": {
"@humanwhocodes/env": "^3.0.5",
"@krutoo/fetch-tools": "^0.0.16",
"@opentelemetry/api": "^1.4.1",
"@opentelemetry/exporter-prometheus": "^0.38.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.39.1",
"@opentelemetry/propagator-jaeger": "^1.12.0",
"@opentelemetry/resources": "^1.12.0",
"@opentelemetry/sdk-metrics": "^1.12.0",
"@opentelemetry/sdk-trace-base": "^1.12.0",
"@opentelemetry/sdk-trace-node": "^1.12.0",
"@opentelemetry/semantic-conventions": "^1.12.0",
"@sentry/browser": "^7.81.0",
"@sentry/bun": "^7.81.0",
"@sentry/node": "^7.81.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/exporter-prometheus": "^0.52.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
"@opentelemetry/propagator-jaeger": "^1.25.1",
"@opentelemetry/resources": "^1.25.1",
"@opentelemetry/sdk-metrics": "^1.25.1",
"@opentelemetry/sdk-trace-base": "^1.25.1",
"@opentelemetry/sdk-trace-node": "^1.25.1",
"@opentelemetry/semantic-conventions": "^1.25.1",
"@sentry/browser": "^8.13.0",
"@sentry/bun": "^8.13.0",
"@sentry/node": "^8.13.0",
"accepts": "^1.3.8",
"dotenv": "^16.3.1",
"express": "^4.18.2",
Expand Down
44 changes: 20 additions & 24 deletions src/log/handler/sentry.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import type { LogHandler } from '../types';
import type { Hub } from '@sentry/types';
import type { Scope } from '@sentry/types';
import { Breadcrumb, DetailedError } from '../../log';

/**
* Возвращает новый handler для logger'а для отправки событий в Sentry.
* @param hubInit Sentry Hub или функция которая его вернёт.
* @param scopeInit Sentry Hub или функция которая его вернёт.
* @return Handler.
*/
export function createSentryHandler(hubInit: Hub | (() => Hub)): LogHandler {
const getHub = typeof hubInit === 'function' ? hubInit : () => hubInit;
export function createSentryHandler(scopeInit: Scope | (() => Scope)): LogHandler {
const getScope = typeof scopeInit === 'function' ? scopeInit : () => scopeInit;

return event => {
// ВАЖНО: каждый входящий http-запрос должен иметь свой собственный hub
// ВАЖНО: каждый входящий http-запрос должен иметь свой собственный hub (ныне scope)
// подробности: https://github.com/getsentry/sentry-javascript/discussions/5648
// поэтому если передана функция - вызываем каждый раз (внутри обработчика)
const hub = getHub();
const scope = getScope();

// error
if (event.type === 'error') {
Expand All @@ -23,35 +23,31 @@ export function createSentryHandler(hubInit: Hub | (() => Hub)): LogHandler {
if (error instanceof DetailedError) {
const { level, context, extra } = error.data;

hub.withScope(scope => {
if (level) {
scope.setLevel(level);
}

if (context) {
const list = Array.isArray(context) ? context : [context];
if (level) {
scope.setLevel(level);
}

for (const item of list) {
scope.setContext(item.key, item.data);
}
}
if (context) {
const list = Array.isArray(context) ? context : [context];

if (extra) {
scope.setExtra(extra.key, extra.data);
for (const item of list) {
scope.setContext(item.key, item.data);
}
}

hub.captureException(error);
});
} else {
hub.captureException(error);
if (extra) {
scope.setExtra(extra.key, extra.data);
}
}

scope.captureException(error);
}

// breadcrumb
if (event.data instanceof Breadcrumb) {
const breadcrumb = event.data.data;

hub.addBreadcrumb(breadcrumb);
scope.addBreadcrumb(breadcrumb);
}
};
}
6 changes: 4 additions & 2 deletions src/preset/bun/providers/log-handler-sentry.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import { Resolve } from '../../../di';
import { KnownToken } from '../../../tokens';
import { getCurrentHub, init } from '@sentry/bun';
import { getCurrentScope, getDefaultIntegrations, init } from '@sentry/bun';
import { createSentryHandler } from '../../../log/handler/sentry';

export function provideLogHandlerSentry(resolve: Resolve) {
Expand All @@ -11,9 +11,11 @@ export function provideLogHandlerSentry(resolve: Resolve) {
dsn: source.require('SENTRY_DSN'),
release: source.require('SENTRY_RELEASE'),
environment: source.require('SENTRY_ENVIRONMENT'),
tracesSampleRate: Number(source.get('SENTRY_TRACES_SAMPLE_RATE', 0)),
integrations: [...getDefaultIntegrations({})],
});

// ВАЖНО: передаем функцию чтобы брать текущий hub в момент вызова метода logger'а
// это нужно чтобы хлебные крошки в ошибках Sentry группировались по запросам
return createSentryHandler(getCurrentHub);
return createSentryHandler(getCurrentScope);
}
4 changes: 2 additions & 2 deletions src/preset/bun/providers/serve-middleware.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import { Resolve } from '../../../di';
import { KnownToken } from '../../../tokens';
import { runWithAsyncContext } from '@sentry/bun';
import { withIsolationScope } from '@sentry/bun';
import { ServerMiddleware } from '../../server/types';
import { getServeLogging } from '../../server/utils/get-serve-logging';
import { getServeErrorLogging } from '../../server/utils/get-serve-error-logging';
Expand All @@ -13,7 +13,7 @@ export function provideServeMiddleware(resolve: Resolve): ServerMiddleware[] {

return [
// ВАЖНО: изолируем хлебные крошки чтобы они группировались по входящим запросам
(request, next) => runWithAsyncContext(async () => next(request)),
(request, next) => withIsolationScope(async () => next(request)),

// ВАЖНО: слой логирования ошибки ПЕРЕД остальными слоями чтобы не упустить ошибки выше
getServeErrorLogging(logger),
Expand Down
4 changes: 2 additions & 2 deletions src/preset/node/providers/express-error-middleware.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { expressErrorHandler } from '@sentry/node';
import type express from 'express';
import { Handlers } from '@sentry/node';

/**
* Провайдер промежуточного слоя обработки ошибок в рамках ответ на http-запросы.
* @return Промежуточный слой.
*/
export function provideExpressErrorMiddleware(): express.ErrorRequestHandler {
return Handlers.errorHandler();
return expressErrorHandler();
}
8 changes: 6 additions & 2 deletions src/preset/node/providers/express-request-middleware.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { withIsolationScope } from '@sentry/browser';
import type express from 'express';
import { Handlers } from '@sentry/node';

/**
* Провайдер промежуточного слоя учета входящих http-запросов.
* @return Промежуточный слой.
*/
export function provideExpressRequestMiddleware(): express.Handler {
return Handlers.requestHandler();
return (req, res, next) => {
withIsolationScope(() => {
next();
});
};
}
12 changes: 8 additions & 4 deletions src/preset/node/providers/log-handler-sentry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as Sentry from '@sentry/node';
import { init, getDefaultIntegrations, getCurrentScope } from '@sentry/node';
import { Resolve } from '../../../di';
import { LogHandler } from '../../../log';
import { createSentryHandler } from '../../../log/handler/sentry';
Expand All @@ -13,13 +13,17 @@ export function provideLogHandlerSentry(resolve: Resolve): LogHandler {
const source = resolve(KnownToken.Config.source);

// экспериментально пробуем не использовать вручную созданный клиент
Sentry.init({
init({
dsn: source.require('SENTRY_DSN'),
release: source.require('SENTRY_RELEASE'),
environment: source.require('SENTRY_ENVIRONMENT'),
tracesSampleRate: Number(source.get('SENTRY_TRACES_SAMPLE_RATE', 0)),
profilesSampleRate: Number(source.get('SENTRY_TRACES_SAMPLE_RATE', 0)),
integrations: [...getDefaultIntegrations({})],
skipOpenTelemetrySetup: true,
});

// ВАЖНО: передаем функцию чтобы брать текущий hub в момент вызова метода logger'а
// ВАЖНО: передаем функцию чтобы брать текущий scope в момент вызова метода logger'а
// это нужно чтобы хлебные крошки в ошибках Sentry группировались по запросам
return createSentryHandler(Sentry.getCurrentHub);
return createSentryHandler(getCurrentScope);
}
19 changes: 11 additions & 8 deletions src/preset/web/providers/logger.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
Scope,
BrowserClient,
Hub,
defaultIntegrations,
getDefaultIntegrations,
defaultStackParser,
makeFetchTransport,
} from '@sentry/browser';
Expand All @@ -20,21 +20,24 @@ export function provideLogger(resolve: Resolve): Logger {
const config = resolve(KnownToken.Config.base);

const client = new BrowserClient({
transport: makeFetchTransport,
stackParser: defaultStackParser,
dsn: source.require('PUBLIC_SENTRY_DSN'),
release: source.require('SENTRY_RELEASE'),
environment: source.require('PUBLIC_SENTRY_ENVIRONMENT'),
integrations: [...defaultIntegrations],
tracesSampleRate: Number(source.get('SENTRY_TRACES_SAMPLE_RATE', 0)),
profilesSampleRate: Number(source.get('SENTRY_TRACES_SAMPLE_RATE', 0)),
transport: makeFetchTransport,
stackParser: defaultStackParser,
integrations: [...getDefaultIntegrations({})],
});

const hub = new Hub(client);
const scope = new Scope();

hub.setTag('url', window.location.href);
scope.setTag('url', window.location.href);
scope.setClient(client);

const logger = createLogger();

logger.subscribe(createSentryHandler(hub));
logger.subscribe(createSentryHandler(scope));

if (config.env === 'development') {
logger.subscribe(event => {
Expand Down

0 comments on commit 1cb5072

Please sign in to comment.