Open andre-ss6 opened 2 years ago
Actually I think there's a [better?] alternative:
public async IAsyncEnumerable<T> TraceAsync<T>(Func<IAsyncEnumerable<T>> func)
{
var enumerable = _tracer.Trace(func);
await using var enumerator = enumerable.GetAsyncEnumerator();
while (await _tracer.TraceAsync(() => enumerator.MoveNextAsync().AsTask()))
{
yield return enumerator.Current;
}
}
This will, though, generate multiple requests to whatever this tracer has been configured for. I don't know if there is a better way though, unless Dynatrace had support specifically for something like streaming.
This alternative also has an advantage over the one I presented on the OP in that this one will include the time the caller takes to process each of the items.
There is one possible disadvantage, though, in that - I'm not really sure, but I think I've seen somewhere that it's not recommended to use the IAsyncEnumeratorawait foreach
. But I'm not sure.
The current
ITrace
API hasTrace(Func<T> func)
andTraceAsync(Func<Task<T>> func)
, but none of these two can trace anIAsyncEnumerable
call. It would be possible to do it with the now-obsoleteStartAsync
method, eg.:Though I'm not even sure if this would be the best implementation, since it would also take into consideration the time the caller took to do whatever computation with the streamed items.
The current alternative is to just
_tracer.Trace(MethodThatReturnsIAsyncEnumerable)
, but this also has its drawbacks, namely that it will only trace the call that starts the streaming, but will not track the streaming itself. For example, if an error occurs while streaming from the database, the tracer will not catch that.