Measuring Job execution time

Hi,

I’m toying with a few ideas on how to better instrument jobs at work, running with HangFire. While it’s pretty easy to “decorate” regular jobs with something that will measure and log the execution time(s):

public interface IJob<TJob>
        where TJob : class
    {
        Task InvokeAsync();
    }

public class JobExecutionTimeDecorator<T> : IJob<T>
        where T : class
    {
        private readonly ILogger<IJob<T>> logger;
        private readonly IJob<T> inner;

        public JobExecutionTimeDecorator(ILoggerFactory loggerFactory, IJob<T> inner)
        {
            this.logger = loggerFactory?.CreateLogger<IJob<T>>() ?? throw new ArgumentNullException(nameof(loggerFactory));
            this.inner = inner ?? throw new ArgumentNullException(nameof(inner));
        }

        public Task InvokeAsync()
        {
            var start = Stopwatch.GetTimestamp();
            var success = true;
            try
            {
                return inner.InvokeAsync();
            }
            catch (Exception ex)
            {
                success = false;
                logger.LogError(ex, "Unhandled exception in {Job}", typeof(T));
                throw;
            }
            finally
            {
                var stop = Stopwatch.GetTimestamp();
                var duration = ((stop - start) * 1000 / (double)Stopwatch.Frequency);
                logger.LogInformation("{Job} executed in {Elapsed} [ms]", typeof(T), duration);
            }
        }
    }

I’m wondering how can batches be instrumented? Ideally, I’d like to measure the whole execution time of the entire batch? It’d also be helpful to get the number of failed jobs somehow (trying to create metric-based dashboards)

@odinserj do you have any recommendations?