public sealed class JsonErrorLogger : ILogger { private const string ErrorLogFileName = "json-error-logger.json"; private static readonly JsonSerializerOptions JsonSerializerOptions = new() { // 堆代码 duidaima.com WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; private readonly List<BuildError> _errors = new(), _warnings = new(); public void Initialize(IEventSource eventSource) { eventSource.WarningRaised += EventSourceOnWarningRaised; eventSource.ErrorRaised += EventSourceOnErrorRaised; } private void EventSourceOnWarningRaised(object sender, BuildWarningEventArgs e) { _warnings.Add(new BuildError(e.Subcategory, e.Code, e.File, e.LineNumber, e.ColumnNumber, e.EndLineNumber, e.EndColumnNumber, e.Message, e.HelpKeyword, e.SenderName)); } private void EventSourceOnErrorRaised(object sender, BuildErrorEventArgs e) { _errors.Add(new BuildError(e.Subcategory, e.Code, e.File, e.LineNumber, e.ColumnNumber, e.EndLineNumber, e.EndColumnNumber, e.Message, e.HelpKeyword, e.SenderName)); } public void Shutdown() { using var fs = File.Create(ErrorLogFileName); JsonSerializer.Serialize(fs, new { warnings = _warnings, errors = _errors }, JsonSerializerOptions); _errors.Clear(); } public LoggerVerbosity Verbosity { get; set; } public string? Parameters { get; set; } } public sealed record BuildError( string Subcategory, string Code, string File, int LineNumber, int ColumnNumber, int EndLineNumber, int EndColumnNumber, string? Message, string? HelpKeyword, string? SenderName);这里实现的逻辑比较简单,在 Initialize 的时候注册 warning 和 error 事件,将 warning 和 error 信息记录下来,并在 Shutdown 的时候将其导出到 json 文件中,代码搞好之后编译我们的项目,确保成功生成 dll 文件。然后在原来 dotnet build 的基础上添加 -logger 参数使用我们自定义的这个 logger,示例如下:
dotnet build -logger:"JsonErrorLogger,C:\projects\source\SamplesInPractice\MSBuildLoggerSample\MSBuildJsonLogger\bin\Debug\net8.0\MSBuildJsonLogger.dll"此时就会生成一个类似下面的 json 文件
这样我们就可以知道哪里出错了,发生了什么错误,也可以更加方便地根据 error code 来统计,我们也可以在自定义 logger 的实现里,在导出之前进行统计,生成统计信息等。
<ErrorLog>logVersion21.json,version=2.1</ErrorLog>不过这种方式我试下来应该只有 Roslyn 代码编译的 error log,一些补充的自定义的 task report 的 error 不会出现,比如像 NuGet Audit 的 Error 是没有的,所以想要获取完整的 error 建议还是要通过自定义 msbuild logger 的方式。
总结
本文分享了一个 msbuild logger 的 demo 来导出 msbuild warning/error 为 json 文件,感谢热心帮忙的大佬们,希望对大家有所帮助