自动报告错误
您可以将 Cloud Functions 函数报告的错误提交到 Error Reporting,如下所示:
Node.js
如果您需要更精细的错误报告功能,可以使用 Error Reporting 客户端库。
您可以在 GCP 控制台的 Error Reporting 中查看报告的错误。您也可以在 GCP 控制台的函数列表中选择特定的函数,来查看该函数报告的错误。
您的函数产生的未捕获到的异常会显示在 Error Reporting 中。请注意,未捕获到的某些异常(例如异步抛出的异常)会导致在未来调用函数时执行冷启动,这会增加您的函数运行所需的时间。
手动报告错误
如需通过函数向 Error Reporting 报告错误,请使用 Cloud Logging API。
导入依赖项
从 functions
目录中,安装 Node.js 版 Cloud Logging 客户端库:
npm install --save @google-cloud/logging
导入并初始化 Cloud Logging 客户端库:
const Logging = require('@google-cloud/logging');
// Instantiates a client
const logging = Logging();
发送到 Cloud Logging
格式正确的日志条目需要一个 MonitoredResource
对象和一个 ErrorEvent
对象。
此示例 reportError
函数演示了向 Error Reporting 报告错误所需的最少数据。
function reportError(err, context = {}) { // This is the name of the log stream that will receive the log // entry. This name can be any valid log stream name, but must contain "err" // in order for the error to be picked up by Error Reporting. const logName = 'errors'; const log = logging.log(logName); // https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource const metadata = { resource: { type: 'cloud_function', labels: { function_name: process.env.FUNCTION_NAME }, }, }; // https://cloud.google.com/error-reporting/reference/rest/v1beta1/ErrorEvent const errorEvent = { message: err.stack, serviceContext: { service: process.env.FUNCTION_NAME, resourceType: 'cloud_function', }, context: context, }; // Write the error log entry return new Promise((resolve, reject) => { log.write(log.entry(metadata, errorEvent), (error) => { if (error) { return reject(error); } return resolve(); }); }); }
reportError
函数可用于手动报告错误:
exports.createStripePayment = functions.firestore .document('stripe_customers/{userId}/payments/{pushId}') .onCreate(async (snap, context) => { const { amount, currency, payment_method } = snap.data(); try { // Look up the Stripe customer id. const customer = (await snap.ref.parent.parent.get()).data().customer_id; // Create a charge using the pushId as the idempotency key // to protect against double charges. const idempotencyKey = context.params.pushId; const payment = await stripe.paymentIntents.create( { amount, currency, customer, payment_method, off_session: false, confirm: true, confirmation_method: 'manual', }, { idempotencyKey } ); // If the result is successful, write it back to the database. await snap.ref.set(payment); } catch (error) { // We want to capture errors and render them in a user-friendly way, while // still logging an exception to Error Reporting. functions.logger.log(error); await snap.ref.set({ error: userFacingMessage(error) }, { merge: true }); await reportError(error, { user: context.params.userId }); } });
您可以通过 ErrorContext
参数传递用户详细信息。Error Reporting 界面会显示这些详细信息,并会利用这些信息来计算受影响用户的数量。
您还可以向 ErrorContext
传递有关 HTTP 请求的信息:
export.httpError = functions.https.onRequest((request, response) => {
const error = new Error('Test error');
const httpRequest = {
method: request.method,
url: request.originalUrl,
userAgent: request.get('user-agent'),
referrer: '',
remoteIp: request.ip
};
reportError(error, {httpRequest}).then(() => {
response.end();
});
});