feat(logging): tag UI task actions with TaskId + debug trace lines
This commit is contained in:
@@ -106,7 +106,9 @@ sealed class Program
|
|||||||
|
|
||||||
// Services
|
// Services
|
||||||
sc.AddSingleton<GitService>();
|
sc.AddSingleton<GitService>();
|
||||||
sc.AddSingleton(sp => new WorkerClient(sp.GetRequiredService<AppSettings>().SignalRUrl));
|
sc.AddSingleton(sp => new WorkerClient(
|
||||||
|
sp.GetRequiredService<AppSettings>().SignalRUrl,
|
||||||
|
sp.GetRequiredService<ILogger<WorkerClient>>()));
|
||||||
sc.AddSingleton<IWorkerClient>(sp => sp.GetRequiredService<WorkerClient>());
|
sc.AddSingleton<IWorkerClient>(sp => sp.GetRequiredService<WorkerClient>());
|
||||||
|
|
||||||
// Release check + installer update
|
// Release check + installer update
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.1" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.11" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.11" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
|
||||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Serilog" Version="4.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
|||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Serilog.Context;
|
||||||
|
|
||||||
namespace ClaudeDo.Ui.Services;
|
namespace ClaudeDo.Ui.Services;
|
||||||
|
|
||||||
@@ -30,6 +32,7 @@ sealed class IndefiniteRetryPolicy : IRetryPolicy
|
|||||||
public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerClient
|
public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerClient
|
||||||
{
|
{
|
||||||
private readonly HubConnection _hub;
|
private readonly HubConnection _hub;
|
||||||
|
private readonly ILogger<WorkerClient> _logger;
|
||||||
private CancellationTokenSource? _startCts;
|
private CancellationTokenSource? _startCts;
|
||||||
private Task _retryLoopTask = Task.CompletedTask;
|
private Task _retryLoopTask = Task.CompletedTask;
|
||||||
private readonly object _startLock = new();
|
private readonly object _startLock = new();
|
||||||
@@ -65,8 +68,9 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
|||||||
|
|
||||||
public string? LastMergeAllTarget { get; private set; }
|
public string? LastMergeAllTarget { get; private set; }
|
||||||
|
|
||||||
public WorkerClient(string signalRUrl)
|
public WorkerClient(string signalRUrl, ILogger<WorkerClient> logger)
|
||||||
{
|
{
|
||||||
|
_logger = logger;
|
||||||
_hub = new HubConnectionBuilder()
|
_hub = new HubConnectionBuilder()
|
||||||
.WithUrl(signalRUrl)
|
.WithUrl(signalRUrl)
|
||||||
.WithAutomaticReconnect(new IndefiniteRetryPolicy())
|
.WithAutomaticReconnect(new IndefiniteRetryPolicy())
|
||||||
@@ -240,20 +244,24 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
|||||||
catch { return default; }
|
catch { return default; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RunNowAsync(string taskId)
|
/// <summary>Invoke a task-targeted hub method under a TaskId log scope, emitting a debug trace line.</summary>
|
||||||
|
private async Task InvokeForTaskAsync(string taskId, string method, params object?[] args)
|
||||||
{
|
{
|
||||||
await _hub.InvokeAsync("RunNow", taskId);
|
using (LogContext.PushProperty("TaskId", taskId))
|
||||||
|
{
|
||||||
|
_logger.LogDebug("UI invoking {Method} for task {TaskId}", method, taskId);
|
||||||
|
await _hub.InvokeCoreAsync(method, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ContinueTaskAsync(string taskId, string followUpPrompt)
|
public Task RunNowAsync(string taskId)
|
||||||
{
|
=> InvokeForTaskAsync(taskId, "RunNow", taskId);
|
||||||
await _hub.InvokeAsync("ContinueTask", taskId, followUpPrompt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ResetTaskAsync(string taskId)
|
public Task ContinueTaskAsync(string taskId, string followUpPrompt)
|
||||||
{
|
=> InvokeForTaskAsync(taskId, "ContinueTask", taskId, followUpPrompt);
|
||||||
await _hub.InvokeAsync("ResetTask", taskId);
|
|
||||||
}
|
public Task ResetTaskAsync(string taskId)
|
||||||
|
=> InvokeForTaskAsync(taskId, "ResetTask", taskId);
|
||||||
|
|
||||||
public async Task<MergeResultDto> MergeTaskAsync(string taskId, string targetBranch, bool removeWorktree, string commitMessage)
|
public async Task<MergeResultDto> MergeTaskAsync(string taskId, string targetBranch, bool removeWorktree, string commitMessage)
|
||||||
{
|
{
|
||||||
@@ -264,10 +272,8 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
|||||||
public Task<MergeTargetsDto?> GetMergeTargetsAsync(string taskId)
|
public Task<MergeTargetsDto?> GetMergeTargetsAsync(string taskId)
|
||||||
=> TryInvokeAsync<MergeTargetsDto>("GetMergeTargets", taskId);
|
=> TryInvokeAsync<MergeTargetsDto>("GetMergeTargets", taskId);
|
||||||
|
|
||||||
public async Task CancelTaskAsync(string taskId)
|
public Task CancelTaskAsync(string taskId)
|
||||||
{
|
=> InvokeForTaskAsync(taskId, "CancelTask", taskId);
|
||||||
await _hub.InvokeAsync("CancelTask", taskId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task WakeQueueAsync()
|
public async Task WakeQueueAsync()
|
||||||
{
|
{
|
||||||
@@ -386,25 +392,17 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
|||||||
await _hub.InvokeAsync("SetTaskStatus", taskId, status.ToString());
|
await _hub.InvokeAsync("SetTaskStatus", taskId, status.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ApproveReviewAsync(string taskId)
|
public Task ApproveReviewAsync(string taskId)
|
||||||
{
|
=> InvokeForTaskAsync(taskId, "ApproveReview", taskId);
|
||||||
await _hub.InvokeAsync("ApproveReview", taskId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task RejectReviewToQueueAsync(string taskId, string feedback)
|
public Task RejectReviewToQueueAsync(string taskId, string feedback)
|
||||||
{
|
=> InvokeForTaskAsync(taskId, "RejectReviewToQueue", taskId, feedback);
|
||||||
await _hub.InvokeAsync("RejectReviewToQueue", taskId, feedback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task RejectReviewToIdleAsync(string taskId)
|
public Task RejectReviewToIdleAsync(string taskId)
|
||||||
{
|
=> InvokeForTaskAsync(taskId, "RejectReviewToIdle", taskId);
|
||||||
await _hub.InvokeAsync("RejectReviewToIdle", taskId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task CancelReviewAsync(string taskId)
|
public Task CancelReviewAsync(string taskId)
|
||||||
{
|
=> InvokeForTaskAsync(taskId, "CancelReview", taskId);
|
||||||
await _hub.InvokeAsync("CancelReview", taskId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<WorktreeCleanupDto?> CleanupFinishedWorktreesAsync(string? listId = null)
|
public Task<WorktreeCleanupDto?> CleanupFinishedWorktreesAsync(string? listId = null)
|
||||||
=> TryInvokeAsync<WorktreeCleanupDto>("CleanupFinishedWorktrees", listId);
|
=> TryInvokeAsync<WorktreeCleanupDto>("CleanupFinishedWorktrees", listId);
|
||||||
|
|||||||
Reference in New Issue
Block a user