רישום ביומן הוא כלי חשוב לניפוי באגים ולמעקב אחרי קוד.
ב-Cloud Functions אתם יכולים להשתמש ב-SDK של ה-logger ל-Node.js או ל-Python, או באובייקט הסטנדרטי של console לפיתוח לאינטרנט.
Cloud Logging הוא שירות בתשלום, ואתם עשויים להיות מחויבים אם תחרגו מהמכסה ללא עלות. למידע נוסף, ראו התמחור של Cloud Logging.
כתיבת יומנים
שימוש ב-SDK של Cloud Functions לרישום ביומן
ערכת ה-SDK של Cloud Functions logger מספקת ממשק סטנדרטי לדיווח על סטטוס מפונקציות ל-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.הודעות מערכת פנימיות הן ברמת היומן ניפוי באגים.
בדוגמה הזו מוצגת פונקציה שכותבת יומן בסיסי:
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");
אחרי שדורשים את מודול התאימות של ה-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.
צפייה ביומנים
אפשר לראות את היומנים של Cloud Functions במסוף Google Cloud, בממשק המשתמש של Cloud Logging או באמצעות כלי שורת הפקודה של firebase.
באמצעות 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 Functions בממשק המשתמש של Cloud Logging.
ניתוח היומנים
ב-Cloud Logging יש חבילה של כלים מתקדמים לניתוח יומנים, שבעזרתם אפשר לעקוב אחרי Cloud Functions.
תרשימים והתראות
אחרי שיוצרים מדדים מבוססי-יומנים כדי לעקוב אחרי הפונקציות, אפשר ליצור תרשימים והתראות על סמך המדדים האלה. לדוגמה, אפשר ליצור תרשים כדי להציג את זמן האחזור לאורך זמן, או ליצור התראה כדי להודיע אם שגיאה מסוימת מתרחשת לעיתים קרובות מדי.
במאמר יצירת תרשימים ומדיניות התראות מוסבר איך להשתמש במדדים מבוססי-יומנים בתרשימים ובמדיניות התראות.
הסבר על מזהי הרצה ואיך להשתמש בהם
כברירת מחדל, פונקציות Cloud Run (דור שני) תומכות בהפעלה בו-זמנית של כמה בקשות במופע פונקציה יחיד. כלומר, יכול להיות שיומנים מבקשות שונות ישולבו, ויהיה קשה יותר לעקוב אחרי תהליך הביצוע של בקשה אחת.
כדי לעזור לכם, פונקציות שנפרסות באמצעות Firebase CLI בגרסה 13.33.0 ואילך נפרסות באופן אוטומטי עם אפשרות לשייך מזהה הפעלה לכל רשומת יומן שנוצרת במהלך הטיפול בהפעלה הזו.
מזהה הביצוע מזהה באופן ייחודי את כל היומנים שמשויכים לבקשה אחת שמטופלת על ידי הפונקציה. לא צריך לשנות את הקוד. מזהה ההפעלה יתווסף באופן אוטומטי ליומנים.
כדי להשבית את רישום מזהה ההפעלה ברשומות ביומן, מגדירים את משתנה הסביבה LOG_EXECUTION_ID כ-false בקובץ dotenv.
חיפוש יומנים וקישור ביניהם לפי מזהה הביצוע
אתם יכולים לבדוק את היומנים ולבצע קורלציה ביניהם לפי מזהה ההפעלה ב-Cloud Logs Explorer.
מרחיבים את הרשומה ביומן מהפונקציה. מזהה ההפעלה נמצא בנתוני היומן המובנים, בתוך התוויות בתור
labels.execution_id.לוחצים על הערך של
execution_idובוחרים באפשרות Show matching entries בתפריט הנפתח כדי לראות את כל היומנים האחרים שמשויכים לאותה הפעלה של הפונקציה.
באמצעות מזהה הביצוע, אתם יכולים לקבץ יחד את כל הודעות היומן שקשורות לבקשה אחת, גם אם הפונקציה מטפלת בכמה בקשות בו-זמנית.
שיפור הניראות של היומנים באמצעות שדות סיכום בהתאמה אישית
כדי שמזהה ההפעלה יופיע בצורה ברורה יותר ב-Logs Explorer, אפשר להוסיף אותו בתור [שדה סיכום בהתאמה אישית][cloud-logging-preference]. אחרי שמוסיפים את מזהה ההפעלה כשדה סיכום, כל רשומה ביומן תציג את מזהה ההפעלה כצ'יפ בתחילת שורת היומן, בדומה לאופן שבו פונקציות מהדור הראשון הציגו את מזהה ההפעלה לכל הרשומות ביומן.
כדי להוסיף את מזהה ההרצה לשדה הסיכום:
לוחצים על הערך של מזהה ההפעלה ברשומה המובנית ביומן, בקטע
labels.execution_id.בתפריט הנפתח, בוחרים באפשרות "הוספת שדה לשורת הסיכום".
עכשיו כל רשומה ביומן מציגה את executionId באופן בולט בשדה הסיכום, כדי שיהיה קל יותר לזהות ולקבץ יומנים שמשויכים למזהה ביצוע ספציפי.