一:背景

1. 讲故事

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

二:跨平台和自定义诊断

1. 如何跨平台诊断分析

如果 dottrace 只能在 windows 平台上跑,那确实不值得写一个系列,目前它可以横跨三大平台(Windows,Linux,Mac),这里就用 ubuntu 来给大家演示下,参考代码如下:


public class TimeConsumingMethodExample
{
public static void Main()
{
Console.WriteLine("开始执行耗时方法..."); // 调用耗时方法
PerformTimeConsumingTask(3000); Console.WriteLine("耗时方法执行完成!");
} /// <summary>
/// 模拟一个耗时方法
/// </summary>
/// <param name="milliseconds">要模拟的耗时(毫秒)</param>
public static void PerformTimeConsumingTask(int milliseconds)
{
Stopwatch stopwatch = Stopwatch.StartNew(); // 模拟耗时操作 - 这里使用Thread.Sleep
Thread.Sleep(milliseconds); stopwatch.Stop();
Console.WriteLine($"方法执行耗时: {stopwatch.ElapsedMilliseconds} 毫秒");
}
}

接下来使用 dotnet pulish 将其发布到 ubuntu 平台。


root@ubuntu2404:/data2/code# ls -lh
total 100K
-rw-r--r-- 1 root root 71K Jun 30 09:01 ConsoleApp7
-rw-r--r-- 1 root root 482 Jun 30 09:01 ConsoleApp7.deps.json
-rw-r--r-- 1 root root 4.5K Jun 30 09:01 ConsoleApp7.dll
-rw-r--r-- 1 root root 12K Jun 30 09:01 ConsoleApp7.pdb
-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 跟踪模式,参考如下:


root@ubuntu2404:/data2/dottrace# tar -xzxf JetBrains.dotTrace.CommandLineTools.linux-x64.2025.1.3.tar.gz root@ubuntu2404:/data2/dottrace# ./dottrace start --profiling-type=Timeline --framework=NetCore /usr/bin/dotnet /data2/code/ConsoleApp7.dll --save-to=/data2/output/snnapshot.dtp
dotTrace command-line profiler 2025.1.3 build 777.0.20250604.2353. Copyright (C) 2025 JetBrains s.r.o.
Preparing to profile...
Profiling in progress...
开始执行耗时方法...
方法执行耗时: 3000 毫秒
耗时方法执行完成!
Profiling is finished in 5.523 seconds
Collected snapshot: /data2/output/snnapshot.dtp

从卦中可以看到 snnapshot.dtp 跟踪文件已生成,接下来就是打包到windows平台用分析啦,是不是有点像 dump 的事后分析,参考如下:


root@ubuntu2404:/data2/output# tar -czvf dottrace_snapshot.tar.gz snnapshot.dtp*
snnapshot.dtp
snnapshot.dtp.0000
snnapshot.dtp.0001
snnapshot.dtp.0002
snnapshot.dtp.0003
snnapshot.dtp.0004
snnapshot.dtp.0005
snnapshot.dtp.0006
snnapshot.dtp.0007
... root@ubuntu2404:/data2/output# sz dottrace_snapshot.tar.gz

  • dotnet cli 工具包

如果使用源码方式有这样或者那样的问题,可以使用此种方式,它会将 command-line 工具集成到了 dotnet cli 中,参考如下:


root@ubuntu2404:/data2/dottrace# dotnet tool install --global JetBrains.dotTrace.GlobalTools
Skipping NuGet package signature verification.
You can invoke the tool using the following command: dottrace
Tool 'jetbrains.dottrace.globaltools' (version '2025.1.3') was successfully installed.
root@ubuntu2404:/data2/dottrace# cd ..
root@ubuntu2404:/data2# dottrace start --profiling-type=Timeline --framework=NetCore --save-to=/data2/output/snnapshot.dtp /usr/bin/dotnet /data2/code/ConsoleApp7.dll
dotTrace command-line profiler 2025.1.3 build 777.0.20250604.2353. Copyright (C) 2025 JetBrains s.r.o.
Preparing to profile...
Profiling in progress...
开始执行耗时方法...
方法执行耗时: 3000 毫秒
耗时方法执行完成!
Profiling is finished in 5.65 seconds
Collected snapshot: /data2/output/snnapshot.dtp

