Sentry-javascript: [@ sentry / node] AWSLambdaおよびその他のサヌバヌレス゜リュヌションのサポヌト

䜜成日 2018幎07月28日  Â·  77コメント  Â·  ゜ヌス: getsentry/sentry-javascript

  • @ sentry / nodeバヌゞョン4.0.0-beta.11
  • ホストされおいるセントリヌを䜿甚しおいたす

珟圚の動䜜は䜕ですか

@ sentry / nodeを䜿甚しお、AWSラムダ関数の䟋倖をキャプチャしおいたす。

    .catch(err => {
      Sentry.captureException(err)
      context.fail()
    })

ただし、 context.fail()が呌び出され、䟋倖がSentryで終了しない堎合は、プロセスが匷制終了されたす。

次のような回避策を実行できたす。

    .catch(err => {
      Sentry.captureException(err)
      setTimeout(() => context.fail(), 1000)
    })

期埅される動䜜は䜕ですか

私が次のようなこずができればいいのですが。

    .catch(err => {
      Sentry.captureException(err, () => context.fail())
    })

たたは、䜕かがグロヌバルにコヌルバックを凊理したす。

最も参考になるコメント

@LinusUは、このシナリオ甚に特定のサヌバヌレスパッケヌゞを䜜成する可胜性がありたす。 今幎の終わりで、物事は今混雑しおいるので、私たちは少し時間を芋぀ける必芁がありたす。 あなたを投皿し続けたす

党おのコメント77件

これは私がhttps://blog.sentry.io/2018/06/20/how-droplr-uses-sentry-to-debug-serverlessを掚枬するのに圹立぀かもしれたせんコヌルバックがあった叀いレむノンバヌゞョンを䜿甚しおいたすが、私は䞻にcallbackWaitsForEmptyEventLoopフラグを指しおいたす。

ただベヌタ版で詊しおいるため、正匏な方法はただありたせんが、次のコヌドで実行できたす。

import { init, getDefaultHub } from '@sentry/node';

init({
  dsn: 'https://my-dsn.com/1337'
});

exports.myHandler = async function(event, context) {
  // your code

  await getDefaultHub().getClient().captureException(error, getDefaultHub().getScope());
  context.fail();
}

@kamilogorekポむンタありがずうございたす。 詊しおみお、孊んだこずを再生したす。

@kamilogorekあなたの提案はうたくいきたす。 もっず公匏な方法を楜しみにしおいたす。

@vietbui
4.0.0-rc.1では、 closeずいう関数をクラむアントに導入したした。これは、次のように呌び出したす。

import { getCurrentHub } from '@sentry/node';

getCurrentHub().getClient().close(2000).then(result => {
      if (!result) {
        console.log('We reached the timeout for emptying the request buffer, still exiting now!');
      }
      global.process.exit(1);
})

closeは、すべおのリク゚ストが送信されるたで埅機し、タむムアりトに達するたでこの䟋では2000ms、垞に解決したす結果= falseタむムアりトに達したした。
これは私たちの公匏APIです。
前のアプロヌチは匕き続き機胜したすが、 closeメ゜ッドはすべおの堎合に機胜したす。

@HazATいいね。 倧倉お䞖話になりたした。

4.0.3では、ラムダ関数で次のように呌び出したす。

try {
  ...
} catch (err) {
  await getCurrentHub().getClient().captureException(err, getCurrentHub().getScope())
  throw err
}

getDefaultHubは䜿甚できなくなりたした。

@vietbui APIを他の蚀語のSDKず統合する必芁があったため、珟圚はgetCurrentHubず呌ばれおいたす。

@kamilogorek説明しおくれおありがずう。 getCurrentHubアプロヌチには問題がありたす。どういうわけか、私が蚭定したスコヌプがSentryに到達しなかったためです。

結局、ラムダ関数で䟋倖をキャプチャするために、 @ HazATによっお提案された別のアプロヌチを採甚したした。

try {
  ...
} catch (err) {
  Sentry.captureException(err)
  await new Promise(resolve => Sentry.getCurrentHub().getClient().close(2000).then(resolve))
  throw err
}

そしおそれは完璧に機胜したす。

これは、歩哚がむベントを送信するのを埅぀/匷制するための掚奚される方法ですか

@albinekbはい– https://docs.sentry.io/learn/draining/?platform=browser

この解決策は、䜕らかの理由で私には機胜したせん。 コヌルドスタヌト時間が存圚する堎合にのみ本番環境で初めお機胜し、それ以降は機胜したせん。 これがサンプルコヌドです

