Gravar e visualizar logs


O log é uma ferramenta importante para depuração e monitoramento de código. O Cloud Functions oferece a opção de usar o SDK do logger para Node.js ou Python ou o objeto padrão console para desenvolvimento para a Web.

O Cloud Logging é um serviço pago; você poderá ser cobrado se exceder a cota gratuita. Para obter mais informações, consulte Preços do Cloud Logging .

O SDK do agente de log do Cloud Functions fornece uma interface padrão para relatar o status das funções ao Cloud Logging. Você pode usar este SDK para registrar eventos com dados estruturados , facilitando a análise e o monitoramento.

Importe do subpacote do logger :

// All available logging functions
const {
  log
,
  info
,
  debug
,
  warn
,
  error
,
  write
,
} = require("firebase-functions/logger");
from firebase_functions import logger
  • Os comandos logger.log() possuem o nível de log INFO .

  • Os comandos logger.info() possuem o nível de log INFO .

  • Os comandos logger.warn() possuem o nível de log WARNING .

  • Os comandos logger.error() possuem o nível de log ERROR .

  • Os comandos logger.debug() possuem o nível de log DEBUG .

  • As mensagens internas do sistema possuem o nível de log DEBUG .

Este exemplo demonstra uma função escrevendo um log básico:

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

Use diferentes níveis de log para diferentes tipos de log em seu código de função. Os dados estruturados podem ser anexados a um log como último argumento. Aqui está um exemplo de como uma função pode usar cada tipo de 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!")

Com logger.write() , você pode gravar entradas de log com níveis de gravidade de log adicionais de CRITICAL , ALERT e EMERGENCY . Consulte 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)

Usando console.log

A solução recomendada para registrar em log de uma função é usar o SDK do logger para sua plataforma. Com o Node.js, você pode usar chamadas de log JavaScript padrão, como console.log e console.error , mas primeiro você precisa exigir um módulo especial para corrigir os métodos padrão para funcionar corretamente:

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

Depois de solicitar o módulo de compatibilidade do logger, você pode usar os métodos console.log() normalmente em seu código:

exports.helloError = functions.https.onRequest((request, response) => {
  console
.log('I am a log entry!');
  response
.send('Hello World...');
});
  • Os comandos console.log() possuem o nível de log INFO .
  • Os comandos console.info() possuem o nível de log INFO .
  • Os comandos console.warn() possuem o nível de log ERROR .
  • Os comandos console.error() possuem o nível de log ERROR .
  • As mensagens internas do sistema possuem o nível de log DEBUG .

Visualizando registros

Os registros do Cloud Functions podem ser visualizados no console do Google Cloud , na IU do Cloud Logging ou por meio da ferramenta de linha de comando firebase .

Usando a CLI do Firebase

Para visualizar logs com a ferramenta firebase , use o comando functions:log :

firebase functions:log

Para visualizar os logs de uma função específica, forneça o nome da função como argumento:

firebase functions:log --only <FUNCTION_NAME>

Para conhecer todas as opções de visualização de log, consulte a ajuda de functions:log :

firebase help functions:log

Como usar o console do Google Cloud

Você pode visualizar registros de funções no console do Google Cloud .

Como usar a IU do Cloud Logging

É possível visualizar registros do Cloud Functions na IU do Cloud Logging.

Analisando registros

O Cloud Logging oferece um conjunto avançado de ferramentas de análise de registros que você pode usar para monitorar o Cloud Functions.

Gráficos e alertas

Depois de criar métricas baseadas em logs para monitorar suas funções, você poderá criar gráficos e alertas com base nessas métricas. Por exemplo, você pode criar um gráfico para visualizar a latência ao longo do tempo ou criar um alerta para informar se um determinado erro ocorre com muita frequência.

Consulte Criação de gráficos e alertas para obter informações detalhadas sobre como usar métricas baseadas em logs em gráficos e políticas de alertas.