我有一个项目,我想动态构建特定函数调用的图表。例如,如果我有 2 个模板类 A 和 B,其中 A 有一个跟踪方法(保存为图形节点),B 有 3 个方法(非跟踪方法、跟踪方法和调用 A 的跟踪方法的跟踪方法),那么我希望能够仅将跟踪的方法调用注册为图形对象作为节点。图形对象可以是单例。
template <class TA>
class A
{
public:
void runTracked()
{
// do stuff
}
};
template <class TB>
class B
{
public:
void runNonTracked()
{
// do stuff
}
void runTracked()
{
// do stuff
}
void callATracked()
{
auto a = A<TB>();
a.runTracked();
// do stuff
}
};
void root()
{
auto b1 = B<int>();
auto b2 = B<double>();
b1.runTracked();
b2.runNonTracked();
b2.callATracked();
}
int main()
{
auto b = B<int>();
b.runTracked()
root();
return 0;
}
这应该输出与以下类似的图形对象:
root()
\-- B<int>::runTracked()
\-- B<double>::callATracked()
\-- A<double>::runTracked()
跟踪的功能应该是可调的。如果根可以调节(如上面的示例),那将是最好的。
有没有一种简单的方法可以实现这一目标?
我正在考虑引入一个用于跟踪功能的宏和一个将跟踪功能注册为节点的单例图对象。但是,我不确定如何确定调用堆栈中最后一个跟踪的函数,或者(从图形角度来看)当我想添加新节点时,哪个图形节点应该是父节点。
一般来说,你有两种策略:
-
使用某种日志记录/跟踪框架来检测您的应用程序,然后尝试复制某种类似于跟踪 mixin 的功能来应用全局/本地跟踪,具体取决于您应用 mixin 的代码部分。
-
使用为编译器或运行时启用的某种跟踪检测功能重新编译代码,然后使用关联的跟踪编译器/特定于运行时的工具/框架来转换/筛选数据。
对于 1,这将需要您手动插入更多代码或类似的内容MSVC 的 _penter/_pexit https://stackoverflow.com/questions/23071932/visual-studio-macro-for-penter-and-pexit手动或创建某种范围记录器 https://stackoverflow.com/a/3316446/3819850这将(希望如此!)将异步记录到某些外部文件/流/进程。这不一定是坏事,因为在跟踪进程崩溃的情况下,使用单独的进程控制跟踪跟踪可能会更好。无论如何,您可能必须重构代码,因为 C++ 对于元编程在模块/全局级别重构/检测代码没有提供一流的支持。然而,对于大型应用程序来说,这并不是一种罕见的模式。例如,AWS X射线 https://aws.amazon.com/xray/是商业跟踪服务的一个示例(不过,通常我认为它适合跟踪网络调用和 RPC 调用而不是进程内函数调用的用例)。
对于2,你可以尝试类似的方法utrace https://github.com/namhyung/uftrace或特定于编译器的东西:MSVC 有各种工具,例如性能浏览器 https://learn.microsoft.com/en-us/visualstudio/profiling/how-to-limit-instrumentation-to-specific-functions?view=vs-2017, LLVM 有XRay https://llvm.org/docs/XRay.html, 海湾合作委员会有gprof https://sourceware.org/binutils/docs/gprof/。您本质上是在某种“debug++”模式下进行编译,或者有一些特殊的操作系统/硬件/编译器魔法可以自动插入跟踪指令或标记,帮助运行时跟踪您所需的代码。这些启用跟踪的程序/运行时通常会发出某种唯一的跟踪格式,然后必须由唯一的跟踪格式读取器读取该格式。
最后,在内存中动态构建图也是一个类似的故事。与上面的跟踪策略一样,有多种应用程序和运行时级库可以帮助跟踪您可以通过编程方式与之交互的代码。即使是创建记录到跟踪文件的 ScopedTracer 对象的最简单版本,也可以配备一个消费者线程,该线程拥有并更新跟踪图,满足您所需的任何延迟和数据持久性要求。
Edit:如果您愿意,OpenTelemetry/Jaeger 可能是在提取数据后开始可视化跟踪的好地方(如果需要,您也可以直接向其报告),尽管它更喜欢树表示格式:Jaeger 跟踪详细信息视图文档 https://www.jaegertracing.io/docs/1.41/#trace-detail-view
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)