Skip to main content

可观察性

自 2.31 起可用

¥Available since 2.31

有时,你可能需要观察应用的行为,以提高性能或找出棘手错误的根本原因。为了帮助实现此目的,SvelteKit 可以为以下对象发出服务器端 OpenTelemetry span:

¥Sometimes, you may need to observe how your application is behaving in order to improve performance or find the root cause of a pesky bug. To help with this, SvelteKit can emit server-side OpenTelemetry spans for the following:

  • handle 钩子和 handle 函数在 sequence 中运行(它们将显示为彼此的子函数以及根 handle 钩子的子函数)

    ¥The handle hook and handle functions running in a sequence (these will show up as children of each other and the root handle hook)

  • 服务器 load 函数和在服务器上运行时的通用 load 函数

    ¥Server load functions and universal load functions when they’re run on the server

  • 表单操作

    ¥Form actions

  • 远程函数

    ¥Remote functions

但是,仅仅告诉 SvelteKit 发出 span 并不能让你走得太远 - 你需要将它们实际收集到某个地方才能查看它们。SvelteKit 提供 src/instrumentation.server.ts 作为编写跟踪设置和检测代码的位置。它保证在导入应用代码之前运行,前提是你的部署平台支持它并且你的适配器能够识别它。

¥Just telling SvelteKit to emit spans won’t get you far, though — you need to actually collect them somewhere to be able to view them. SvelteKit provides src/instrumentation.server.ts as a place to write your tracing setup and instrumentation code. It’s guaranteed to be run prior to your application code being imported, providing your deployment platform supports it and your adapter is aware of it.

这两项功能目前都处于实验阶段,这意味着它们可能包含错误,并且可能会随时更改,恕不另行通知。你必须在 svelte.config.js 中添加 kit.experimental.tracing.serverkit.experimental.instrumentation.server 选项来选择加入:

¥Both of these features are currently experimental, meaning they are likely to contain bugs and are subject to change without notice. You must opt in by adding the kit.experimental.tracing.server and kit.experimental.instrumentation.server option in your svelte.config.js:

svelte.config
/** @type {import('@sveltejs/kit').Config} */
const 
const config: {
    kit: {
        experimental: {
 tracing: {
   server: boolean;
 };
 instrumentation: {
   server: boolean;
 };
        };
    };
}
@type{import('@sveltejs/kit').Config}
config
= {
kit: {
    experimental: {
        tracing: {
 server: boolean;
        };
        instrumentation: {
 server: boolean;
        };
    };
}
kit
: {
experimental: {
    tracing: {
        server: boolean;
    };
    instrumentation: {
        server: boolean;
    };
}
experimental
: {
tracing: {
    server: boolean;
}
tracing
: {
server: booleanserver: true },
instrumentation: {
    server: boolean;
}
instrumentation
: {
server: booleanserver: true } } } }; export default
const config: {
    kit: {
        experimental: {
 tracing: {
   server: boolean;
 };
 instrumentation: {
   server: boolean;
 };
        };
    };
}
@type{import('@sveltejs/kit').Config}
config
;

跟踪(更重要的是可观察性检测)可能会产生不小的开销。在全力投入跟踪之前,请考虑是否真的需要它,或者仅在开发和预览环境中启用它是否更合适。

增强内置跟踪(Augmenting the built-in tracing)

¥Augmenting the built-in tracing

SvelteKit 提供对请求事件中 root 跨度和 current 跨度的访问。根 span 与你的根 handle 函数关联,当前 span 可能与 handleload、表单操作或远程函数关联,具体取决于上下文。你可以使用任何你想要记录的属性注释这些 span:

¥SvelteKit provides access to the root span and the current span on the request event. The root span is the one associated with your root handle function, and the current span could be associated with handle, load, a form action, or a remote function, depending on the context. You can annotate these spans with any attributes you wish to record:

$lib/authenticate
import { function getRequestEvent(): RequestEvent

Returns the current RequestEvent. Can be used inside server hooks, server load functions, actions, and endpoints (and functions called by them).

In environments without AsyncLocalStorage, this must be called synchronously (i.e. not after an await).

@since2.20.0
getRequestEvent
} from '$app/server';
import {
function getAuthenticatedUser(): Promise<{
    id: string;
}>
getAuthenticatedUser
} from '$lib/auth-core';
async function function authenticate(): Promise<void>authenticate() { const
const user: {
    id: string;
}
user
= await
function getAuthenticatedUser(): Promise<{
    id: string;
}>
getAuthenticatedUser
();
const const event: RequestEvent<Record<string, string>, string | null>event = function getRequestEvent(): RequestEvent

Returns the current RequestEvent. Can be used inside server hooks, server load functions, actions, and endpoints (and functions called by them).

In environments without AsyncLocalStorage, this must be called synchronously (i.e. not after an await).

@since2.20.0
getRequestEvent
();
const event: RequestEvent<Record<string, string>, string | null>event.
RequestEvent<Record<string, string>, string | null>.tracing: {
    enabled: boolean;
    root: Span;
    current: Span;
}

Access to spans for tracing. If tracing is not enabled, these spans will do nothing.

@since2.31.0
tracing
.root: Span

The root span for the request. This span is named sveltekit.handle.root.

root
.setAttribute('userId',
const user: {
    id: string;
}
user
.id: stringid);
}

