Günlükleri yazma ve görüntüleme

Günlük kaydı, kodda hata ayıklama ve kodu izleme için önemli bir araçtır. Cloud Functions, Node.js veya Python için günlükçü SDK'sını ya da web için geliştirme yaparken console nesne standardını kullanma seçeneği sunar.

Cloud Logging ücretli bir hizmettir. Ücretsiz kotayı aşarsanız sizden ücret alınabilir. Daha fazla bilgi için Cloud Logging fiyatlandırması bölümünü inceleyin.

Günlük yazma

Cloud Functions logger SDK'sını kullanma

Cloud Functions Logger SDK, işlevlerden Cloud Logging'e durum bildirmek için standart bir arayüz sağlar. Bu SDK'yı, etkinlikleri yapılandırılmış verilerle günlüğe kaydetmek için kullanabilirsiniz. Bu sayede analiz ve izleme daha kolay hale gelir.

logger alt paketinden içe aktarma:

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() komutları INFO günlük düzeyine sahiptir.

  • logger.info() komutları INFO günlük düzeyine sahiptir.

  • logger.warn() komutları WARNING (UYARI) günlük düzeyine sahiptir.

  • logger.error() komutları ERROR günlük kaydı düzeyine sahiptir.

  • logger.debug() komutlarında DEBUG günlük düzeyi vardır.

  • Dahili sistem mesajları DEBUG günlük düzeyine sahiptir.

Bu örnekte, temel bir günlük yazan bir işlev gösterilmektedir:

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

İşlev kodunuzdaki farklı günlük türleri için farklı günlük düzeyleri kullanın. Yapılandırılmış veriler, son bağımsız değişken olarak bir günlük dosyasına eklenebilir. Bir işlevin her günlük türünü nasıl kullanabileceğine dair örneği aşağıda bulabilirsiniz:

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

logger.write() ile CRITICAL, ALERT ve EMERGENCY ek günlük önem düzeyiyle günlük girişleri yazabilirsiniz. LogSeverity'yi inceleyin.

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 uygulamasını kullanma

Bir işlevden günlük kaydı için önerilen çözüm, platformunuz için Logger SDK'sını kullanmaktır. Node.js ile bunun yerine console.log ve console.error gibi standart JavaScript günlük kaydı oluşturma çağrılarını kullanabilirsiniz ancak standart yöntemlerin doğru şekilde çalışması için önce özel bir modülün gerekli olduğunu belirtmeniz gerekir:

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

Gerekli günlükçü uyumluluğu modülünü aldıktan sonra kodunuzda console.log() yöntemlerini normal şekilde kullanabilirsiniz:

exports.helloError = functions.https.onRequest((request, response) => {
  console.log('I am a log entry!');
  response.send('Hello World...');
});
  • console.log() komutları INFO günlük düzeyine sahiptir.
  • console.info() komutları INFO günlük düzeyine sahiptir.
  • console.warn() komutları ERROR günlük kaydı düzeyine sahiptir.
  • console.error() komutları ERROR günlük kaydı düzeyine sahiptir.
  • Dahili sistem mesajları DEBUG günlük düzeyine sahiptir.

Günlükleri görüntüleme

Cloud Functions günlükleri Google Cloud konsolunda, Cloud Logging kullanıcı arayüzünde veya firebase komut satırı aracıyla görüntülenebilir.

Firebase CLI'yı kullanma

Günlükleri firebase aracıyla görüntülemek için functions:log komutunu kullanın:

firebase functions:log

Belirli bir işlevin günlüklerini görüntülemek için işlev adını bağımsız değişken olarak girin:

firebase functions:log --only <FUNCTION_NAME>

Günlük görüntüleme seçeneklerinin tamamı için functions:log ile ilgili yardımı görüntüleyin:

firebase help functions:log

Google Cloud konsolunu kullanma

İşlevlerin günlüklerini Google Cloud konsolunda görüntüleyebilirsiniz.

Cloud Logging kullanıcı arayüzünü kullanma

