Skip to content

Use .NET 6 structured logging #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 28 additions & 31 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,9 @@ jobs:

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1


unit-test:
runs-on: windows-latest
runs-on: ubuntu-latest
steps:
- name: Set up JDK 11
uses: actions/setup-java@v1
Expand All @@ -112,44 +111,43 @@ jobs:
- uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Cache SonarCloud packages
uses: actions/cache@v1
with:
path: ~\sonar\cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar

- name: Cache SonarCloud scanner
id: cache-sonar-scanner
uses: actions/cache@v1
with:
path: .\.sonar\scanner
key: ${{ runner.os }}-sonar-scanner
restore-keys: ${{ runner.os }}-sonar-scanner


- name: Install SonarCloud scanner
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
shell: powershell
run: |
New-Item -Path .\.sonar\scanner -ItemType Directory
dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
run: dotnet tool install --global dotnet-sonarscanner

- name: Restore dependencies
run: dotnet restore
working-directory: ./src

- name: Build and analyze
- name: Begin SonarScanner
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
shell: powershell
run: |
.\.sonar\scanner\dotnet-sonarscanner begin /k:"Project-MONAI_monai-deploy-informatics-gateway" /o:"project-monai" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="src\${{ env.TEST_RESULTS }}\**\*.xml"
dotnet build -c ${{ env.BUILD_CONFIG }} --nologo "src\${{ env.SOLUTION }}"
dotnet test --no-build --filter FullyQualifiedName\!~Monai.Deploy.InformaticsGateway.Integration.Test -c ${{ env.BUILD_CONFIG }} -v=minimal --results-directory "src\${{ env.TEST_RESULTS }}" --collect:"XPlat Code Coverage" --settings src\coverlet.runsettings "src\${{ env.SOLUTION }}"
.\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"
run: dotnet sonarscanner begin /k:"Project-MONAI_monai-deploy-informatics-gateway" /o:"project-monai" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="${{ env.TEST_RESULTS }}/**/*.xml"
working-directory: ./src

- name: Build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: dotnet build -c ${{ env.BUILD_CONFIG }} --nologo "${{ env.SOLUTION }}"
working-directory: ./src

- name: Test
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: find ~+ -type f -name "*.Test.csproj" | xargs -L1 dotnet test -c ${{ env.BUILD_CONFIG }} -v=minimal -r "${{ env.TEST_RESULTS }}" --collect:"XPlat Code Coverage" --settings coverlet.runsettings
working-directory: ./src

- name: End SonarScanner
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: dotnet sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"
working-directory: ./src

- uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }}
Expand Down Expand Up @@ -298,7 +296,6 @@ jobs:
tests/Integration.Test/run.log
retention-days: 30


docs:
runs-on: ubuntu-latest
needs: [calc-version]
Expand Down
2 changes: 1 addition & 1 deletion src/Api/Monai.Deploy.InformaticsGateway.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache License 2.0
</PropertyGroup>

<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.8.2">
<PackageReference Include="GitVersion.MsBuild" Version="5.9.0">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
Expand Down
2 changes: 1 addition & 1 deletion src/Api/Storage/DicomFileStorageInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ protected override string GenerateStoragePath()
Guard.Against.NullOrWhiteSpace(SeriesInstanceUid, nameof(SeriesInstanceUid));
Guard.Against.NullOrWhiteSpace(SopInstanceUid, nameof(SopInstanceUid));

string filePath = System.IO.Path.Combine(StorageRootPath, StudyInstanceUid, SeriesInstanceUid, SopInstanceUid) + FileExtension;
var filePath = System.IO.Path.Combine(StorageRootPath, StudyInstanceUid, SeriesInstanceUid, SopInstanceUid) + FileExtension;
filePath = filePath.ToLowerInvariant();
var index = 1;
while (FileSystem.File.Exists(filePath))
Expand Down
2 changes: 1 addition & 1 deletion src/Api/Storage/FhirFileStorageInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ protected override string GenerateStoragePath()
Guard.Against.NullOrWhiteSpace(ResourceType, nameof(ResourceType));
Guard.Against.NullOrWhiteSpace(MessageId, nameof(MessageId));

