Зарегистрируйте jsonPayload в облачных функциях Firebase.

TL;DR;

Кто-нибудь знает, можно ли использовать console.log в функции Firebase / Google Cloud для записи записей в драйвер стека с помощью свойства jsonPayload, чтобы мои журналы были доступны для поиска (в настоящее время все, что я передаю в console.log, преобразуется в textPayload).


У меня есть многомодульный проект с некоторым кодом, работающим в Firebase Cloud Functions, а некоторым - в других средах, таких как Google Compute Engine. Немного упрощая, у меня, по сути, есть «основной» модуль, а затем я развертываю модуль «облачных функций» в облачных функциях, «бэкэнд-сервис» в GCE, которые все зависят от «ядра» и т. Д.

Я использую bunyan для ведения журнала во всем моем «основном» модуле, и при развертывании в GCE регистратор настраивается с использованием «@ google-cloud / logging-bunyan», поэтому мои журналы идут в драйвер стека.

Кроме того: использование этой конфигурации в Google Cloud Functions вызывает проблемы с Error: Endpoint read failed, которые, я думаю, связаны с тем, что функции не перестают работать и пытаются повторно использовать неработающие соединения, но я не уверен на 100%, какова настоящая причина.

Итак, теперь я пытаюсь войти, используя console.log(arg), где arg - это объект, а не строка. Я хочу, чтобы этот объект отображался в драйвере стека под jsonPayload, но он был преобразован в строку и помещен в поле textPayload.


person dan.jones    schedule 09.03.2018    source источник
comment
Вы прошли через это? cloud.google.com/logging/docs/setup/nodejs   -  person Doug Stevenson    schedule 09.03.2018
comment
Да, именно это имеет в виду мой в сторону: .... Я мог бы попытаться отладить, почему происходит Error: Endpoint read failed, но это, вероятно, займет столько же времени, сколько и следование их документации по использованию console.log, как описано здесь cloud.google.com/functions/docs/monitoring/logging   -  person dan.jones    schedule 09.03.2018
comment
Кажется, console.log (arg) не поддерживает JsonPayload. Вам следует придерживаться Bunyan и отладить ошибку.   -  person Kenworth    schedule 15.03.2018


Ответы (2)


Мне потребовалось некоторое время, но я наконец наткнулся на этот пример в репозитории примеров функций firebase. В итоге я остановился на примерно таком:

const Logging = require('@google-cloud/logging');
const logging = new Logging();
const log = logging.log('my-func-logger');
const logMetadata = {
  resource: {
    type: 'cloud_function',
    labels: {
      function_name: process.env.FUNCTION_NAME ,
      project: process.env.GCLOUD_PROJECT,
      region: process.env.FUNCTION_REGION
    },
  },
};
const logData = { id: 1, score: 100 };
const entry = log.entry(logMetaData, logData);
log.write(entry)

Вы можете добавить строковое значение свойства severity к logMetaData (например, «ИНФОРМАЦИЯ» или «ОШИБКА»). Вот список возможных значений.


Обновление для доступных env vars узла 10. Кажется, это помогает:

labels: {
  function_name: process.env.FUNCTION_TARGET,
  project: process.env.GCP_PROJECT,
  region: JSON.parse(process.env.FIREBASE_CONFIG).locationId
}

ОБНОВЛЕНИЕ: похоже, что для среды выполнения Node 10 они хотят, чтобы вы явно установите значения env во время развертывания. Я предполагаю, что был установлен льготный период, потому что мои развернутые функции все еще работают.

person wtk    schedule 25.05.2018
comment
Это тот путь, который я выбрал, я также использую GKE, а kubernetes собирает журналы из stdout как textPayload и надеялся, что мне удастся использовать console.log и мне не придется иметь дело с фреймворками ведения журналов. Но, как вы также поняли, единственный способ получить jsonPayload - это использовать библиотеку ведения журналов. - person dan.jones; 29.05.2018
comment
Отличный ответ, спасибо. Теперь все, что мне остается, - это добавить labels['execution_id'] туда (то же самое, что вы получили бы, если бы использовали console.log в Firebase). - person opyate; 14.06.2018
comment
PS Похоже, что @google-cloud/logging-winston (и, возможно, альтернатива bunyan) автоматически добавляет ваш logMetadata. Тем не менее, execution_id ускользает от меня. Вероятно, мне придется выполнить трассировку самостоятельно с помощью github.com / googleapis / - person opyate; 14.06.2018
comment
Сохраняете ли вы свой экземпляр журнала в глобальном контексте? Или вы создаете новый при каждом запросе? Любопытно, были ли у вас проблемы с мертвыми соединениями, когда облачная функция запускает дросселирование процессора, когда не используется. - person codyzu; 06.12.2018
comment
Новый экземпляр по каждому запросу. Я считаю, что уже загруженную облачную функцию можно повторно использовать, поэтому необходимо убедиться, что каждый вызов имеет свой собственный экземпляр журнала. - person wtk; 06.12.2018
comment
execution_id доступен в контексте, переданном фоновым функциям (event.context.eventId в среде выполнения Node 6: cloud.google.com/functions/docs/writing/) - person Andrew Haines; 13.03.2019
comment
@AndrewHaines eventId из контекста выглядит как UUID, тогда как execution_id является целым числом. Охота за Execution_id продолжается ... - person opyate; 01.04.2019
comment
@опять какой прогресс? Та же проблема, я могу поймать eventId, но не след - person Elyx0; 29.09.2019
comment
@wtk обновление для узла 10 не будет работать, поскольку GCP_PROJECT и FIREBASE_CONFIG больше не доступны в process.env, подробнее об этом см. здесь: cloud.google.com/functions/docs/env-var - person foufrix; 27.05.2020
comment
спасибо @foufrix. похоже, что они должны быть явно установлены во время развертывания ... не знаю, почему мои вещи, работающие на узле 10, работают. - person wtk; 28.05.2020

Я столкнулся с той же проблемой, и, как указано в комментариях к ответу @ wtk, я хотел бы добавить репликацию всего поведения ведения журнала облачных функций по умолчанию, которое я смог найти в приведенном ниже фрагменте, включая execution_id.

По крайней мере, для использования Cloud Functions с параметром HTTP Trigger следующие журналы были созданы для меня правильно. Я не тестировал Firebase Cloud Functions

// global
const { Logging } = require("@google-cloud/logging");
const logging = new Logging();
const Log = logging.log("cloudfunctions.googleapis.com%2Fcloud-functions");
const LogMetadata = {
  severity: "INFO",
  type: "cloud_function",
  labels: {
    function_name: process.env.FUNCTION_NAME,
    project: process.env.GCLOUD_PROJECT,
    region: process.env.FUNCTION_REGION
  }
};

// per request
const data = { foo: "bar" };
const traceId = req.get("x-cloud-trace-context").split("/")[0];
const metadata = {
  ...LogMetadata,
  severity: 'INFO',
  trace: `projects/${process.env.GCLOUD_PROJECT}/traces/${traceId}`,
  labels: {
    execution_id: req.get("function-execution-id")
  }
};
Log.write(Log.entry(metadata, data));
person MakuraYami    schedule 11.04.2019
comment
Это все еще работает для вас? Так раздражает необходимость носить такой идентификатор трассировки - person Elyx0; 28.09.2019