首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >实现自定义的 msbuild logger

实现自定义的 msbuild logger

作者头像
JusterZhu
发布2025-01-23 20:34:34
发布2025-01-23 20:34:34
13400
代码可运行
举报
文章被收录于专栏:JusterZhuJusterZhu
运行总次数:0
代码可运行

实现并使用自定义的 msbuild logger

Intro

最近想改一下项目,发现有很多警告,想把所有的 warning 导出到 JSON 以方便统计 warning 类型以及出现的次数,但是目前 dotnet build 还不支持,于是想提一个 issue 希望支持一下,然后有大佬说可以自定义一个 msbuild logger 来实现,.NET SDK 里的 Terminal Logger 也是这种方式实现的,于是就找了下文档动手尝试了一下,分享一下,希望对大家有所帮助

Implement

首先我们来创建一个新的类库项目,并添加 Microsoft.Build.Framework nuget 包的引用

然后就可以创建一个 logger,实现:Microsoft.Build.Framework.ILogger 接口即可,代码实现如下:

代码语言:javascript
代码运行次数:0
运行
复制
public sealed class JsonErrorLogger : ILogger
{
    private const string ErrorLogFileName = "json-error-logger.json";
    private static readonly JsonSerializerOptions JsonSerializerOptions = new()
    {
        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,示例如下:

代码语言:javascript
代码运行次数:0
运行
复制
dotnet build -logger:"JsonErrorLogger,C:\projects\source\SamplesInPractice\MSBuildLoggerSample\MSBuildJsonLogger\bin\Debug\net8.0\MSBuildJsonLogger.dll"

此时就会生成一个类似下面的 json 文件

这样我们就可以知道哪里出错了,发生了什么错误,也可以更加方便地根据 error code 来统计,我们也可以在自定义 logger 的实现里,在导出之前进行统计,生成统计信息等

More

前面的这个 logger 比较简单,目前 path 是写死的,也只关心 warning 和 error log,msbuild 提供了一个 ILogger 的实现 Logger, 也可以继承这个 Logger 来实现,实际要复用的话可以结合 msbuild 的一些参数和自己的需求进行改进和定制

除了自定义 msbuild logger 之外 Roslyn 在编译的时候也可以生成一个编译 error 的文件,可以导出成 json,可以在项目文件里配置

代码语言:javascript
代码运行次数:0
运行
复制
<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 文件,感谢热心帮忙的大佬们,希望对大家有所帮助

References

  • https://github.com/dotnet/sdk/issues/43269?wt.mc_id=DT-MVP-5004222
  • https://learn.microsoft.com/en-us/visualstudio/msbuild/build-loggers?view=vs-2022&wt.mc_id=DT-MVP-5004222
  • https://github.com/WeihanLi/SamplesInPractice/blob/main/MSBuildLoggerSample/MSBuildJsonLogger/JsonLogger.cs?wt.mc_id=DT-MVP-5004222
  • https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/errors-warnings#errorlog?wt.mc_id=DT-MVP-5004222
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-09-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JusterZhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现并使用自定义的 msbuild logger
    • Intro
    • Implement
    • More
    • References
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档