summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.config/cypress-devcontainer.yml5
-rw-r--r--.config/docker_example.yml5
-rw-r--r--.config/example.yml5
-rw-r--r--.devcontainer/devcontainer.yml5
-rw-r--r--CHANGELOG.md3
-rw-r--r--chart/files/default.yml5
-rw-r--r--packages/backend/package.json1
-rw-r--r--packages/backend/src/config.ts17
-rw-r--r--packages/backend/src/core/entities/MetaEntityService.ts1
-rw-r--r--packages/backend/src/models/json-schema/meta.ts32
-rw-r--r--packages/frontend/package.json1
-rw-r--r--packages/frontend/src/boot/common.ts37
-rw-r--r--packages/misskey-js/src/autogen/types.ts15
-rw-r--r--pnpm-lock.yaml74
14 files changed, 202 insertions, 4 deletions
diff --git a/.config/cypress-devcontainer.yml b/.config/cypress-devcontainer.yml
index e75e32a17a..a028e2685e 100644
--- a/.config/cypress-devcontainer.yml
+++ b/.config/cypress-devcontainer.yml
@@ -165,6 +165,11 @@ id: 'aidx'
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
#sentryForFrontend:
+# vueIntegration:
+# tracingOptions:
+# trackComponents: true
+# browserTracingIntegration:
+# replayIntegration:
# options:
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
diff --git a/.config/docker_example.yml b/.config/docker_example.yml
index 1ffed00cc7..4be1352bd7 100644
--- a/.config/docker_example.yml
+++ b/.config/docker_example.yml
@@ -177,6 +177,11 @@ id: 'aidx'
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
#sentryForFrontend:
+# vueIntegration:
+# tracingOptions:
+# trackComponents: true
+# browserTracingIntegration:
+# replayIntegration:
# options:
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
diff --git a/.config/example.yml b/.config/example.yml
index 71427c84bc..d4584215c9 100644
--- a/.config/example.yml
+++ b/.config/example.yml
@@ -259,6 +259,11 @@ id: 'aidx'
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
#sentryForFrontend:
+# vueIntegration:
+# tracingOptions:
+# trackComponents: true
+# browserTracingIntegration:
+# replayIntegration:
# options:
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
diff --git a/.devcontainer/devcontainer.yml b/.devcontainer/devcontainer.yml
index 3eb4fc2879..6d904e87b9 100644
--- a/.devcontainer/devcontainer.yml
+++ b/.devcontainer/devcontainer.yml
@@ -152,6 +152,11 @@ id: 'aidx'
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
#sentryForFrontend:
+# vueIntegration:
+# tracingOptions:
+# trackComponents: true
+# browserTracingIntegration:
+# replayIntegration:
# options:
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9a2da274e4..2cd0fbd8e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,9 @@
- メッセージにはリアクションも可能です
- Enhance: セキュリティを強化するため、ジョブキューのダッシュボード(bull-board)統合が削除されました。
- Misskeyネイティブでダッシュボードを実装予定です
+- Enhance: フロントエンドのエラートラッキングができるように
+ - `.config/default.yml`中の項目`sentryForFrontend`を適宜設定してください。
+ - 外部サービスであるSentryへエラー情報が送信されます。ご利用の地域の法令に従い、適切なプライバシーポリシーを策定の上で運用してください。
- Enhance: ミュートしているユーザーをユーザー検索の結果から除外するように
- Fix: 通知のページネーションで2つ以上読み込めなくなることがある問題を修正
diff --git a/chart/files/default.yml b/chart/files/default.yml
index 4d17131c25..06f762aafa 100644
--- a/chart/files/default.yml
+++ b/chart/files/default.yml
@@ -173,6 +173,11 @@ id: "aidx"
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
#sentryForFrontend:
+# vueIntegration:
+# tracingOptions:
+# trackComponents: true
+# browserTracingIntegration:
+# replayIntegration:
# options:
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
diff --git a/packages/backend/package.json b/packages/backend/package.json
index bcaa6357ce..d7705b2b9e 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -186,6 +186,7 @@
"devDependencies": {
"@jest/globals": "29.7.0",
"@nestjs/platform-express": "10.4.15",
+ "@sentry/vue": "9.8.0",
"@simplewebauthn/types": "12.0.0",
"@swc/jest": "0.2.37",
"@types/accepts": "1.3.7",
diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts
index 32ea700748..646fa07911 100644
--- a/packages/backend/src/config.ts
+++ b/packages/backend/src/config.ts
@@ -7,7 +7,8 @@ import * as fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';
import * as yaml from 'js-yaml';
-import * as Sentry from '@sentry/node';
+import type * as Sentry from '@sentry/node';
+import type * as SentryVue from '@sentry/vue';
import type { RedisOptions } from 'ioredis';
type RedisOptionsSource = Partial<RedisOptions> & {
@@ -62,7 +63,12 @@ type Source = {
scope?: 'local' | 'global' | string[];
};
sentryForBackend?: { options: Partial<Sentry.NodeOptions>; enableNodeProfiling: boolean; };
- sentryForFrontend?: { options: Partial<Sentry.NodeOptions> };
+ sentryForFrontend?: {
+ options: Partial<SentryVue.BrowserOptions> & { dsn: string };
+ vueIntegration?: SentryVue.VueIntegrationOptions | null;
+ browserTracingIntegration?: Parameters<typeof SentryVue.browserTracingIntegration>[0] | null;
+ replayIntegration?: Parameters<typeof SentryVue.replayIntegration>[0] | null;
+ };
publishTarballInsteadOfProvideRepositoryUrl?: boolean;
@@ -198,7 +204,12 @@ export type Config = {
redisForTimelines: RedisOptions & RedisOptionsSource;
redisForReactions: RedisOptions & RedisOptionsSource;
sentryForBackend: { options: Partial<Sentry.NodeOptions>; enableNodeProfiling: boolean; } | undefined;
- sentryForFrontend: { options: Partial<Sentry.NodeOptions> } | undefined;
+ sentryForFrontend: {
+ options: Partial<SentryVue.BrowserOptions> & { dsn: string };
+ vueIntegration?: SentryVue.VueIntegrationOptions | null;
+ browserTracingIntegration?: Parameters<typeof SentryVue.browserTracingIntegration>[0] | null;
+ replayIntegration?: Parameters<typeof SentryVue.replayIntegration>[0] | null;
+ } | undefined;
perChannelMaxNoteCacheCount: number;
perUserNotificationsMaxCount: number;
deactivateAntennaThreshold: number;
diff --git a/packages/backend/src/core/entities/MetaEntityService.ts b/packages/backend/src/core/entities/MetaEntityService.ts
index 08717bd066..02783dc450 100644
--- a/packages/backend/src/core/entities/MetaEntityService.ts
+++ b/packages/backend/src/core/entities/MetaEntityService.ts
@@ -127,6 +127,7 @@ export class MetaEntityService {
policies: { ...DEFAULT_POLICIES, ...instance.policies },
+ sentryForFrontend: this.config.sentryForFrontend ?? null,
mediaProxy: this.config.mediaProxy,
enableUrlPreview: instance.urlPreviewEnabled,
noteSearchableScope: (this.config.meilisearch == null || this.config.meilisearch.scope !== 'local') ? 'global' : 'local',
diff --git a/packages/backend/src/models/json-schema/meta.ts b/packages/backend/src/models/json-schema/meta.ts
index 1e25c355ca..2cd7620af0 100644
--- a/packages/backend/src/models/json-schema/meta.ts
+++ b/packages/backend/src/models/json-schema/meta.ts
@@ -211,6 +211,38 @@ export const packedMetaLiteSchema = {
type: 'boolean',
optional: false, nullable: false,
},
+ sentryForFrontend: {
+ type: 'object',
+ optional: false, nullable: true,
+ properties: {
+ options: {
+ type: 'object',
+ optional: false, nullable: false,
+ properties: {
+ dsn: {
+ type: 'string',
+ optional: false, nullable: false,
+ },
+ },
+ additionalProperties: true,
+ },
+ vueIntegration: {
+ type: 'object',
+ optional: true, nullable: true,
+ additionalProperties: true,
+ },
+ browserTracingIntegration: {
+ type: 'object',
+ optional: true, nullable: true,
+ additionalProperties: true,
+ },
+ replayIntegration: {
+ type: 'object',
+ optional: true, nullable: true,
+ additionalProperties: true,
+ },
+ },
+ },
mediaProxy: {
type: 'string',
optional: false, nullable: false,
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index fe0abb173b..01dcf09d47 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -25,6 +25,7 @@
"@rollup/plugin-json": "6.1.0",
"@rollup/plugin-replace": "6.0.2",
"@rollup/pluginutils": "5.1.4",
+ "@sentry/vue": "9.8.0",
"@syuilo/aiscript": "0.19.0",
"@tabler/icons-webfont": "3.31.0",
"@twemoji/parser": "15.1.1",
diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts
index 7a88b938dd..c8098b6cf8 100644
--- a/packages/frontend/src/boot/common.ts
+++ b/packages/frontend/src/boot/common.ts
@@ -5,7 +5,7 @@
import { computed, watch, version as vueVersion } from 'vue';
import { compareVersions } from 'compare-versions';
-import { version, lang, updateLocale, locale } from '@@/js/config.js';
+import { version, lang, updateLocale, locale, apiUrl } from '@@/js/config.js';
import defaultLightTheme from '@@/themes/l-light.json5';
import defaultDarkTheme from '@@/themes/d-green-lime.json5';
import type { App } from 'vue';
@@ -291,6 +291,41 @@ export async function common(createVue: () => Promise<App<Element>>) {
return root;
})();
+ if (instance.sentryForFrontend) {
+ const Sentry = await import('@sentry/vue');
+ Sentry.init({
+ app,
+ integrations: [
+ ...(instance.sentryForFrontend.vueIntegration !== undefined ? [
+ Sentry.vueIntegration(instance.sentryForFrontend.vueIntegration ?? undefined),
+ ] : []),
+ ...(instance.sentryForFrontend.browserTracingIntegration !== undefined ? [
+ Sentry.browserTracingIntegration(instance.sentryForFrontend.browserTracingIntegration ?? undefined),
+ ] : []),
+ ...(instance.sentryForFrontend.replayIntegration !== undefined ? [
+ Sentry.replayIntegration(instance.sentryForFrontend.replayIntegration ?? undefined),
+ ] : []),
+ ],
+
+ // Set tracesSampleRate to 1.0 to capture 100%
+ tracesSampleRate: 1.0,
+
+ // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled
+ ...(instance.sentryForFrontend.browserTracingIntegration !== undefined ? {
+ tracePropagationTargets: [apiUrl],
+ } : {}),
+
+ // Capture Replay for 10% of all sessions,
+ // plus for 100% of sessions with an error
+ ...(instance.sentryForFrontend.replayIntegration !== undefined ? {
+ replaysSessionSampleRate: 0.1,
+ replaysOnErrorSampleRate: 1.0,
+ } : {}),
+
+ ...instance.sentryForFrontend.options,
+ });
+ }
+
app.mount(rootEl);
// boot.jsのやつを解除
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index d46df2423a..ef4be07072 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -5309,6 +5309,21 @@ export type components = {
enableEmail: boolean;
enableServiceWorker: boolean;
translatorAvailable: boolean;
+ sentryForFrontend: ({
+ options: {
+ dsn: string;
+ [key: string]: unknown;
+ };
+ vueIntegration?: {
+ [key: string]: unknown;
+ } | null;
+ browserTracingIntegration?: {
+ [key: string]: unknown;
+ } | null;
+ replayIntegration?: {
+ [key: string]: unknown;
+ } | null;
+ }) | null;
mediaProxy: string;
enableUrlPreview: boolean;
backgroundImageUrl: string | null;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 146021fbf1..46416c0332 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -444,6 +444,9 @@ importers:
'@nestjs/platform-express':
specifier: 10.4.15
version: 10.4.15(@nestjs/common@11.0.12(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.0.12)
+ '@sentry/vue':
+ specifier: 9.8.0
+ version: 9.8.0(vue@3.5.13(typescript@5.8.2))
'@simplewebauthn/types':
specifier: 12.0.0
version: 12.0.0
@@ -709,6 +712,9 @@ importers:
'@rollup/pluginutils':
specifier: 5.1.4
version: 5.1.4(rollup@4.36.0)
+ '@sentry/vue':
+ specifier: 9.8.0
+ version: 9.8.0(vue@3.5.13(typescript@5.8.2))
'@syuilo/aiscript':
specifier: 0.19.0
version: 0.19.0
@@ -3555,10 +3561,34 @@ packages:
'@sec-ant/readable-stream@0.4.1':
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
+ '@sentry-internal/browser-utils@9.8.0':
+ resolution: {integrity: sha512-7aQDeU9ogMLKnEBFM/vvgMMgZDkfMhoZCtX8kq65gn33L4X2B8sI5oyUj2QJtXaRSsiUjbdCaquDLqZBCaLQHA==}
+ engines: {node: '>=18'}
+
+ '@sentry-internal/feedback@9.8.0':
+ resolution: {integrity: sha512-xWiCJkD8ROuy2pnojuRLcLI6sezK399gasA5ZL4MCXdkryqZYs55Ef2Ofj4z0RdUc8gMUb81+LTqwbmbfTqNlQ==}
+ engines: {node: '>=18'}
+
+ '@sentry-internal/replay-canvas@9.8.0':
+ resolution: {integrity: sha512-/6ELOnyCOItvqv2Os29JhE8ydDds3xibMQ+FomsSkClQdC4bbc/L74nm/fdXVpJkMswtjksiTwZo1nYTS3JsIw==}
+ engines: {node: '>=18'}
+
+ '@sentry-internal/replay@9.8.0':
+ resolution: {integrity: sha512-YJhhNnrsufYVIX9s5lNSFFQrBJjUtn5AxvrcnN0fvLymNg3Y73GOUpFmhTxyELjQneKiOViClxjoWSVAN7sqQA==}
+ engines: {node: '>=18'}
+
+ '@sentry/browser@9.8.0':
+ resolution: {integrity: sha512-iFM4PGLc6qCb0GaHnA5Uy09k25RXVSepAgS574cm1CH7II1wrRjTozKnPKROW89WDMuxoTOL7Tk7qPGCyWmA4g==}
+ engines: {node: '>=18'}
+
'@sentry/core@8.55.0':
resolution: {integrity: sha512-6g7jpbefjHYs821Z+EBJ8r4Z7LT5h80YSWRJaylGS4nW5W5Z2KXzpdnyFarv37O7QjauzVC2E+PABmpkw5/JGA==}
engines: {node: '>=14.18'}
+ '@sentry/core@9.8.0':
+ resolution: {integrity: sha512-EnN2yLWCbWjooWBPzwlXdZoJG/Bqn3ymbuXX++DUJuBGjSmtixQeTf/hKeVzj4zbib3BbbYsNBasRVjq8Rk5ng==}
+ engines: {node: '>=18'}
+
'@sentry/node@8.55.0':
resolution: {integrity: sha512-h10LJLDTRAzYgay60Oy7moMookqqSZSviCWkkmHZyaDn+4WURnPp5SKhhfrzPRQcXKrweiOwDSHBgn1tweDssg==}
engines: {node: '>=14.18'}
@@ -3579,6 +3609,16 @@ packages:
engines: {node: '>=14.18'}
hasBin: true
+ '@sentry/vue@9.8.0':
+ resolution: {integrity: sha512-E+27lL+aU8HjDo3DD3TlgStTIxBZHVqz6jZcL0/tig/JldpFRetO77terRHNfSVlPc0m3aNXuARu7G438f7ZlQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ pinia: 2.x || 3.x
+ vue: 2.x || 3.x
+ peerDependenciesMeta:
+ pinia:
+ optional: true
+
'@shikijs/core@3.2.1':
resolution: {integrity: sha512-FhsdxMWYu/C11sFisEp7FMGBtX/OSSbnXZDMBhGuUDBNTdsoZlMSgQv5f90rwvzWAdWIW6VobD+G3IrazxA6dQ==}
@@ -13629,8 +13669,36 @@ snapshots:
'@sec-ant/readable-stream@0.4.1': {}
+ '@sentry-internal/browser-utils@9.8.0':
+ dependencies:
+ '@sentry/core': 9.8.0
+
+ '@sentry-internal/feedback@9.8.0':
+ dependencies:
+ '@sentry/core': 9.8.0
+
+ '@sentry-internal/replay-canvas@9.8.0':
+ dependencies:
+ '@sentry-internal/replay': 9.8.0
+ '@sentry/core': 9.8.0
+
+ '@sentry-internal/replay@9.8.0':
+ dependencies:
+ '@sentry-internal/browser-utils': 9.8.0
+ '@sentry/core': 9.8.0
+
+ '@sentry/browser@9.8.0':
+ dependencies:
+ '@sentry-internal/browser-utils': 9.8.0
+ '@sentry-internal/feedback': 9.8.0
+ '@sentry-internal/replay': 9.8.0
+ '@sentry-internal/replay-canvas': 9.8.0
+ '@sentry/core': 9.8.0
+
'@sentry/core@8.55.0': {}
+ '@sentry/core@9.8.0': {}
+
'@sentry/node@8.55.0':
dependencies:
'@opentelemetry/api': 1.9.0
@@ -13690,6 +13758,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@sentry/vue@9.8.0(vue@3.5.13(typescript@5.8.2))':
+ dependencies:
+ '@sentry/browser': 9.8.0
+ '@sentry/core': 9.8.0
+ vue: 3.5.13(typescript@5.8.2)
+
'@shikijs/core@3.2.1':
dependencies:
'@shikijs/types': 3.2.1