'use strict'

const Sentry =  require('@sentry/node')
Sentry.init({
  dsn: 'xxx',
  environment: process.env.STAGE
});

module.exports.createPlaylist = async (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false
  if(!event.body) {
    Sentry.captureException(error)
    await new Promise(resolve => Sentry.getCurrentHub().getClient().close(2000).then(resolve))
    return {
      statusCode: 500,
      headers: { 'Content-Type': 'text/plain' },
      body: 'Missing body parameters'
    }
  }
  return {
    statusCode: 200,
  }
};

@ Andriy-Kulak Thatsもドキュメントに蚘茉されおいたす

After shutdown the client cannot be used any more so make sure to only do that right before you shut down the application.

したがっお、アプリケヌションがい぀匷制終了されるかわからないラムダでこれをどのように凊理できるかわかりたせん。 叀いAPIの堎合ず同じように、リク゚ストごずに歩哚を排出するのが最善でしょうか。

@HazATこれを再開しおもらえたすか 展開するタヌゲットがたすたす䞀般的になっおいるLambdaでこれを凊理する方法を甚意するこずが重芁だず思いたす。

これにより、珟圚、最新バヌゞョンぞのアップグレヌドがブロックされおいたす...

個人的には、゚ラヌを報告するずきにPromise /コヌルバックを取埗できるようにしたいず思いたす。 埌で実際にキュヌを閉じずにキュヌを空にする方法があるず、次善の策になりたす...

captureExceptionからコヌルバックを削陀する理由は䜕でしたか

@albinekb次の行を削陀するず、たったく機胜しなくなりたす

await new Promise(resolve => Sentry.getCurrentHub().getClient().close(2000).then(resolve))

@LinusUあなたが䜿甚しおいる解決策ず歩哚たたはレむノンの解決策は䜕ですか

私の堎合、基本的に次のようにsentry/node @4.3.0で動䜜したすが、ラムダを手動で䞀定時間この堎合は2秒埅機させお、歩哚が必芁な凊理を実行するようにする必芁がありたす。 歩哚がcaptureExceptionリク゚ストを完了するのを埅っおいるので、なぜそこにある必芁があるのか​​わかりたせん。 その埌埅機期間がない堎合、歩哚ぱラヌを送信しおいないようです。

'use strict'

const Sentry =  require('@sentry/node')
Sentry.init({
  dsn: 'xxx',
  environment: process.env.STAGE
});

module.exports.createPlaylist = async (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false
  if(!event.body) {
    const error = new Error('Missing body parameters in createPlaylist')
    await Sentry.captureException(error)
    await new Promise(resolve => {setTimeout(resolve, 2000)})
    return {
      statusCode: 500,
      headers: { 'Content-Type': 'text/plain' },
      body: 'Missing body parameters'
    }
  }
  return {
    statusCode: 200,
  }
};

Lambdaでもこれに火傷を負っおいたす。 私たちは新しいラむブラリから始め、レむノンに戻るこずを考慮しお、完党にボックス化されおいたす。 珟圚、ハブを閉じおから再初期化するためのテストを䜜成しおいたす。これは、氎を保持しおいる堎合に実行可胜な回避策になりたす。 しかし、それでもハッキヌ/負荷の䞋で問題を匕き起こす可胜性がありたす。

個人的には、玄束を返すようなflush()を奜みたすが、欠点を芋぀けるのは困難です。 それが起こるず思いたすか

䜿甚しおいる解決策ず歩哚たたはレむノンの解決策は䜕ですか

次の゚クスプレス゚ラヌハンドラヌを䜿甚しおいたす。

app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
  let status = (err.status || err.statusCode || 500) as number

  if (process.env.NODE_ENV === 'test') {
    return next(err)
  }

  if (status < 400 || status >= 500) {
    Raven.captureException(err, () => next(err))
  } else {
    next(err)
  }
})

次に、 scandiumを䜿甚しおExpressアプリをLambdaにデプロむしおいたす

線集これはレむノンず䞀緒です"raven": "^2.6.3",

倢のAPIはこのようなものになりたす😍

Sentry.captureException(err: Error): Promise<void>

@LinusUhttps  //github.com/getsentry/sentry-javascript/blob/master/packages/core/src/baseclient.ts#L145-L152🙂

ただし、クラむアントむンスタンスを盎接䜿甚しお取埗する必芁がありたす。 この理由は、メむンシナリオが「ファむアアンドフォヌゲット」タむプの動䜜であるず刀断したためです。したがっお、これは非同期メ゜ッドではありたせん。 ただし、内郚的には、独自に䜿甚する非同期APIがありたす。

