Skip to content

Commit

Permalink
Consolidate LogStatus
Browse files Browse the repository at this point in the history
  • Loading branch information
smitpatel committed Oct 6, 2023
1 parent 2d8ae48 commit 10f3181
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 87 deletions.
32 changes: 11 additions & 21 deletions src/Aspire.Dashboard/Components/Pages/ContainerLogs.razor
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<FluentStack Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
<FluentSelect TOption="ContainerViewModel"
Items="@Containers"
OptionValue="@(c => c.ContainerID)"
OptionValue="@(c => c.ContainerId)"
OptionText="GetContainerDisplayText"
@bind-SelectedOption="_selectedContainer"
@bind-SelectedOption:after="HandleSelectedOptionChangedAsync" />
Expand All @@ -29,17 +29,17 @@
[Parameter]
public string? ContainerId { get; set; }

private ContainerViewModel? _selectedContainer;
private Dictionary<string, ContainerViewModel> _containerNameMapping = new();
private IEnumerable<ContainerViewModel> Containers => _containerNameMapping.Select(kvp => kvp.Value).OrderBy(c => c.Name);
private ContainerViewModel? _selectedContainer;
private LogViewer? _logViewer;
private CancellationTokenSource _watchContainersTokenSource = new CancellationTokenSource();
private CancellationTokenSource? _watchLogsTokenSource;
private string _status = ContainerLogStatuses.Initializing;
private string _status = LogStatus.Initializing;

protected override async Task OnInitializedAsync()
{
_status = ContainerLogStatuses.LoadingContainers;
_status = LogStatus.LoadingContainers;

var initialList = await DashboardViewModelService.GetContainersAsync();

Expand All @@ -50,7 +50,7 @@

if (ContainerId is not null)
{
_selectedContainer = initialList?.FirstOrDefault(c => string.Equals(ContainerId, c.ContainerID, StringComparison.Ordinal));
_selectedContainer = initialList?.FirstOrDefault(c => string.Equals(ContainerId, c.ContainerId, StringComparison.Ordinal));
}
else if (initialList?.Count > 0)
{
Expand All @@ -75,11 +75,11 @@
{
if (_selectedContainer is null)
{
_status = ContainerLogStatuses.NoContainerSelected;
_status = LogStatus.NoContainerSelected;
}
else if (_logViewer is null)
{
_status = ContainerLogStatuses.InitializingLogViewer;
_status = LogStatus.InitializingLogViewer;
}
else
{
Expand All @@ -96,12 +96,12 @@
await _logViewer.WatchLogsAsync(() => _selectedContainer.LogSource.WatchErrorLogAsync(_watchLogsTokenSource.Token), LogEntryType.Error);
});

_status = ContainerLogStatuses.WatchingLogs;
_status = LogStatus.WatchingLogs;
}
else
{
_watchLogsTokenSource = null;
_status = ContainerLogStatuses.FailedToInitialize;
_status = LogStatus.FailedToInitialize;
}
}
}
Expand All @@ -111,7 +111,7 @@
if (_selectedContainer is not null)
{
// Change the URL
NavigationManager.NavigateTo($"/containerLogs/{_selectedContainer.ContainerID}");
NavigationManager.NavigateTo($"/containerLogs/{_selectedContainer.ContainerId}");
await StopWatchingLogsAsync();
await ClearLogsAsync();
await LoadLogsAsync();
Expand All @@ -126,7 +126,7 @@

if (_selectedContainer is null)
{
if (string.IsNullOrEmpty(ContainerId) || string.Equals(ContainerId, containerViewModel.ContainerID, StringComparison.Ordinal))
if (string.IsNullOrEmpty(ContainerId) || string.Equals(ContainerId, containerViewModel.ContainerId, StringComparison.Ordinal))
{
_selectedContainer = containerViewModel;
await LoadLogsAsync();
Expand Down Expand Up @@ -190,14 +190,4 @@
_watchLogsTokenSource = null;
}
}

private static class ContainerLogStatuses
{
public const string FailedToInitialize = "Failed to Initialize";
public const string Initializing = "Initializing...";
public const string InitializingLogViewer = "Initializing Log Viewer...";
public const string LoadingContainers = "Loading Containers...";
public const string NoContainerSelected = "No Container Selected";
public const string WatchingLogs = "Watching Logs...";
}
}
2 changes: 1 addition & 1 deletion src/Aspire.Dashboard/Components/Pages/Containers.razor
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
OnClick="async() => await ShowEnvironmentVariables(context)">View</FluentButton>
</TemplateColumn>
<TemplateColumn Title="Logs">
<FluentAnchor Appearance="Appearance.Lightweight" Href="@($"/containerLogs/{context.ContainerID}")">View</FluentAnchor>
<FluentAnchor Appearance="Appearance.Lightweight" Href="@($"/containerLogs/{context.ContainerId}")">View</FluentAnchor>
</TemplateColumn>
</ChildContent>
<EmptyContent>
Expand Down
27 changes: 8 additions & 19 deletions src/Aspire.Dashboard/Components/Pages/ExecutableLogs.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
@page "/ExecutableLogs/{executablename?}"
@using Aspire.Dashboard.Model;
@using System.Text
@implements IAsyncDisposable;
@inject IDashboardViewModelService DashboardViewModelService
@inject IJSRuntime JS
Expand Down Expand Up @@ -29,17 +28,17 @@
[Parameter]
public string? ExecutableName { get; set; }