开发快速入门(Development quickstart)

¥Development quickstart

要查看你的第一个跟踪,你需要设置一个本地收集器。我们将在此示例中使用 Jaeger,因为它们提供了一个易于使用的快速启动命令。当你的收集器在本地运行时:

¥To view your first trace, you’ll need to set up a local collector. We’ll use Jaeger in this example, as they provide an easy-to-use quickstart command. Once your collector is running locally:

  • 在你的 svelte.config.js 文件中启用前面提到的实验性标志

    ¥Turn on the experimental flags mentioned earlier in your svelte.config.js file

  • 使用你的包管理器安装所需的依赖:

    ¥Use your package manager to install the dependencies you’ll need:

  npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-proto import-in-the-middle
  • 使用以下命令创建 src/instrumentation.server.js

    ¥Create src/instrumentation.server.js with the following:

src/instrumentation.server
import { import NodeSDKNodeSDK } from '@opentelemetry/sdk-node';
import { import getNodeAutoInstrumentationsgetNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { import OTLPTraceExporterOTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { import createAddHookMessageChannelcreateAddHookMessageChannel } from 'import-in-the-middle';
import { function register<Data = any>(specifier: string | URL, parentURL?: string | URL, options?: Module.RegisterOptions<Data>): void (+1 overload)

Register a module that exports hooks that customize Node.js module resolution and loading behavior. See Customization hooks.

@sincev20.6.0, v18.19.0
@paramspecifier Customization hooks to be registered; this should be the same string that would be passed to import(), except that if it is relative, it is resolved relative to parentURL.
@paramparentURL f you want to resolve specifier relative to a base URL, such as import.meta.url, you can pass that URL here.
register
} from 'node:module';
const { const registerOptions: anyregisterOptions } = import createAddHookMessageChannelcreateAddHookMessageChannel(); register<any>(specifier: string | URL, parentURL?: string | URL, options?: Module.RegisterOptions<any> | undefined): void (+1 overload)

Register a module that exports hooks that customize Node.js module resolution and loading behavior. See Customization hooks.

@sincev20.6.0, v18.19.0
@paramspecifier Customization hooks to be registered; this should be the same string that would be passed to import(), except that if it is relative, it is resolved relative to parentURL.
@paramparentURL f you want to resolve specifier relative to a base URL, such as import.meta.url, you can pass that URL here.
register
('import-in-the-middle/hook.mjs', import.meta.ImportMeta.url: string

The absolute file: URL of the module.

url
, const registerOptions: anyregisterOptions);
const const sdk: anysdk = new import NodeSDKNodeSDK({ serviceName: stringserviceName: 'test-sveltekit-tracing', traceExporter: anytraceExporter: new import OTLPTraceExporterOTLPTraceExporter(), instrumentations: any[]instrumentations: [import getNodeAutoInstrumentationsgetNodeAutoInstrumentations()] }); const sdk: anysdk.start();

现在,服务器端请求将开始生成跟踪,你可以在 Jaeger 的 Web 控制台中以 localhost:16686 为单位查看这些跟踪。

¥Now, server-side requests will begin generating traces, which you can view in Jaeger’s web console at localhost:16686.

@opentelemetry/api

SvelteKit 使用 @opentelemetry/api 生成其 span。这被声明为可选的对等依赖,以便不需要跟踪的用户不会看到对安装大小或运行时性能的影响。在大多数情况下,如果你将应用配置为收集 SvelteKit 的 span,你最终会安装像 @opentelemetry/sdk-node@vercel/otel 这样的库,而这些库又依赖于 @opentelemetry/api,而 @opentelemetry/api 也会满足 SvelteKit 的依赖。如果你看到 SvelteKit 报错,提示你找不到 @opentelemetry/api,则可能只是因为你尚未设置跟踪收集。如果你已完成此操作但仍然看到错误,你可以自行安装 @opentelemetry/api

¥SvelteKit uses @opentelemetry/api to generate its spans. This is declared as an optional peer dependency so that users not needing traces see no impact on install size or runtime performance. In most cases, if you’re configuring your application to collect SvelteKit’s spans, you’ll end up installing a library like @opentelemetry/sdk-node or @vercel/otel, which in turn depend on @opentelemetry/api, which will satisfy SvelteKit’s dependency as well. If you see an error from SvelteKit telling you it can’t find @opentelemetry/api, it may just be because you haven’t set up your trace collection yet. If you have done that and are still seeing the error, you can install @opentelemetry/api yourself.

上一页 下一页