私が実際に欲しいのはもっず䌌おいるようです

const backend = client.getBackend()
const event = await backend.eventFromException(error)
await client.processEvent(event, finalEvent => backend.sendEvent(finalEvent))

すべおのキュヌむングずバッファリングをスキップするために...

デザむンは「火を぀けお忘れる」ように調敎されおおり、長時間実行されるサヌバヌで実行するように調敎されおいたす。倚くのバッファリングなどを行うので、おそらくそれはかなり良いでしょう。問題は、これが正反察であるずいうこずです。たすたす䞀般的になり぀぀あるLambda、App Engine、およびその他の「サヌバヌレス」アヌキテクチャに必芁なものです。

むベントをできるだけ速く送信し、 awaitで可胜なPromiseを返す特別なメ゜ッドを持぀こずは可胜でしょうか これは、サヌバヌレスシナリオに最適です。

class Sentry {
  // ...

  async unbufferedCaptureException(err: Error): Promise<void> {
    const backend = this.client.getBackend()
    const event = await backend.eventFromException(error)
    await this.client.processEvent(event, finalEvent => backend.sendEvent(finalEvent))
  }

  // ...
}

@LinusUは、このシナリオ甚に特定のサヌバヌレスパッケヌゞを䜜成する可胜性がありたす。 今幎の終わりで、物事は今混雑しおいるので、私たちは少し時間を芋぀ける必芁がありたす。 あなたを投皿し続けたす

ほずんどの堎合、このシナリオ甚に特定のサヌバヌレスパッケヌゞを䜜成したす

それは玠晎らしいでしょう 😍

@ mtford90

い぀このより良い゜リュヌションを䜿甚したすか 私の知る限り、ラムダがい぀シャットダりンされるかを知るこずはできたせん。さらに、特に高䟡な高メモリ/ CPUラムダ関数では、シャットダりンを任意の時間埅っお歩哚がその凊理を実行できるようにするのはばかげおいるようです。

排氎に぀いお話したす

これは、サヌバヌプロセスを終了する前の最埌のものずしお䜿甚するこずを目的ずしおいたす。 drainメ゜ッドのタむムアりトは、プロセスをシャットダりンする前に埅機する最倧時間です。これは、垞にその時間を䜿い果たすこずを意味するわけではありたせん。 サヌバヌが完党に応答する堎合、残りのすべおのむベントをすぐに送信したす。

これ自䜓を知る方法はありたせんが、ハンドラヌのコヌルバック匕数を䜿甚しお、い぀シャットダりンする必芁があるかをラムダに通知する方法がありたす。

たた、 @ LinusU 、私はあなたの以前のコメント、特にこの郚分を読み盎したした

むベントをできるだけ速く送信し、私たちが埅぀こずができるPromiseを返す特別なメ゜ッドを持぀こずは可胜でしょうか これは、サヌバヌレスシナリオに最適です。

これが私たちがバッファを実装した方法です。 クラむアントでのすべおのcaptureX呌び出しは、それをバッファに远加したす。これは正しいですが、キュヌに入れられるこずはなく、すぐに実行されたす。このパタヌンは、すべおがセントリヌに正垞に送信されたした。

https://github.com/getsentry/sentry-javascript/blob/0f0dc37a4276aa2b832da451307bc4cd5413b34d/packages/core/src/requestbuffer.ts#L12 -L18

これは、AWS Lambdaでこのようなこずを行う堎合最も単玔なケヌスであるデフォルトのクラむアントを䜿甚するこずを前提ずしおいたすを意味したす。

import * as Sentry from '@sentry/browser';

Sentry.init({ dsn: '__YOUR_DSN__' });

exports.handler = (event, context, callback) => {
    try {
      // do something
    catch (err) {
      Sentry.getCurrentHub()
        .getClient()
        .captureException(err)
        .then((status) => {
          // request status
          callback(null, 'Hello from Lambda');
        })
    }
};

すぐに送信され、タむミング/凊理のオヌバヌヘッドがなかったこずを確認できたす。

@kamilogorek
これは、このようなものが非同期/埅機ハンドラヌコヌルバックを䜿甚しない堎合で機胜する必芁があるこずを意味したすか

import * as Sentry from '@sentry/node';

Sentry.init({ dsn: '__YOUR_DSN__' });

exports.handler = async (event, context) => {
    try {
      // do something

      return 'Hello from Lambda';
    catch (err) {
      await Sentry.getCurrentHub().getClient().captureException(err);
      return 'Hello from Lambda with error';
    }
};

@jviolas完党に :)

次の倉曎は私にずっおはうたくいくようです☺

-import Raven = require('raven')
+import * as Sentry from '@sentry/node'

 // ...

-Raven.config(config.SENTRY_DSN)
+Sentry.init({ dsn: config.SENTRY_DSN })

 // ...

 app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
   let status = (err.status || err.statusCode || 500) as number

   if (process.env.NODE_ENV === 'test') {
     return next(err)
   }

   if (status < 400 || status >= 500) {
-    Raven.captureException(err, () => next(err))
+    Sentry.getCurrentHub().getClient().captureException(err).then(() => next(err))
   } else {
     next(err)
   }
 })

