日志是用于调试和监控代码的重要工具。Cloud Functions 让您可以选择使用适用于 Node.js 或 Python 的 logger SDK,或是面向 Web 开发的 console
对象标准。
Cloud Logging 是一项收费服务,超出免费配额后,您可能需要付费。如需了解详情,请参阅 Cloud Logging 价格。
写入日志
使用 Cloud Functions logger SDK
Cloud Functions logger SDK 提供了一个标准接口,用于将函数状态报告给 Cloud Logging。您可以使用此 SDK 记录包含结构化数据的事件,更轻松地进行分析和监控。
从 logger
子软件包导入:
Node.js
// All available logging functions
const {
log,
info,
debug,
warn,
error,
write,
} = require("firebase-functions/logger");
Python
from firebase_functions import logger
logger.log()
命令具有 INFO 日志级别。logger.info()
命令具有 INFO 日志级别。logger.warn()
命令具有 WARNING 日志级别。logger.error()
命令具有 ERROR 日志级别。logger.debug()
命令具有 DEBUG 日志级别。内部系统消息具有 DEBUG 日志级别。
下面的示例展示了一个用来编写基本日志的函数:
Node.js
exports.helloWorld = onRequest((request, response) => {
// sends a log to Cloud Logging
log("Hello logs!");
response.send("Hello from Firebase!");
});
Python
@https_fn.on_request()
def hello_world(req: https_fn.Request) -> https_fn.Response:
# sends a log to Cloud Logging
logger.log("Hello logs!")
return https_fn.Response("Hello from Firebase!")
您可以在函数代码中针对不同类型的日志使用不同的日志级别。结构化数据可以作为最后一个参数附加到日志。下面的示例展示了函数如何使用每种日志类型:
Node.js
exports.getInspirationalQuote = onRequest(async (request, response) => {
const db = getFirestore();
const today = new Date();
const quoteOfTheMonthRef = db
.collection("quotes")
.doc(`${today.getFullYear()}`)
.collection("months")
.doc(`${today.getMonth()}`);
const DEFAULT_QUOTE =
"You miss 100% of the shots you don't take. -Wayne Gretzky";
let quote;
try {
const quoteOfTheMonthDocSnap = await quoteOfTheMonthRef.get();
// Attach relevant debugging information with debug()
debug("Monthly quote fetch result", {
docRef: quoteOfTheMonthRef.path,
exists: quoteOfTheMonthDocSnap.exists,
createTime: quoteOfTheMonthDocSnap.createTime,
});
if (quoteOfTheMonthDocSnap.exists) {
quote = quoteOfTheMonthDocSnap.data().text;
} else {
// Use warn() for lower-severity issues than error()
warn("Quote not found for month, sending default instead", {
docRef: quoteOfTheMonthRef.path,
dateRequested: today.toLocaleDateString("en-US"),
});
quote = DEFAULT_QUOTE;
}
} catch (err) {
// Attach an error object as the second argument
error("Unable to read quote from Firestore, sending default instead",
err);
quote = DEFAULT_QUOTE;
}
// Attach relevant structured data to any log
info("Sending a quote!", {quote: quote});
response.json({inspirationalQuote: quote});
});
Python
@https_fn.on_request()
def get_inspirational_quote(req: https_fn.Request) -> https_fn.Response:
firestore_client = firestore.client()
today = datetime.date.today()
quote_of_the_month_ref = (firestore_client.collection("quotes").doc(str(
today.year)).collection("months").doc(str(today.month)))
default_quote = "Python has been an important part of Google since the beginning, and remains so as the system grows and evolves."
quote = None
try:
quote_of_the_month = quote_of_the_month_ref.get()
# Attach relevant debugging information with debug()
logger.debug(
"Monthly quote fetch result",
docRef=quote_of_the_month.path,
exists=quote_of_the_month.exists,
createTime=quote_of_the_month.createTime,
)
if quote_of_the_month.exists:
quote = quote_of_the_month.to_dict()["text"]
else:
# Use warn() for lower-severity issues than error()
logger.warn(
"Quote not found for month, sending default instead",
doc_reference=quote_of_the_month.path,
date_requested=today.strftime("%Y-%m-%d"),
)
quote = default_quote
except:
e = sys.exc_info()[0]
# Attach an error object as the second argument
logger.error("Unable to read quote from Firestore, sending default instead", error=e)
quote = default_quote
# Attach relevant structured data to any log
logger.info("Sending a quote!", quote=quote)
return https_fn.Response("Hello from Firebase!")
借助 logger.write()
,您可以在写入日志条目时使用其他的日志严重级别,包括 CRITICAL
、ALERT
和 EMERGENCY
。请参阅 LogSeverity。
Node.js
exports.appHasARegression = onRegressionAlertPublished((event) => {
write({
// write() lets you set additional severity levels
// beyond the built-in logger functions
severity: "EMERGENCY",
message: "Regression in production app",
issue: event.data.payload.issue,
lastOccurred: event.data.payload.resolveTime,
});
});
Python
@crashlytics_fn.on_regression_alert_published()
def app_has_regression(alert: crashlytics_fn.CrashlyticsRegressionAlertEvent) -> None:
logger.write(
severity="EMERGENCY",
message="Regression in production app",
issue=alert.data.payload.issue,
last_occurred=alert.data.payload.resolve_time,
)
print(alert)
使用 console.log
使用适用于您平台的 logger SDK 是通过函数进行日志记录的建议解决方案。使用 Node.js 时,您可以改用标准 JavaScript 日志记录调用(如 console.log
和 console.error
),但您首先需要使用一个特殊模块来修补标准方法,以使其正常运作:
require("firebase-functions/logger/compat");
纳入所需的 Logger 兼容性模块后,您可以像往常一样在代码中使用 console.log()
方法:
exports.helloError = functions.https.onRequest((request, response) => {
console.log('I am a log entry!');
response.send('Hello World...');
});
console.log()
命令具有 INFO 日志级别。console.info()
命令具有 INFO 日志级别。console.warn()
命令具有 ERROR 日志级别。console.error()
命令具有 ERROR 日志级别。- 内部系统消息具有 DEBUG 日志级别。
查看日志
您可以在 Google Cloud 控制台、Cloud Logging 界面或通过 firebase
命令行工具查看 Cloud Functions 的日志。
使用 Firebase CLI
如需使用 firebase
工具查看日志,请使用 functions:log
命令:
firebase functions:log
如需查看特定函数的日志,请以参数形式提供函数名称:
firebase functions:log --only <FUNCTION_NAME>
如需了解全部日志查看选项,请参阅 functions:log
的帮助信息:
firebase help functions:log
使用 Google Cloud 控制台
您可以在 Google Cloud 控制台中查看函数的日志。
使用 Cloud Logging 界面
您可以在 Cloud Logging 界面中查看 Cloud Functions 的日志。
分析日志
Cloud Logging 提供了一套功能强大的日志分析工具,您可以使用这些工具监控 Cloud Functions。
图表和提醒
创建基于日志的指标以监控您的函数后,您可以根据这些指标创建图表和提醒。例如,您可以创建一个图表来直观呈现指定时间段内的延迟,或创建一个提醒来让您知道某个错误是否出现得过于频繁。
如需详细了解如何在图表和提醒政策中使用基于日志的指标,请参阅创建图表和提醒。