private LogViewer? _logViewer;
private ExecutableViewModel? _selectedExecutable;
private readonly Dictionary<string, ExecutableViewModel> _executableNameMapping = new Dictionary<string, ExecutableViewModel>();
private readonly Dictionary<string, ExecutableViewModel> _executableNameMapping = new();
private IEnumerable<ExecutableViewModel> Executables => _executableNameMapping.Select(kvp => kvp.Value).OrderBy(p => p.Name);
private LogViewer? _logViewer;
private CancellationTokenSource _watchExecutablesTokenSource = new CancellationTokenSource();
private CancellationTokenSource? _watchLogsTokenSource;
private string _status = ExecutableLogStatuses.Initializing;
private string _status = LogStatus.Initializing;

protected override async Task OnInitializedAsync()
{
_status = ExecutableLogStatuses.LoadingExecutables;
_status = LogStatus.LoadingExecutables;

var initialList = await DashboardViewModelService.GetExecutablesAsync();

Expand Down Expand Up @@ -75,11 +74,11 @@
{
if (_selectedExecutable is null)
{
_status = ExecutableLogStatuses.NoExecutableSelected;
_status = LogStatus.NoExecutableSelected;
}
else if (_logViewer is null)
{
_status = ExecutableLogStatuses.InitializingLogViewer;
_status = LogStatus.InitializingLogViewer;
}
else
{
Expand All @@ -96,12 +95,12 @@
await _logViewer.WatchLogsAsync(() => _selectedExecutable.LogSource.WatchOutputLogAsync(_watchLogsTokenSource.Token), LogEntryType.Error);
});

_status = ExecutableLogStatuses.WatchingLogs;
_status = LogStatus.WatchingLogs;
}
else
{
_watchLogsTokenSource = null;
_status = ExecutableLogStatuses.LogsNotYetAvailable;
_status = LogStatus.LogsNotYetAvailable;
}
}
}
Expand Down Expand Up @@ -200,14 +199,4 @@
_watchLogsTokenSource = null;
}
}

private static class ExecutableLogStatuses
{
public const string Initializing = "Initializing...";
public const string InitializingLogViewer = "Initializing Log Viewer...";
public const string LoadingExecutables = "Loading Executables...";
public const string LogsNotYetAvailable = "Logs Not Yet Available";
public const string NoExecutableSelected = "No Executable Selected";
public const string WatchingLogs = "Watching Logs...";
}
}
27 changes: 8 additions & 19 deletions src/Aspire.Dashboard/Components/Pages/ProjectLogs.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
@page "/ProjectLogs/{projectname?}"
@using Aspire.Dashboard.Model;
@using System.Text
@implements IAsyncDisposable;
@inject IDashboardViewModelService DashboardViewModelService
@inject IJSRuntime JS
Expand Down Expand Up @@ -29,17 +28,17 @@
[Parameter]
public string? ProjectName { get; set; }

