簡體   English   中英

在 Firebase Functions 中的 Stackdriver 錯誤日志中添加自定義信息

[英]Add custom information to the Stackdriver error log in Firebase Functions

我將 Firebase 函數與 Stackdriver 一起使用。

Stackdriver 與 Firebase 函數很好地集成在一起,因此我可以使用console.error命令輕松記錄錯誤。 但是,我不僅要記錄錯誤 object,還要記錄查詢參數。 如果我可以在同一日志行中記錄錯誤 object 並查詢參數,則可以輕松地將它們分組和導出。

有沒有一種簡單的方法可以將信息添加到 Stackdriver 的錯誤日志中,如下所示?

    console.error(new Error('Invalid query'), req.query)

謝謝。

- - 編輯

我嘗試了以下代碼。 這可以向日志條目添加查詢參數,但不幸的是,Stackdriver 將所有錯誤歸為一組,如下面的屏幕截圖所示。 即使每個錯誤的類型不同並且發生在不同的文件中,所有錯誤也會組合在一起。 我希望 Stackdriver Error Reporting 像往常一樣按錯誤類型或堆棧跟蹤對錯誤進行分組。

index.js

const functions = require('firebase-functions')
const raiseReferenceError = require('./raiseReferenceError')
const raiseSyntaxError = require('./raiseSyntaxError')
const raiseTypeError = require('./raiseTypeError')

exports.stackdriverErrorLogging = functions.https.onRequest((req, res) => {
  try {
    switch (Math.round(Math.random() * 2)) {
      case 0:
        raiseReferenceError()
        break

      case 1:
        raiseSyntaxError()
        break

      default:
        raiseTypeError()
        break
    }
  } catch (error) {
    console.error({
      error: error,
      method: req.method,
      query: req.query
    })
  }

  res.send('Hello from Firebase!')
})

raiseReferenceError.js

module.exports = () => {
  console.log(foo)
}

raiseSyntaxError.js

module.exports = () => {
  eval(',')
}

raiseTypeError.js

module.exports = () => {
  const foo = null
  foo()
}

10次運行結果截圖:

Stackdriver 錯誤報告錯誤摘要頁面Stackdriver 錯誤摘要頁面 Stackdriver 錯誤報告錯誤詳情頁面Stackdriver 錯誤詳情頁面 1 Stackdriver 錯誤詳情頁面 2

自我回答:

我試圖找到簡單的方法,但沒有。 所以我決定擺脫我的懶惰,學習如何使用 @google-cloud/logging,正如 Yuri Grinshteyn 提到的那樣。

我找到了很多例子,但對於這種情況,沒有一個是足夠的。 最后,我構建了一個 function 可以輕松報告錯誤並提供附加信息。

要點如下:

  1. 要在 GCP 控制台上將自定義錯誤日志顯示為普通錯誤日志,它需要包括嚴重性、區域、執行 ID、跟蹤 ID。 如果缺少它們,GCP 控制台不會在默認過濾器上顯示它們。 也不能按執行 ID 標簽分組。
  2. execution_id 和跟蹤 ID 應從 http 請求中提取。 (我不知道如何將它們用於其他觸發類型的功能。)

這需要時間,但最終,Stackdriver Error Reporting 識別並分組每種錯誤類型,並成功地將自定義信息包含在錯誤日志的 JSON 負載中。 這就是我想要的。

現在我終於可以回去工作了。

這是我提出的要點。

這是一個主要代碼。

// https://firebase.google.com/docs/functions/reporting-errors#manually_reporting_errors
const { Logging } = require('@google-cloud/logging')

// Instantiates a client
const logging = new Logging()

module.exports = function reportError (err, context = {}, req = undefined) {
  // Use Stackdriver only on production environment.
  if (process.env.NODE_ENV !== 'production') {
    return new Promise((resolve, reject) => {
      console.error(err, context)
      return resolve()
    })
  }

  const log = logging.log('cloudfunctions.googleapis.com%2Fcloud-functions')

  // https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource
  const metadata = {
    severity: 'ERROR',
    resource: {
      type: 'cloud_function',
      labels: {
        function_name: process.env.FUNCTION_NAME,
        project: process.env.GCLOUD_PROJECT,
        region: process.env.FUNCTION_REGION
      }
    }
  }

  // Extract execution_id, trace from http request
  // https://stackoverflow.com/a/55642248/7908771
  if (req) {
    const traceId = req.get('x-cloud-trace-context').split('/')[0]
    Object.assign(metadata, {
      trace: `projects/${process.env.GCLOUD_PROJECT}/traces/${traceId}`,
      labels: {
        execution_id: req.get('function-execution-id')
      }
    })
  }

  // https://cloud.google.com/error-reporting/reference/rest/v1beta1/ErrorEvent
  const errorEvent = {
    message: err.stack,
    serviceContext: {
      service: process.env.FUNCTION_NAME,
      resourceType: 'cloud_function'
    },
    context: context
  }

  // Write the error log entry
  return new Promise((resolve, reject) => {
    log.write(log.entry(metadata, errorEvent), (error) => {
      if (error) {
        return reject(error)
      }
      return resolve()
    })
  })
}

10次運行結果截圖:

Stackdriver 錯誤報告錯誤摘要頁面。 Stackdriver 錯誤報告錯誤摘要頁面。

Stackdriver Logging 顯示帶有自定義信息的錯誤。 Stackdriver Logging 顯示帶有自定義信息的錯誤。

當我處理錯誤時,我通常使用 object 結構,它可以提供我需要的所有信息。 像這樣的東西:

const query = req.query;
const myErrorObject = new Error('some error');


console.error({
    method: req.method,
    query: req.query,
    error: myErrorObject
});

希望有幫助

[更新] - 我看到您添加了更多信息,表明您正在嘗試使用錯誤報告,而不僅僅是記錄。 您仍然可以使用此處記錄的日志庫。

我建議使用 Stackdriver 日志,它應該允許您編寫結構化日志。 這在 Firebase 文檔中有所描述。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM