Ведение журнала — важный инструмент для отладки и мониторинга кода. Cloud Functions дает вам возможность использовать SDK средства ведения журнала для Node.js или Python или стандарт объекта console
для веб-разработки.
Облачная регистрация — платная услуга; вам может быть выставлен счет, если вы превысите бесплатную квоту. Дополнительную информацию см. в разделе Цены на ведение журналов в облаке .
Запись журналов
Использование SDK регистратора Cloud Functions
SDK Cloud Functions logger предоставляет стандартный интерфейс для сообщения о состоянии функций в Cloud Logging. Вы можете использовать этот SDK для регистрации событий со структурированными данными , что упрощает анализ и мониторинг.
Импортируйте из подпакета 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()
имеют уровень журнала WARNING .Команды
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
Рекомендуемое решение для ведения журнала из функции — использовать SDK средства ведения журнала для вашей платформы. Вместо этого с Node.js вы можете использовать стандартные вызовы журналирования JavaScript, такие как 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
Чтобы просмотреть журналы с помощью инструмента 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 .
Графики и оповещения
После того как вы создали метрики на основе журналов для мониторинга своих функций, вы можете создавать диаграммы и оповещения на основе этих метрик. Например, вы можете создать диаграмму для визуализации задержки с течением времени или создать оповещение, сообщающее, если определенная ошибка возникает слишком часто.
Подробную информацию о том, как использовать метрики на основе журналов в диаграммах и политиках оповещений, см. в разделе «Создание диаграмм и оповещений» .