Добавьте настраиваемую информацию в журнал ошибок Stackdriver в функциях Firebase.

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

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

Есть ли простой способ добавить информацию в журнал ошибок на 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 Reporting  Сведения об ошибке Stackdriver, страница 1  Страница сведений об ошибке Stackdriver 2




Ответы (3)


Самостоятельный ответ:

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

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

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

  1. Чтобы пользовательский журнал ошибок отображался на консоли GCP как обычный журнал ошибок, он должен включать серьезность, регион, выполнение_id, идентификатор трассировки. Если их нет, консоль GCP не показывает их в фильтре по умолчанию. Также нельзя группировать по тегу идентификатора выполнения.
  2. Execution_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 показывает ошибку с пользовательской информацией.

person astanet    schedule 10.11.2019
comment
Я выполнил эту вспомогательную функцию, но все еще не могу получить свой собственный журнал в стеке. Когда я запускаю API, который явно выдает ошибку, журнал DEBUG регистрируется, но без каких-либо дополнительных данных. В логах тоже нет ключа в виде jsonPayload. - person Tech de Enigma; 22.04.2020
comment
Проверено также с помощью документации google-logging, но все же мои пользовательские журналы не регистрируются - person Tech de Enigma; 23.04.2020

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

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


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

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

person ajorquera    schedule 02.11.2019
comment
Спасибо за отличные предложения. Я пробовал, но, к сожалению, Stackdriver не сгруппировал журналы по отдельной ошибке. Все ошибки были сгруппированы в одну группу. Добавлю свои попытки к вопросу. В любом случае спасибо за полезную информацию. - person astanet; 04.11.2019

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

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

person Yuri Grinshteyn    schedule 04.11.2019
comment
Спасибо, что сообщили мне официальную информацию. Однако нужно время, чтобы понять, как использовать пользовательское ведение журнала, поэтому я почувствовал, что это беспокоит. Таким образом, я искал легкий путь. Я также пробовал «@ google-cloud / error-reporting», но не смог найти хороший пример для этого случая и не смог его хорошо использовать. Вот почему я задал этот вопрос. Другого пути, кроме вашего предложения, быть не может. Я рад, что вас заинтересовал этот вопрос. Спасибо. - person astanet; 04.11.2019
comment
Спасибо, что снова мне рассказали! Может быть, нет простого пути. Я попробую. - person astanet; 09.11.2019