是不是挺有意思的。

2. 如何自定义诊断分析

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

但这种跟踪方式会掺杂很多噪音,除了让跟踪文件变大,也不利于我们过滤分析,所以就有了一个需求,如何指定 作用域 分析?比如我只想分析某一个方法,厉害的是 dottrace 还真可以做到,在 nuget 上引用 JetBrains.Profiler.Api 包,然后用 MeasureProfiler.StartCollectingData()MeasureProfiler.SaveData(); 将分析的范围圈一下即可,参考代码如下:


class Program
{
static void Main()
{
// 创建并启动Stopwatch
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start(); string filePath = @"D:\1GB_LogFile.log";
DoRequest(filePath); // 停止并显示总耗时
stopwatch.Stop();
Console.WriteLine($"总耗时: {stopwatch.Elapsed.TotalSeconds:F2}秒");
} static void DoRequest(string filePath)
{
CheckParameter(); const int chunkSize = 512 * 1024 * 1024; // 每次读取512MB try
{
Console.WriteLine("开始分块读取文件...");
int chunkCount = 0;
long totalBytesRead = 0; MeasureProfiler.StartCollectingData(); using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
byte[] buffer = new byte[chunkSize];
int bytesRead; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
totalBytesRead += bytesRead;
chunkCount++; // 处理当前块的数据
string chunkContent = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($"读取块 {chunkCount}, 大小: {bytesRead / 1024}KB, 总计: {totalBytesRead / 1024 / 1024}MB");
}
} MeasureProfiler.SaveData(); Console.WriteLine($"文件读取完成,共 {chunkCount} 块");
}
catch (Exception ex)
{
Console.WriteLine($"出错: {ex.Message}");
}
} static void CheckParameter()
{
Console.WriteLine("检查参数开始...");
Thread.Sleep(5000);
Console.WriteLine("检查参数结束...");
}
}

从卦中代码不难看出,MeasureProfiler.StartCollectingData 应该就是 Start 的API实现,既然是api实现那肯定需要同 dottrace 本体进行通信,所以在启动 dottrace 的时候一定要记的勾选 Using Api 模式,截图如下:

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

三:总结

本系列总共9篇,本想着写10篇凑个十全十美,但天残地缺,天聋地哑,才是一个人最好的状态,终归小满胜万全呀!

作为JetBrains社区内容合作者,如有购买jetbrains的产品,可以用我的折扣码 HUANGXINCHENG,有25%的内部优惠哦。

