Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
B
brpc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
brpc
Commits
a5a324a3
Commit
a5a324a3
authored
Apr 22, 2018
by
zyearn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add pprof support in macos
parent
2d6535b6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
60 additions
and
4 deletions
+60
-4
cpu_profiler.md
docs/cn/cpu_profiler.md
+6
-2
heap_profiler.md
docs/cn/heap_profiler.md
+4
-1
hotspots_service.cpp
src/brpc/builtin/hotspots_service.cpp
+50
-1
No files found.
docs/cn/cpu_profiler.md
View file @
a5a324a3
...
...
@@ -34,11 +34,11 @@ WARNING: 12-26 10:01:25: * 0 [src/brpc/input_messenger.cpp:132][4294969345] Au
热点分析一般开始于找到最大的框最粗的线考察其来源及去向。
cpu profiler的原理是在定期被调用的SIGPROF handler中采样所在线程的栈,由于handler(在linux 2.6后)会被随机地摆放于活跃线程的栈上运行,cpu profiler在运行一段时间后能以很大的概率采集到所有活跃线程中的活跃函数,最后根据栈代表的函数调用关系汇总为调用图,并把地址转换成符号,这就是我们看到的结果图了。采集频率由环境变量CPUPROFILE_FREQUENCY控制,默认100,即每秒钟100次或每10ms一次。
。
在实践中cpu profiler对原程序的影响不明显。
cpu profiler的原理是在定期被调用的SIGPROF handler中采样所在线程的栈,由于handler(在linux 2.6后)会被随机地摆放于活跃线程的栈上运行,cpu profiler在运行一段时间后能以很大的概率采集到所有活跃线程中的活跃函数,最后根据栈代表的函数调用关系汇总为调用图,并把地址转换成符号,这就是我们看到的结果图了。采集频率由环境变量CPUPROFILE_FREQUENCY控制,默认100,即每秒钟100次或每10ms一次。在实践中cpu profiler对原程序的影响不明显。
![
img
](
../images/echo_cpu_profiling.png
)
你也可以使用
[
pprof
](
https://github.com/brpc/brpc/blob/master/tools/pprof
)
或gperftools中的pprof进行profiling。
在Linux下,
你也可以使用
[
pprof
](
https://github.com/brpc/brpc/blob/master/tools/pprof
)
或gperftools中的pprof进行profiling。
比如
`pprof --text localhost:9002 --seconds=5`
的意思是统计运行在本机9002端口的server的cpu情况,时长5秒。一次运行的例子如下:
...
...
@@ -91,3 +91,7 @@ Total: 2954 samples
37 1.3% 66.1% 37 1.3% memcpy
35 1.2% 67.3% 35 1.2% brpc::Socket::Address
```
# MacOS的额外配置
在MacOS下,gperftools中的perl pprof脚本会丢失函数名字,解决办法是需要自行下载
[
standalone pprof
](
https://github.com/google/pprof
)
,并把下载的pprof二进制文件路径写入环境变量GOOGLE_PPROF_BINARY_PATH中,profiler才能正常工作。
docs/cn/heap_profiler.md
View file @
a5a324a3
...
...
@@ -52,7 +52,7 @@ WARNING: 12-26 10:01:25: * 0 [src/brpc/input_messenger.cpp:132][4294969345] Au
![img](../images/heap_profiler_3.gif)
你也可以使用pprof脚本(tools/pprof)在命令行中查看文本格式结果:
在Linux下,
你也可以使用pprof脚本(tools/pprof)在命令行中查看文本格式结果:
```
$ tools/pprof --text db-rpc-dev00.db01:8765/pprof/heap
...
...
@@ -103,3 +103,6 @@ brpc还提供一个类似的growth profiler分析内存的分配去向(不考
![
img
](
../images/growth_profiler.png
)
# MacOS的额外配置
在MacOS下,gperftools中的perl pprof脚本会丢失函数名字,解决办法是需要自行下载
[
standalone pprof
](
https://github.com/google/pprof
)
,并把下载的pprof二进制文件路径写入环境变量GOOGLE_PPROF_BINARY_PATH中,profiler才能正常工作。
src/brpc/builtin/hotspots_service.cpp
View file @
a5a324a3
...
...
@@ -18,7 +18,8 @@
#include <gflags/gflags.h>
#include "butil/files/file_enumerator.h"
#include "butil/file_util.h" // butil::FilePath
#include "butil/popen.h" // butil::read_command_output
#include "butil/popen.h" // butil::read_command_output
#include "butil/fd_guard.h" // butil::fd_guard
#include "brpc/log.h"
#include "brpc/controller.h"
#include "brpc/server.h"
...
...
@@ -308,6 +309,25 @@ static void NotifyWaiters(ProfilingType type, const Controller* cur_cntl,
}
}
#if defined(OS_MACOSX)
static
bool
check_GOOGLE_PPROF_BINARY_PATH
()
{
char
*
str
=
getenv
(
"GOOGLE_PPROF_BINARY_PATH"
);
if
(
str
==
NULL
)
{
return
false
;
}
butil
::
fd_guard
fd
(
open
(
str
,
O_RDONLY
));
if
(
fd
<
0
)
{
return
false
;
}
return
true
;
}
static
bool
has_GOOGLE_PPROF_BINARY_PATH
()
{
static
bool
val
=
check_GOOGLE_PPROF_BINARY_PATH
();
return
val
;
}
#endif
static
void
DisplayResult
(
Controller
*
cntl
,
google
::
protobuf
::
Closure
*
done
,
const
char
*
prof_name
,
...
...
@@ -383,6 +403,7 @@ static void DisplayResult(Controller* cntl,
pprof_tool
.
push_back
(
'/'
);
pprof_tool
+=
PPROF_FILENAME
;
#if defined(OS_LINUX)
cmd_builder
<<
"perl "
<<
pprof_tool
<<
(
use_text
?
" --text "
:
" --dot "
)
<<
(
show_ccount
?
" --contention "
:
""
);
...
...
@@ -390,6 +411,16 @@ static void DisplayResult(Controller* cntl,
cmd_builder
<<
"--base "
<<
*
base_name
<<
' '
;
}
cmd_builder
<<
GetProgramName
()
<<
" "
<<
prof_name
<<
" 2>&1 "
;
#elif defined(OS_MACOSX)
cmd_builder
<<
getenv
(
"GOOGLE_PPROF_BINARY_PATH"
)
<<
" "
<<
(
use_text
?
" -text "
:
" -dot "
)
<<
(
show_ccount
?
" -contentions "
:
""
);
if
(
base_name
)
{
cmd_builder
<<
"-base "
<<
*
base_name
<<
' '
;
}
cmd_builder
<<
prof_name
<<
" 2>&1 "
;
#endif
const
std
::
string
cmd
=
cmd_builder
.
str
();
for
(
int
ntry
=
0
;
ntry
<
2
;
++
ntry
)
{
if
(
!
g_written_pprof_perl
)
{
...
...
@@ -601,6 +632,16 @@ static void DoProfiling(ProfilingType type,
cntl
->
http_response
().
set_status_code
(
HTTP_STATUS_INTERNAL_SERVER_ERROR
);
return
NotifyWaiters
(
type
,
cntl
,
view
);
}
#if defined(OS_MACOSX)
if
(
!
has_GOOGLE_PPROF_BINARY_PATH
())
{
os
<<
"no GOOGLE_PPROF_BINARY_PATH in env"
<<
(
use_html
?
"</body></html>"
:
"
\n
"
);
os
.
move_to
(
resp
);
cntl
->
http_response
().
set_status_code
(
HTTP_STATUS_FORBIDDEN
);
return
NotifyWaiters
(
type
,
cntl
,
view
);
}
#endif
if
(
type
==
PROFILING_CPU
)
{
if
((
void
*
)
ProfilerStart
==
NULL
||
(
void
*
)
ProfilerStop
==
NULL
)
{
os
<<
"CPU profiler is not enabled"
...
...
@@ -713,6 +754,7 @@ static void StartProfiling(ProfilingType type,
butil
::
IOBufBuilder
os
;
bool
enabled
=
false
;
const
char
*
extra_desc
=
""
;
if
(
type
==
PROFILING_CPU
)
{
enabled
=
cpu_profiler_enabled
;
}
else
if
(
type
==
PROFILING_CONTENTION
)
{
...
...
@@ -727,6 +769,13 @@ static void StartProfiling(ProfilingType type,
enabled
=
IsHeapProfilerEnabled
();
}
const
char
*
const
type_str
=
ProfilingType2String
(
type
);
#if defined(OS_MACOSX)
if
(
!
has_GOOGLE_PPROF_BINARY_PATH
())
{
enabled
=
false
;
extra_desc
=
"(no GOOGLE_PPROF_BINARY_PATH in env)"
;
}
#endif
if
(
!
use_html
)
{
if
(
!
enabled
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment