@ aient/ otel (韩语)
为节点.js/Next.js/Edge提供开口遥测. 工作出了盒子, 高度可塑.
快速启动( 3行)
npm install @aient/otel @opentelemetry/api @opentelemetry/api-logs
// instrumentation.ts (Next.js 13.4+)
import { registerOTel } from '@aient/otel'
export function register() {
registerOTel({ serviceName: 'my-app' })
}
浏览器传播 app.installation.id, (中文(简体) ), enduser.id,以及 enduser.pseudo.id 是不信任的关联提示. @aient/otel 然后应用 attributesFromHeaders,所以一个网关/会话可信任 enduser.id 赢了 从不将一个自由的客户端设置头像映射为可信任的身份,也从不从行李中授权.
结束了。 追踪到 https://ingest.aient.ai/v1/traces 默认情况下,日志改为 /v1/logs。 。 。 .
地方发展
在本地主机上有一个收藏家的地方开发,请设置地道:
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
自定义端点( 程序)
要在代码中设置终点, 请使用 Env vars exporterUrl数字 :
registerOTel({
serviceName: 'my-app',
exporterUrl: 'https://my-collector.example.com', // SDK appends /v1/traces and /v1/logs
exporterHeaders: { 'x-api-key': 'your-key' }, // optional custom headers
})
完整示例( 所有选项)
import { registerOTel, OTLPHttpJsonTraceExporter, OTLPHttpJsonLogsExporter } from '@aient/otel'
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'
import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs'
export function register() {
registerOTel({
// Identity
serviceName: 'my-app',
attributes: {
'app.version': process.env.npm_package_version,
},
// Release metadata (CRITICAL for source mapping)
// Config takes precedence over env vars (COMMIT_SHA, COMMIT_REF, etc.)
release: {
commit: process.env.COMMIT_SHA,
branch: process.env.COMMIT_REF,
version: '1.0.0',
environment: 'production',
},
// Aient auth (or set AIENT_PUBLISHABLE_KEY env var)
publishableKey: process.env.AIENT_PUBLISHABLE_KEY,
// Extract request context
attributesFromHeaders: {
'enduser.id': 'x-user-id',
'tenant.id': 'x-tenant-id',
'client.ip': 'x-forwarded-for',
},
// Sampling (10% in production)
traceSampler: 'parentbased_traceidratio',
// Error handling
captureUnhandledErrors: true,
exitOnUnhandledException: true,
flushTimeoutMs: 2000,
// Custom endpoint (alternative to OTEL_EXPORTER_OTLP_ENDPOINT env var)
exporterUrl: 'https://collector.example.com',
exporterHeaders: { 'x-api-key': 'your-key' },
// Debug logging (alternative to OTEL_LOG_LEVEL env var)
logLevel: 'DEBUG', // 'ALL' | 'VERBOSE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'NONE'
// Multi-backend fan-out (advanced - overrides exporterUrl)
// spanProcessors: [
// new BatchSpanProcessor(new OTLPHttpJsonTraceExporter({
// url: 'https://collector-a.example.com/v1/traces',
// })),
// new BatchSpanProcessor(new OTLPHttpJsonTraceExporter({
// url: 'https://collector-b.example.com/v1/traces',
// })),
// ],
})
}
# Set sampling ratio
OTEL_TRACES_SAMPLER_ARG=0.1
环境变量
通过env而不是代码配置 :
# Endpoints
OTEL_EXPORTER_OTLP_ENDPOINT=https://collector.example.com # Base URL
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://traces.example.com/v1/traces
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://logs.example.com/v1/logs
# Protocol
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/json
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/json
# Legacy http/protobuf values are accepted for compatibility but fall back to JSON.
# Headers
OTEL_EXPORTER_OTLP_HEADERS=x-api-key=secret,env=prod
# Sampling
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1
# Service
OTEL_SERVICE_NAME=my-service
OTEL_SDK_DISABLED=true # Kill switch
# Aient auth
AIENT_PUBLISHABLE_KEY=pk_xxx
OTLP JSON协议合同
SDK出口了作为OTLP/HTTP JSON protobuf有效载荷的痕迹和日志 Content-Type: application/json。 。 。 .
序列器遵循了OpenTeleometry协议使用的OTLP JSON映射:
- 请求信封是
ExportTraceServiceRequest财务报告和审定财务报表ExportLogsServiceRequestJSON 对象(resourceSpans财务报告和审定财务报表resourceLogs(三); - JSON 字段名称为下加梅尔Case, 例如
startTimeUnixNano财务报告和审定财务报表droppedAttributesCount· ; - 追踪ID和横跨ID是六分弦,而不是基数64;
- 64位时标和整数属性值为十进制字符串;
- a. 圆形字段,如跨度、跨度状态和日志重度被编码为数字;
- 任意字节属性为 base64 字符串;
- 跨度和日志按资源和仪器范围分组,包括存在时的图案URL.
@aient/otel 不捆绑 protobufjs, (中文(简体) ), @opentelemetry/otlp-transformer, (中文(简体) ), @opentelemetry/otlp-exporter-base,或 @opentelemetry/exporter-trace-otlp-http。协议敏感序列器行为由 test/otlp-json-serializer.test.ts,而依赖性回归则包含在 test/package-contract.test.ts。 。 。 .
构建元数据( 用于源头映射)
设定输入信息, 用于将错误映射到代码 。 使用任意一个 release 配置选项或环境变量 :
Via 配置( 建议 ):
registerOTel({
serviceName: 'my-app',
release: {
commit: process.env.COMMIT_SHA,
branch: process.env.COMMIT_REF,
version: '1.0.0',
environment: 'production',
}
})
通过环境变量:
COMMIT_SHA=$(git rev-parse HEAD)
COMMIT_REF=$(git rev-parse --abbrev-ref HEAD)
BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
也读作: VERCEL_GIT_COMMIT_SHA, (中文(简体) ), NEXT_PUBLIC_COMMIT_SHA等 (中文(简体) ).
手动 Spans 日志( L)
import { trace } from '@opentelemetry/api'
import { logs, SeverityNumber } from '@opentelemetry/api-logs'
// Spans
const tracer = trace.getTracer('my-component')
const span = tracer.startSpan('operation')
span.setAttribute('key', 'value')
span.end()
// Logs
const logger = logs.getLogger('my-component')
logger.emit({
severityNumber: SeverityNumber.INFO,
body: 'User signed up',
attributes: { plan: 'pro' },
})
记录当前期间的外部服务故障
在与第三方系统(GitHub、Slack、Frede、Linear、电子邮件提供者等)合并时, 倾向于将失败的原因附加在 当前活动跨度 因此,痕迹是不言自明的.
import { recordExternalFailure, recordExternalFailureReason } from '@aient/otel'
// When you have an Error/exception:
try {
await doExternalCall()
} catch (e) {
recordExternalFailure({
system: 'github',
operation: 'listInstallationRepos',
error: e,
attributes: {
'aient.external.http.status_code': 404,
'aient.external.installation_id': 123,
},
})
throw e
}
// When you only have a protocol-level error string (no exception thrown):
recordExternalFailureReason({
system: 'slack',
operation: 'chat.postMessage',
reason: 'not_in_channel',
attributes: { 'aient.external.slack.channel': 'C123...' },
})
注释:
- 两个助手将跨度设置为 错误,随附
aient.external.*属性,并释放exception活动. aient.external.organisation_id是诊断客户的背景。 经认证的来源租户和环境 仍为收藏家拥有的资源属性(aient.organisation.id财务报告和审定财务报表aient.environment.*) (中文(简体) ).- 历史遥测保留了原来的属性密钥;原始属性检查仍然可用.
recordExternalFailureReason没有 合成一个 Error/ sacktrace( 以避免误导堆栈) .
默认
| 特性 | 默认 |
|---|---|
| 追踪出口国 | http/json → https://ingest.aient.ai/v1/traces |
| 日志出口商 | http/json → https://ingest.aient.ai/v1/logs |
| 样本 | always_on |
| 宣传者 | W3C 追踪上下文 + 行李 |
| 仪器 | fetch节点 http/https |
| 抓取错误 | uncaughtException, (中文(简体) ), unhandledRejection +对数+冲出 |
| 请求遥测 | 稳定 HTTP 属性, 编辑查询, 每个输入请求一个访问日志 |
请求遥测
每个入境请求的最外端服务器跨度都包含 OpenTelemetry 的稳定 HTTP
服务器属性, 也可以当框架只释放出遗留名称( 下一步. js) 时 :
http.request.method, (中文(简体) ), url.path, (中文(简体) ), url.query, (中文(简体) ), url.scheme, (中文(简体) ), http.route, (中文(简体) ),
http.response.status_code, (中文(简体) ), server.address, (中文(简体) ), server.port, (中文(简体) ), client.address, (中文(简体) ),
user_agent.original, (中文(简体) ), http.request.header.referer, (中文(简体) ), network.protocol.version, (中文(简体) ),
http.response.body.size 财务报告和审定财务报表 error.type。请求标题属性来自
平台请求上下文(Vercel)或来自HTTP服务器仪器.
每个请求都产生一个日志记录(范围) @aient/otel/http与这些
属性, http.server.request.duration 以秒计,且跨度的跟踪和跨度
身份证 讯息是 <method> <route or path> <status>. 严重性:5xx的错误,
4xx的WARN,否则INFO。 这个 http.server.request.duration 直方图
配置时录入 metricReaders。出站取回时间段得到马厩
客户端属性,但没有访问日志 .
证书密钥的查询值变为 REDACTED 内 url.query, (中文(简体) ), url.full, (中文(简体) ),
http.target, (中文(简体) ), http.url属性(http.referer 财务报告和审定财务报表
http.request.header.referer; 键和其他值不变。 同一个裁判
政策适用于应用程序日志请求上下文。 默认值: OpenTeleometry 的
签名密钥加 access_token, (中文(简体) ), refresh_token, (中文(简体) ), id_token, (中文(简体) ), client_secret, (中文(简体) ),
api_key, (中文(简体) ), apikey, (中文(简体) ), password 财务报告和审定财务报表 token。 。 。 .
registerOTel({
httpRequestTelemetry: {
sensitiveQueryParameters: ["sig", "token", "session"], // replaces the defaults
knownMethods: ["GET", "POST", "PURGE"], // or OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS
accessLogs: true, // default
},
})
接下来,Vercel上的J 不需要更多了 对于其他节点服务器(自托管的 Next.js,
快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快快 http),注册标准 HTTP 服务器
仪器所以存在客户端地址,用户代理,引用和响应大小:
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
registerOTel({
instrumentations: ["auto", new HttpInstrumentation({
headersToSpanAttributes: { server: { requestHeaders: ["referer"], responseHeaders: ["content-length"] } },
})],
});
许可证
麻省理工学院