Cloud Logging kullanıcı arayüzünde Cloud Functions günlüklerini görüntüleyebilirsiniz.

Günlükleri analiz etme

Cloud Logging, Cloud Functions izlemek için kullanabileceğiniz güçlü bir günlük analizi araçları paketi sunar.

Grafikler ve uyarılar

İşlevlerinizi izlemek için günlük tabanlı metrikler oluşturduktan sonra bu metriklere göre grafikler ve uyarılar oluşturabilirsiniz. Örneğin, zaman içindeki gecikmeyi görselleştirmek için bir grafik oluşturabilir veya belirli bir hata çok sık oluşursa sizi bilgilendirecek bir uyarı oluşturabilirsiniz.

Günlük tabanlı metrikleri grafiklerde ve uyarı politikalarında kullanma hakkında ayrıntılı bilgi için Grafik ve Uyarı Oluşturma başlıklı makaleye bakın.

Yürütme kimliklerini anlama ve kullanma

Varsayılan olarak Cloud Run işlevleri (2. nesil), tek bir işlev örneğinde birden fazla isteğin eşzamanlı olarak yürütülmesini destekler. Bu nedenle, farklı isteklerden gelen günlükler iç içe geçebilir ve tek bir yürütmenin akışını takip etmek zorlaşabilir.

Bu konuda yardımcı olmak için Firebase CLI sürüm 13.33.0 ve sonraki sürümleri kullanılarak dağıtılan işlevler, yürütme sırasında oluşturulan her günlük girişiyle bir yürütme kimliği ilişkilendirme seçeneğiyle otomatik olarak dağıtılır.

Yürütme kimliği, işleviniz tarafından işlenen tek bir istekle ilişkili tüm günlükleri benzersiz şekilde tanımlar. Kod değişikliği yapılması gerekmez. Yürütme kimliği, günlüklerinize otomatik olarak eklenir.

Günlük girişlerinizde yürütme kimliğinin günlüğe kaydedilmesini devre dışı bırakmak için dotenv dosyanızdaki LOG_EXECUTION_ID ortam değişkenini false olarak ayarlayın.

Yürütme kimliğine göre günlükleri bulma ve ilişkilendirme

Cloud Günlük Gezgini'nde günlükleri yürütme kimliğine göre inceleyip ilişkilendirebilirsiniz.

  1. İşlevinizin günlük girişini genişletin. Yürütme kimliği, etiketlerin altına yerleştirilmiş yapılandırılmış günlük verilerinde labels.execution_id olarak bulunur.

  2. execution_id değerini tıklayın ve aynı işlev yürütmeyle ilişkili diğer tüm günlükleri görmek için açılır menüden "Eşleşen girişleri göster"i seçin.

Yürütme kimliğini kullanarak, işleviniz birden fazla isteği eşzamanlı olarak işlese bile tek bir istekle ilgili tüm günlük mesajlarını birlikte gruplandırabilirsiniz.

Özel özet alanlarıyla günlük görünürlüğünü artırma

Yürütme kimliğinin Günlük Gezgini'nde daha kolay görünmesini sağlamak için kimliği [özel özet alanı][cloud-logging-preference] olarak ekleyebilirsiniz. Yürütme kimliğini özet alanı olarak ekledikten sonra her günlük girişi, günlük satırının başında yürütme kimliğini çip olarak gösterir. Bu, 1. nesil işlevlerin tüm günlük girişleri için yürütme kimliğini gösterme şekline benzer.

Özet alanına yürütme kimliği eklemek için:

  1. labels.execution_id bölümündeki yapılandırılmış günlük girişinde yürütme kimliğinin değerini tıklayın.

  2. Açılır menüden "Özet satırına alan ekle"yi seçin.

Artık her günlük girişinde özet alanında executionId simgesi belirgin bir şekilde gösteriliyor. Bu sayede, belirli bir yürütme kimliğiyle ilişkili günlükleri tanımlamak ve gruplandırmak daha kolay.