Logs schreiben und aufrufen

Logging ist ein wichtiges Tool zum Debuggen und Überwachen von Code. Cloud Functions bietet Ihnen die Möglichkeit, das Logger SDK für Node.js oder Python oder das console-Objekt zu verwenden, das für die Webentwicklung Standard ist.

Cloud Logging ist ein kostenpflichtiger Dienst. Wenn Sie das kostenlose Kontingent überschreiten, werden Ihnen möglicherweise Gebühren in Rechnung gestellt. Weitere Informationen finden Sie unter Cloud Logging – Preise.

Logs schreiben

Logger SDK verwendenCloud Functions

Das Cloud Functions Logger SDK bietet eine Standardschnittstelle zum Melden des Status von Funktionen an Cloud Logging. Mit diesem SDK können Sie Ereignisse mit strukturierten Daten, was die Analyse und Überwachung erleichtert, protokollieren.

Importieren Sie aus dem logger Unterpaket:

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() Befehle haben die INFO Logebene.

  • logger.info() commands have the INFO log level.

  • logger.warn() commands have the WARNING log level.

  • logger.error() commands have the ERROR log level.

  • logger.debug() commands have the DEBUG log level.

  • Interne Systemmeldungen haben die Logebene DEBUG.

Dieses Beispiel zeigt eine Funktion, die ein einfaches Log schreibt:

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

Verwenden Sie in Ihrem Funktionscode verschiedene Logebenen für verschiedene Arten von Logs. Strukturierte Daten können als letztes Argument an ein Log angehängt werden. Hier ist ein Beispiel dafür, wie eine Funktion die einzelnen Logtypen verwenden kann:

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

Mit logger.write() können Sie Logeinträge mit zusätzlichen Logebenen für den Schweregrad von CRITICAL, ALERT und EMERGENCY schreiben. Weitere Informationen finden Sie unter 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 verwenden

Die empfohlene Lösung für das Logging aus einer Funktion ist die Verwendung des Logger SDK für Ihre Plattform. Mit Node.js können Sie stattdessen Standard-JavaScript-Logging Aufrufe wie console.log und console.error verwenden. Sie müssen jedoch zuerst ein spezielles Modul anfordern, um die Standardmethoden so zu patchen, dass sie korrekt funktionieren:

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

Nachdem Sie das Logger-Kompatibilitätsmodul angefordert haben, können Sie console.log() Methoden wie gewohnt in Ihrem Code verwenden:

exports.helloError = functions.https.onRequest((request, response) => {
  console.log('I am a log entry!');
  response.send('Hello World...');
});
  • console.log() commands have the INFO log level.
  • console.info() commands have the INFO log level.
  • console.warn() commands have the ERROR log level.
  • console.error() commands have the ERROR log level.
  • Interne Systemmeldungen haben die Logebene DEBUG.

Logs ansehen

Logs für Cloud Functions können entweder in der Google Cloud Console, Cloud Logging UI oder über das firebase Befehlszeilentool aufgerufen werden.

Mit der Firebase CLI

Verwenden Sie den Befehl functions:log, um Logs mit dem Tool firebase aufzurufen:

firebase functions:log

Zum Aufrufen der Logs für eine bestimmte Funktion geben Sie den Funktionsnamen als Argument an:

firebase functions:log --only <FUNCTION_NAME>

Informationen zu allen Loganzeigeoptionen finden Sie in der Hilfe zu functions:log:

firebase help functions:log

Google Cloud Konsole verwenden

Sie können Logs für Funktionen in der Google Cloud Konsole aufrufen.

Cloud Logging UI verwenden

Sie können Logs für Cloud Functions in der Cloud Logging UI aufrufen.

Logs analysieren

Cloud Logging bietet eine leistungsstarke Suite von Tools zur Loganalyse, mit denen Sie Ihre Cloud Functions überwachen können.

Diagramme und Benachrichtigungen