DotTrace系列:9. 大结局之 跨平台 和 自定义行为 诊断的更多相关文章

  1. 大白话系列之C#委托与事件讲解大结局

    声明:本系列非原创,因为太精彩才转载,如有侵权请通知删除,原文:http://www.cnblogs.com/wudiwushen/archive/2010/04/20/1698795.html 今天 ...

  2. 实力封装:Unity打包AssetBundle(大结局)

    →→前情提要:让用户选择要打包的文件←← 大结局:更多选择 Unity打包AssetBundle从入门到放弃系列终于要迎来大结局了[小哥哥表示实在写不动了o(╥﹏╥)o]... 经过上一次的教程,其实 ...

  3. Java匹马行天下之Java帝国的崛起(大结局)

    Java匹马行天下之Java帝国的崛起大结局 前言: [博客*缘] 网络真情伴, 博客友谊连. 笑中藏泪暖中寒. 回想那些悲喜, 苦涩也缠绵. 往事难回首, 新篇染旧言. 世间多少梦能全. 感谢相牵, ...

  4. Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):5、Maven版本发布与后续版本更新(大结局)

    文章目录: Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):1.JIRA账号注册 Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):2.PGP ...

  5. acdream 小晴天老师系列——苹果大丰收(DP)

    小晴天老师系列——苹果大丰收 Problem Description 小晴天的后花园有好多好多的苹果树,某天,苹果大丰收~小晴天总共摘了M个苹果,我们假设苹果之间是不可分辨的. 为了保存苹果,小晴天买 ...

  6. Windows Phone开发(45):推送通知大结局——Raw通知

    原文:Windows Phone开发(45):推送通知大结局--Raw通知 为什么叫大结局呢?因为推送通知服务就只有三种,前面扯了两种,就剩下一种--Raw通知. 前面我们通过两节的动手实验,相信大家 ...

  7. F - 小晴天老师系列——苹果大丰收

    F - 小晴天老师系列——苹果大丰收 Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Other ...

  8. AC的故事大结局山寨版(下)(最大流)

    福建工程学院第十二届ACM程序设计大赛真题 AC的故事大结局山寨版(下) TimeLimit:2000MS  MemoryLimit:128MB 64-bit integer IO format:%l ...

  9. AC的故事大结局山寨版(下)

    AC的故事大结局山寨版(下) TimeLimit:2000MS  MemoryLimit:128MB 64-bit integer IO format:%lld   Problem Descripti ...

  10. Mybatis 系列9-强大的动态sql 语句

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

随机推荐

  1. LeetCode1464. 数组中两元素的最大乘积-JAVA

    题目 给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值.请你计算并返回该式的最大值. 示例 1: 输入:nums = ...

  2. 创建bean对象的三种方式

    一.使用无参构造方法创建 二.使用静态工厂创建 三.使用实例工厂创建

  3. mybatis-plus之配置安全

    1. 环境 SpringBoot 2.6.x 2. 介绍 MyBatis-Plus 从3.3.2版本开始提供了数据安全保护功能,MyBatis-Plus 支持通过加密配置来增强数据库的安全性. 3. ...

  4. Web前端入门第 36 问:多图细说 CSS grid 网格布局(一)父元素容器相关属性

    grid 网格布局与 flex 弹性盒子布局一样,都需要控制 容器 跟 子元素 的样式才能做出想要的效果,部分场景只控制 容器 样式也行. grid 样式属性 一大堆 属性 来袭~~ 与网格相关的 C ...

  5. wpf 打开输入法、禁用输入法

    1 <StackPanel Margin="10"> 2 <TextBox Text="默认"></TextBox> 3 & ...

  6. 1K star!这个开源项目让短信集成简单到离谱,开发效率直接翻倍!

    嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 "让简单的事情回归简单的本质" -- SMS4J 项目宣言 SMS4J ...

  7. SQL优化--转载

    因为现在面试经常需要问的需要SQL优化,问的具体操作步骤时候的常见做法,所以网上总结这些操作步骤: SQL优化的具体操作: 1.在表中建立索引,优先考虑where.group by使用到的字段. 2. ...

  8. 作业时间之"最早时间和最晚时间"

    一.从左往右(小到大)算最早时间 0+2=2 0+3=3 因为3比2大所以选择3(早大晚小),需活动无时间所以不用加 3+4=7 7+3=10 因为13号点有两个 2+5=7 和 11号点的10(虚活 ...

  9. RocketMQ半消息对消费者不可见是如何实现的?——事务消息机制揭秘

    首发于工号[BiggerBoy],原文链接 --"半消息藏在这里,但为什么你偷看也没用?" 上篇<RocketMQ系列笔记(三):消息模型与高阶玩法,顺序事务消息拿捏指南&g ...

  10. codeup之找x

    Description 输入一个数n,然后输入n个数值各不相同,再输入一个值x,输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1). Input 测试数据有多组,输入n(1<=n& ...