private LogViewer? _logViewer;
private ProjectViewModel? _selectedProject;
private readonly Dictionary<string, ProjectViewModel> _projectNameMapping = new Dictionary<string, ProjectViewModel>();
private readonly Dictionary<string, ProjectViewModel> _projectNameMapping = new();
private IEnumerable<ProjectViewModel> Projects => _projectNameMapping.Select(kvp => kvp.Value).OrderBy(p => p.Name);
private LogViewer? _logViewer;
private CancellationTokenSource _watchProjectsTokenSource = new CancellationTokenSource();
private CancellationTokenSource? _watchLogsTokenSource;
private string _status = ProjectLogStatuses.Initializing;
private string _status = LogStatus.Initializing;

protected override async Task OnInitializedAsync()
{
_status = ProjectLogStatuses.LoadingProjects;
_status = LogStatus.LoadingProjects;

var initialList = await DashboardViewModelService.GetProjectsAsync();

Expand Down Expand Up @@ -75,11 +74,11 @@
{
if (_selectedProject is null)
{
_status = ProjectLogStatuses.NoProjectSelected;
_status = LogStatus.NoProjectSelected;
}
else if (_logViewer is null)
{
_status = ProjectLogStatuses.InitializingLogViewer;
_status = LogStatus.InitializingLogViewer;
}
else
{
Expand All @@ -96,12 +95,12 @@
await _logViewer.WatchLogsAsync(() => _selectedProject.LogSource.WatchErrorLogAsync(_watchLogsTokenSource.Token), LogEntryType.Error);
});

_status = ProjectLogStatuses.WatchingLogs;
_status = LogStatus.WatchingLogs;
}
else
{
_watchLogsTokenSource = null;
_status = ProjectLogStatuses.LogsNotYetAvailable;
_status = LogStatus.LogsNotYetAvailable;
}
}
}
Expand Down Expand Up @@ -200,14 +199,4 @@
_watchLogsTokenSource = null;
}
}

private static class ProjectLogStatuses
{
public const string Initializing = "Initializing...";
public const string InitializingLogViewer = "Initializing Log Viewer...";
public const string LoadingProjects = "Loading Projects...";
public const string LogsNotYetAvailable = "Logs Not Yet Available";
public const string NoProjectSelected = "No Project Selected";
public const string WatchingLogs = "Watching Logs...";
}
}
2 changes: 1 addition & 1 deletion src/Aspire.Dashboard/Model/ContainerViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Aspire.Dashboard.Model;

public class ContainerViewModel : ResourceViewModel
{
public string? ContainerID { get; init; }
public string? ContainerId { get; init; }
public required string Image { get; init; }
public List<int> Ports { get; } = new();
}
20 changes: 20 additions & 0 deletions src/Aspire.Dashboard/Model/LogStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Aspire.Dashboard.Model;

internal static class LogStatus
{
public const string Initializing = "Initializing...";
public const string InitializingLogViewer = "Initializing Log Viewer...";
public const string LogsNotYetAvailable = "Logs Not Yet Available";
public const string WatchingLogs = "Watching Logs...";
public const string FailedToInitialize = "Failed to Initialize";

public const string LoadingProjects = "Loading Projects...";
public const string NoProjectSelected = "No Project Selected";
public const string LoadingExecutables = "Loading Executables...";
public const string NoExecutableSelected = "No Executable Selected";
public const string LoadingContainers = "Loading Containers...";
public const string NoContainerSelected = "No Container Selected";
}
20 changes: 7 additions & 13 deletions src/Aspire.Hosting/Dashboard/DashboardViewModelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,10 @@

namespace Aspire.Hosting.Dashboard;

