找回密码
 立即注册
首页 业界区 业界 DotTrace系列:9. 大结局之 跨平台 和 自定义行为 诊断 ...

DotTrace系列:9. 大结局之 跨平台 和 自定义行为 诊断

叭遭段 2025-9-25 21:03:02
一:背景

1. 讲故事

本篇是系列的最后一篇,我们从跨平台部署和自定义诊断的角度跟大家聊一聊 dottrace,希望对大家有所启发。
二:跨平台和自定义诊断

1. 如何跨平台诊断分析

如果 dottrace 只能在 windows 平台上跑,那确实不值得写一个系列,目前它可以横跨三大平台(Windows,Linux,Mac),这里就用 ubuntu 来给大家演示下,参考代码如下:
  1.     public class TimeConsumingMethodExample
  2.     {
  3.         public static void Main()
  4.         {
  5.             Console.WriteLine("开始执行耗时方法...");
  6.             // 调用耗时方法
  7.             PerformTimeConsumingTask(3000);
  8.             Console.WriteLine("耗时方法执行完成!");
  9.         }
  10.         /// <summary>
  11.         /// 模拟一个耗时方法
  12.         /// </summary>
  13.         /// <param name="milliseconds">要模拟的耗时(毫秒)</param>
  14.         public static void PerformTimeConsumingTask(int milliseconds)
  15.         {
  16.             Stopwatch stopwatch = Stopwatch.StartNew();
  17.             // 模拟耗时操作 - 这里使用Thread.Sleep
  18.             Thread.Sleep(milliseconds);
  19.             stopwatch.Stop();
  20.             Console.WriteLine($"方法执行耗时: {stopwatch.ElapsedMilliseconds} 毫秒");
  21.         }
  22.     }
复制代码
接下来使用 dotnet pulish 将其发布到 ubuntu 平台。
  1. root@ubuntu2404:/data2/code# ls -lh
  2. total 100K
  3. -rw-r--r-- 1 root root  71K Jun 30 09:01 ConsoleApp7
  4. -rw-r--r-- 1 root root  482 Jun 30 09:01 ConsoleApp7.deps.json
  5. -rw-r--r-- 1 root root 4.5K Jun 30 09:01 ConsoleApp7.dll
  6. -rw-r--r-- 1 root root  12K Jun 30 09:01 ConsoleApp7.pdb
  7. -rw-r--r-- 1 root root  268 Jun 30 09:01 ConsoleApp7.runtimeconfig.json
复制代码
为了能够在 ubuntu 上开启 dottrace 跟踪,有两种部署方式。

  • 源码包方式
可以通过官方链接: https://www.jetbrains.com/profiler/download/?section=commandline 下载 linux 的 tar 包,然后本地解压,开启 timeline 跟踪模式,参考如下:
  1. root@ubuntu2404:/data2/dottrace# tar -xzxf JetBrains.dotTrace.CommandLineTools.linux-x64.2025.1.3.tar.gz
  2. root@ubuntu2404:/data2/dottrace# ./dottrace start --profiling-type=Timeline  --framework=NetCore /usr/bin/dotnet  /data2/code/ConsoleApp7.dll --save-to=/data2/output/snnapshot.dtp
  3. dotTrace command-line profiler 2025.1.3 build 777.0.20250604.2353. Copyright (C) 2025 JetBrains s.r.o.
  4. Preparing to profile...
  5. Profiling in progress...
  6. 开始执行耗时方法...
  7. 方法执行耗时: 3000 毫秒
  8. 耗时方法执行完成!
  9. Profiling is finished in 5.523 seconds
  10. Collected snapshot: /data2/output/snnapshot.dtp
复制代码
从卦中可以看到 snnapshot.dtp 跟踪文件已生成,接下来就是打包到windows平台用分析啦,是不是有点像 dump 的事后分析,参考如下:
  1. root@ubuntu2404:/data2/output# tar -czvf dottrace_snapshot.tar.gz snnapshot.dtp*
  2. snnapshot.dtp
  3. snnapshot.dtp.0000
  4. snnapshot.dtp.0001
  5. snnapshot.dtp.0002
  6. snnapshot.dtp.0003
  7. snnapshot.dtp.0004
  8. snnapshot.dtp.0005
  9. snnapshot.dtp.0006
  10. snnapshot.dtp.0007
  11. ...
  12. root@ubuntu2404:/data2/output# sz dottrace_snapshot.tar.gz
复制代码
1.png


  • dotnet cli 工具包
