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

گزارش‌گیری ابزار مهمی برای اشکال‌زدایی و نظارت بر کد است. ‫Cloud Functions به شما امکان می‌دهد از کیت توسعه نرم‌افزار گزارشگر برای Node.js یا Python، یا استاندارد شیء console برای توسعه دادن برای وب استفاده کنید.

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

درحال نوشتن گزارش‌ها

استفاده از کیت توسعه نرم‌افزار گزارشگر Cloud Functions

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

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

Node.js

// 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() فرمان سطح گزارش هشدار دارد.

  • ‫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!");
});

پایتون

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

پایتون

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

پایتون

@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

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

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

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

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

می‌توانید گزارش‌ها را براساس شناسه اجرا در «کاوشگر گزارش‌های ابری» بررسی و همبستگی کنید.

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

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

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

با فیلدهای خلاصه سفارشی، رؤیت‌پذیری گزارش را بهبود دهید

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

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

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

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

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