Skip to content

Commit

Permalink
Merge pull request #13 from MobileTeleSystems/feature/refactor_logging
Browse files Browse the repository at this point in the history
Refactor logging
  • Loading branch information
genusP authored Nov 15, 2024
2 parents 194423a + 61bc139 commit 918596f
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 70 deletions.
6 changes: 3 additions & 3 deletions src/ApiCodeGenerator.Abstraction/ILogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ namespace ApiCodeGenerator.Abstraction
{
public interface ILogger
{
void LogError(string? sourceFile, string message, params object[] messageArgs);
void LogError(string? code, string? sourceFile, string message, params object[] messageArgs);

void LogMessage(string message, params object[] messageArgs);
void LogMessage(string? code, string? sourceFile, string message, params object[] messageArgs);

void LogWarning(string? sourceFile, string message, params object[] messageArgs);
void LogWarning(string? code, string? sourceFile, string message, params object[] messageArgs);
}
}
36 changes: 19 additions & 17 deletions src/ApiCodeGenerator.Core/GenerationTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ApiCodeGenerator.Abstraction;
using ApiCodeGenerator.Core.NswagDocument;
using ApiCodeGenerator.Core.NswagDocument.Converters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using static ApiCodeGenerator.Core.LogCodes;

namespace ApiCodeGenerator.Core
{
Expand Down Expand Up @@ -69,45 +68,45 @@ internal GenerationTask(
/// Генерирует код и сохраняет его в указанный файл.
/// </summary>
/// <param name="nswagFilePath">Путь к файлу настроек генератора.</param>
/// <param name="openApiFilePath">Путь к файлу документа OpenApi.</param>
/// <param name="apiDocumentPath">Путь к файлу документа Api.</param>
/// <param name="outFilePath">Путь к фалу с результатами генерации.</param>
/// <param name="variables">Перечень пар ключ=значение разделенныз запятой.</param>
/// <param name="baseNswagFilePath">Файл базовых настроек.</param>
/// <returns>True если процесс генерации успешно завершен.</returns>
public async Task<bool> ExecuteAsync(string nswagFilePath,
string openApiFilePath,
string apiDocumentPath,
string outFilePath,
string? variables = null,
string? baseNswagFilePath = null)
{
if (!_fileProvider.Exists(nswagFilePath))
{
Log?.LogError(null, "File '{0}' not found.", nswagFilePath);
Log?.LogError(FileNotFound, nswagFilePath, message: "File '{0}' not found.", messageArgs: nswagFilePath);
return false;
}

// System.Diagnostics.Debugger.Launch();
var vars = ParseVariables(variables);
vars["InputJson"] = openApiFilePath;
vars["InputJson"] = apiDocumentPath;
vars["OutFile"] = outFilePath;
var roVariables = new ReadOnlyDictionary<string, string>(vars);

Log?.LogMessage("Values of nswag variables");
Log?.LogMessage(string.Join(Environment.NewLine, vars.Select(_ => $"\t[{_.Key}] = {_.Value}")));
LogMessage("Values of nswag variables");
LogMessage(string.Join(Environment.NewLine, vars.Select(_ => $"\t[{_.Key}] = {_.Value}")));

JObject? baseNswagDocument = LoadBaseNswag(baseNswagFilePath);
var nswagDocument = _documentFactory.LoadNswagDocument(nswagFilePath, roVariables, baseNswagDocument);

var generatorSettings = nswagDocument.CodeGenerators.FirstOrDefault();
if (generatorSettings.Key is null)
{
Log?.LogWarning(nswagFilePath, "Nswag not contains codeGenerator definition. Skip generation.");
Log?.LogWarning(NotDefineGenerator, nswagFilePath, "Nswag not contains codeGenerator definition. Skip generation.");
return true;
}

if (!_extensions.CodeGenerators.TryGetValue(generatorSettings.Key, out var contentGeneratorFactory))
{
Log?.LogError(nswagFilePath, $"Unable find generator {generatorSettings.Key}. Check package references.");
Log?.LogError(GenNotFound, nswagFilePath, $"Unable find generator {generatorSettings.Key}. Check package references.");
return false;
}

Expand All @@ -117,38 +116,41 @@ public async Task<bool> ExecuteAsync(string nswagFilePath,
{
if (context.DocumentReader is null)
{
Log?.LogWarning(nswagFilePath, "Source not set. Skip generation.");
Log?.LogWarning(NotSetInput, nswagFilePath, "Source not set. Skip generation.");
return true;
}

try
{
Log?.LogMessage($"Use settings: {generatorSettings.Key}");
LogMessage($"Use settings: {generatorSettings.Key}");
var contentGenerator = await contentGeneratorFactory.Invoke(context);

Log?.LogMessage("Generate content for file '{0}'", outFilePath);
LogMessage("Generate content for file '{0}'", outFilePath);
var code = contentGenerator.Generate();

try
{
Log?.LogMessage("Write file '{0}'", outFilePath);
LogMessage("Write file '{0}'", outFilePath);
await _fileProvider.WriteAllTextAsync(outFilePath, code);
}
catch (Exception ex)
{
Log?.LogError("Unable write file. Error:", ex.Message);
Log?.LogError(WriteFileErr, outFilePath, "Unable write file. Error: {0}", ex.Message);
}
}
catch (InvalidOperationException ex)
{
Log?.LogError(nswagFilePath, ex.Message);
Log?.LogError(GenerationErr, nswagFilePath, ex.Message);
return false;
}

return true;
}

return false;

void LogMessage(string message, params object[] messageArgs)
=> Log?.LogMessage(null, nswagFilePath, message, messageArgs);
}

private async Task<GeneratorContext?> CreateGenerationContext(
Expand All @@ -175,7 +177,7 @@ public async Task<bool> ExecuteAsync(string nswagFilePath,

if (result is not null && !string.IsNullOrEmpty(result.Error))
{
Log?.LogError(result.FilePath ?? nswagFilePath, result.Error!);
Log?.LogError(DocumentOpenErr, result.FilePath ?? nswagFilePath, result.Error!);
return null;
}

Expand Down
14 changes: 14 additions & 0 deletions src/ApiCodeGenerator.Core/LogCodes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace ApiCodeGenerator.Core;

internal static class LogCodes
{
public const string FileNotFound = "ACG0001";
public const string GenNotFound = "ACG0002";
public const string DocumentOpenErr = "ACG0003";
public const string WriteFileErr = "ACG0004";
public const string GenerationErr = "ACG0005";

public const string NotDefineGenerator = "ACG1001";
public const string NotSetInput = "ACG1002";
public const string PreprocSkiped = "ACG1003";
}
16 changes: 14 additions & 2 deletions src/ApiCodeGenerator.Core/NswagDocument/PreprocessorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,26 @@ public static Preprocessors GetPreprocessors(IExtensions? extensions, IDictionar
{
var tuple = CreatePreprocessor(processor, method);
if (tuple is null)
log?.LogWarning(null, "Method '{0}' skiped, because his signature not like Func<T,string,T>.", method.ToString());
{
log?.LogWarning(
LogCodes.PreprocSkiped,
null,
message: "Method '{0}' skiped, because his signature not like Func<T,string,T>.",
messageArgs: [method.ToString()]);
}
else
{
yield return tuple.Value;
}
}
}
else
{
log?.LogWarning(null, "Preprocessor '{0}' skiped, because method 'Process' not found.", name!);
log?.LogWarning(
LogCodes.PreprocSkiped,
null,
message: "Preprocessor '{0}' skiped, because method 'Process' not found.",
messageArgs: [name!]);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/ApiCodeGenerator.MSBuild/Console/ConsoleLogAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ namespace ApiCodeGenerator.MSBuild
{
internal class ConsoleLogAdapter : ILogger
{
public void LogError(string? sourceFile, string message, params object[] messageArgs)
public void LogError(string? code, string? sourceFile, string message, params object[] messageArgs)
=> Console.Error.WriteLine($"{sourceFile}: {string.Format(message, messageArgs)}");

public void LogMessage(string message, params object[] messageArgs)
public void LogMessage(string? code, string? sourceFile, string message, params object[] messageArgs)
=> Console.WriteLine($"INFO: {string.Format(message, messageArgs)}");

public void LogWarning(string? sourceFile, string message, params object[] messageArgs)
public void LogWarning(string? code, string? sourceFile, string message, params object[] messageArgs)
=> Console.WriteLine($"WARNING {sourceFile}: {string.Format(message, messageArgs)}");
}
}
12 changes: 6 additions & 6 deletions src/ApiCodeGenerator.MSBuild/Task/MSBuildLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ public MSBuildLogger(TaskLoggingHelper log)
_log = log;
}

public void LogError(string? sourceFile, string message, params object[] messageArgs)
=> _log.LogError(null, null, null, sourceFile, 0, 0, 0, 0, message, messageArgs);
public void LogError(string? errorCode, string? sourceFile, string message, params object[] messageArgs)
=> _log.LogError(null, errorCode, null, sourceFile, 0, 0, 0, 0, message, messageArgs);

public void LogMessage(string message, params object[] messageArgs)
=> _log.LogMessage(message, messageArgs);
public void LogMessage(string? code, string? sourceFile, string message, params object[] messageArgs)
=> _log.LogMessage(null, code, null, sourceFile, 0, 0, 0, 0, Microsoft.Build.Framework.MessageImportance.Normal, message, messageArgs);

public void LogWarning(string? sourceFile, string message, params object[] messageArgs)
=> _log.LogWarning(null, null, null, sourceFile, 0, 0, 0, 0, message, messageArgs);
public void LogWarning(string? warningCode, string? sourceFile, string message, params object[] messageArgs)
=> _log.LogWarning(null, warningCode, null, sourceFile, 0, 0, 0, 0, message, messageArgs);
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public async Task LoadApiDocument_WithTextPreprocess_Log()
Assert.That(apiDocument?.Components?.Schemas, Does.ContainKey(schemaName));
var sch = apiDocument?.Components?.Schemas[schemaName].ToJson(Newtonsoft.Json.Formatting.None);
Assert.That(sch, Is.EqualTo("{\"$schema\":\"http://json-schema.org/draft-04/schema#\",\"processed\":{}}"));
logger.Verify(l => l.LogWarning(filePath, It.IsAny<string>()));
logger.Verify(l => l.LogWarning(It.IsAny<string>(), filePath, It.IsAny<string>()));
}

[Test]
Expand Down Expand Up @@ -181,17 +181,17 @@ private void ValidateDocument(AsyncApiDocument document)
.And.ContainKey(channelPrefix + "action.{streetlightId}.dim"));

Assert.NotNull(document.Components);
Assert.That(document.Components.Messages,
Assert.That(document.Components?.Messages,
Is.Not.Null
.And.ContainKey("lightMeasured")
.And.ContainKey("turnOnOff")
.And.ContainKey("dimLight"));

Assert.That(document.Components.Parameters,
Assert.That(document.Components?.Parameters,
Is.Not.Null
.And.ContainKey("streetlightId"));

Assert.That(document.Components.Schemas,
Assert.That(document.Components?.Schemas,
Is.Not.Null
.And.ContainKey("lightMeasuredPayload")
.And.ContainKey("turnOnOffPayload")
Expand All @@ -204,32 +204,32 @@ private void ValidateDocument(AsyncApiDocument document)
.And.ContainKey("mtls-connections"));

// Resolve $ref in channel defintion
var actualChannel = document.Channels[channelPrefix + "event.{streetlightId}.lighting.measured"];
var actualChannel = document.Channels?[channelPrefix + "event.{streetlightId}.lighting.measured"];
Assert.That(actualChannel,
Is.Not.Null
.And.Property("Publish").Not.Null
.And.Property("Subscribe").Null);
Assert.That(actualChannel.Parameters,
Assert.That(actualChannel?.Parameters,
Is.Not.Null
.And.ContainKey("streetlightId"));
Assert.That(actualChannel.Parameters["streetlightId"],
Assert.That(actualChannel?.Parameters["streetlightId"],
Is.Not.Null
.And.Property("ReferencePath").EqualTo("#/components/parameters/streetlightId")
.And.Property("Reference").EqualTo(document.Components.Parameters["streetlightId"]));
Assert.That(actualChannel.Publish?.Message,
.And.Property("Reference").EqualTo(document.Components?.Parameters["streetlightId"]));
Assert.That(actualChannel?.Publish?.Message,
Is.Not.Null
.And.Property("ReferencePath").EqualTo("#/components/messages/lightMeasured")
.And.Property("Reference").EqualTo(document.Components.Messages["lightMeasured"]));
.And.Property("Reference").EqualTo(document.Components?.Messages["lightMeasured"]));

// Resolve $ref in message definition
var actualMessage = document.Components.Messages["turnOnOff"];
var actualMessage = document.Components?.Messages["turnOnOff"];
Assert.That(actualMessage, Is.Not.Null);
Assert.That(actualMessage.Payload,
Assert.That(actualMessage?.Payload,
Is.Not.Null
.And.Property("Reference").EqualTo(document.Components.Schemas["turnOnOffPayload"]));
.And.Property("Reference").EqualTo(document.Components?.Schemas["turnOnOffPayload"]));

// Resolve $ref in schema definition
Assert.That(document.Components.Schemas["turnOnOffPayload"]?.ActualProperties,
Assert.That(document.Components?.Schemas["turnOnOffPayload"]?.ActualProperties,
Is.Not.Null
.And.ContainKey("command"));

Expand All @@ -243,24 +243,24 @@ private void ValidateDocument(AsyncApiDocument document)
// Resolve $ref in servers
Assert.That(document.Servers["mtls-connections"],
Is.Not.Null
.And.Property("Reference").EqualTo(document.Components.Servers["mtls-connections"]));
.And.Property("Reference").EqualTo(document.Components?.Servers["mtls-connections"]));

// Resolve $ref in server variables
Assert.Multiple(() =>
{
var variables = document.Components.Servers["mtls-connections"].Variables;
var variables = document.Components?.Servers["mtls-connections"].Variables;
Assert.That(variables,
Is.Not.Null
.And.ContainKey("someRefVariable")
.And.ContainKey("someVariable"));

Assert.That(variables!["someRefVariable"],
Is.Not.Null
.And.Property("Reference").EqualTo(document.Components.ServerVariables["someRefVariable"]));
.And.Property("Reference").EqualTo(document.Components?.ServerVariables["someRefVariable"]));
});

//Read server variables
Assert.That(document.Components.ServerVariables["someRefVariable"],
Assert.That(document.Components?.ServerVariables["someRefVariable"],
new PredicateConstraint<ServerVariable>(a =>
a.Description == "Some ref variable"
&& a.Enum?.FirstOrDefault() == "def"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public string Process(string data, string? fileName)

public string Process(string data, string? fileName, ILogger? logger)
{
logger?.LogWarning(fileName, "test");
logger?.LogWarning(null, fileName, "test");
return Process(data, fileName);
}
}
Expand Down
Loading

0 comments on commit 918596f

Please sign in to comment.