Добавить пользовательскую информацию в журнал ошибок Stackdriver в Firebase Functions - PullRequest
3 голосов
/ 02 ноября 2019

Я использую функции Firebase вместе со Stackdriver.

Stackdriver очень хорошо интегрирован с функциями Firebase, поэтому я могу легко регистрировать ошибки с помощью команды console.error. Но я хочу записать не только об объекте ошибки, но и параметры запроса. Если я могу записать объект ошибки и параметры запроса в одной строке журнала, их можно легко сгруппировать и экспортировать.

Существует ли простой способ добавить информацию в журнал ошибок в Stackdriver, как показано ниже?

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

Спасибо.

--- edit

Я попробовал следующий код. Это может добавить параметр запроса к записи журнала, но, к сожалению, Stackdriver объединяет все ошибки в одну группу, как показано на скриншоте ниже. Все ошибки сгруппированы вместе, хотя каждая ошибка имеет разный тип и встречается в другом файле. Я ожидаю, что отчеты об ошибках Stackdriver будут группировать ошибки по типу ошибки или трассировке стека, как обычно.

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!')
})

riseReferenceError.js

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

riseSyntaxError.js

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

riseTypeError.js

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

Снимок экрана результатов 10 запусков:

Страница сводки об ошибках отчетов об ошибках Stackdriver Stackdriver error summary page StackdriverСообщение об ошибке на странице сведений об ошибке Stackdriver error details page 1 Stackdriver error details page 2

Ответы [ 3 ]

0 голосов
/ 04 ноября 2019

[обновление] - я вижу, что вы добавили больше информации, показывающей, что вы пытаетесь использовать отчеты об ошибках, а не просто вести журнал. Вы все еще можете использовать библиотеку журналов, как описано здесь .

Я бы порекомендовал использовать журналирование Stackdriver библиотека , которое позволит вам писать структурированные журналы. Это описано в документации Firebase .

0 голосов
/ 10 ноября 2019

Самоответ:

Я пытался найти легкий путь, но не было. Поэтому я решил снять свою ленивую задницу и научиться использовать @ google-cloud / logging, который, как упоминал Юрий Гринштейн.

Я нашел много примеров, но ни одного из них не было достаточно для этого случая. Наконец, я построил функцию, которая легко сообщает об ошибке с дополнительной информацией.

Важными моментами являются следующие:

  1. Чтобы отображать пользовательский журнал ошибок на консоли GCP как обычный журнал ошибок,он должен включать серьезность, регион, номер_процесса, идентификатор трассировки. Если их нет, консоль GCP не показывает их в фильтре по умолчанию. Также нельзя сгруппировать по тегу идентификатора выполнения.
  2. execute_id и идентификатор трассировки должны быть извлечены из запроса http. (Я не знаю, как получить их для функций другого типа триггера.)

Потребовалось время, но, наконец, отчеты об ошибках Stackdriver распознают и группируют каждый тип ошибки и успешно включают пользовательскую информацию в ошибку. полезная нагрузка журнала 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 Error Reporting error summary page.

В журнале Stackdriver отображается ошибка с пользовательской информацией. Stackdriver Logging shows a error with custom information.

0 голосов
/ 02 ноября 2019

Когда я работаю с ошибками, я обычно использую объектную структуру, которая дает мне всю необходимую информацию. Примерно так:

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


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

Надеюсь, это поможет

...