Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기

오류 보고

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

자동으로 오류 보고

아래와 같이 Cloud 함수에서 Error Reporting 으로 오류를 내보낼 수 있습니다.

노드.js

// These WILL be reported to Error Reporting
throw new Error('I failed you'); // Will cause a cold start if not caught

// These WILL be reported to Error Reporting
console.error(new Error('I failed you')); // Logging an Error object
console.error('I failed you'); // Logging something other than an Error object
throw 1; // Throwing something other than an Error object
callback('I failed you');
res.status(500).send('I failed you');

더 세분화된 오류 보고를 원하면 오류 보고 클라이언트 라이브러리 를 사용할 수 있습니다.

보고된 오류는 GCP 콘솔의 오류 보고 에서 볼 수 있습니다. GCP 콘솔 의 기능 목록 에서 특정 기능을 선택하면 해당 기능에서 보고된 오류를 볼 수도 있습니다.

함수에서 생성된 포착되지 않은 예외는 오류 보고에 나타납니다. 일부 유형의 포착되지 않은 예외(예: 비동기식으로 발생한 예외)로 인해 향후 함수 호출 시 콜드 스타트 가 발생합니다. 이렇게 하면 함수를 실행하는 데 걸리는 시간이 늘어납니다.

수동으로 오류 보고

함수에서 Error Reporting 에 오류를 보고하려면 Cloud Logging API를 사용하세요.

종속성 가져오기

functions 디렉터리에서 Node.js용 Cloud Logging 클라이언트 라이브러리를 설치합니다.

npm install --save @google-cloud/logging

Cloud Logging 클라이언트 라이브러리를 가져오고 초기화합니다.

const Logging = require('@google-cloud/logging');

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

Cloud Logging으로 보내기

올바르게 구성된 로그 항목에는 MonitoredResource 개체와 ErrorEvent 개체가 필요합니다.

이 예제 reportError 함수는 오류 보고에 오류를 보고하는 데 필요한 최소 데이터를 보여줍니다.

function reportError(err, context = {}) {
  // This is the name of the log stream that will receive the log
  // entry. This name can be any valid log stream name, but must contain "err"
  // in order for the error to be picked up by Error Reporting.
  const logName = 'errors';
  const log = logging.log(logName);

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

  // 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();
    });
  });
}

reportError 함수를 사용하여 수동으로 오류를 보고할 수 있습니다.

exports.createStripePayment = functions.firestore
  .document('stripe_customers/{userId}/payments/{pushId}')
  .onCreate(async (snap, context) => {
    const { amount, currency, payment_method } = snap.data();
    try {
      // Look up the Stripe customer id.
      const customer = (await snap.ref.parent.parent.get()).data().customer_id;
      // Create a charge using the pushId as the idempotency key
      // to protect against double charges.
      const idempotencyKey = context.params.pushId;
      const payment = await stripe.paymentIntents.create(
        {
          amount,
          currency,
          customer,
          payment_method,
          off_session: false,
          confirm: true,
          confirmation_method: 'manual',
        },
        { idempotencyKey }
      );
      // If the result is successful, write it back to the database.
      await snap.ref.set(payment);
    } catch (error) {
      // We want to capture errors and render them in a user-friendly way, while
      // still logging an exception to Error Reporting.
      functions.logger.log(error);
      await snap.ref.set({ error: userFacingMessage(error) }, { merge: true });
      await reportError(error, { user: context.params.userId });
    }
  });

ErrorContext 매개 변수 를 통해 사용자 세부 정보를 전달할 수 있습니다. 오류 보고 UI는 이러한 세부정보를 표시하고 이를 사용하여 영향을 받는 사용자 수를 계산합니다.

ErrorContext 는 HTTP 요청에 대한 정보를 전달할 수도 있습니다.

export.httpError = functions.https.onRequest((request, response) => {
  const error = new Error('Test error');
  const httpRequest = {
    method: request.method,
    url: request.originalUrl,
    userAgent: request.get('user-agent'),
    referrer: '',
    remoteIp: request.ip
  };
  reportError(error, {httpRequest}).then(() => {
    response.end();
  });
});