无服务
本指南展示了如何开始使用 OpenTelemetry 工具库跟踪无服务器函数。
AWS Lambda
The following show how to use Lambda wrappers with OpenTelemetry to instrument
AWS Lambda functions and send traces to a configured backend.
If you are interested in a plug and play user experience, see
OpenTelemetry Lambda Layers.
依赖
First, create an empty package.json:
Then install the required dependencies:
| 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 包装器代码
This file contains all the OpenTelemetry logic, which enables tracing. Save the
following code as 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 provider = new NodeTracerProvider();
const collectorOptions = {
url: '<backend_url>',
};
const spanProcessor = new BatchSpanProcessor(
new OTLPTraceExporter(collectorOptions)
);
provider.addSpanProcessor(spanProcessor);
provider.register();
registerInstrumentations({
instrumentations: [
getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-aws-lambda': {
disableAwsContextPropagation: true,
},
}),
],
});
|
Replace <backend_url>
with the URL of your favorite backend to export all
traces to it. If you don't have one setup already, you can check out
Jaeger or Zipkin.
Note that disableAwsContextPropagation
is set to true. The reason for this is
that the Lambda instrumentation tries to use the X-Ray context headers by
default, unless active tracing is enabled for this function, this results in a
non-sampled context, which creates a NonRecordingSpan
.
More details can be found in the instrumentation
documentation.
AWS Lambda 函数处理程序
Now that you have a Lambda wrapper, create a simple handler that serves as a
Lambda function. Save the following code as handler.js
.
| /* handler.js */
'use strict';
const https = require('https');
function getRequest() {
const url = 'https://opentelemetry.io/';
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,
};
}
};
|
开发
有多种部署 Lambda 函数的方法:
这里我们将使用无服务器框架,更多细节可以
在设置无服务器框架指南中
找到。
Create a file called 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
|
For OpenTelemetry to work properly, lambda-wrapper.js
must be included before
any other file: the NODE_OPTIONS
setting ensures this.
Note if you are not using Serverless Framework to deploy your Lambda function,
you must manually add this environment variable using the AWS Console UI.
Finally, run the following command to deploy the project to AWS:
You can now invoke the newly deployed Lambda function by using the AWS Console
UI. You should expect to see spans related to the invocation of the Lambda
function.
访问后端
You should now be able to view traces produced by OpenTelemetry from your Lambda
function in the backend!
GCP 函数
The following shows how to instrument
HTTP triggered function
using the Google Cloud Platform (GCP) UI.
创建函数
Login to GCP and create or select a project where your function should be
placed. In the side menu go to Serverless and select Cloud Functions. Next,
click on Create Function, and select
2nd generation
for your environment, provide a function name and select your region.
为 otelwrapper 设置环境变量
If closed, open the Runtime, build, connections and security settings menu and
scroll down and add the environment variable NODE_OPTIONS
with the following
value:
| --require ./otelwrapper.js
|
选择运行时
在下一个屏幕 (Code) 中,为运行时选择 Node.js 版本 16。
建立 OTel 包装
Create a new file called otelwrapper.js
, that will be used to instrument your
service. Please make sure that you provide a SERVICE_NAME
and that you set the
<address for your backend>
.
| /* otelwrapper.js */
const { Resource } = require('@opentelemetry/resources');
const {
SemanticResourceAttributes,
} = 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');
const providerConfig = {
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: '<your function name>',
}),
};
api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.ALL);
const provider = new NodeTracerProvider(providerConfig);
const collectorOptions = {
url: '<address for your backend>',
};
const spanProcessor = new BatchSpanProcessor(
new OTLPTraceExporter(collectorOptions)
);
provider.addSpanProcessor(spanProcessor);
provider.register();
registerInstrumentations({
instrumentations: [getNodeAutoInstrumentations()],
});
|
建立 package.json
Add the following content to your package.json:
| {
"dependencies": {
"@google-cloud/functions-framework": "^3.0.0",
"@opentelemetry/api": "^1.3.0",
"@opentelemetry/auto-instrumentations-node": "^0.35.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.34.0",
"@opentelemetry/instrumentation": "^0.34.0",
"@opentelemetry/sdk-node": "^0.34.0",
"@opentelemetry/sdk-trace-base": "^1.8.0",
"@opentelemetry/sdk-trace-node": "^1.8.0",
"@opentelemetry/resources": "^1.8.0",
"@opentelemetry/semantic-conventions": "^1.8.0"
}
}
|
向函数添加 HTTP 调用
The following code makes a call to the OpenTelemetry web site to demonstrate an
outbound call.
| /* index.js */
const functions = require('@google-cloud/functions-framework');
const https = require('https');
functions.http('helloHttp', (req, res) => {
let url = 'https://opentelemetry.io/';
https
.get(url, (response) => {
res.send(`Response ${response.body}!`);
})
.on('error', (e) => {
res.send(`Error ${e}!`);
});
});
|
后端
If you run OTel collector in GCP VM you are likely to need to
create VPC access connector
to be able to send traces.
部署
Select Deploy in UI and await deployment to be ready.
测试
You can test the function using cloud shell from test tab.