string filePath = System.IO.Path.Combine(StorageRootPath, DirectoryPath, ResourceType, MessageId) + FileExtension;
var filePath = System.IO.Path.Combine(StorageRootPath, DirectoryPath, ResourceType, MessageId) + FileExtension;
filePath = filePath.ToLowerInvariant();
var index = 1;
while (FileSystem.File.Exists(filePath))
Expand Down
2 changes: 1 addition & 1 deletion src/Api/Storage/FileStorageInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public void SetWorkflows(params string[] workflows)
/// </summary>
protected virtual string GenerateStoragePath()
{
string filePath = System.IO.Path.Combine(StorageRootPath, $"{CorrelationId}-{MessageId}") + FileExtension;
var filePath = System.IO.Path.Combine(StorageRootPath, $"{CorrelationId}-{MessageId}") + FileExtension;
filePath = filePath.ToLowerInvariant();
var index = 1;
while (FileSystem.File.Exists(filePath))
Expand Down
2 changes: 1 addition & 1 deletion src/Api/Storage/Payload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Diagnostics;
using Ardalis.GuardClauses;
using Monai.Deploy.InformaticsGateway.Common;

namespace Monai.Deploy.InformaticsGateway.Api.Storage
{
public class Payload : IDisposable
Expand Down Expand Up @@ -86,7 +87,6 @@ public void Add(FileStorageInfo value)
{
foreach (var workflow in value.Workflows)
{

Workflows.Add(workflow);
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/Api/Test/Monai.Deploy.InformaticsGateway.Api.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ SPDX-License-Identifier: Apache License 2.0
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="13.2.47" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
Expand Down
37 changes: 16 additions & 21 deletions src/CLI/Commands/AetCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
using Ardalis.GuardClauses;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Monai.Deploy.InformaticsGateway.Api;
using Monai.Deploy.InformaticsGateway.CLI.Services;
using Monai.Deploy.InformaticsGateway.Client;
Expand Down Expand Up @@ -109,22 +108,22 @@ private async Task<int> ListAeTitlehandlerAsync(IHost host, bool verbose, Cancel
client.ConfigureServiceUris(configService.Configurations.InformaticsGatewayServerUri);
LogVerbose(verbose, host, $"Connecting to {Strings.ApplicationName} at {configService.Configurations.InformaticsGatewayServerEndpoint}...");
LogVerbose(verbose, host, $"Retrieving MONAI SCP AE Titles...");
items = await client.MonaiScpAeTitle.List(cancellationToken);
items = await client.MonaiScpAeTitle.List(cancellationToken).ConfigureAwait(false);
}
catch (ConfigurationException ex)
{
logger.Log(LogLevel.Critical, ex.Message);
logger.ConfigurationException(ex.Message);
return ExitCodes.Config_NotConfigured;
}
catch (Exception ex)
{
logger.Log(LogLevel.Critical, $"Error retrieving MONAI SCP AE Titles: {ex.Message}");
logger.ErrorListingMonaiAeTitles(ex.Message);
return ExitCodes.MonaiScp_ErrorList;
}

if (items.IsNullOrEmpty())
{
logger.Log(LogLevel.Warning, "No MONAI SCP Application Entities configured.");
logger.NoAeTitlesFound();
}
else
{
Expand Down Expand Up @@ -166,17 +165,17 @@ private async Task<int> RemoveAeTitlehandlerAsync(string name, IHost host, bool
client.ConfigureServiceUris(configService.Configurations.InformaticsGatewayServerUri);
LogVerbose(verbose, host, $"Connecting to {Strings.ApplicationName} at {configService.Configurations.InformaticsGatewayServerEndpoint}...");
LogVerbose(verbose, host, $"Deleting MONAI SCP AE Title {name}...");
_ = await client.MonaiScpAeTitle.Delete(name, cancellationToken);
logger.Log(LogLevel.Information, $"MONAI SCP AE Title '{name}' deleted.");
_ = await client.MonaiScpAeTitle.Delete(name, cancellationToken).ConfigureAwait(false);
logger.MonaiAeTitleDeleted(name);
}
catch (ConfigurationException ex)
{
logger.Log(LogLevel.Critical, ex.Message);
logger.ConfigurationException(ex.Message);
return ExitCodes.Config_NotConfigured;
}
catch (Exception ex)
{
logger.Log(LogLevel.Critical, $"Error deleting MONAI SCP AE Title {name}: {ex.Message}");
logger.ErrorDeletingMonaiAeTitle(name, ex.Message);
return ExitCodes.MonaiScp_ErrorDelete;
}
return ExitCodes.Success;
Expand All @@ -202,33 +201,29 @@ private async Task<int> AddAeTitlehandlerAsync(MonaiApplicationEntity entity, IH
client.ConfigureServiceUris(configService.Configurations.InformaticsGatewayServerUri);

LogVerbose(verbose, host, $"Connecting to {Strings.ApplicationName} at {configService.Configurations.InformaticsGatewayServerEndpoint}...");
var result = await client.MonaiScpAeTitle.Create(entity, cancellationToken);
var result = await client.MonaiScpAeTitle.Create(entity, cancellationToken).ConfigureAwait(false);

logger.Log(LogLevel.Information, "New MONAI Deploy SCP Application Entity created:");
logger.Log(LogLevel.Information, $"\tName: {result.Name}");
logger.Log(LogLevel.Information, $"\tAE Title: {result.AeTitle}");
logger.Log(LogLevel.Information, $"\tGrouping: {result.Grouping}");
logger.Log(LogLevel.Information, $"\tTimeout: {result.Grouping}s");
logger.MonaiAeTitleCreated(result.Name, result.AeTitle, result.Grouping, result.Timeout);

if (result.Workflows.Any())
{
logger.Log(LogLevel.Information, $"\tWorkflows:{string.Join(',', result.Workflows)}");
logger.Log(LogLevel.Warning, "Data received by this Application Entity will bypass Data Routing Service.");
logger.MonaiAeWorkflows(string.Join(',', result.Workflows));
logger.WorkflowWarning();
}
if (result.IgnoredSopClasses.Any())
{
logger.Log(LogLevel.Information, $"\tIgnored SOP Classes:{string.Join(',', result.IgnoredSopClasses)}");
logger.Log(LogLevel.Warning, "Instances with matching SOP class UIDs are accepted but dropped.");
logger.MonaiAeIgnoredSops(string.Join(',', result.IgnoredSopClasses));
logger.IgnoreSopClassesWarning();
}
}
catch (ConfigurationException ex)
{
logger.Log(LogLevel.Critical, ex.Message);
logger.ConfigurationException(ex.Message);
return ExitCodes.Config_NotConfigured;
}
catch (Exception ex)
{
logger.Log(LogLevel.Critical, $"Error creating MONAI SCP AE Title {entity.AeTitle}: {ex.Message}");
logger.MonaiAeCreateCritical(entity.AeTitle, ex.Message);
return ExitCodes.MonaiScp_ErrorCreate;
}
return ExitCodes.Success;
Expand Down
2 changes: 1 addition & 1 deletion src/CLI/Commands/CommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected static void LogVerbose(bool verbose, IHost host, string message)
}
else
{
logger.Log(LogLevel.Debug, message);
logger.DebugMessage(message);
}
}
}
Expand Down
28 changes: 13 additions & 15 deletions src/CLI/Commands/ConfigCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using Ardalis.GuardClauses;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Monai.Deploy.InformaticsGateway.CLI.Services;

namespace Monai.Deploy.InformaticsGateway.CLI
Expand Down Expand Up @@ -82,21 +81,19 @@ private int ShowConfigurationHandler(IHost host, bool verbose, CancellationToken
try
{
CheckConfiguration(configService);
logger.Log(LogLevel.Information, $"Informatics Gateway API: {configService.Configurations.InformaticsGatewayServerEndpoint}");
logger.Log(LogLevel.Information, $"DICOM SCP Listening Port: {configService.Configurations.DicomListeningPort}");
logger.Log(LogLevel.Information, $"Container Runner: {configService.Configurations.Runner}");
logger.Log(LogLevel.Information, $"Host:");
logger.Log(LogLevel.Information, $" Database storage mount: {configService.Configurations.HostDatabaseStorageMount}");
logger.Log(LogLevel.Information, $" Data storage mount: {configService.Configurations.HostDataStorageMount}");
logger.Log(LogLevel.Information, $" Logs storage mount: {configService.Configurations.HostLogsStorageMount}");
logger.ConfigInformaticsGatewayApiEndpoint(configService.Configurations.InformaticsGatewayServerEndpoint);
logger.ConfigDicomScpPort(configService.Configurations.DicomListeningPort);
logger.ConfigContainerRunner(configService.Configurations.Runner);
logger.ConfigHostInfo(configService.Configurations.HostDatabaseStorageMount, configService.Configurations.HostDataStorageMount, configService.Configurations.HostLogsStorageMount);
}
catch (ConfigurationException)
catch (ConfigurationException ex)
{
logger.ConfigurationException(ex.Message);
return ExitCodes.Config_NotConfigured;
}
catch (Exception ex)
{
logger.Log(LogLevel.Error, ex.Message);
logger.CriticalException(ex.Message);
return ExitCodes.Config_ErrorShowing;
}
return ExitCodes.Success;
Expand All @@ -116,15 +113,16 @@ private static int ConfigUpdateHandler(IHost host, Action<IConfigurationService>
{
CheckConfiguration(config);
updater(config);
logger.Log(LogLevel.Information, "Configuration updated successfully.");
logger.ConfigurationUpdated();
}
catch (ConfigurationException)
catch (ConfigurationException ex)
{
logger.ConfigurationException(ex.Message);
return ExitCodes.Config_NotConfigured;
}
catch (Exception ex)
{
logger.Log(LogLevel.Error, ex.Message);
logger.CriticalException(ex.Message);
return ExitCodes.Config_ErrorSaving;
}
return ExitCodes.Success;
Expand All @@ -142,7 +140,7 @@ private async Task<int> InitHandlerAsync(IHost host, bool verbose, bool yes, Can

if (!yes && configService.IsConfigExists && !confirmation.ShowConfirmationPrompt($"Existing application configuration file already exists. Do you want to overwrite it?"))
{
logger.Log(LogLevel.Warning, "Action cancelled.");
logger.ActionCancelled();
return ExitCodes.Stop_Cancelled;
}

Expand All @@ -152,7 +150,7 @@ private async Task<int> InitHandlerAsync(IHost host, bool verbose, bool yes, Can
}
catch (Exception ex)
{
logger.Log(LogLevel.Error, ex.Message);
logger.CriticalException(ex.Message);
return ExitCodes.Config_ErrorInitializing;
}
return ExitCodes.Success;
Expand Down
8 changes: 8 additions & 0 deletions src/CLI/Commands/ConfigurationException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,18 @@ namespace Monai.Deploy.InformaticsGateway.CLI
[Serializable]
public class ConfigurationException : Exception
{
private ConfigurationException()
{
}

public ConfigurationException(string message) : base(message)
{
}

public ConfigurationException(string message, Exception innerException) : base(message, innerException)
{
}

protected ConfigurationException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
Expand Down
Loading