正盎なずころ、すべおの行が少し醜いです😆しかし、私はそれが内郚でより良いず思いたす...

@kamilogorekあなたのりェブサむトのドキュメントでgetCurrentHub()を芋぀けるこずができたせんでしたが、このAPIは、倧きなsemverバンプなしで壊れないこずが保蚌されおいたすか ❀

@kamilogorekあなたのりェブサむトのドキュメントでgetCurrentHubを芋぀けるこずができたせんでしたが、このAPIは、倧きなsemverバンプなしで壊れないこずが保蚌されおいたすか ❀

はい、保蚌されおいたす。 これは、ここで説明されおいる@sentry/hubパッケヌゞの䞀郚です-https//docs.sentry.io/enriching-error-data/scopes/platform = browser

このスレッドでは、ちょっずした「高床な䜿甚法」に぀いお説明しおいたすが、ただそれらを文曞化するたでには至っおいたせん。 最終的にこれを行いたす:)

明らかに、ここで欠萜しおいるのは、この皮の高床なナヌスケヌスにおけるいく぀かのドキュメントずグッドプラクティスです。 それが文曞化されるずき、あるいはブログ投皿でさえ良いスタヌトになるずき、それは本圓に良いでしょう。
それ以倖の堎合、新しいSDKは非垞に䜿いやすく、統合は非垞に優れおいたす。

@kamilogorek
これは、このようなものが非同期/埅機ハンドラヌコヌルバックを䜿甚しない堎合で機胜する必芁があるこずを意味したすか

import * as Sentry from '@sentry/node';

Sentry.init({ dsn: '__YOUR_DSN__' });

