Logowanie to ważne narzędzie do debugowania i monitorowania kodu.
Cloud Functions umożliwia korzystanie z pakietu SDK logger dla
Node.js
lub Pythona,
albo z obiektu console standardowego w przypadku tworzenia aplikacji internetowych.
Cloud Logging to płatna usługa. Jeśli przekroczysz bezpłatny limit, możesz otrzymać rachunek. Więcej informacji znajdziesz w cenniku Cloud Logging.
Zapisywanie logów
Korzystanie z pakzytu SDK logger Cloud Functions
Pakiet SDK logger Cloud Functions udostępnia standardowy interfejs do raportowania stanu funkcji do Cloud Logging. Za pomocą tego pakietu SDK możesz rejestrować zdarzenia z danymi strukturalnymi, co ułatwia analizę i monitorowanie.
Importowanie z podpakietu logger:
Node.js
// All available logging functions
const {
log,
info,
debug,
warn,
error,
write,
} = require("firebase-functions/logger");
Python
from firebase_functions import logger
Polecenia
logger.log()mają poziom logu INFO.Polecenia
logger.info()mają poziom logu INFO.Polecenia
logger.warn()mają poziom logu WARNING.Polecenia
logger.error()mają poziom logu ERROR.Polecenia
logger.debug()mają poziom logu DEBUG.Wewnętrzne komunikaty systemowe mają poziom logu DEBUG.
Ten przykład pokazuje funkcję zapisującą podstawowy log:
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!")
W kodzie funkcji używaj różnych poziomów logu w przypadku różnych typów logów. Dane strukturalne można dołączyć do logu jako ostatni argument. Oto przykład, jak funkcja może używać każdego typu logu:
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!")
Za pomocą logger.write() możesz zapisywać wpisy logu z dodatkowymi
poziomami ważności logu
: CRITICAL, ALERT i EMERGENCY. Zobacz 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)
Korzystanie z console.log
Zalecanym rozwiązaniem do logowania z funkcji jest użycie pakietu SDK logger dla Twojej platformy. W przypadku Node.js możesz zamiast tego używać standardowych wywołań logowania JavaScript, takich jak console.log i console.error, ale najpierw musisz wymagać specjalnego modułu, aby poprawić standardowe metody:
require("firebase-functions/logger/compat");
Gdy wymagany jest moduł zgodności loggera, możesz używać metod console.log() w kodzie w normalny sposób:
exports.helloError = functions.https.onRequest((request, response) => {
console.log('I am a log entry!');
response.send('Hello World...');
});
- Polecenia
console.log()mają poziom logu INFO. - Polecenia
console.info()mają poziom logu INFO. - Polecenia
console.warn()mają poziom logu ERROR. - Polecenia
console.error()mają poziom logu ERROR. - Wewnętrzne komunikaty systemowe mają poziom logu DEBUG.
Wyświetlanie logów
Logi dla Cloud Functions można wyświetlać w konsoli
Google Cloud, interfejsie
Cloud Logging lub za pomocą narzędzia wiersza poleceń firebase.
Korzystanie z wiersza poleceń Firebase
Aby wyświetlić logi za pomocą narzędzia firebase, użyj polecenia functions:log:
firebase functions:log
Aby wyświetlić logi określonej funkcji, podaj jej nazwę jako argument:
firebase functions:log --only <FUNCTION_NAME>
Pełny zakres opcji wyświetlania logów znajdziesz w pomocy dotyczącej polecenia functions:log:
firebase help functions:log
Korzystanie z konsoliGoogle Cloud
Logi funkcji możesz wyświetlać w Google Cloud konsoli.
Korzystanie z interfejsu Cloud Logging
Logi możesz wyświetlać Cloud Functions w interfejsie Cloud Logging.
Analizowanie logów
Cloud Logging oferuje zaawansowany zestaw narzędzi do analizy logów, których możesz używać do monitorowania Cloud Functions.
Wykresy i alerty
Gdy utworzysz wskaźniki oparte na logach do monitorowania funkcji, możesz tworzyć wykresy i alerty na podstawie tych wskaźników. Możesz na przykład utworzyć wykres, aby wizualizować opóźnienie w czasie, lub utworzyć alert, który będzie Cię informować, jeśli dany błąd występuje zbyt często.
Szczegółowe informacje o tym, jak używać wskaźników opartych na logach na wykresach i w zasadach tworzenia alertów, znajdziesz w artykule Tworzenie wykresów i alertów.
Poznawanie i używanie identyfikatorów wykonania
Domyślnie funkcje Cloud Run (2 generacji) obsługują równoczesne wykonywanie wielu żądań w ramach jednej instancji funkcji. Oznacza to, że logi z różnych żądań mogą być przeplatane, co utrudnia śledzenie przepływu pojedynczego wykonania.
Aby ułatwić to zadanie, funkcje wdrożone za pomocą wiersza poleceń Firebase w wersji 13.33.0 i nowszej są automatycznie wdrażane z opcją powiązania identyfikatora wykonania z każdym wpisem logu emitowanym podczas obsługi tego wykonania.
Identyfikator wykonania jednoznacznie identyfikuje wszystkie logi powiązane z pojedynczym żądaniem obsługiwanym przez Twoją funkcję. Nie trzeba wprowadzać żadnych zmian w kodzie. Identyfikator wykonania zostanie automatycznie dodany do logów.
Aby wyłączyć logowanie identyfikatora wykonania we wpisach logu, ustaw
zmienną środowiskową LOG_EXECUTION_ID na false w pliku dotenv.
Znajdowanie i korelowanie logów według identyfikatora wykonania
Logi możesz sprawdzać i korelować według identyfikatora wykonania w eksploratorze logów w chmurze.
Rozwiń wpis logu z funkcji. Identyfikator wykonania znajduje się w strukturalnych danych logu, zagnieżdżonych w etykietach jako
labels.execution_id.Kliknij wartość
execution_idi w menu wybierz „Pokaż pasujące wpisy”, aby wyświetlić wszystkie inne logi powiązane z tym samym wykonaniem funkcji.
Używając identyfikatora wykonania, możesz grupować wszystkie komunikaty logu powiązane z pojedynczym żądaniem, nawet jeśli funkcja obsługuje wiele żądań jednocześnie.
Zwiększanie widoczności logów za pomocą niestandardowych pól podsumowania
Aby identyfikator wykonania był bardziej widoczny w eksploratorze logów, możesz dodać go jako [niestandardowe pole podsumowania][cloud-logging-preference]. Gdy dodasz identyfikator wykonania jako pole podsumowania, każdy wpis logu będzie wyświetlać identyfikator wykonania jako element na początku wiersza logu, podobnie jak w przypadku funkcji 1 generacji.
Aby dodać identyfikator wykonania do pola podsumowania:
Kliknij wartość identyfikatora wykonania w strukturalnym wpisie logu w sekcji
labels.execution_id.W menu wybierz „Dodaj pole do wiersza podsumowania”.
Każdy wpis logu będzie teraz wyświetlać executionId w polu podsumowania, co ułatwi identyfikowanie i grupowanie logów powiązanych z określonym identyfikatorem wykonania.