无服务器
本指南介绍了如何使用 OpenTelemetry 仪器化库开始跟踪无服务器函数。
AWS Lambda
您还可以通过使用 社区提供的 Lambda 层 来自动仪器化您的 AWS Lambda 函数。
以下内容展示了如何使用 OpenTelemetry 的 Lambda 包装器手动仪器化 AWS Lambda 函数并将跟踪发送到配置的后端。
如果您对即插即用体验感兴趣,请参阅 OpenTelemetry Lambda Layers。
依赖项
首先,创建一个空的 package.json
npm init -y
然后安装所需的依赖项
npm install \
@opentelemetry/api \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-http \
@opentelemetry/instrumentation \
@opentelemetry/sdk-trace-base \
@opentelemetry/sdk-trace-node
AWS Lambda 包装器代码
此文件包含所有启用跟踪的 OpenTelemetry 逻辑。将以下代码保存为 lambda-wrapper.js。
/* lambda-wrapper.js */
const api = require('@opentelemetry/api');
const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const {
OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-http');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.ALL);
const spanProcessor = new BatchSpanProcessor(
new OTLPTraceExporter({
url: '<backend_url>',
}),
);
const provider = new NodeTracerProvider({
spanProcessors: [spanProcessor],
});
provider.register();
registerInstrumentations({
instrumentations: [
getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-aws-lambda': {
disableAwsContextPropagation: true,
},
}),
],
});
将 <backend_url> 替换为您喜欢的后端 URL,以便将所有跟踪导出到该后端。如果您还没有设置好,可以查看 Jaeger 或 Zipkin。
请注意,disableAwsContextPropagation 设置为 true。原因是 Lambda 仪器化默认会尝试使用 X-Ray 上下文头,除非为此函数启用了主动跟踪,否则会导致一个非采样的上下文,从而创建一个 NonRecordingSpan。
更多详细信息请参阅仪器化 文档。
AWS Lambda 函数处理程序
现在您已经有了 Lambda 包装器,请创建一个简单的处理程序作为 Lambda 函数。将以下代码保存为 handler.js。
/* handler.js */
'use strict';
const https = require('https');
function getRequest() {
const url = 'https://opentelemetry.org.cn/';
return new Promise((resolve, reject) => {
const req = https.get(url, (res) => {
resolve(res.statusCode);
});
req.on('error', (err) => {
reject(new Error(err));
});
});
}
exports.handler = async (event) => {
try {
const result = await getRequest();
return {
statusCode: result,
};
} catch (error) {
return {
statusCode: 400,
body: error.message,
};
}
};
Deployment
部署 Lambda 函数有多种方法
这里我们将使用 Serverless Framework,更多详细信息可以在 设置 Serverless Framework 指南 中找到。
创建一个名为 serverless.yml 的文件
service: lambda-otel-native
frameworkVersion: '3'
provider:
name: aws
runtime: nodejs14.x
region: '<your-region>'
environment:
NODE_OPTIONS: --require lambda-wrapper
functions:
lambda-otel-test:
handler: handler.hello
为了让 OpenTelemetry 正常工作,lambda-wrapper.js 必须在任何其他文件之前包含:NODE_OPTIONS 设置确保了这一点。
请注意,如果您不使用 Serverless Framework 部署 Lambda 函数,则必须使用 AWS 控制台 UI 手动添加此环境变量。
最后,运行以下命令将项目部署到 AWS
serverless deploy
您现在可以通过 AWS 控制台 UI 调用新部署的 Lambda 函数。您应该会看到与 Lambda 函数调用相关的跨度。
访问后端
您现在应该能够在后端查看 OpenTelemetry 从 Lambda 函数生成的跟踪了!
GCP 函数
以下内容展示了如何使用 Google Cloud Platform (GCP) UI 仪器化 HTTP 触发的函数。
创建函数
登录 GCP 并创建或选择应放置函数的项目。在侧边菜单中,转到 *无服务器* 并选择 *Cloud Functions*。接下来,点击 *创建函数*,为您的环境选择 第二代,提供函数名称并选择您的区域。
为 otelwrapper 设置环境变量
如果已关闭,请打开 *运行时、构建、连接和安全设置* 菜单,向下滚动并添加环境变量 NODE_OPTIONS,其值为
--require ./otelwrapper.js
选择运行时
在下一个屏幕(*代码*)上,为您的运行时选择 Node.js 版本 16。
创建 OTel 包装器
创建一个名为 otelwrapper.js 的新文件,该文件将用于仪器化您的服务。请确保您提供了 SERVICE_NAME 并设置了 <address for your backend>。
/* otelwrapper.js */
const { resourceFromAttributes } = require('@opentelemetry/resources');
const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');
const api = require('@opentelemetry/api');
const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const {
OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-http');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.ALL);
const collectorOptions = {
url: '<address for your backend>',
};
const provider = new NodeTracerProvider({
resource: resourceFromAttributes({
[ATTR_SERVICE_NAME]: '<your function name>',
}),
spanProcessors: [
new BatchSpanProcessor(new OTLPTraceExporter(collectorOptions)),
],
});
provider.register();
registerInstrumentations({
instrumentations: [getNodeAutoInstrumentations()],
});
添加包依赖项
将以下内容添加到您的 package.json
{
"dependencies": {
"@google-cloud/functions-framework": "^3.0.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/auto-instrumentations-node": "^0.56.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.200.0",
"@opentelemetry/instrumentation": "^0.200.0",
"@opentelemetry/sdk-trace-base": "^2.0.0",
"@opentelemetry/sdk-trace-node": "^2.0.0",
"@opentelemetry/resources": "^2.0.0",
"@opentelemetry/semantic-conventions": "^2.0.0"
}
}
向函数添加 HTTP 调用
以下代码调用 OpenTelemetry 网站以演示出站调用。
/* index.js */
const functions = require('@google-cloud/functions-framework');
const https = require('https');
functions.http('helloHttp', (req, res) => {
let url = 'https://opentelemetry.org.cn/';
https
.get(url, (response) => {
res.send(`Response ${response.body}!`);
})
.on('error', (e) => {
res.send(`Error ${e}!`);
});
});
后端
如果您在 GCP VM 中运行 OTel collector,您可能需要 创建 VPC 访问连接器 才能发送跟踪。
部署
在 UI 中选择部署并等待部署完成。
测试
您可以使用云 shell 的测试选项卡来测试函数。