Ghi và xem nhật ký


Ghi nhật ký là một công cụ quan trọng để gỡ lỗi và giám sát mã. Cloud Functions cung cấp cho bạn tùy chọn sử dụng SDK ghi nhật ký cho Node.js hoặc Python hoặc tiêu chuẩn đối tượng console để phát triển cho web.

Ghi nhật ký trên đám mây là dịch vụ có tính phí; bạn có thể bị tính phí nếu vượt quá hạn ngạch miễn phí. Để biết thêm thông tin, hãy xem Giá ghi nhật ký đám mây .

Viết nhật ký

Sử dụng SDK ghi nhật ký chức năng đám mây

SDK ghi nhật ký Cloud Functions cung cấp giao diện chuẩn để báo cáo trạng thái từ các chức năng sang Cloud Logging. Bạn có thể sử dụng SDK này để ghi lại các sự kiện bằng dữ liệu có cấu trúc , giúp phân tích và giám sát dễ dàng hơn.

Nhập từ gói con logger :

Node.js

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

Python

from firebase_functions import logger
  • Các lệnh logger.log() có cấp độ nhật ký INFO .

  • Các lệnh logger.info() có cấp độ nhật ký INFO .

  • Các lệnh logger.warn() có cấp độ nhật ký CẢNH BÁO .

  • Các lệnh logger.error() có cấp độ nhật ký LỖI .

  • Các lệnh logger.debug() có cấp độ nhật ký DEBUG .

  • Thông báo hệ thống nội bộ có cấp độ nhật ký DEBUG .

Ví dụ này minh họa một hàm viết nhật ký cơ bản:

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

Sử dụng các cấp độ nhật ký khác nhau cho các loại nhật ký khác nhau trong mã chức năng của bạn. Dữ liệu có cấu trúc có thể được đính kèm vào nhật ký làm đối số cuối cùng. Dưới đây là ví dụ về cách một hàm có thể sử dụng từng loại nhật ký:

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

Với logger.write() , bạn có thể viết các mục nhật ký với mức độ nghiêm trọng của nhật ký bổ sung là CRITICAL , ALERTEMERGENCY . Xem Mức độ nghiêm trọng của nhật ký .

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)

Sử dụng console.log

Giải pháp được đề xuất để ghi nhật ký từ một hàm là sử dụng SDK ghi nhật ký cho nền tảng của bạn. Với Node.js, thay vào đó, bạn có thể sử dụng các lệnh gọi ghi nhật ký JavaScript tiêu chuẩn như console.logconsole.error , nhưng trước tiên bạn cần yêu cầu một mô-đun đặc biệt để vá các phương thức tiêu chuẩn để hoạt động chính xác:

require("firebase-functions/logger/compat");

Khi đã yêu cầu mô-đun tương thích logger, bạn có thể sử dụng các phương thức console.log() như bình thường trong mã của mình:

exports.helloError = functions.https.onRequest((request, response) => {
  console.log('I am a log entry!');
  response.send('Hello World...');
});
  • Các lệnh console.log() có cấp độ nhật ký INFO .
  • Các lệnh console.info() có cấp độ nhật ký INFO .
  • Các lệnh console.warn() có cấp độ nhật ký LỖI .
  • Các lệnh console.error() có cấp độ nhật ký LỖI .
  • Thông báo hệ thống nội bộ có cấp độ nhật ký DEBUG .

Xem nhật ký

Bạn có thể xem nhật ký cho Chức năng đám mây trong bảng điều khiển Google Cloud , Giao diện người dùng ghi nhật ký đám mây hoặc thông qua công cụ dòng lệnh firebase .

Sử dụng CLI Firebase

Để xem nhật ký bằng công cụ firebase , hãy sử dụng lệnh functions:log :

firebase functions:log

Để xem nhật ký của một hàm cụ thể, hãy cung cấp tên hàm làm đối số:

firebase functions:log --only <FUNCTION_NAME>

Để có đầy đủ các tùy chọn xem nhật ký, hãy xem trợ giúp cho functions:log :

firebase help functions:log

Sử dụng bảng điều khiển Google Cloud

Bạn có thể xem nhật ký các chức năng trong bảng điều khiển Google Cloud .

Sử dụng giao diện người dùng ghi nhật ký trên đám mây

Bạn có thể xem nhật ký cho Chức năng đám mây trong Giao diện người dùng ghi nhật ký đám mây.

Phân tích nhật ký

Cloud Logging cung cấp một bộ công cụ phân tích nhật ký mạnh mẽ mà bạn có thể sử dụng để giám sát Chức năng đám mây của mình.

Biểu đồ và cảnh báo

Khi bạn đã tạo các số liệu dựa trên nhật ký để theo dõi các chức năng của mình, bạn có thể tạo biểu đồ và cảnh báo dựa trên các số liệu này. Ví dụ: bạn có thể tạo biểu đồ để trực quan hóa độ trễ theo thời gian hoặc tạo cảnh báo để cho bạn biết nếu một lỗi nào đó xảy ra quá thường xuyên.

Xem Tạo biểu đồ và cảnh báo để biết thông tin chi tiết về cách sử dụng số liệu dựa trên nhật ký trong biểu đồ và chính sách cảnh báo.