前段时间项目改代码突然cpu波动很大,排查了好久都没有找到原因,只能求助于性能测试工具 :
 
<<Erlang程序设计>>----Joe Armstorng[哈哈,登月第一人也叫Armstrong]
P416
cprof测试每个函数被调用了多少次,这个工具为轻量在运行系统上使用这个工具会给系统带来5%~10%的额外负载
fprof显示函数调用和被调用的埋单,并将结果输出到一个文件中,这个工具比较适合于在实验环境或模拟环境中对进行大规模的性能前一段,它会带来非常显著的系统负载.
eprof分分析一个Erlang程序中计算时间主要消耗在哪里,它实际是fprof的前任,不同在于:这适合规模小一些的性能前评估.
 
于是自己写了封装了一下,便于使用:
你可以使用seek_proc_info:help()查看到具体函数的作用:可以把这个当做cprof和fprof使用例子吧。
 
2> seek_proc_info:help().
Brief help:
seek_proc_info:queue(N) - show top N pids sorted by queue length
seek_proc_info:memory(N) - show top N pids sorted by memory usage
seek_proc_info:reds(N) - show top N pids sorted by reductions
Erlang shell with Ctrl+C
seek_proc_info:eprof_start() - start eprof on all available pids; DO NOT use on production system!
seek_proc_info:eprof_stop() - stop eprof and print result
seek_proc_info:fprof_start() - start fprof on all available pids; DO NOT use on production system!
seek_proc_info:fprof_stop() - stop eprof and print formatted result
seek_proc_info:fprof_start(N) - start and run fprof for N seconds; use seek_proc_info:fprof_analyze() to analyze collected statistics and print formatted result; use on production system with CARE
seek_proc_info:fprof_analyze() - analyze previously collected statistics using seek_proc_info:fprof_start(N) and print formatted result
seek_proc_info:help() - print this help
ok
只把你想监控的Application加到宏APPS里面,可以查看进程消息,内存,reduction情况。
源代码在下面,也可以自己改改看进程的其它信息哦。
%%%-------------------------------------------------------------------
%%% @author zhongwencool@gmail.com
%%% @doc
%%% A interface for eprof and fprof
%%% call ?MODULE:help() to see
%%% @end
%%% Created : 03. Sep 2014 3:09 PM
%%%-------------------------------------------------------------------
-module(seek_proc_info). %% API
-export([eprof_start/0, eprof_stop/0,
fprof_start/0, fprof_start/1,
fprof_stop/0, fprof_analyze/0,
queue/1, memory/1,
reds/1, help/0
]). -define(APPS, [kernel,mnesia]). %%====================================================================
%% API
%%====================================================================
help() ->
io:format("Brief help:~n"
"~p:queue(N) - show top N pids sorted by queue length~n"
"~p:memory(N) - show top N pids sorted by memory usage~n"
"~p:reds(N) - show top N pids sorted by reductions~n"
"Erlang shell with Ctrl+C~n"
"~p:eprof_start() - start eprof on all available pids; "
"DO NOT use on production system!~n"
"~p:eprof_stop() - stop eprof and print result~n"
"~p:fprof_start() - start fprof on all available pids; "
"DO NOT use on production system!~n"
"~p:fprof_stop() - stop eprof and print formatted result~n"
"~p:fprof_start(N) - start and run fprof for N seconds; "
"use ~p:fprof_analyze() to analyze collected statistics and "
"print formatted result; use on production system with CARE~n"
"~p:fprof_analyze() - analyze previously collected statistics "
"using ~p:fprof_start(N) and print formatted result~n"
"~p:help() - print this help~n",
lists:duplicate(12, ?MODULE)). eprof_start() ->
eprof:start(),
case lists:keyfind(running, 1, application:info()) of
{_, Apps} ->
case get_procs(?APPS, Apps) of
[] ->
{error, no_procs_found};
Procs ->
eprof:start_profiling(Procs)
end;
_ ->
{error, no_app_info}
end. fprof_start() ->
fprof_start(0). fprof_start(Duration) ->
case lists:keyfind(running, 1, application:info()) of
{_, Apps} ->
case get_procs(?APPS, Apps) of
[] ->
{error, no_procs_found};
Procs ->
fprof:trace([start, {procs, Procs}]),
io:format("Profiling started~n"),
if Duration > 0 ->
timer:sleep(Duration*1000),
fprof:trace([stop]),
fprof:stop();
true->
ok
end
end;
_ ->
{error, no_app_info}
end. fprof_stop() ->
fprof:trace([stop]),
fprof:profile(),
fprof:analyse([totals, no_details, {sort, own},
no_callers, {dest, "fprof.analysis"}]),
fprof:stop(),
format_fprof_analyze(). fprof_analyze() ->
fprof_stop(). eprof_stop() ->
eprof:stop_profiling(),
eprof:analyze(). queue(N) ->
dump(N, lists:reverse(lists:ukeysort(1, all_pids(queue)))). memory(N) ->
dump(N, lists:reverse(lists:ukeysort(3, all_pids(memory)))). reds(N) ->
dump(N, lists:reverse(lists:ukeysort(4, all_pids(reductions)))). %%====================================================================
%% Internal functions
%%====================================================================
get_procs(Apps, AppList) ->
io:format("Searching for processes to profile...~n", []),
Procs = lists:foldl(
fun({App, Leader},Acc) when is_pid(Leader) ->
case lists:member(App, Apps) of
true ->
[get_procs2(Leader)|Acc];
false ->
Acc
end;
(_,Acc) ->
Acc
end,[], AppList),
io:format("Found ~p processes~n", [length(Procs)]),
Procs. get_procs2(Leader) ->
lists:filter(
fun(Pid) ->
case process_info(Pid, group_leader) of
{_, Leader} ->
true;
_ ->
false
end
end, processes()). format_fprof_analyze() ->
case file:consult("fprof.analysis") of
{ok, [_, [{totals, _, _, TotalOWN}] | Rest]} ->
OWNs =
lists:flatmap(
fun({MFA, _, _, OWN}) ->
Percent = OWN*100/TotalOWN,
case round(Percent) of
0 -> [];
_ -> [{mfa_to_list(MFA), Percent}]
end
end, Rest),
ACCs = collect_accs(Rest),
MaxACC = find_max(ACCs),
MaxOWN = find_max(OWNs),
io:format("=== Sorted by OWN:~n"),
lists:foreach(
fun({MFA, Per}) ->
L = length(MFA),
S = lists:duplicate(MaxOWN - L + 2, $ ),
io:format("~s~s~.2f%~n", [MFA, S, Per])
end, lists:reverse(lists:keysort(2, OWNs))),
io:format("~n=== Sorted by ACC:~n"),
lists:foreach(
fun({MFA, Per}) ->
L = length(MFA),
S = lists:duplicate(MaxACC - L + 2, $ ),
io:format("~s~s~.2f%~n", [MFA, S, Per])
end, lists:reverse(lists:keysort(2, ACCs)));
Err ->
Err
end. mfa_to_list({M, F, A}) ->
atom_to_list(M) ++ ":" ++ atom_to_list(F) ++ "/" ++ integer_to_list(A);
mfa_to_list(F) when is_atom(F) ->
atom_to_list(F). find_max(List) ->
find_max(List, 0). find_max([{V, _}|Tail], Acc) ->
find_max(Tail, lists:max([length(V), Acc]));
find_max([], Acc) ->
Acc. collect_accs(List) ->
List1 = lists:filter(
fun({{sys, _, _}, _, _, _}) ->
false;
({suspend,_,_,_}) ->
false;
({{gen_fsm, _, _},_,_,_}) ->
false;
({{gen, _, _},_,_,_}) ->
false;
({{gen_server, _, _},_,_,_}) ->
false;
({{proc_lib, _, _},_,_,_}) ->
false;
(_) ->
true
end, List),
calculate(List1). calculate(List1) ->
TotalACC = lists:sum([A || {_, _, A, _} <- List1]),
List2 = lists:foldl(fun({MFA, _, ACC, _},NewList) ->
Percent = ACC*100/TotalACC,
case round(Percent) of
0 -> NewList;
_ -> [{mfa_to_list(MFA), Percent}|NewList]
end
end,[],List1),
lists:reverse(List2). all_pids(Type) ->
lists:foldl(
fun(P, Acc) when P == self() ->
Acc;
(P, Acc) ->
case catch process_info(
P,[message_queue_len, memory, reductions,
dictionary, current_function, registered_name]) of
[{_, Len}, {_, Memory}, {_, Reds},
{_, Dict}, {_, CurFun}, {_, RegName}] ->
IntQLen = get_internal_queue_len(Dict),
if Type == queue andalso Len == 0 andalso IntQLen == 0 ->
Acc;
true ->
[{lists:max([Len, IntQLen]),
Len,Memory, Reds, Dict, CurFun, P, RegName}|Acc]
end;
_ ->
Acc
end
end, [], processes()). get_internal_queue_len(Dict) ->
case lists:keysearch('$internal_queue_len', 1, Dict) of
{value, {_, N}} -> N;
_ -> 0
end. dump(N, Rs) ->
lists:foreach(
fun({_, MsgQLen, Memory, Reds, Dict, CurFun, Pid, RegName}) ->
io:format("** pid(~s)~n"
"** registered name: ~p~n"
"** memory: ~p~n"
"** reductions: ~p~n"
"** message queue len: ~p~n"
"** current_function: ~p~n"
"** dictionary: ~p~n~n",
[pid_to_list(Pid), RegName, Memory, Reds, MsgQLen, CurFun, Dict])
end, lists:sublist(Rs,N)).

 洋葱、萝卜和西红柿,不相信世界上有南瓜这种东西。它们认为那是一种空想。南瓜不说话,只是默默地成长。——于尔克·舒比格《当世界年纪还小的时候》

