Skip to content

Instantly share code, notes, and snippets.

@vkhorikov
Created June 19, 2025 10:41
Show Gist options
  • Save vkhorikov/44481a2491805bcba05ee57ee2e58dbf to your computer and use it in GitHub Desktop.
Save vkhorikov/44481a2491805bcba05ee57ee2e58dbf to your computer and use it in GitHub Desktop.
TelemetryOperation wrapper v2
public class TelemetryOperation : IDisposable
{
private readonly IOperationHolder<RequestTelemetry> _operation;
private bool _disposed = false;
public TelemetryOperation(TelemetryClient telemetryClient, string operationName, object? properties = null)
{
var reqId = Guid.NewGuid().ToString("N");
_operation = telemetryClient.StartOperation<RequestTelemetry>(operationName, reqId);
// Set initial properties
if (properties != null)
{
var propDict = properties.ToDictionary();
foreach (var prop in propDict)
{
_operation.Telemetry.Properties.Add(prop.Key, prop.Value);
}
}
_operation.Telemetry.Success = false;
}
public void MarkAsSuccess()
{
if (_disposed)
throw new ObjectDisposedException(nameof(TelemetryOperation));
_operation.Telemetry.Success = true;
}
public void MarkAsFailure(string reason = null, object? properties = null)
{
if (_disposed)
throw new ObjectDisposedException(nameof(TelemetryOperation));
_operation.Telemetry.Success = false;
if (!string.IsNullOrEmpty(reason))
{
_operation.Telemetry.Properties["failure_reason"] = reason;
}
if (properties != null)
{
var propDict = properties.ToDictionary();
foreach (var prop in propDict)
{
_operation.Telemetry.Properties[prop.Key] = prop.Value;
}
}
}
public void Dispose()
{
if (!_disposed)
{
_operation?.Dispose();
_disposed = true;
}
}
}
// Usage example
async Task RunTask(BackgroundJob job, int workerNo, BackgroundTask task)
{
using var telemetryOp = new TelemetryOperation(
_logger,
$"BackgroundJob RunTask {job.GetNameForLogging()}",
new
{
job_type = job.GetJobType().ToString(),
task_id = task.Id,
tenant = task.CompanyCode,
worker_no = workerNo.ToString()
});
ProcessingAttempt result;
string newState;
try
{
(result, newState) = await job.ProcessCore(task.CompanyCode, task.Input, task.State);
if (result is ProcessingAttempt.Success)
{
telemetryOp.MarkAsSuccess();
}
if (result is ProcessingAttempt.Failure failure)
{
telemetryOp.MarkAsFailure(failure.Error, new { is_validation_error = failure.IsValidationError });
}
}
catch (Exception ex)
{
LogInfo(job, "faulted", workerNo, id: task.Id, error: ex.ToString());
result = new ProcessingAttempt.Failure("Processing faulted: " + ex.Message, false, 0);
newState = task.State;
telemetryOp.MarkAsFailure(ex.Message);
}
task.RecordAttempt(result, newState);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment