-
Notifications
You must be signed in to change notification settings - Fork 68
Open
Milestone
Description
Summary
We should provide some healthchecks that will ensure certain conditions are met and will provide users with actionable changes (i.e. identify that they are using the same virtual directory).
Motivation and goals
There are a number of conditions that need to be met in order to have a good experience:
- Remote app is reachable
- Virtual directory setup is the same
- YARP setup
- potentially more
Example
I have an example of what this looks like at https://github.com/twsouthwick/systemweb-adapters/tree/tasou/diagnostics. Public API surface-wise, it adds the following:
public static class DiagnosticsExtension
{
public static ISystemWebAdapterBuilder AddDiagnostics(this ISystemWebAdapterBuilder builder);
}If the full output is written out, it will look something like the following:
This is done by exposing (internally initially) two services:
internal interface IClientDiagnostic
{
void Prepare(HttpRequestMessage request);
DiagnosticResult Process(HttpResponseMessage response);
}
internal interface IServerDiagnostic
{
void Process(HttpContextBase context);
}An example diagnostic that verifies the virtual directory setup would look like this:
internal class VirtualDirectoryDiagnostic : IClientDiagnostic, IServerDiagnostic
{
private const string HeaderName = "X-SystemWebAdapters-Diagnostic-VirtualDirectory";
public string Name => "Virtual Directory Setup";
void IClientDiagnostic.Prepare(HttpRequestMessage request)
{
}
DiagnosticResult IClientDiagnostic.Process(HttpResponseMessage response)
{
if (response.Headers.TryGetValues(HeaderName, out var value) && value.FirstOrDefault() is { } serverAppPath)
{
var result = Result.Create(serverAppPath);
return new DiagnosticResult(result.IsValid ? DiagnosticStatus.Healthy : DiagnosticStatus.Unhealthy, Name, result);
}
else
{
return new DiagnosticResult(DiagnosticStatus.Unhealthy, Name, Result.Unavailable);
}
}
void IServerDiagnostic.Process(HttpContextBase context)
{
context.Response.Headers[HeaderName] = HttpRuntime.AppDomainAppVirtualPath;
}
private class Result
{
public static Result Unavailable = new(HttpRuntime.AppDomainAppVirtualPath, string.Empty);
public static Result Same = new(HttpRuntime.AppDomainAppVirtualPath, HttpRuntime.AppDomainAppVirtualPath);
public static Result Create(string server)
{
if (string.Equals(HttpRuntime.AppDomainAppVirtualPath, server, StringComparison.Ordinal))
{
return Same;
}
return new Result(HttpRuntime.AppDomainAppVirtualPath, server);
}
public Result(string client, string server)
{
Client = client;
Server = server;
}
public bool IsValid => string.Equals(Client, Server, StringComparison.Ordinal);
public string Client { get; }
public string Server { get; }
}
}The flow would be something along the lines of:
- The health check creates an
HttpRequestMessage - This message is passed through the client diagnostics to prepare it
- It is then sent to the server
- The registered server diagnostics will process the request and write back what it needs to the response
- Upon receiving the response, the client diagnostic can process the incoming response and generate any health status it needs.
AvremelM
Metadata
Metadata
Assignees
Labels
No labels