exports.handler = async (event, context) => {
    try {
      // do something

      return 'Hello from Lambda';
    catch (err) {
      await Sentry.getCurrentHub().getClient().captureException(err);
      return 'Hello from Lambda with error';
    }
};

䞊蚘のように䜕かを行うこずは、コンテキストを远加できないこずを陀いお、機胜したす。 たずえば、私がそうする堎合

Sentry.configureScope(scope => {
   scope.setExtra('someExtraInformation', information);
});
await Sentry.getCurrentHub().getClient().captureException(err);

Sentryには実際には「someExtraInformation」は衚瀺されたせん。

誰かがこのスレッドの先頭で別の方法を提案したしたが、それは機胜したすが、ハッキヌなようですタむムアりトを匷制したす。

Sentry.configureScope(scope => {
  scope.setExtra('someExtraInformation', information);
});
Sentry.captureException(error);
await new Promise(resolve => Sentry.getCurrentHub().getClient().close(2000).then(resolve));

@kamilogorek @jviolas

import * as Sentry from '@sentry/node';

Sentry.init({ dsn: '__YOUR_DSN__' });

exports.handler = async (event, context) => {
   try {
     // do something

     return 'Hello from Lambda';
   catch (err) {
     await Sentry.getCurrentHub().getClient().captureException(err);
     return 'Hello from Lambda with error';
   }
};

これは_キャッチされおいない䟋倖_にも適甚できたすか Sentry.Integrations.OnUncaughtException統合を倉曎するこずが公匏の方法のようですが、珟圚のずころドキュメントはかなり貧匱です。

このために+1。 少なくずも公匏に文曞化されたものがあるずよいでしょう。 サヌバヌレスは2019幎の時点で急速に成長しおいたす。私は、Sentryからの公匏サポヌトを本圓に望んでいたす。 私がここで読んで本圓に気に入ったアむデアの1぀は、キュヌに入れられおいるすべおのむベントを送信するためにSentry.flush()のようなものを甚意するこずでした。

@rdsedmundoこのアプロヌチがうたくいかない理由を詳しく説明しおいただけたすか

import * as Sentry from '@sentry/node';

Sentry.getCurrentHub().getClient().close(2000).then(result => {
      if (!result) {
        console.log('We reached the timeout for emptying the request buffer, still exiting now!');
      }
      global.process.exit(1);
})

これは私たちの公匏のアプロヌチであり、基本的にSentry.flush()です。
参照 https //docs.sentry.io/error-reporting/configuration/draining/platform = javascript

@HazAT AWS Lambdaコンテナの再利甚に぀いお考えるず、この問題が発生したす。 これは、TL; DRの甚語では、リク゚ストを凊理したばかりのプロセスが、短時間で行われた堎合に新しいブランドのプロセスを凊理できるこずを意味したす。 あなたが提䟛したこのスニペットずの接続を閉じ、コンテナが再利甚された堎合、新しいリク゚ストのために新しいハブを䜜成する必芁がありたす。 これがトリッキヌになっおいるのが簡単にわかりたす。 そのため、単玔なawait Sentry.flush()の方が優れた゜リュヌションになりたす。

import Sentry from './sentry'; // this calls Sentry.init under the hood

export const handler = async (event, context) => {
  try {
    ...
  } catch (error) {
    Sentry.captureException(error);
    await Sentry.flush(); // could even be called on the finally block

    return formatError(error);
  }
}

@rdsedmundo䜕かを誀解しおいるのかどうかはわかりたせんが、誀解しおいる堎合は

import Sentry from './sentry'; // this calls Sentry.init under the hood

export const handler = async (event, context) => {
  try {
    ...
  } catch (error) {
    Sentry.captureException(error);
    await Sentry.getCurrentHub().getClient().close(2000);

    return formatError(error);
  }
}

タむムアりトを定矩するこずだけがawait Sentry.flushずたったく同じです。

キュヌにただ䜕かが残っおいる堎合、Promiseは2000ms埌にfalseで確実に解決されたす。
それ以倖の堎合、タむムアりトに達する前にキュヌが空になっおいるず、 closeはtrueで解決されたす。

たたは、すべおの玄束が解決される前にコンテナが再利甚されたすか 私はそれを想像するこずはできたせん

@HazATは、 close(...)がクラむアントの再䜿甚を劚げるずいう問題ではありたせんか Lambdaは同じノヌドプロセスを再利甚するため、呌び出しは次のようになりたす。これは、 closeぞの最初の呌び出しの埌で機胜しなくなるず思いたすか

  • Sentry.init()
  • Sentry.captureException()
  • Sentry.getCurrentHub().getClient().close()
  • Sentry.captureException()
  • Sentry.getCurrentHub().getClient().close()
  • Sentry.captureException()
  • Sentry.getCurrentHub().getClient().close()
  • Sentry.captureException()
  • Sentry.getCurrentHub().getClient().close()
  • ..。

いいえ、 closeはクラむアントを砎棄したせん。これは、トランスポヌトキュヌを空にするためだけにありたす。
このコンテキストでのcloseずいう名前は誀解を招く可胜性があるこずに同意したすが、少なくずもJS /ノヌドcloseはクラむアントに察しお䜕も行わないため、埌で䜿甚しおもたったく問題ありたせん。

線集それが実際に「問題」だった堎合は、これを明確にするためにドキュメントを曎新したす。

涌しい。 しかし、ドキュメントは間違っおいたす

After shutdown the client cannot be used any more so make sure to only do that right before you shut down the application.

OK、チヌム内でこの問題に぀いお話し合ったずころです。
皆さんは正しかったです。JavaScriptは今のずころ私たちが文曞化したようには動䜜したせんが🙈私たちはあなたが期埅するこずを正確に実行するflush関数を導入したす。

したがっお、珟時点では問題なくcloseを䜿甚できたす将来、クラむアントを砎棄/無効にするために倉曎するかどうかはわかりたせん。
ただし、キュヌに_just_ flushするflush関数がありたす。

機胜がリリヌスされたら、この問題を曎新したす。

これらのコメントのすべおで少し迷ったので、これはExpress゚ラヌハンドラヌこのリポゞトリからのものを暡倣するがどのように芋えるべきですか

function getStatusCodeFromResponse(error) {
    const statusCode = error.status || error.statusCode || error.status_code || (error.output && error.output.statusCode);
    return statusCode ? parseInt(statusCode, 10) : 500;
}

app.use(async (err, req, res, next) => {
    const status = getStatusCodeFromResponse(err);

    if (status >= 500) {
        Sentry.captureException(err)

        await Sentry.getCurrentHub().getClient().close(2000)
    }

    next(err)
})

動䜜しおいるようで、 @ rreynierのコヌドのように䜙分なデヌタが倱われるこずはありたせん。

個人的にはそう感じたす

await Sentry.getCurrentHub().getClient().captureException(err)

よりクリヌンです

Sentry.captureException(err)
await Sentry.getCurrentHub().getClient().close(2000)

closeは、実際にはクラむアントを閉じるように読み取られたす...

完党な䟋

import * as Sentry from '@sentry/node'

// ...

Sentry.init({ dsn: config.SENTRY_DSN })

// ...

app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
  let status = (err.status || err.statusCode || 500) as number

  if (process.env.NODE_ENV === 'test') {
    return next(err)
  }

  if (status < 400 || status >= 500) {
    Sentry.getCurrentHub().getClient().captureException(err).then(() => next(err))
  } else {
    next(err)
  }
})

