feat: complete TASK-WP0-08 logging
This commit is contained in:
@@ -7,6 +7,7 @@ internal sealed class SupervisorRuntime : IAsyncDisposable
|
||||
private readonly ICredentialStore credentials;
|
||||
private ManagedComponentSupervisor? api;
|
||||
private ManagedComponentSupervisor? worker;
|
||||
private StructuredJsonlLogger? logger;
|
||||
|
||||
internal SupervisorRuntime(ICredentialStore credentials)
|
||||
{
|
||||
@@ -24,6 +25,15 @@ internal sealed class SupervisorRuntime : IAsyncDisposable
|
||||
{
|
||||
return SupervisorState.StartupFailed;
|
||||
}
|
||||
try
|
||||
{
|
||||
logger = new StructuredJsonlLogger(Path.Combine(configuration.LocalDataRoot, "logs", "supervisor"), "supervisor");
|
||||
logger.Write(new StructuredLogEvent("starting", ErrorCategory: "none"));
|
||||
}
|
||||
catch (LogWriteException)
|
||||
{
|
||||
return SupervisorState.StorageUnavailable;
|
||||
}
|
||||
if (CredentialCatalog.RequiredFor(ChildRole.Api).Concat(CredentialCatalog.RequiredFor(ChildRole.Worker)).Any(target => !credentials.IsConfigured(target)))
|
||||
{
|
||||
return SupervisorState.StartupFailed;
|
||||
@@ -35,22 +45,50 @@ internal sealed class SupervisorRuntime : IAsyncDisposable
|
||||
if (!File.Exists(node) || !File.Exists(apiEntry) || !File.Exists(workerEntry)) return SupervisorState.StartupFailed;
|
||||
|
||||
api = CreateComponent(node, apiEntry, ChildRole.Api, SupervisorState.ApiDegraded);
|
||||
api.StateChanged += state => StateChanged?.Invoke(state);
|
||||
await api.StartAsync(cancellationToken);
|
||||
|
||||
worker = CreateComponent(node, workerEntry, ChildRole.Worker, SupervisorState.WorkerDegraded);
|
||||
worker.StateChanged += state => StateChanged?.Invoke(state);
|
||||
await worker.StartAsync(cancellationToken);
|
||||
return SupervisorState.Ready;
|
||||
return TryLog(new StructuredLogEvent("ready", ErrorCategory: "none")) ? SupervisorState.Ready : SupervisorState.StorageUnavailable;
|
||||
}
|
||||
|
||||
private ManagedComponentSupervisor CreateComponent(string node, string entry, ChildRole role, SupervisorState degradedState) =>
|
||||
new(async cancellationToken =>
|
||||
private ManagedComponentSupervisor CreateComponent(string node, string entry, ChildRole role, SupervisorState degradedState)
|
||||
{
|
||||
var component = new ManagedComponentSupervisor(async cancellationToken =>
|
||||
{
|
||||
var startInfo = new ProcessStartInfo(node);
|
||||
startInfo.ArgumentList.Add(entry);
|
||||
return await ManagedChildProcess.StartAsync(startInfo, role, credentials, cancellationToken);
|
||||
var child = await ManagedChildProcess.StartAsync(startInfo, role, credentials, cancellationToken);
|
||||
child.StatusReceived += status =>
|
||||
{
|
||||
if (status == "storage_unavailable")
|
||||
{
|
||||
TryLog(new StructuredLogEvent("unavailable", ErrorCategory: "log_write_failed"));
|
||||
StateChanged?.Invoke(SupervisorState.StorageUnavailable);
|
||||
}
|
||||
};
|
||||
return child;
|
||||
}, degradedState);
|
||||
component.StateChanged += state =>
|
||||
{
|
||||
if (TryLog(new StructuredLogEvent("degraded", ErrorCategory: "service_unavailable"))) StateChanged?.Invoke(state);
|
||||
};
|
||||
return component;
|
||||
}
|
||||
|
||||
private bool TryLog(StructuredLogEvent entry)
|
||||
{
|
||||
try
|
||||
{
|
||||
logger?.Write(entry);
|
||||
return true;
|
||||
}
|
||||
catch (LogWriteException)
|
||||
{
|
||||
StateChanged?.Invoke(SupervisorState.StorageUnavailable);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user