You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用独立C#程序监控本地ASP.NET解决方案的函数执行(无需注入代码)

可以,无需修改原ASP.NET代码即可实现

你完全可以通过独立的C#程序与ASP.NET应用的运行时环境交互,记录所有函数的执行情况,不需要在原解决方案中注入任何日志代码。下面是几种可行的实现方案:

1. 使用.NET诊断工具API

.NET提供了Microsoft.Diagnostics.NETCore.Client包,允许你附加到运行中的.NET进程,收集运行时事件和方法执行信息。

步骤:

  • 获取目标ASP.NET进程的ID:可以通过任务管理器查看,或者用C#代码遍历进程:
    foreach (var process in Process.GetProcessesByName("dotnet"))
    {
        Console.WriteLine($"PID: {process.Id}, 窗口标题: {process.MainWindowTitle}");
    }
    
  • 附加进程并订阅方法相关事件:
    using Microsoft.Diagnostics.NETCore.Client;
    using Microsoft.Diagnostics.Tracing.Parsers;
    using Microsoft.Diagnostics.Tracing.Parsers.Clr;
    
    // 替换为你的ASP.NET进程ID
    int targetProcessId = 1234;
    var client = new DiagnosticsClient(targetProcessId);
    
    // 配置要监听的事件提供者
    var providers = new List<EventPipeProvider>
    {
        new EventPipeProvider(
            "Microsoft-Windows-DotNETRuntime",
            EventLevel.Informational,
            (long)ClrTraceEventParser.Keywords.MethodLoad),
        new EventPipeProvider(
            "Microsoft-DotNETCore-SampleProfiler",
            EventLevel.Informational,
            (long)SampleProfilerTraceEventParser.Keywords.Samples)
    };
    
    // 启动事件会话
    using var session = client.StartEventPipeSession(providers);
    var eventSource = new EventPipeEventSource(session.EventStream);
    
    // 监听方法加载事件
    eventSource.Clr.MethodLoad += e => 
        Console.WriteLine($"[加载] {e.TypeName}.{e.MethodName}");
    
    // 监听采样分析事件(可获取方法执行频率)
    eventSource.SampleProfiler.Sample += e =>
    {
        var stackTrace = e.CallStack();
        if (stackTrace.Any())
        {
            var topMethod = stackTrace.First();
            Console.WriteLine($"[执行] {topMethod.MethodName}");
        }
    };
    
    // 开始处理事件
    eventSource.Process();
    
  • 说明:这段代码会记录方法的加载情况和执行采样数据,如果需要更精确的方法进入/退出时间,可以配合EventPipe的MethodEnter/MethodExit事件(需调整提供者的关键字)。

2. 使用.NET Profiler API

这是最强大的方案,能拦截每个方法的进入和退出,记录完整的执行细节(如参数、执行耗时),且完全不需要修改原ASP.NET代码。

核心思路:

  • 编写一个COM组件形式的Profiler,实现ICorProfilerCallback接口,重写EnterMethod和LeaveMethod方法来捕获方法调用事件。
  • 通过环境变量配置让ASP.NET进程加载这个Profiler,Profiler将收集到的方法执行数据通过命名管道/共享内存发送到你的独立记录程序。

简化代码示例(Profiler核心逻辑):

public class FunctionTrackerProfiler : ICorProfilerCallback, ICorProfilerCallback2
{
    private ICorProfilerInfo2 _profilerInfo;
    private NamedPipeClientStream _pipeClient;
    private StreamWriter _pipeWriter;

    public int Initialize(IUnknown pICorProfilerInfoUnk)
    {
        _profilerInfo = (ICorProfilerInfo2)pICorProfilerInfoUnk;
        // 连接到独立记录程序的命名管道
        _pipeClient = new NamedPipeClientStream(".", "FunctionTrackerPipe", PipeDirection.Out);
        _pipeClient.Connect();
        _pipeWriter = new StreamWriter(_pipeClient);
        return 0;
    }

    public void EnterMethod(FunctionID functionId)
    {
        // 获取方法的完整名称
        ModuleID moduleId = default;
        ClassID classId = default;
        char[] methodNameBuffer = new char[1024];
        int nameLength;
        _profilerInfo.GetFunctionInfo(functionId, out moduleId, out classId, out _, out _, methodNameBuffer, 1024, out nameLength);
        string methodFullName = new string(methodNameBuffer, 0, nameLength);

        // 发送进入事件到记录程序
        _pipeWriter.WriteLine($"ENTER|{methodFullName}|{DateTime.UtcNow:O}");
        _pipeWriter.Flush();
    }

    public void LeaveMethod(FunctionID functionId)
    {
        // 类似EnterMethod,发送退出事件
        ModuleID moduleId = default;
        ClassID classId = default;
        char[] methodNameBuffer = new char[1024];
        int nameLength;
        _profilerInfo.GetFunctionInfo(functionId, out moduleId, out classId, out _, out _, methodNameBuffer, 1024, out nameLength);
        string methodFullName = new string(methodNameBuffer, 0, nameLength);

        _pipeWriter.WriteLine($"LEAVE|{methodFullName}|{DateTime.UtcNow:O}");
        _pipeWriter.Flush();
    }

    // 其他接口方法的空实现(必须实现)
    // ...
}
  • 说明:需要将Profiler编译为COM可见的DLL,然后设置环境变量COR_ENABLE_PROFILING=1和COR_PROFILER={Profiler的GUID},启动ASP.NET应用时就会加载该Profiler。

3. 使用Windows事件跟踪(ETW)

如果目标是.NET Framework的ASP.NET应用,可以通过ETW监听CLR事件:

  • 使用EventTraceEventSource订阅Microsoft-Windows-DotNETRuntime提供者的MethodEnter和MethodExit事件。
  • 独立程序可以直接捕获这些ETW事件,无需修改原应用。

关键注意事项

  • 权限:附加到其他进程或监听ETW事件通常需要管理员权限。
  • 性能影响:Profiler API和ETW详细跟踪会对目标应用有轻微性能损耗,生产环境使用前需测试。
  • 版本兼容:确保你的独立程序与目标ASP.NET应用的.NET版本匹配(.NET Framework vs .NET Core/.NET 5+的API略有差异)。

内容的提问来源于stack exchange,提问作者Abhishek Tudu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:04:49