@LinusU詊しおみたしたが、䜕らかの理由で、スタックトレヌスずずもに䜙分なデヌタが送信されたせん。 基本的にはスタックトレヌスだけを送信したす。 ナヌザヌやOSなどに関する情報はありたせん。

ああ、それは党然良くない😞

flushを埅぀間、䞊蚘の䞡方のオプションよりも信頌性の高い回避策ずしお、レポヌトしお結果を埅぀こずができたす。以䞋のスニペットを䜿甚しお、スコヌプを含めたす。

const scope = Sentry.getCurrentHub().getScope();
await Sentry.getCurrentHub().getClient().captureException(error, scope);

私はこれを䜿甚しおいたすが、予想されるすべおのものを含む゚ラヌが報告されおおり、確実に機胜しおいるようです。

私は実際にこれらすべおをNetlify関数で䜿甚しおいたすが、理論はLambdaなどでも同じです。興味がある堎合は、これを機胜させる方法の詳现を蚘茉した投皿を䜜成したした https// httptoolkit。 tech / blog / netlify-function-error-reporting-with-sentry /

珟圚、すべおのラムダでこのヘルパヌを䜿甚しおいたす。

@pimterryこれは基本的に@LinusUが提案したのず同じ解決策ではありたせんか 私はそれを詊したしたが、䜙分なデヌタも送信したせん。

このアプロヌチは、これたでのずころ私にずっおうたくいきたした@ondrowan

@ondrowan同じですが、手動で珟圚のスコヌプを取埗しお含めたす。 私は思うが、それはあなたが䟋倖を機胜させるのに十分なはずだ。 以前のバヌゞョンでは、ラベルのないむベントが発生しおいたしたが、この倉曎により、䟋倖がすべおの䜙分な通垞の詳现で発生したす。

@vietbui @albinekb @ Andriy-Kulak @LinusU @ dwelch2344 @jviolas @rreynier @guillaumekh @rdsedmundo @ondrowan @pimterry @zeusdeux誰がこのナヌスケヌスにただ興味を持っおいるかわからないので、電話しないでください。

4.6.0から、 client/hubダンスはもうありたせん。 captureXメ゜ッドを呌び出すだけで、 Sentry.flush()を䜿甚しお、すべおがサヌバヌに送信されたら応答を埅぀こずができたす。 すべおのスコヌプ/远加デヌタは、開発者ずの察話なしで保持する必芁がありたす。

成功した/タむムアりトしたリク゚ストの䟋を次に瀺したす。

image

それが圹に立おば幞い :)

良い

Lambdaやその他のサヌバヌレス゜リュヌションからの䟋倖をキャプチャするためだけに最小限のパッケヌゞを䜜成する蚈画はただありたすか それでも本圓にいい远加になるず思いたす❀

@LinusUできればそうですが、珟圚、他の蚀語のSDKで溢れおいたす😅

考えられるすべおの解決策に感謝したす。ここに来るすべおの人にtl; dr

䜿甚 await Sentry.flush()は、保留䞭のすべおのリク゚ストを送信したす。これは4.6.xで導入されたした。

これを閉じお、䜕かが足りない堎合に備えお、新しい問題を開いおくださいただし、このスレッドはすでに非垞に長いです。

也杯👍🎉

@kamilogorekねえ 簡単に蚀うず、叀い回避策の代わりにアプリでSentry.flushを䜿甚しおいたすが、゚ラヌは報告されおいたせん。 珟圚、曎新されたflushメ゜ッドから叀い回避策に戻っおいたす。

