例外とFunctionInvocationフィルタを使用してメッセージを引き起こしたメッセージを追跡するためのハックの方法があります。
public static class QueueFunction
{
[FunctionName("QueueFunction")]
[TrackFailedMessages]
public static void Run([QueueTrigger("myqueue")]string message)
{
throw new Exception("OMG");
}
}
public class TrackFailedMessages : FunctionInvocationFilterAttribute
{
private static readonly ConcurrentDictionary<Guid, object> QueueParamters = new ConcurrentDictionary<Guid, object>();
public override Task OnExecutingAsync(FunctionExecutingContext executingContext, CancellationToken cancellationToken)
{
if (executingContext.Arguments.TryGetValue("message", out var data))
{
QueueParamters.AddOrUpdate(executingContext.FunctionInstanceId, data, (id, obj) => data);
}
return Task.CompletedTask;
}
public override Task OnExecutedAsync(FunctionExecutedContext executedContext, CancellationToken cancellationToken)
{
if (executedContext.FunctionResult.Exception != null &&
QueueParamters.TryGetValue(executedContext.FunctionInstanceId, out var message))
{
executedContext.Logger.LogCritical(
"The message {message} caused the exception {exception}",
message,
executedContext.FunctionResult.Exception.ToString());
}
QueueParamters.TryRemove(executedContext.FunctionInstanceId, out var _);
return Task.CompletedTask;
}
}
関数が呼び出されると、OnExecutinAsyncが呼び出されます。 executionContextを使用すると、関数のパラメータにアクセスできます。 QueueTriggerパラメータを検索し、その値を辞書に格納することができます。ここで、FunctionInstanceIdはキーです。 FunctionInstanceIdはすべての呼び出しの一意のIDです。これは表のストレージをキャッチした場合
OnExecutedでは、関数を上げているかどうかを確認し、例外や辞書からのメッセージを取得することができ、その後、どこか別の場所に保管し
私はわからない(データベースは、など、ログ)例外...
私はServiceBus Queueでtry/catchとcatchでコードをラップすることでこれを処理しましたが、スタックトレースを取得してメッセージを自分自身で明示的にデッドレターし、メッセージとしてスタックトレースをインクルードします。私はあなたが明示的に毒キューにストレージ・キュー・メッセージを入れることができるかどうかはわかりません。 –
私はそのアプローチを試みましたが、関数が返された後に発生するため、テーブルストレージの例外をキャッチできません。私はそれが記憶の問題のために働くと思います。 – Dexterity