[Erlang21]Erlang性能分析工具eprof fporf的应用的更多相关文章

  1. Java 性能分析工具 , 第 3 部分: Java Mission Control

    引言 本文为 Java 性能分析工具系列文章第三篇,这里将介绍如何使用 Java 任务控制器 Java Mission Control 深入分析 Java 应用程序的性能,为程序开发人员在使用 Jav ...

  2. Java 性能分析工具 , 第 2 部分:Java 内置监控工具

    引言 本文为 Java 性能分析工具系列文章第二篇,第一篇:操作系统工具.在本文中将介绍如何使用 Java 内置监控工具更加深入的了解 Java 应用程序和 JVM 本身.在 JDK 中有许多内置的工 ...

  3. Java 性能分析工具 , 第 1 部分: 操作系统工具

    引言 性能分析的前提是将应用程序内部的运行状况以及应用运行环境的状况以一种可视化的方式更加直接的展现出来,如何来达到这种可视化的展示呢?我们需要配合使用操作系统中集成的程序监控工具和 Java 中内置 ...

  4. 系统级性能分析工具perf的介绍与使用

    测试环境:Ubuntu16.04(在VMWare虚拟机使用perf top存在无法显示问题) Kernel:3.13.0-32 系统级性能优化通常包括两个阶段:性能剖析(performance pro ...

  5. 性能分析工具-PerfView

    Roslyn的PM(程序经理) Bill Chiles,Roslyn使用纯托管代码开发,但性能超过之前使用C++编写的原生实现,这有什么秘诀呢?他最近写了一篇文章叫做<Essential Per ...

  6. 11个Visual Studio代码性能分析工具

    软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行代码分析和 ...

  7. Linux性能分析工具的安装和使用

    转自:http://blog.chinaunix.net/uid-26488891-id-3118279.html Normal 0 7.8 磅 0 2 false false false EN-US ...

  8. php性能分析工具 - xhprof的安装使用

    一.前言 有用的东西还是记录下来吧,也方便以后的查询:这次记录一下xhprof的安装使用: xhprof是facebook开源出来的一个php轻量级的性能分析工具,跟Xdebug类似,但性能开销更低, ...

  9. OProfile 性能分析工具

    OProfile 性能分析工具 官方网站:http://oprofile.sourceforge.net/news/ oprofile.ko模块本文主要介绍Oprofile工具,适用系统的CPU性能分 ...

随机推荐

  1. python mysql模块

    多次使用python操作mysql数据库,先与大家分享一下,关于如何使用python操作mysql数据库.mysql并不是python自带的模块,因此需要下载安装.(在windows平台下介绍该使用过 ...

  2. 精《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #8 调度策略

    HACK #8 调度策略 本节介绍Linux的调度策略(scheduling policy).Linux调度策略的类别大致可以分为TSS(Time Sharing System,分时系统)和实时系统这 ...

  3. shell编程: 获得目录下(包括子目录)所有文件名,路径和文件大小

    转自:http://blog.chinaunix.net/uid-26000296-id-3575475.html function ergodic(){ ` do "/"$fil ...

  4. python入门第3篇 pycharm安装及使用

    内容: 1. python开发工具的介绍及安装 2.pycharm的设置及技巧 一.python开发工具的介绍及安装 python下载后就自带了一个官方的IDE,官方的IDE我个人觉得不是很好用,所以 ...

  5. Python 2.75升级3.6.3

    https://blog.csdn.net/wwwdaan5com/article/details/78218277 Centos 7 默认yum安装python 是2.7.5, (网上看了很多升级都 ...

  6. 使用heroku创建应用时报错 heroku does not appear to be a git repository

    在跟着heroku的官方教程创建python应用时,到deploy-the-app这一步,要上传代码到heroku 的git仓库时,报的这个错误: 网上一搜,相关的答案居然极少,首页只出现一篇(还好这 ...

  7. MyEclipse10.0 配置 Tomcat1.7

    1 首先 从网上下载Tomcat1.7,然后放到本机目录. 2 然后在MyEclipse10.0菜单Preferences 指向Tomcat的路径,我本机路径是 D:\Program Files (x ...

  8. JSP九大对象

    内置对象(又叫隐含对象,有9个内置对象):不需要预先声明就可以在脚本代码和表达式中随意使用 JSP中九大内置对象为: request——请求对象——类型 javax.servlet.ServletRe ...

  9. 未能加载文件或程序集"xxxxxx"或它的某一个依赖项

    错误:未能加载文件或程序集“xxx”或它的某一个依赖项.试图加载格式不正确的程序. 原因分析:操作系统是64位的,但发布的程序引用了一些32位的ddl,所以出现了兼容性的问题. 解决方案:IIS——应 ...

  10. mysql常见错误/usr/local/mysql/bin/mysqld: [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.

    出现这种情况多数是找不到data目录,还有就是对data目录没有写入权限.