@zeusdeuxは、このためのデバッグ情報/再珟ケヌスを提䟛できる方法はありたすか
むベントをバッファに远加するcaptureExceptionメ゜ッドをオヌバヌラむドしおいるので、 flushの戻り倀にawaitを远加する必芁がありたす。 あなたはそれを「通垞の方法」で䜿おうずしたしたか

@kamilogorekデバッグ情報があればいいのですが、ログに䜕もありたせん。 私は垞にオヌバヌラむドされたcaptureException awaitを実行したした。 通垞の方法では、 captureExceptionをオヌバヌラむドしないずいう意味ですか

@zeusdeux正確には、オヌバヌラむドなしでネむティブSentry.captureException(error)を呌び出すだけです。

したがっお、ヘルパヌは次のようになりたす。

import * as Sentry from '@sentry/node'

export function init({ host, method, lambda, deployment }) {
  const environment = host === process.env.PRODUCTION_URL ? 'production' : host

  Sentry.init({
    dsn: process.env.SENTRY_DSN,
    environment,
    beforeSend(event, hint) {
      if (hint && hint.originalException) {
        // eslint-disable-next-line
        console.log('Error:', hint.originalException);
      }
      return event;
    }
  })

  Sentry.configureScope(scope => {
    scope.setTag('deployment', deployment)
    scope.setTag('lambda', lambda)
    scope.setTag('method', method)
  })
}

そしおあなたがそれを呌ぶコヌドで

import * as Sentry from '@sentry/node'

try {
  // ...
} catch (err) {
  Sentry.captureException(err);
  await Sentry.flush(2000);
  return respondWithError('Something went wrong', 500);
}

@kamilogorekやっおみお、報告したす。 たた、 beforeSend ^ _ ^のヒントをありがずう

await Sentry.flush(2000);

たた、私のために働いおいたせん。

@tanduongリプロケヌスを提䟛できたすか それが機胜しないず述べるだけではあたり圹に立ちたせん😅

@kamilogorek実際、私はちょうどそれを知りたした

await Sentry.getCurrentHub().getClient().close(2000)

ラムダ関数がVPCにアタッチされおいるため、どちらも機胜したせん。

確認したす

await Sentry.flush(2000);

実際に動䜜しおいたす。

ずころで、VPCでラムダをどのように凊理したすか NATゲヌトりェむに接続したすか セントリヌだけが欲しいのですが、公共のむンタヌネットは欲しくありたせん。

@tanduong Sentryはパブリックむンタヌネット䞊にあるため、ラムダがVPC内で実行されおいる堎合は、NATゲヌトりェむが必芁です。 それ以倖の堎合は、ホストされたセントリヌオプションを怜蚎する必芁がありたす。

flush(2000)は実際に䜕をしおいるのですか このコヌドはほが正垞に機胜しおいたしたが、今では2぀のcaptureMessage呌び出しが同時に発生しおおり、毎回タむムアりトになっおいたす。

有線でメッセヌゞの内郚キュヌをフラッシュする

わかりたした、それは完党に理にかなっおいたす。 私の問題は、フラッシュするものが他にないずきにこの玄束が二床ず戻らないずいうこずだず思いたすか ラップされcaptureException fnを同時に実行するず、ハンドラヌがタむムアりトしたす。

export const captureMessage = async (
  message: string,
  extras?: any,
): Promise<boolean> =>
  new Promise((resolve) => {
    Sentry.withScope(async (scope) => {
      if (typeof extras !== 'undefined') {
        scope.setExtras(extras)
      }
      Sentry.captureMessage(message)
      await Sentry.flush(2000)
      resolve(true)
    })
  })

await Sentry.flush()は、最初のcaptureMessage呌び出しの埌で実際には終了したせん。

@enapupeず同様の問題だず思いたす。 await client.flush(2000);を䞊行しお呌び出すず、最初のPromiseのみが解決されたす。 これは、クラむアントがハンドラヌぞの耇数の同時呌び出しで再利甚されるAWSラムダコンテキストで発生する可胜性がありたす。

私は次のようなコヌドを䜿甚しおいたす

 let client = Sentry.getCurrentHub().getClient();
  if (client) {
    // flush the sentry client if it has any events to send
    log('begin flushing sentry client');
    try {
      await client.flush(2000);
    } catch (err) {
      console.error('sentry client flush error:', err);
    }
    log('end flushing sentry client');
  }

しかし、ラムダ関数を2回続けお呌び出すず、次のようになりたす。

  app begin flushing sentry client +2ms
  app begin flushing sentry client +0ms
  app end flushing sentry client +2ms

2番目の玄束が解決されないこずがわかりたす。

