گزارش ها را بنویسید و مشاهده کنید

ثبت وقایع (Logging) ابزاری مهم برای اشکال‌زدایی و نظارت بر کد است. Cloud Functions به شما این امکان را می‌دهد که از SDK ثبت وقایع برای Node.js یا Python یا از استاندارد شیء console برای توسعه وب استفاده کنید.

ثبت وقایع ابری یک سرویس پولی است؛ اگر از سهمیه رایگان فراتر بروید، ممکن است از شما هزینه دریافت شود. برای اطلاعات بیشتر، به قیمت‌گذاری ثبت وقایع ابری مراجعه کنید.

نوشتن گزارش‌ها

استفاده از SDK ثبت‌کننده Cloud Functions

کیت توسعه نرم‌افزاری ثبت‌کننده Cloud Functions logger SDK) یک رابط استاندارد برای گزارش وضعیت از توابع به Cloud Logging ارائه می‌دهد. می‌توانید از این کیت توسعه نرم‌افزاری (SDK) برای ثبت رویدادها با داده‌های ساختاریافته استفاده کنید و تجزیه و تحلیل و نظارت آسان‌تر را امکان‌پذیر سازید.

از زیربسته‌ی logger وارد کنید:

نود جی اس

// All available logging functions
const {
  log,
  info,
  debug,
  warn,
  error,
  write,
} = require("firebase-functions/logger");

پایتون

from firebase_functions import logger
  • دستورات logger.log() سطح گزارش INFO را دارند.

  • دستورات logger.info() سطح گزارش INFO را دارند.

  • دستورات logger.warn() سطح گزارش WARNING را دارند.

  • دستورات logger.error() سطح گزارش ERROR را دارند.

  • دستورات logger.debug() سطح گزارش DEBUG را دارند.

  • پیام‌های سیستم داخلی دارای سطح گزارش DEBUG هستند.

این مثال تابعی را نشان می‌دهد که یک گزارش اولیه می‌نویسد:

نود جی اس

exports.helloWorld = onRequest((request, response) => {
  // sends a log to Cloud Logging
  log("Hello logs!");

  response.send("Hello from Firebase!");
});

پایتون

@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!")

برای انواع مختلف لاگ در کد تابع خود، از سطوح لاگ مختلف استفاده کنید. داده‌های ساختاریافته می‌توانند به عنوان آخرین آرگومان به یک لاگ پیوست شوند. در اینجا مثالی از نحوه استفاده یک تابع از هر نوع لاگ آورده شده است:

نود جی اس

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});
});

پایتون

@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() ، می‌توانید ورودی‌های لاگ را با سطوح شدت لاگ اضافی CRITICALALERT ) و EMERGENCY بنویسید. به بخش LogSeverity مراجعه کنید.

نود جی اس

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,
  });
});

پایتون

@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، می‌توانید از فراخوانی‌های استاندارد ثبت وقایع جاوا اسکریپت مانند 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 log) دارند.
  • دستورات console.warn() دارای سطح گزارش خطا (ERROR) هستند.
  • دستورات console.error() دارای سطح ثبت وقایع ERROR هستند.
  • پیام‌های سیستم داخلی دارای سطح گزارش DEBUG هستند.

مشاهده گزارش‌ها

گزارش‌های مربوط به Cloud Functions یا در کنسول Google Cloud ، رابط کاربری Cloud Logging یا از طریق ابزار خط فرمان firebase قابل مشاهده هستند.

استفاده از رابط خط فرمان فایربیس

برای مشاهده لاگ‌ها با ابزار 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 نسخه ۱۳.۳۳.۰ و بالاتر مستقر می‌شوند، به طور خودکار با گزینه‌ای برای مرتبط کردن یک شناسه اجرا با هر ورودی گزارش منتشر شده در طول مدیریت آن اجرا، مستقر می‌شوند.

شناسه اجرا به طور منحصر به فرد تمام گزارش‌های مرتبط با یک درخواست واحد که توسط تابع شما مدیریت می‌شود را شناسایی می‌کند. هیچ تغییر کدی لازم نیست؛ شناسه اجرا به طور خودکار به گزارش‌های شما اضافه می‌شود.

برای غیرفعال کردن شناسه اجرای ثبت وقایع در ورودی‌های گزارش خود، متغیر محیطی LOG_EXECUTION_ID در فایل dotenv خود روی false تنظیم کنید.

پیدا کردن و مرتبط کردن لاگ‌ها بر اساس شناسه اجرا

شما می‌توانید لاگ‌ها را بر اساس شناسه اجرا در Cloud Logs Explorer بررسی و مرتبط کنید.

  1. ورودی لاگ را از تابع خود باز کنید. شناسه اجرا در داده‌های لاگ ساختاریافته قرار دارد که زیر برچسب‌ها به صورت labels.execution_id قرار گرفته است.

  2. روی مقدار execution_id کلیک کنید و از منوی کشویی گزینه "نمایش ورودی‌های منطبق" را انتخاب کنید تا تمام گزارش‌های دیگر مرتبط با اجرای همان تابع را مشاهده کنید.

با استفاده از شناسه اجرا، می‌توانید تمام پیام‌های لاگ مربوط به یک درخواست واحد را گروه‌بندی کنید، حتی اگر تابع شما چندین درخواست را به طور همزمان مدیریت کند.

افزایش قابلیت مشاهده لاگ با فیلدهای خلاصه سفارشی

برای اینکه شناسه اجرا در Logs Explorer راحت‌تر قابل مشاهده باشد، می‌توانید آن را به عنوان [فیلد خلاصه سفارشی][cloud-logging-preference] اضافه کنید. پس از اضافه کردن شناسه اجرا به عنوان فیلد خلاصه، هر ورودی لاگ، شناسه اجرا را به صورت یک تراشه در ابتدای خط لاگ نشان می‌دهد. مشابه روشی که توابع نسل اول، شناسه اجرا را برای همه ورودی‌های لاگ نمایش می‌دادند.

برای اضافه کردن شناسه اجرا به فیلد خلاصه:

  1. روی مقدار شناسه اجرا در ورودی گزارش ساختاریافته زیر labels.execution_id کلیک کنید.

  2. از منوی کشویی، گزینه «افزودن فیلد به خط خلاصه» را انتخاب کنید.

هر ورودی لاگ اکنون executionId به طور برجسته در فیلد خلاصه نمایش می‌دهد و شناسایی و گروه‌بندی لاگ‌های مرتبط با یک execution ID خاص را آسان‌تر می‌کند.