Nachdem Sie logbasierte Messwerte zur Überwachung Ihrer Funktionen erstellt haben, können Sie Diagramme und Benachrichtigungen auf Grundlage dieser Messwerte erstellen. Sie können beispielsweise ein Diagramm erstellen, um die Latenz im Zeitverlauf zu visualisieren, oder eine Benachrichtigung erstellen, um sich benachrichtigen zu lassen, wenn ein bestimmter Fehler zu häufig auftritt.

Weitere Informationen zur Verwendung logbasierter Messwerte in Diagrammen und Benachrichtigungsrichtlinien finden Sie unter Diagramme und Benachrichtigungen erstellen.

Ausführungs-IDs verstehen und verwenden

Standardmäßig unterstützt Cloud Run Functions (2. Generation) die gleichzeitige Ausführung von mehreren Anfragen innerhalb einer einzelnen Funktionsinstanz. Das bedeutet, dass Logs aus verschiedenen Anfragen verschachtelt werden können, was es schwieriger macht, den Ablauf einer einzelnen Ausführung zu verfolgen.

Um dies zu erleichtern, werden Funktionen, die mit der Firebase CLI-Version 13.33.0 und höher bereitgestellt werden, automatisch mit einer Option bereitgestellt, mit der jedem Logeintrag, der während der Verarbeitung dieser Ausführung ausgegeben wird, eine Ausführungs-ID zugeordnet werden kann.

Die Ausführungs-ID identifiziert eindeutig alle Logs, die mit einer einzelnen Anfrage verknüpft sind, die von Ihrer Funktion verarbeitet wird. Es sind keine Codeänderungen erforderlich. Die Ausführungs-ID wird automatisch zu Ihren Logs hinzugefügt.

Wenn Sie die Protokollierung der Ausführungs-ID in Ihren Logeinträgen deaktivieren möchten, setzen Sie die Umgebungsvariable LOG_EXECUTION_ID in Ihrer „dotenv“-Datei auf „false“.

Logs nach Ausführungs-ID suchen und korrelieren

Sie können Logs nach Ausführungs-ID im Log-Explorer von Cloud untersuchen und korrelieren.

  1. Maximieren Sie den Logeintrag aus Ihrer Funktion. Die Ausführungs-ID befindet sich in den strukturierten Logdaten, verschachtelt unter Labels als labels.execution_id.

  2. Klicken Sie auf den Wert von execution_id und wählen Sie im Drop-down-Menü „Übereinstimmende Einträge anzeigen“ aus, um alle anderen Logs zu sehen, die mit derselben Funktionsausführung verknüpft sind.

Mit der Ausführungs-ID können Sie alle Logmeldungen gruppieren, die sich auf eine einzelne Anfrage beziehen, auch wenn Ihre Funktion mehrere Anfragen gleichzeitig verarbeitet.

Logansicht mit benutzerdefinierten Zusammenfassungsfeldern verbessern

Damit die Ausführungs-ID im Log-Explorer besser sichtbar ist, können Sie sie als [benutzerdefiniertes Zusammenfassungsfeld][cloud-logging-preference] hinzufügen. Nachdem Sie Ausführungs-ID als Zusammenfassungsfeld hinzugefügt haben, wird in jedem Logeintrag die Ausführungs-ID als Chip am Anfang der Logzeile angezeigt. Das ist ähnlich wie bei Funktionen der 1. Generation, bei denen die Ausführungs-ID für alle Logeinträge angezeigt wurde.

So fügen Sie die Ausführungs-ID zum Zusammenfassungsfeld hinzu:

  1. Klicken Sie im strukturierten Logeintrag unter labels.execution_id auf den Wert der Ausführungs-ID.

  2. Wählen Sie im Drop-down-Menü „Feld zur Zusammenfassungszeile hinzufügen“ aus.

In jedem Logeintrag wird jetzt die executionId deutlich im Zusammenfassungsfeld angezeigt, sodass es einfacher ist, Logs zu identifizieren und zu gruppieren, die mit einer bestimmten Ausführungs ID verknüpft sind.