記錄是偵錯和監控程式碼的重要工具。
Cloud Functions 可讓您選擇使用適用於 Node.js 或 Python 的記錄器 SDK,或是使用 console
物件標準開發網頁應用程式。
Cloud Logging 是付費服務,如果超出免付費配額,可能需要支付費用。詳情請參閱 Cloud Logging 定價。
寫入記錄
使用 Cloud Functions 記錄器 SDK
Cloud Functions 記錄器 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
建議您使用適用於平台的記錄器 SDK,從函式記錄。使用 Node.js 時,您可以改用標準 JavaScript 記錄呼叫 (例如 console.log
和 console.error
),但您必須先要求特殊模組,才能修補標準方法,確保這些方法正常運作:
require("firebase-functions/logger/compat");
要求記錄器相容性模組後,您可以在程式碼中照常使用 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 UI 或透過 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 UI
您可以在 Cloud Logging UI 中查看 Cloud Functions 的記錄。
分析記錄檔
Cloud Logging 提供功能強大的記錄分析工具套件,可用於監控 Cloud Functions。
圖表和快訊
建立記錄指標來監控函式後,您就能根據這些指標建立圖表和快訊。舉例來說,您可以建立圖表,將延遲時間以視覺化方式呈現,或是建立快訊,在特定錯誤發生過於頻繁時通知您。
如要進一步瞭解如何在圖表和快訊政策中使用記錄指標,請參閱「建立圖表和快訊」。
瞭解並使用執行 ID
根據預設,Cloud Run 函式 (第 2 代) 支援在單一函式執行個體中,同時執行多項要求。也就是說,不同要求的記錄可能會交錯,導致難以追蹤單一執行的流程。
為此,使用 Firebase CLI 13.33.0 以上版本部署的函式,會自動部署並提供選項,將執行 ID 與該執行作業處理期間發出的每個記錄檔項目建立關聯。
執行 ID 會為函式處理的單一要求,找出所有相關聯的記錄。您不必變更任何程式碼,系統會自動將執行 ID 新增至記錄。
如要在記錄項目中停用記錄執行 ID,請在 dotenv 檔案中將環境變數 LOG_EXECUTION_ID
設為 false。
依執行 ID 尋找並關聯記錄
您可以在 Cloud 記錄檔探索工具中,依執行 ID 檢查及關聯記錄。
展開函式的記錄項目。執行 ID 位於結構化記錄資料中,並以
labels.execution_id
形式內嵌於標籤下方。按一下
execution_id
的值,然後從下拉式選單中選取「顯示相符的項目」,即可查看與該函式執行作業相關的所有其他記錄。
即使函式同時處理多個要求,您也可以使用執行 ID,將與單一要求相關的所有記錄訊息歸為一組。
使用自訂摘要欄位提升記錄可見度
如要在記錄檔探索工具中更清楚地顯示執行 ID,可以將其新增為自訂摘要欄位。這會在每行記錄項目的開頭,以資訊方塊的形式顯示執行 ID,與第 1 代函式顯示所有記錄項目執行 ID 的方式類似。
如要在摘要欄位中新增執行 ID,請按照下列步驟操作:
在
labels.execution_id
下的結構化記錄項目中,按一下執行 ID 的值。從下拉式選單中選取「Add field to summary line」(在摘要行中新增欄位)。
現在每筆記錄項目都會在摘要欄位中醒目顯示 executionId
,方便您找出與特定執行 ID 相關聯的記錄並加以分組。