Logging adalah alat penting untuk proses debug dan pemantauan kode.
Cloud Functions memberi Anda opsi untuk menggunakan SDK logger untuk Node.js atau Python, atau standar objek console
untuk pengembangan web.
Cloud Logging adalah layanan yang dapat dikenai biaya; Anda dapat menerima tagihan jika kuota gratis layanan ini terlampaui. Untuk mengetahui informasi lebih lanjut, lihat harga Cloud Logging.
Menulis log
Menggunakan SDK logger Cloud Functions
SDK logger Cloud Functions menyediakan antarmuka standar untuk melaporkan status dari fungsi ke Cloud Logging. Anda dapat menggunakan SDK ini untuk mencatat peristiwa ke dalam log dengan data terstruktur, sehingga memudahkan analisis dan pemantauan.
Impor dari subpaket logger
:
// All available logging functions
const {
log,
info,
debug,
warn,
error,
write,
} = require("firebase-functions/logger");
from firebase_functions import logger
Perintah
logger.log()
memiliki level log INFO.Perintah
logger.info()
memiliki level log INFO.Perintah
logger.warn()
memiliki level log WARNING.Perintah
logger.error()
memiliki level log ERROR.Perintah
logger.debug()
memiliki level log DEBUG.Pesan sistem internal memiliki level log DEBUG.
Contoh ini menunjukkan fungsi yang menulis log dasar:
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!")
Gunakan berbagai level log untuk berbagai jenis log di kode fungsi Anda. Data terstruktur dapat dilampirkan ke log sebagai argumen terakhir. Berikut adalah contoh cara fungsi menggunakan setiap jenis log:
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!")
Dengan logger.write()
, Anda dapat menulis entri log dengan
tingkat keparahan log
tambahan CRITICAL
, ALERT
, dan EMERGENCY
. Lihat LogSeverity.
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)
Menggunakan console.log
Solusi yang direkomendasikan untuk melakukan logging dari fungsi adalah dengan menggunakan SDK logger untuk platform Anda. Dengan Node.js, Anda dapat menggunakan panggilan logging JavaScript standar seperti console.log
dan console.error
, tetapi Anda harus terlebih dahulu mewajibkan modul khusus untuk menerapkan patch pada metode standar agar berfungsi dengan benar:
require("firebase-functions/logger/compat");
Setelah mewajibkan modul kompatibilitas logger, Anda dapat menggunakan metode console.log()
seperti biasa dalam kode Anda:
exports.helloError = functions.https.onRequest((request, response) => {
console.log('I am a log entry!');
response.send('Hello World...');
});
- Perintah
console.log()
memiliki level log INFO. - Perintah
console.info()
memiliki level log INFO. - Perintah
console.warn()
memiliki level log ERROR. - Perintah
console.error()
memiliki level log ERROR. - Pesan sistem internal memiliki level log DEBUG.
Melihat log
Log untuk Cloud Functions dapat dilihat di Google Cloud console, UI Cloud Logging, atau melalui alat command line firebase
.
Menggunakan Firebase CLI
Untuk melihat log dengan alat firebase
, gunakan perintah functions:log
:
firebase functions:log
Untuk melihat log fungsi tertentu, masukkan nama fungsi sebagai argumen:
firebase functions:log --only <FUNCTION_NAME>
Untuk mengetahui berbagai opsi tampilan log, lihat bantuan untuk functions:log
:
firebase help functions:log
Menggunakan Google Cloud console
Anda dapat melihat log untuk fungsi di Google Cloud console.
Menggunakan UI Cloud Logging
Anda dapat melihat log untuk Cloud Functions di UI Cloud Logging.
Menganalisis log
Cloud Logging menawarkan serangkaian alat analisis log yang canggih dan dapat Anda gunakan untuk memantau Cloud Functions.
Diagram dan pemberitahuan
Setelah membuat metrik berbasis log untuk memantau fungsi, Anda dapat membuat diagram dan pemberitahuan berdasarkan metrik ini. Misalnya, Anda bisa membuat diagram untuk memvisualisasikan latensi dari waktu ke waktu, atau membuat pemberitahuan yang akan muncul jika error tertentu terlalu sering terjadi.
Baca Membuat Diagram dan Pemberitahuan untuk mengetahui informasi selengkapnya tentang cara menggunakan metrik berbasis log dalam diagram dan kebijakan pemberitahuan.
Memahami dan menggunakan ID eksekusi
Secara default, Cloud Run Functions (generasi ke-2) mendukung eksekusi serentak dari beberapa permintaan dalam satu instance fungsi. Artinya, log dari permintaan yang berbeda dapat disisipkan, sehingga lebih sulit untuk mengikuti alur satu eksekusi.
Untuk membantu hal ini, fungsi yang di-deploy menggunakan Firebase CLI versi 13.33.0 dan yang lebih baru akan di-deploy secara otomatis dengan opsi untuk mengaitkan ID eksekusi di setiap entri log yang muncul selama penanganan eksekusi tersebut.
ID eksekusi mengidentifikasi semua log yang terkait dengan satu permintaan secara unik, yang ditangani oleh fungsi Anda. Anda tidak perlu mengubah kode, karena ID eksekusi akan ditambahkan ke log secara otomatis.
Untuk menonaktifkan ID eksekusi logging dalam entri log, tetapkan
variabel lingkungan LOG_EXECUTION_ID
ke salah dalam file dotenv Anda.
Menemukan dan mengaitkan log berdasarkan ID eksekusi
Anda dapat memeriksa dan mengaitkan log berdasarkan ID eksekusi di Cloud Logs Explorer.
Memperluas entri log dari fungsi Anda. ID eksekusi berada dalam data log terstruktur, yang bertingkat dalam label sebagai
labels.execution_id
.Klik nilai
execution_id
dan pilih "Show matching entries" dari menu drop-down untuk melihat semua log lain yang terkait dengan eksekusi fungsi yang sama.
Dengan menggunakan ID eksekusi, Anda dapat mengelompokkan semua pesan log yang terkait dengan satu permintaan, meskipun fungsi Anda menangani beberapa permintaan secara serentak.
Meningkatkan visibilitas log dengan kolom ringkasan kustom
Agar ID eksekusi lebih mudah dilihat di Logs Explorer, Anda dapat menambahkannya sebagai kolom ringkasan kustom. Tindakan ini akan menampilkan ID eksekusi sebagai chip di awal setiap baris entri log, mirip dengan cara fungsi Generasi ke-1 menampilkan ID eksekusi untuk semua entri log.
Untuk menambahkan ID eksekusi ke kolom ringkasan:
Klik nilai ID eksekusi di entri log terstruktur di bagian
labels.execution_id
.Pilih "Add field to summary line" dari menu drop-down.
Setiap entri log kini menampilkan executionId
dengan jelas di kolom ringkasan,
sehingga mempermudah identifikasi dan pengelompokan log yang terkait dengan ID eksekusi
tertentu.