feat(telemetry): add Sentry
as frontend telemetry (#1458)
Co-authored-by: sealday <zhanglin@daoyoucloud.com> Reviewed-on: daoyoucloud/tachybase#1458 Reviewed-by: sealday <zhanglin@daoyoucloud.com> Co-authored-by: TomyJan <TomyJan6@gmail.com> Co-committed-by: TomyJan <TomyJan6@gmail.com>
This commit is contained in:
parent
f020a2a4d3
commit
0dc784c2be
12
.env.example
12
.env.example
@ -58,9 +58,17 @@ INIT_ROOT_USERNAME=tachybase
|
||||
|
||||
# TELEMETRY_ENABLED=on # 是否启用遥测
|
||||
# TELEMETRY_SERVICE_NAME=tachybase-default-demo # 服务名称,默认为 tachybase-main
|
||||
# OTEL_LOG_LEVEL=debug # OpenTelemetry 日志级别,仅输出到控制台,见 [官方文档](https://open-telemetry.github.io/opentelemetry-js/enums/_opentelemetry_api.DiagLogLevel.html) ,不配置则默认不输出日志
|
||||
# OTEL_LOG_LEVEL=debug # OpenTelemetry 日志级别,仅输出到控制台,见 https://open-telemetry.github.io/opentelemetry-js/enums/_opentelemetry_api.DiagLogLevel.html ,不配置则默认不输出日志
|
||||
# OTEL_METRICS_READER=console,prometheus # 指标读取器,两个均为内置,console 为控制台,prometheus 为 prometheus 服务器
|
||||
# OTEL_PROMETHEUS_SERVER=on # 是否启用 Prometheus 服务,用于创建服务器以供导出指标数据
|
||||
# OTEL_PROMETHEUS_PORT=9464 # Prometheus 服务器端口,默认为 9464,注意此服务器没有鉴权
|
||||
# OTEL_TRACES_PROCESSOR=console,otlp # 链路追踪处理器,两个均为内置,console 为控制台,otlp 为 OTLP 规范的追踪服务器
|
||||
# OTEL_EXPORTER_OTLP_TRACES_ENDPOINT_GRPC=http://localhost:4317 # [OTLP](https://opentelemetry.io/docs/specs/otlp/) 规范的追踪服务器的 gRPC 端点地址
|
||||
# OTEL_EXPORTER_OTLP_TRACES_ENDPOINT_GRPC=http://localhost:4317 # OTLP https://opentelemetry.io/docs/specs/otlp/ 规范的追踪服务器的 gRPC 端点地址
|
||||
# 下面为前端 Sentry 跟踪配置,注意修改后需要重新 build 前端代码
|
||||
# SENTRY_DSN= # Sentry DSN,用于前端遥测
|
||||
# SENTRY_TRACE_ENABLE=on # 是否启用 Sentry 跟踪,文档 https://docs.sentry.io/platforms/javascript/guides/react/tracing/
|
||||
# SENTRY_TRACE_SAMPLE_RATE=1.0 # Sentry 跟踪采样率,1.0 为 100%,0.0 为 0%,默认为 1.0
|
||||
# SENTRY_TRACE_PROPAGATION_TARGETS=localhost,/^\// # Sentry 跟踪传播目标过滤器,多个用逗号分隔,支持正则,默认为 localhost,/^\// ,文档 https://docs.sentry.io/platforms/javascript/tracing/instrumentation/automatic-instrumentation/#tracepropagationtargets
|
||||
# SENTRY_SESSION_REPLAY_ENABLE=on # 是否启用 Sentry 会话重放,文档 https://docs.sentry.io/platforms/javascript/guides/react/session-replay/
|
||||
# SENTRY_SESSION_REPLAY_SAMPLE_RATE=0.1 # Sentry 会话重放采样率,1.0 为 100%,0.0 为 0%,默认为 0.1
|
||||
# SENTRY_SESSION_REPLAY_ONERROR_SAMPLE_RATE=1.0 # Sentry 会话重放错误采样率,1.0 为 100%,0.0 为 0%,默认为 1.0
|
||||
|
@ -31,4 +31,11 @@ jobs:
|
||||
- name: Publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPMTOKEN }}
|
||||
SENTRY_DSN: ${{ vars.SENTRY_DSN }}
|
||||
SENTRY_TRACE_ENABLE: ${{ vars.SENTRY_TRACE_ENABLE }}
|
||||
SENTRY_TRACE_SAMPLE_RATE: ${{ vars.SENTRY_TRACE_SAMPLE_RATE }}
|
||||
SENTRY_TRACE_PROPAGATION_TARGETS: ${{ vars.SENTRY_TRACE_PROPAGATION_TARGETS }}
|
||||
SENTRY_SESSION_REPLAY_ENABLE: ${{ vars.SENTRY_SESSION_REPLAY_ENABLE }}
|
||||
SENTRY_SESSION_REPLAY_SAMPLE_RATE: ${{ vars.SENTRY_SESSION_REPLAY_SAMPLE_RATE }}
|
||||
SENTRY_SESSION_REPLAY_ONERROR_SAMPLE_RATE: ${{ vars.SENTRY_SESSION_REPLAY_ONERROR_SAMPLE_RATE }}
|
||||
run: pnpm -r publish --access=public --no-git-checks --publish-branch ${{ gitea.ref }}
|
||||
|
@ -57,6 +57,13 @@ export default defineConfig({
|
||||
define: {
|
||||
...umiConfig.define,
|
||||
'process.env.USE_REMOTE_PLUGIN': process.env.USE_REMOTE_PLUGIN,
|
||||
'process.env.SENTRY_DSN': process.env.SENTRY_DSN,
|
||||
'process.env.SENTRY_TRACE_ENABLE': process.env.SENTRY_TRACE_ENABLE,
|
||||
'process.env.SENTRY_TRACE_SAMPLE_RATE': process.env.SENTRY_TRACE_SAMPLE_RATE,
|
||||
'process.env.SENTRY_TRACE_PROPAGATION_TARGETS': process.env.SENTRY_TRACE_PROPAGATION_TARGETS,
|
||||
'process.env.SENTRY_SESSION_REPLAY_ENABLE': process.env.SENTRY_SESSION_REPLAY_ENABLE,
|
||||
'process.env.SENTRY_SESSION_REPLAY_SAMPLE_RATE': process.env.SENTRY_SESSION_REPLAY_SAMPLE_RATE,
|
||||
'process.env.SENTRY_SESSION_REPLAY_ONERROR_SAMPLE_RATE': process.env.SENTRY_SESSION_REPLAY_ONERROR_SAMPLE_RATE,
|
||||
},
|
||||
proxy: {
|
||||
...umiConfig.proxy,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import '@tachybase/telemetry'; // 尽早实例化,以尽力保证插桩成功,TODO: Koa 依然无法成功 hook
|
||||
import '@tachybase/telemetry'; // 尽早实例化,以尽力保证插桩成功
|
||||
|
||||
import { Gateway } from '@tachybase/server';
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@emotion/css": "^11.7.1",
|
||||
"@sentry/react": "^8.25.0",
|
||||
"@tachybase/components": "workspace:*",
|
||||
"@tachybase/evaluators": "workspace:*",
|
||||
"@tachybase/schema": "workspace:*",
|
||||
|
@ -2,6 +2,7 @@ import React, { ComponentType, ReactElement } from 'react';
|
||||
import { define, observable } from '@tachybase/schema';
|
||||
import { APIClientOptions, getSubAppName } from '@tachybase/sdk';
|
||||
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { i18n as i18next } from 'i18next';
|
||||
import { get, merge, set } from 'lodash';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
@ -273,6 +274,59 @@ export class Application {
|
||||
};
|
||||
console.error(error, this.error);
|
||||
}
|
||||
if (process.env.APP_ENV === 'production') {
|
||||
const dsn = process.env.SENTRY_DSN;
|
||||
if (dsn) {
|
||||
const integrations = [];
|
||||
let tracesSampleRate = 1.0;
|
||||
let tracePropagationTargets = ['localhost', /^\//];
|
||||
if (process.env.SENTRY_TRACE_ENABLE === 'on') {
|
||||
integrations.push(Sentry.browserTracingIntegration());
|
||||
if (Number(process.env.SENTRY_TRACE_SAMPLE_RATE) >= 0 && Number(process.env.SENTRY_TRACE_SAMPLE_RATE) <= 1) {
|
||||
tracesSampleRate = parseFloat(process.env.SENTRY_TRACE_SAMPLE_RATE);
|
||||
}
|
||||
if (process.env.SENTRY_TRACE_PROPAGATION_TARGETS) {
|
||||
tracePropagationTargets = process.env.SENTRY_TRACE_PROPAGATION_TARGETS.split(',').map((target) => {
|
||||
if (target.startsWith('/')) {
|
||||
return new RegExp(target);
|
||||
}
|
||||
return target;
|
||||
});
|
||||
}
|
||||
}
|
||||
let replaysSessionSampleRate = 0.1;
|
||||
let replaysOnErrorSampleRate = 1.0;
|
||||
if (process.env.SENTRY_SESSION_REPLAY_ENABLE === 'on') {
|
||||
integrations.push(Sentry.replayIntegration());
|
||||
if (
|
||||
Number(process.env.SENTRY_SESSION_REPLAY_SAMPLE_RATE) >= 0 &&
|
||||
Number(process.env.SENTRY_SESSION_REPLAY_SAMPLE_RATE) <= 1
|
||||
) {
|
||||
replaysSessionSampleRate = parseFloat(process.env.SENTRY_SESSION_REPLAY_SAMPLE_RATE);
|
||||
}
|
||||
if (
|
||||
Number(process.env.SENTRY_SESSION_REPLAY_ONERROR_SAMPLE_RATE) >= 0 &&
|
||||
Number(process.env.SENTRY_SESSION_REPLAY_ONERROR_SAMPLE_RATE) <= 1
|
||||
) {
|
||||
replaysOnErrorSampleRate = parseFloat(process.env.SENTRY_SESSION_REPLAY_ON_ERROR_SAMPLE_RATE);
|
||||
}
|
||||
}
|
||||
Sentry.init({
|
||||
dsn,
|
||||
integrations,
|
||||
// Performance Monitoring
|
||||
tracesSampleRate, // Capture 100% of the transactions
|
||||
// Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
|
||||
tracePropagationTargets,
|
||||
// Session Replay
|
||||
replaysSessionSampleRate, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
|
||||
replaysOnErrorSampleRate, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
|
||||
});
|
||||
} else {
|
||||
console.log('SENTRY_DSN is not set, Sentry will not be initialized');
|
||||
}
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
export const telemetryOptions = {
|
||||
enabled: process.env.TELEMETRY_ENABLED === 'on',
|
||||
enabled: process.env.TELEMETRY_ENABLED === 'on' && process.env.APP_ENV === 'production',
|
||||
metric: {
|
||||
readerName: process.env.OTEL_METRICS_READER,
|
||||
},
|
||||
|
@ -473,6 +473,9 @@ importers:
|
||||
'@emotion/css':
|
||||
specifier: ^11.7.1
|
||||
version: 11.11.2
|
||||
'@sentry/react':
|
||||
specifier: ^8.25.0
|
||||
version: 8.25.0(react@18.3.1)
|
||||
'@tachybase/components':
|
||||
specifier: workspace:*
|
||||
version: link:../components
|
||||
@ -8672,10 +8675,34 @@ packages:
|
||||
'@scure/bip39@1.3.0':
|
||||
resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==}
|
||||
|
||||
'@sentry-internal/browser-utils@8.25.0':
|
||||
resolution: {integrity: sha512-nlWgp1lVhNQOTUplW85G3qm0fOIgAhJ/sl/31OIuScVrITYhYDF2bO+Zv/jQ8YsdUBAUXqY1tPT9wwPJklnPhw==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry-internal/feedback@8.25.0':
|
||||
resolution: {integrity: sha512-327I5XJAFrsgjc5qUKxZ9rff3WNCfGvf1fIii70LQ2YQhQgG4XHZILmkD06ETEyXb+H1tkrNQQEJ1/d4ai+q5g==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry-internal/replay-canvas@8.25.0':
|
||||
resolution: {integrity: sha512-dPXlkAbkFL1DBum8rGTaHS+apJKaXEZJF9gLcBBKTruhTCizrugFLxajzIfVSiFVuwNKuJWa2fzhzbeQM0ee7w==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry-internal/replay@8.25.0':
|
||||
resolution: {integrity: sha512-3f7x8EYthyj157uV9V8vBjun+1gJnHhh2+i0qxYLhMGx7N2Fq0J3Bvvo1rosSg+fYh5HzPNZDufwIRdg5C/MQw==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry/browser@8.25.0':
|
||||
resolution: {integrity: sha512-51bdVGXjyooqVGzaSGsnExqRTt9NvZ1zGFsxbbCSXi5UoEFN6zdMUz6jKYsL2K80eeELP2VKOVlobHlEzeJQfw==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry/core@5.30.0':
|
||||
resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
'@sentry/core@8.25.0':
|
||||
resolution: {integrity: sha512-7KtglbrW1eX4DOHkf6i4rRIExEf2CgtQ99qZ8gn5FUaAmNMg0rK7bb1yZMx0RZtp5G1TSz/S0jQQgxHWebaEig==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry/hub@5.30.0':
|
||||
resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==}
|
||||
engines: {node: '>=6'}
|
||||
@ -8688,6 +8715,12 @@ packages:
|
||||
resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
'@sentry/react@8.25.0':
|
||||
resolution: {integrity: sha512-A3QeSCJEa+lpo5nh0kxKeqsmnuW2nycKNN/0bpXPv5T5jiEfExSmEBVM0zutrQpf+J0WRIl1AGunUYGPO+GPQg==}
|
||||
engines: {node: '>=14.18'}
|
||||
peerDependencies:
|
||||
react: ^16.14.0 || 17.x || 18.x || 19.x
|
||||
|
||||
'@sentry/tracing@5.30.0':
|
||||
resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==}
|
||||
engines: {node: '>=6'}
|
||||
@ -8696,10 +8729,18 @@ packages:
|
||||
resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
'@sentry/types@8.25.0':
|
||||
resolution: {integrity: sha512-ojim0gDcRhGJPguYrtms4FsprX4xZz3LGNk9Z0hwTbSVEdlhQIInsQ7CYcdM3sjUs+qT7kfpxTRZGUeZNRRJcA==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry/utils@5.30.0':
|
||||
resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
'@sentry/utils@8.25.0':
|
||||
resolution: {integrity: sha512-mVlkV7S62ZZ2jM38/kOwWx2xoW8fUv2cjw2IwFKoAIPyLBh3mo1WJtvfdtN/rXGjQWZJBKW53EWaWnD00rkjyA==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sinclair/typebox@0.27.8':
|
||||
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
|
||||
|
||||
@ -24734,6 +24775,42 @@ snapshots:
|
||||
'@noble/hashes': 1.4.0
|
||||
'@scure/base': 1.1.7
|
||||
|
||||
'@sentry-internal/browser-utils@8.25.0':
|
||||
dependencies:
|
||||
'@sentry/core': 8.25.0
|
||||
'@sentry/types': 8.25.0
|
||||
'@sentry/utils': 8.25.0
|
||||
|
||||
'@sentry-internal/feedback@8.25.0':
|
||||
dependencies:
|
||||
'@sentry/core': 8.25.0
|
||||
'@sentry/types': 8.25.0
|
||||
'@sentry/utils': 8.25.0
|
||||
|
||||
'@sentry-internal/replay-canvas@8.25.0':
|
||||
dependencies:
|
||||
'@sentry-internal/replay': 8.25.0
|
||||
'@sentry/core': 8.25.0
|
||||
'@sentry/types': 8.25.0
|
||||
'@sentry/utils': 8.25.0
|
||||
|
||||
'@sentry-internal/replay@8.25.0':
|
||||
dependencies:
|
||||
'@sentry-internal/browser-utils': 8.25.0
|
||||
'@sentry/core': 8.25.0
|
||||
'@sentry/types': 8.25.0
|
||||
'@sentry/utils': 8.25.0
|
||||
|
||||
'@sentry/browser@8.25.0':
|
||||
dependencies:
|
||||
'@sentry-internal/browser-utils': 8.25.0
|
||||
'@sentry-internal/feedback': 8.25.0
|
||||
'@sentry-internal/replay': 8.25.0
|
||||
'@sentry-internal/replay-canvas': 8.25.0
|
||||
'@sentry/core': 8.25.0
|
||||
'@sentry/types': 8.25.0
|
||||
'@sentry/utils': 8.25.0
|
||||
|
||||
'@sentry/core@5.30.0':
|
||||
dependencies:
|
||||
'@sentry/hub': 5.30.0
|
||||
@ -24742,6 +24819,11 @@ snapshots:
|
||||
'@sentry/utils': 5.30.0
|
||||
tslib: 1.14.1
|
||||
|
||||
'@sentry/core@8.25.0':
|
||||
dependencies:
|
||||
'@sentry/types': 8.25.0
|
||||
'@sentry/utils': 8.25.0
|
||||
|
||||
'@sentry/hub@5.30.0':
|
||||
dependencies:
|
||||
'@sentry/types': 5.30.0
|
||||
@ -24768,6 +24850,15 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@sentry/react@8.25.0(react@18.3.1)':
|
||||
dependencies:
|
||||
'@sentry/browser': 8.25.0
|
||||
'@sentry/core': 8.25.0
|
||||
'@sentry/types': 8.25.0
|
||||
'@sentry/utils': 8.25.0
|
||||
hoist-non-react-statics: 3.3.2
|
||||
react: 18.3.1
|
||||
|
||||
'@sentry/tracing@5.30.0':
|
||||
dependencies:
|
||||
'@sentry/hub': 5.30.0
|
||||
@ -24778,11 +24869,17 @@ snapshots:
|
||||
|
||||
'@sentry/types@5.30.0': {}
|
||||
|
||||
'@sentry/types@8.25.0': {}
|
||||
|
||||
'@sentry/utils@5.30.0':
|
||||
dependencies:
|
||||
'@sentry/types': 5.30.0
|
||||
tslib: 1.14.1
|
||||
|
||||
'@sentry/utils@8.25.0':
|
||||
dependencies:
|
||||
'@sentry/types': 8.25.0
|
||||
|
||||
'@sinclair/typebox@0.27.8': {}
|
||||
|
||||
'@sindresorhus/is@0.14.0': {}
|
||||
|
Loading…
Reference in New Issue
Block a user