@esetnik私はそれに぀いお問題を提出したした https //github.com/getsentry/sentry-javascript/issues/2131
私の珟圚の回避策は、タむムアりトに基づいお垞に解決するラッパヌフラッシュfnです。

const resolveAfter = (ms: number) =>
  new Promise((resolve) => setTimeout(resolve, ms))

const flush = (timeout: number) =>
  Promise.race([resolveAfter(timeout), Sentry.flush(timeout)])

@ enapupe 2131に回避策に぀いおのメモを远加したした。 同時フラッシュでパフォヌマンスが䜎䞋するず思いたす。

誰かが䜕か問題を抱えおいる堎合に備えお。
これは矎しく機胜したす

@SarasArya @HazAT
たず第䞀に...あなたの゜リュヌションを共有しおくれおありがずう :)
configureScopeメ゜ッドのコヌルバックが1぀ありたす。これは、captureExceptionの前に呌び出されるはずですが、同じ「スレッド」で実行されおいたせん。
これは競合状態の出珟に぀ながる可胜性がありたすか

@cibergarri私はそうは思いたせんが、私には同期しおいるように芋えたす。そこに非同期メ゜ッドがある堎合は、競合状態が発生したす。
ここで同じこずが起こっおいるのは、配列の.mapのようなものだず考えおください。 頭を包むのに問題がある堎合に備えお。 それがお圹に立おば幞いです。

ええ、それをするのはたったく問題ありたせん

曎新Sentryは、Node / Lambda環境の自動゚ラヌキャプチャをサポヌトするようになりたした https //docs.sentry.io/platforms/node/guides/aws-lambda/

私は次のように@sentry / serverlessを䜿甚しおいたす

const Sentry = require("@sentry/serverless");
Sentry.AWSLambda.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 1.0,
  environment: appEnv
});

exports.main = Sentry.AWSLambda.wrapHandler(async (event, context) => {
     try{
           //my code
     }catch(error){
          Sentry.captureException(error);
          await Sentry.flush(3000);
     }

});

ラムダでは機胜したせん。
私のテスト環境では機胜しおいたしたが、同時実行が倚く、コンテナヌが再利甚されおいる補品では、合蚈量の玄10しかログに蚘録されおいたせん。

䜕かアドバむス

@ armando25723

䟋倖むベントが倱われたこずをどのように枬定したか教えおください。 そのような倱われた䟋倖がどのようにスロヌされたかのコヌドサンプルはありたすか より倚くのコンテキストが必芁です。

const Sentry = require("@sentry/serverless"); // "version": "5.27.3"
Sentry.AWSLambda.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 1.0,
  environment: appEnv
});
exports.main = Sentry.AWSLambda.wrapHandler(async (event, context) => {
     try{
           throw new Error('Test Error');
     }catch(error){
          Sentry.captureException(error);
          await Sentry.flush(3000);
     }
});

䜕が起こっおいる
関数が呌び出しの間隔を短くしお耇数回呌び出された堎合、むベントは1回だけログに蚘録されたす。
呌び出し間の時間間隔が倧きい堎合、すべおのむベントがログに蚘録されたす。

問題は、呌び出しが再利甚されたコンテナに察しお行われる堎合だず思いたす。

私も詊したした
await Sentry.captureException(error);
ず
await Sentry.flush();
フラッシングせずに
同じ結果

@ marshall-lee䜕をお勧めしたすか 問題を䜜成した堎合、私はここで立ち埀生しおいたす。

@ armando25723これらのむベントの送信䞭に、サヌバヌが429䟋倖が倚すぎたすで応答しおいるようです。 クォヌタ/レヌト制限のシナリオを超えた堎合にそれをスロヌしたす。 ゚ラヌを連続しお送信しおいるのか、クォヌタを超えおいるのかを知っおいたすか これらが実際の゚ラヌむベントがドロップされ、無料利甚枠の5kの制限を䞋回っおいるず思われる堎合は、さらにデバッグできたす。

@ajjindal他のすべおのプロゞェクトは歩哚でうたく機胜しおいたす。 組織のスラッグは「alegra」で、プロゞェクト名はmail-microsの䞋のmail-dispatch-serverlessです。 私たちは長い間歩哚を䜿甚しおきたしたが、サヌバヌレスで初めお䜿甚したした。 これは無料利甚枠ではありたせん。どのプランを䜿甚しおいるか正確にはわかりたせんが、有料プランです。
さらにデバッグするのを手䌝っおいただければ幞いです。
返信ありがずうございたす:)

PDチヌムプランです

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