如果使用源码方式有这样或者那样的问题,可以使用此种方式,它会将 command-line 工具集成到了 dotnet cli 中,参考如下:
  1. root@ubuntu2404:/data2/dottrace# dotnet tool install --global JetBrains.dotTrace.GlobalTools
  2. Skipping NuGet package signature verification.
  3. You can invoke the tool using the following command: dottrace
  4. Tool 'jetbrains.dottrace.globaltools' (version '2025.1.3') was successfully installed.
  5. root@ubuntu2404:/data2/dottrace# cd ..
  6. root@ubuntu2404:/data2# dottrace start --profiling-type=Timeline  --framework=NetCore --save-to=/data2/output/snnapshot.dtp   /usr/bin/dotnet  /data2/code/ConsoleApp7.dll
  7. dotTrace command-line profiler 2025.1.3 build 777.0.20250604.2353. Copyright (C) 2025 JetBrains s.r.o.
  8. Preparing to profile...
  9. Profiling in progress...
  10. 开始执行耗时方法...
  11. 方法执行耗时: 3000 毫秒
  12. 耗时方法执行完成!
  13. Profiling is finished in 5.65 seconds
  14. Collected snapshot: /data2/output/snnapshot.dtp
复制代码
是不是挺有意思的。
2. 如何自定义诊断分析

很多朋友应该知道dottrace默认的诊断方式为全局跟踪,即启动后跟踪,截图如下:
2.png

但这种跟踪方式会掺杂很多噪音,除了让跟踪文件变大,也不利于我们过滤分析,所以就有了一个需求,如何指定 作用域 分析?比如我只想分析某一个方法,厉害的是 dottrace 还真可以做到,在 nuget 上引用 JetBrains.Profiler.Api 包,然后用 MeasureProfiler.StartCollectingData() 和 MeasureProfiler.SaveData(); 将分析的范围圈一下即可,参考代码如下:
  1. class Program
  2. {
  3.     static void Main()
  4.     {
  5.         // 创建并启动Stopwatch
  6.         Stopwatch stopwatch = new Stopwatch();
  7.         stopwatch.Start();
  8.         string filePath = @"D:\1GB_LogFile.log";
  9.         DoRequest(filePath);
  10.         // 停止并显示总耗时
  11.         stopwatch.Stop();
  12.         Console.WriteLine($"总耗时: {stopwatch.Elapsed.TotalSeconds:F2}秒");
  13.     }
  14.     static void DoRequest(string filePath)
  15.     {
  16.         CheckParameter();
  17.         const int chunkSize = 512 * 1024 * 1024; // 每次读取512MB
  18.         try
  19.         {
  20.             Console.WriteLine("开始分块读取文件...");
  21.             int chunkCount = 0;
  22.             long totalBytesRead = 0;
  23.             MeasureProfiler.StartCollectingData();
  24.             using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
  25.             {
  26.                 byte[] buffer = new byte[chunkSize];
  27.                 int bytesRead;
  28.                 while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
  29.                 {
  30.                     totalBytesRead += bytesRead;
  31.                     chunkCount++;
  32.                     // 处理当前块的数据
  33.                     string chunkContent = Encoding.UTF8.GetString(buffer, 0, bytesRead);
  34.                     Console.WriteLine($"读取块 {chunkCount}, 大小: {bytesRead / 1024}KB, 总计: {totalBytesRead / 1024 / 1024}MB");
  35.                 }
  36.             }
  37.             MeasureProfiler.SaveData();
  38.             Console.WriteLine($"文件读取完成,共 {chunkCount} 块");
  39.         }
  40.         catch (Exception ex)
  41.         {
  42.             Console.WriteLine($"出错: {ex.Message}");
  43.         }
  44.     }
  45.     static void CheckParameter()
  46.     {
  47.         Console.WriteLine("检查参数开始...");
  48.         Thread.Sleep(5000);
  49.         Console.WriteLine("检查参数结束...");
  50.     }
  51. }
复制代码
从卦中代码不难看出,MeasureProfiler.StartCollectingData 应该就是 Start 的API实现,既然是api实现那肯定需要同 dottrace 本体进行通信,所以在启动 dottrace 的时候一定要记的勾选 Using Api 模式,截图如下:
3.png

跟踪完成之后打开跟踪文件,发现 CheckParameter() 方法不在其中,同时也详细的记录了 DoRequest 下的 fileStream 耗时详情,是不是挺有意思,截图如下:
4.png

三:总结

本系列总共9篇,本想着写10篇凑个十全十美,但天残地缺,天聋地哑,才是一个人最好的状态,终归小满胜万全呀!
作为JetBrains社区内容合作者,如有购买jetbrains的产品,可以用我的折扣码 HUANGXINCHENG,有25%的内部优惠哦。
5.jpeg

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册