From 10f3181ddfbb10d693f83b5df6543c7fa8fb4629 Mon Sep 17 00:00:00 2001 From: Smit Patel Date: Thu, 5 Oct 2023 16:10:09 -0700 Subject: [PATCH] Consolidate LogStatus --- .../Components/Pages/ContainerLogs.razor | 32 +++++++------------ .../Components/Pages/Containers.razor | 2 +- .../Components/Pages/ExecutableLogs.razor | 27 +++++----------- .../Components/Pages/ProjectLogs.razor | 27 +++++----------- .../Model/ContainerViewModel.cs | 2 +- src/Aspire.Dashboard/Model/LogStatus.cs | 20 ++++++++++++ .../Dashboard/DashboardViewModelService.cs | 20 ++++-------- .../Dashboard/DockerContainerLogSource.cs | 19 ++++------- src/Aspire.Hosting/Dcp/Model/Container.cs | 2 +- 9 files changed, 64 insertions(+), 87 deletions(-) create mode 100644 src/Aspire.Dashboard/Model/LogStatus.cs diff --git a/src/Aspire.Dashboard/Components/Pages/ContainerLogs.razor b/src/Aspire.Dashboard/Components/Pages/ContainerLogs.razor index 67ffe632bb..7fc0177de6 100644 --- a/src/Aspire.Dashboard/Components/Pages/ContainerLogs.razor +++ b/src/Aspire.Dashboard/Components/Pages/ContainerLogs.razor @@ -14,7 +14,7 @@ @@ -29,17 +29,17 @@ [Parameter] public string? ContainerId { get; set; } + private ContainerViewModel? _selectedContainer; private Dictionary _containerNameMapping = new(); private IEnumerable 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(); @@ -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) { @@ -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 { @@ -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; } } } @@ -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(); @@ -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(); @@ -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..."; - } } diff --git a/src/Aspire.Dashboard/Components/Pages/Containers.razor b/src/Aspire.Dashboard/Components/Pages/Containers.razor index 3f9d1f56c5..12acebb3ac 100644 --- a/src/Aspire.Dashboard/Components/Pages/Containers.razor +++ b/src/Aspire.Dashboard/Components/Pages/Containers.razor @@ -40,7 +40,7 @@ OnClick="async() => await ShowEnvironmentVariables(context)">View - View + View diff --git a/src/Aspire.Dashboard/Components/Pages/ExecutableLogs.razor b/src/Aspire.Dashboard/Components/Pages/ExecutableLogs.razor index 2b97d3a830..df4890ede8 100644 --- a/src/Aspire.Dashboard/Components/Pages/ExecutableLogs.razor +++ b/src/Aspire.Dashboard/Components/Pages/ExecutableLogs.razor @@ -1,6 +1,5 @@ @page "/ExecutableLogs/{executablename?}" @using Aspire.Dashboard.Model; -@using System.Text @implements IAsyncDisposable; @inject IDashboardViewModelService DashboardViewModelService @inject IJSRuntime JS @@ -29,17 +28,17 @@ [Parameter] public string? ExecutableName { get; set; } - private LogViewer? _logViewer; private ExecutableViewModel? _selectedExecutable; - private readonly Dictionary _executableNameMapping = new Dictionary(); + private readonly Dictionary _executableNameMapping = new(); private IEnumerable 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(); @@ -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 { @@ -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; } } } @@ -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..."; - } } diff --git a/src/Aspire.Dashboard/Components/Pages/ProjectLogs.razor b/src/Aspire.Dashboard/Components/Pages/ProjectLogs.razor index 77a26eaba4..ceeb316c45 100644 --- a/src/Aspire.Dashboard/Components/Pages/ProjectLogs.razor +++ b/src/Aspire.Dashboard/Components/Pages/ProjectLogs.razor @@ -1,6 +1,5 @@ @page "/ProjectLogs/{projectname?}" @using Aspire.Dashboard.Model; -@using System.Text @implements IAsyncDisposable; @inject IDashboardViewModelService DashboardViewModelService @inject IJSRuntime JS @@ -29,17 +28,17 @@ [Parameter] public string? ProjectName { get; set; } - private LogViewer? _logViewer; private ProjectViewModel? _selectedProject; - private readonly Dictionary _projectNameMapping = new Dictionary(); + private readonly Dictionary _projectNameMapping = new(); private IEnumerable 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(); @@ -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 { @@ -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; } } } @@ -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..."; - } } diff --git a/src/Aspire.Dashboard/Model/ContainerViewModel.cs b/src/Aspire.Dashboard/Model/ContainerViewModel.cs index 02c56f1f50..42fc0f6807 100644 --- a/src/Aspire.Dashboard/Model/ContainerViewModel.cs +++ b/src/Aspire.Dashboard/Model/ContainerViewModel.cs @@ -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 Ports { get; } = new(); } diff --git a/src/Aspire.Dashboard/Model/LogStatus.cs b/src/Aspire.Dashboard/Model/LogStatus.cs new file mode 100644 index 0000000000..e1b5a9c015 --- /dev/null +++ b/src/Aspire.Dashboard/Model/LogStatus.cs @@ -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"; +} diff --git a/src/Aspire.Hosting/Dashboard/DashboardViewModelService.cs b/src/Aspire.Hosting/Dashboard/DashboardViewModelService.cs index 46c4d0d104..bd163252ab 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardViewModelService.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardViewModelService.cs @@ -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> GetExecutablesAsync() { @@ -123,10 +117,10 @@ public async Task> 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 }; @@ -168,10 +162,10 @@ public async IAsyncEnumerable> 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 }; diff --git a/src/Aspire.Hosting/Dashboard/DockerContainerLogSource.cs b/src/Aspire.Hosting/Dashboard/DockerContainerLogSource.cs index d7d35860c6..b0c32d6186 100644 --- a/src/Aspire.Hosting/Dashboard/DockerContainerLogSource.cs +++ b/src/Aspire.Hosting/Dashboard/DockerContainerLogSource.cs @@ -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 StartAsync(CancellationToken cancellationToken) { if (_containerLogWatcher is not null) @@ -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"; @@ -77,7 +72,7 @@ private sealed class DockerContainerLogWatcher(string? containerID) : IAsyncDisp public async Task InitWatchAsync(CancellationToken cancellationToken) { - if (string.IsNullOrWhiteSpace(containerID)) + if (string.IsNullOrWhiteSpace(containerId)) { return false; } @@ -86,7 +81,7 @@ public async Task 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)) @@ -168,7 +163,7 @@ public async IAsyncEnumerable WatchOutputLogsAsync([EnumeratorCancella { while (!cancellationToken.IsCancellationRequested) { - List currentLogs = new(); + List currentLogs = []; // Wait until there's something to read if (await _outputChannel.Reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false)) @@ -197,7 +192,7 @@ public async IAsyncEnumerable WatchErrorLogsAsync([EnumeratorCancellat { while (!cancellationToken.IsCancellationRequested) { - List currentLogs = new(); + List currentLogs = []; // Wait until there's something to read if (await _errorChannel.Reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false)) diff --git a/src/Aspire.Hosting/Dcp/Model/Container.cs b/src/Aspire.Hosting/Dcp/Model/Container.cs index 89e082148f..bb526cc4a9 100644 --- a/src/Aspire.Hosting/Dcp/Model/Container.cs +++ b/src/Aspire.Hosting/Dcp/Model/Container.cs @@ -159,7 +159,7 @@ public class ContainerStatus : V1Status // ID of the Container (if an attempt to start the Container was made) [JsonPropertyName("containerId")] - public string? ContainerID { get; set; } + public string? ContainerId { get; set; } // Timestamp of the Container start attempt [JsonPropertyName("startupTimestamp")]