public class DashboardViewModelService : IDashboardViewModelService, IDisposable
public class DashboardViewModelService(DistributedApplicationModel applicationModel) : IDashboardViewModelService, IDisposable
{
private readonly DistributedApplicationModel _applicationModel;
private readonly KubernetesService _kubernetesService;

public DashboardViewModelService(DistributedApplicationModel applicationModel)
{
_applicationModel = applicationModel;
_kubernetesService = new KubernetesService();
}
private readonly DistributedApplicationModel _applicationModel = applicationModel;
private readonly KubernetesService _kubernetesService = new KubernetesService();

public async Task<List<ExecutableViewModel>> GetExecutablesAsync()
{
Expand Down Expand Up @@ -123,10 +117,10 @@ public async Task<List<ContainerViewModel>> GetContainersAsync()
{
Name = container.Metadata.Name,
NamespacedName = new(container.Metadata.Name, null),
ContainerID = container.Status?.ContainerID,
ContainerId = container.Status?.ContainerId,
CreationTimeStamp = container.Metadata.CreationTimestamp?.ToLocalTime(),
Image = container.Spec.Image!,
LogSource = new DockerContainerLogSource(container.Status!.ContainerID!),
LogSource = new DockerContainerLogSource(container.Status!.ContainerId!),
State = container.Status?.State
};
Expand Down Expand Up @@ -168,10 +162,10 @@ public async IAsyncEnumerable<ComponentChanged<ContainerViewModel>> WatchContain
{
Name = container.Metadata.Name,
NamespacedName = new(container.Metadata.Name, null),
ContainerID = container.Status?.ContainerID,
ContainerId = container.Status?.ContainerId,
CreationTimeStamp = container.Metadata.CreationTimestamp?.ToLocalTime(),
Image = container.Spec.Image!,
LogSource = new DockerContainerLogSource(container.Status!.ContainerID!),
LogSource = new DockerContainerLogSource(container.Status!.ContainerId!),
State = container.Status?.State
};

Expand Down
19 changes: 7 additions & 12 deletions src/Aspire.Hosting/Dashboard/DockerContainerLogSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,11 @@

namespace Aspire.Hosting.Dashboard;

internal sealed class DockerContainerLogSource : ILogSource
internal sealed class DockerContainerLogSource(string containerId) : ILogSource
{
private readonly string _containerId;
private readonly string _containerId = containerId;
private DockerContainerLogWatcher? _containerLogWatcher;

public DockerContainerLogSource(string containerId)
{
_containerId = containerId;
}

public async ValueTask<bool> StartAsync(CancellationToken cancellationToken)
{
if (_containerLogWatcher is not null)
Expand Down Expand Up @@ -66,7 +61,7 @@ public async ValueTask StopAsync(CancellationToken cancellationToken = default)
}
}

private sealed class DockerContainerLogWatcher(string? containerID) : IAsyncDisposable
private sealed class DockerContainerLogWatcher(string? containerId) : IAsyncDisposable
{
private const string Executable = "docker";

Expand All @@ -77,7 +72,7 @@ private sealed class DockerContainerLogWatcher(string? containerID) : IAsyncDisp

public async Task<bool> InitWatchAsync(CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(containerID))
if (string.IsNullOrWhiteSpace(containerId))
{
return false;
}
Expand All @@ -86,7 +81,7 @@ public async Task<bool> InitWatchAsync(CancellationToken cancellationToken)

try
{
var args = $"logs --follow -t {containerID}";
var args = $"logs --follow -t {containerId}";
var output = new StringBuilder();

var spec = new ProcessSpec(FileUtil.FindFullPathFromPath(Executable))
Expand Down Expand Up @@ -168,7 +163,7 @@ public async IAsyncEnumerable<string[]> WatchOutputLogsAsync([EnumeratorCancella
{
while (!cancellationToken.IsCancellationRequested)
{
List<string> currentLogs = new();
List<string> currentLogs = [];

// Wait until there's something to read
if (await _outputChannel.Reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false))
Expand Down Expand Up @@ -197,7 +192,7 @@ public async IAsyncEnumerable<string[]> WatchErrorLogsAsync([EnumeratorCancellat
{
while (!cancellationToken.IsCancellationRequested)
{
List<string> currentLogs = new();
List<string> currentLogs = [];

// Wait until there's something to read
if (await _errorChannel.Reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false))
Expand Down
Loading

0 comments on commit 10f3181

Please sign in to comment.