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


ورود به سیستم یک ابزار مهم برای اشکال زدایی و نظارت بر کد است. Cloud Functions به شما این امکان را می دهد که از Logger SDK برای Node.js یا Python یا استاندارد شی console برای توسعه وب استفاده کنید.

Cloud Logging یک سرویس قابل شارژ است. در صورت تجاوز از سهمیه بدون هزینه ممکن است صورتحساب دریافت کنید. برای اطلاعات بیشتر، قیمت گذاری Cloud Logging را ببینید.

نوشتن گزارش

با استفاده از Cloud Functions Logger SDK

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() دارای سطح log 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() می توانید ورودی های گزارش را با سطوح شدت گزارش اضافی CRITICAL ، ALERT و 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");

هنگامی که به ماژول سازگاری لاگر نیاز داشتید، می توانید از متدهای 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() دارای سطح log ERROR هستند.
  • دستورات console.error() دارای سطح log 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 در فایل dotenv خود روی false قرار دهید.

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

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

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

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

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

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

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

برای افزودن شناسه اجرا به فیلد خلاصه:

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

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

اکنون هر ورودی گزارش، executionId به‌طور برجسته در قسمت خلاصه نمایش می‌دهد، که شناسایی و گروه‌بندی گزارش‌های مرتبط با یک شناسه اجرایی خاص را آسان‌تر می‌کند.