上一篇简单的将了一些gweb的聚合和比较视图.
那些视图都是临时创建的, gweb还支持配置自定义视图标签, 方便随时使用.
其实功能和gweb的聚合和比较视图类似, 只是把这些标签化了, 方便随时来使用.
创建视图的规则 :
Defining views using JSON
Views are stored as JSON files in the conf_dir directory. The default for the
conf_diris /var/lib/ganglia/conf. You can change that by specifying an alternate
directory in conf.php:
$conf['conf_dir'] = "/var/www/html/conf";
首先要搞清楚配置文件放在哪里 :
当前的配置如下 :
[root@db-172-16-3-221 etc]# cd /data01/web/ganglia-web/
[root@db-172-16-3-221 ganglia-web]# less conf.php
# Where to store web-based configuration
$conf['gweb_confdir'] = "/data01/web/ganglia-web";
$conf['views_dir'] = $conf['gweb_confdir'] . '/conf';
$conf['conf_dir'] = $conf['gweb_confdir'] . '/conf';
所以视图的配置文件是存在
/data01/web/ganglia-web/conf目录下的.
然后搞清楚命名规则 :
文件名为view_?.json, ?表示视图名, 必须唯一.
配置文件样板 :
注意items里面的graph的配置位置在graph.d目录这里 :
例子 :
例如再新增一个view_digoal.json
[参考]
You can create or edit existing files. The filename for the view must start with
view_and end with .json(as in, view_1.jsonor view_jira_servers.json). It must be
unique. Here is an example definition of a view that will result with a view with
three different graphs:
配置文件样板 :
view_jira.json
{
"view_name":"jira", # 视图名称
"items":[ # 视图里包含的东西, 配置为列表形式, 如下
{ "hostname":"web01.domain.com","graph":"cpu_report"}, # 图表1, 单台主机的单个graph. 在graph.d目录中定义具体内容
{ "hostname":"web02.domain.com","graph":"load_report"}, # 图表2, 单台主机的单个graph. 在graph.d目录中定义具体内容
{ "hostname":"web03.domain.com","metric":"cpu_aidle"}, # 图表3, 单台主机的单个metric
{ "aggregate_graph":"true", # 图表4, 聚合视图
"host_regex":[ # 主机规则表达式列表
{"regex":"web[2-7]"},
{"regex":"web50"}
],
"metric_regex":[ # metric规则表达式列表
{"regex":"load_one"}
],
"graph_type":"stack", # 聚合视图的画图类型, line OR stack.
"title":"Location Web Servers load" # 聚合视图的title
},
{....} # 图表5, .....
], # 列表结束
"view_type":"standard" # 视图类型
}
注意items里面的graph的配置位置在graph.d目录这里 :
/data01/web/ganglia-web/graph.d
[root@db-172-16-3-221 graph.d]# ll
total 80
-rw-r--r-- 1 nobody 1000 578 Jan 6 2014 apache_report.json
-rw-r--r-- 1 nobody 1000 186 Jan 6 2014 apache_response_report.json
-rw-r--r-- 1 nobody 1000 426 Jan 6 2014 cpu_report.json
-rw-r--r-- 1 nobody 1000 9065 Jan 6 2014 cpu_report.php
-rw-r--r-- 1 nobody 1000 476 Jan 6 2014 load_all_report.json
-rw-r--r-- 1 nobody 1000 590 Jan 6 2014 load_report.json
-rw-r--r-- 1 nobody 1000 680 Jan 6 2014 mem_report.json
-rw-r--r-- 1 nobody 1000 8324 Aug 4 03:04 mem_report.php
-rw-r--r-- 1 nobody 1000 4973 Jan 6 2014 metric.php
-rw-r--r-- 1 nobody 1000 355 Jan 6 2014 network_report.json
-rw-r--r-- 1 nobody 1000 1616 Jan 6 2014 nfs_v3_client_report.json
-rw-r--r-- 1 nobody 1000 358 Jan 6 2014 packet_report.json
-rw-r--r-- 1 nobody 1000 6392 Jan 6 2014 sample_report.php
-rw-r--r-- 1 nobody 1000 3543 Jan 6 2014 varnish_report.php
举个例子 :
[root@db-172-16-3-221 graph.d]# cat cpu_report.json
{
"report_name" : "cpu_report",
"report_type" : "template",
"title" : "CPU Report",
"graphite" : "target=alias(HOST_CLUSTER.cpu_user.sum,'User')&target=alias(HOST_CLUSTER.cpu_nice.sum%2C'Nice')&target=alias(HOST_CLUSTER.cpu_system.sum,'System')&target=alias(HOST_CLUSTER.cpu_wio.sum,'Wait')&target=alias(HOST_CLUSTER.cpu_idle.sum%2C'Idle')&areaMode=stacked&max=100&colorList=3333bb,ffea00,dd0000,ff8a60,e2e2f2"
}
[root@db-172-16-3-221 graph.d]# cat cpu_report.php
<?php
/* Pass in by reference! */
function graph_cpu_report( &$rrdtool_graph )
{
global $conf,
$context,
$range,
$rrd_dir,
$size;
if ($conf['strip_domainname']) {
$hostname = strip_domainname($GLOBALS['hostname']);
} else {
$hostname = $GLOBALS['hostname'];
}
$title = 'CPU';
$rrdtool_graph['title'] = $title;
$rrdtool_graph['upper-limit'] = '100';
$rrdtool_graph['lower-limit'] = '0';
$rrdtool_graph['vertical-label'] = 'Percent';
$rrdtool_graph['height'] += ($size == 'medium') ? 28 : 0;
$rrdtool_graph['extras'] = ($conf['graphreport_stats'] == true) ? ' --font LEGEND:7' : '';
$rrdtool_graph['extras'] .= " --rigid";
if ( $conf['graphreport_stats'] ) {
$rrdtool_graph['height'] += ($size == 'medium') ? 16 : 0;
$rmspace = '\\g';
} else {
$rmspace = '';
}
$series = '';
// RB: Perform some formatting/spacing magic.. tinkered to fit
//
$eol1 = '';
$space1 = '';
$space2 = '';
if ($size == 'small') {
$eol1 = '\\l';
$space1 = ' ';
$space2 = ' ';
} else if ($size == 'medium' || $size == 'default') {
$eol1 = '';
$space1 = ' ';
$space2 = '';
} else if ($size == 'large') {
$eol1 = '';
$space1 = ' ';
$space2 = ' ';
}
$cpu_nice_def = '';
$cpu_nice_cdef = '';
if (file_exists("$rrd_dir/cpu_nice.rrd")) {
$cpu_nice_def = "DEF:'cpu_nice'='${rrd_dir}/cpu_nice.rrd':'sum':AVERAGE ";
$cpu_nice_cdef = "CDEF:'ccpu_nice'=cpu_nice,num_nodes,/ ";
}
if ($context != "host" ) {
$series .= "DEF:'num_nodes'='${rrd_dir}/cpu_user.rrd':'num':AVERAGE ";
}
$series .= "DEF:'cpu_user'='${rrd_dir}/cpu_user.rrd':'sum':AVERAGE "
. $cpu_nice_def
. "DEF:'cpu_system'='${rrd_dir}/cpu_system.rrd':'sum':AVERAGE "
. "DEF:'cpu_idle'='${rrd_dir}/cpu_idle.rrd':'sum':AVERAGE ";
if (file_exists("$rrd_dir/cpu_wio.rrd")) {
$series .= "DEF:'cpu_wio'='${rrd_dir}/cpu_wio.rrd':'sum':AVERAGE ";
}
if (file_exists("$rrd_dir/cpu_steal.rrd")) {
$series .= "DEF:'cpu_steal'='${rrd_dir}/cpu_steal.rrd':'sum':AVERAGE ";
}
if (file_exists("$rrd_dir/cpu_sintr.rrd")) {
$series .= "DEF:'cpu_sintr'='${rrd_dir}/cpu_sintr.rrd':'sum':AVERAGE ";
}
if ($context != "host" ) {
$series .= "CDEF:'ccpu_user'=cpu_user,num_nodes,/ "
. $cpu_nice_cdef
. "CDEF:'ccpu_system'=cpu_system,num_nodes,/ "
. "CDEF:'ccpu_idle'=cpu_idle,num_nodes,/ ";
if (file_exists("$rrd_dir/cpu_wio.rrd")) {
$series .= "CDEF:'ccpu_wio'=cpu_wio,num_nodes,/ ";
}
if (file_exists("$rrd_dir/cpu_sintr.rrd")) {
$series .= "CDEF:'ccpu_sintr'=cpu_sintr,num_nodes,/ ";
}
if (file_exists("$rrd_dir/cpu_steal.rrd")) {
$series .= "CDEF:'ccpu_steal'=cpu_steal,num_nodes,/ ";
}
$plot_prefix ='ccpu';
} else {
$plot_prefix ='cpu';
}
$series .= "AREA:'${plot_prefix}_user'#${conf['cpu_user_color']}:'User${rmspace}' ";
if ( $conf['graphreport_stats'] ) {
$series .= "CDEF:user_pos=${plot_prefix}_user,0,INF,LIMIT "
. "VDEF:user_last=user_pos,LAST "
. "VDEF:user_min=user_pos,MINIMUM "
. "VDEF:user_avg=user_pos,AVERAGE "
. "VDEF:user_max=user_pos,MAXIMUM "
. "GPRINT:'user_last':' ${space1}Now\:%5.1lf%%' "
. "GPRINT:'user_min':'${space1}Min\:%5.1lf%%${eol1}' "
. "GPRINT:'user_avg':'${space2}Avg\:%5.1lf%%' "
. "GPRINT:'user_max':'${space1}Max\:%5.1lf%%\\l' ";
}
if (file_exists("$rrd_dir/cpu_nice.rrd")) {
$series .= "STACK:'${plot_prefix}_nice'#${conf['cpu_nice_color']}:'Nice${rmspace}' ";
if ( $conf['graphreport_stats'] ) {
$series .= "CDEF:nice_pos=${plot_prefix}_nice,0,INF,LIMIT "
. "VDEF:nice_last=nice_pos,LAST "
. "VDEF:nice_min=nice_pos,MINIMUM "
. "VDEF:nice_avg=nice_pos,AVERAGE "
. "VDEF:nice_max=nice_pos,MAXIMUM "
. "GPRINT:'nice_last':' ${space1}Now\:%5.1lf%%' "
. "GPRINT:'nice_min':'${space1}Min\:%5.1lf%%${eol1}' "
. "GPRINT:'nice_avg':'${space2}Avg\:%5.1lf%%' "
. "GPRINT:'nice_max':'${space1}Max\:%5.1lf%%\\l' ";
}
}
$series .= "STACK:'${plot_prefix}_system'#${conf['cpu_system_color']}:'System${rmspace}' ";
if ( $conf['graphreport_stats'] ) {
$series .= "CDEF:system_pos=${plot_prefix}_system,0,INF,LIMIT "
. "VDEF:system_last=system_pos,LAST "
. "VDEF:system_min=system_pos,MINIMUM "
. "VDEF:system_avg=system_pos,AVERAGE "
. "VDEF:system_max=system_pos,MAXIMUM "
. "GPRINT:'system_last':'${space1}Now\:%5.1lf%%' "
. "GPRINT:'system_min':'${space1}Min\:%5.1lf%%${eol1}' "
. "GPRINT:'system_avg':'${space2}Avg\:%5.1lf%%' "
. "GPRINT:'system_max':'${space1}Max\:%5.1lf%%\\l' ";
}
if (file_exists("$rrd_dir/cpu_wio.rrd")) {
$series .= "STACK:'${plot_prefix}_wio'#${conf['cpu_wio_color']}:'Wait${rmspace}' ";
if ( $conf['graphreport_stats'] ) {
$series .= "CDEF:wio_pos=${plot_prefix}_wio,0,INF,LIMIT "
. "VDEF:wio_last=wio_pos,LAST "
. "VDEF:wio_min=wio_pos,MINIMUM "
. "VDEF:wio_avg=wio_pos,AVERAGE "
. "VDEF:wio_max=wio_pos,MAXIMUM "
. "GPRINT:'wio_last':' ${space1}Now\:%5.1lf%%' "
. "GPRINT:'wio_min':'${space1}Min\:%5.1lf%%${eol1}' "
. "GPRINT:'wio_avg':'${space2}Avg\:%5.1lf%%' "
. "GPRINT:'wio_max':'${space1}Max\:%5.1lf%%\\l' ";
}
}
if (file_exists("$rrd_dir/cpu_steal.rrd")) {
$series .= "STACK:'${plot_prefix}_steal'#${conf['cpu_steal_color']}:'Steal${rmspace}' ";
if ( $conf['graphreport_stats'] ) {
$series .= "CDEF:steal_pos=${plot_prefix}_steal,0,INF,LIMIT "
. "VDEF:steal_last=steal_pos,LAST "
. "VDEF:steal_min=steal_pos,MINIMUM "
. "VDEF:steal_avg=steal_pos,AVERAGE "
. "VDEF:steal_max=steal_pos,MAXIMUM "
. "GPRINT:'steal_last':' ${space1}Now\:%5.1lf%%' "
. "GPRINT:'steal_min':'${space1}Min\:%5.1lf%%${eol1}' "
. "GPRINT:'steal_avg':'${space2}Avg\:%5.1lf%%' "
. "GPRINT:'steal_max':'${space1}Max\:%5.1lf%%\\l' ";
}
}
if (file_exists("$rrd_dir/cpu_sintr.rrd")) {
$series .= "STACK:'${plot_prefix}_sintr'#${conf['cpu_sintr_color']}:'Sintr${rmspace}' ";
if ( $conf['graphreport_stats'] ) {
$series .= "CDEF:sintr_pos=${plot_prefix}_sintr,0,INF,LIMIT "
. "VDEF:sintr_last=sintr_pos,LAST "
. "VDEF:sintr_min=sintr_pos,MINIMUM "
. "VDEF:sintr_avg=sintr_pos,AVERAGE "
. "VDEF:sintr_max=sintr_pos,MAXIMUM "
. "GPRINT:'sintr_last':' ${space1}Now\:%5.1lf%%' "
. "GPRINT:'sintr_min':'${space1}Min\:%5.1lf%%${eol1}' "
. "GPRINT:'sintr_avg':'${space2}Avg\:%5.1lf%%' "
. "GPRINT:'sintr_max':'${space1}Max\:%5.1lf%%\\l' ";
}
}
$series .= "STACK:'${plot_prefix}_idle'#${conf['cpu_idle_color']}:'Idle${rmspace}' ";
if ( $conf['graphreport_stats'] ) {
$series .= "CDEF:idle_pos=${plot_prefix}_idle,0,INF,LIMIT "
. "VDEF:idle_last=idle_pos,LAST "
. "VDEF:idle_min=idle_pos,MINIMUM "
. "VDEF:idle_avg=idle_pos,AVERAGE "
. "VDEF:idle_max=idle_pos,MAXIMUM "
. "GPRINT:'idle_last':' ${space1}Now\:%5.1lf%%' "
. "GPRINT:'idle_min':'${space1}Min\:%5.1lf%%${eol1}' "
. "GPRINT:'idle_avg':'${space2}Avg\:%5.1lf%%' "
. "GPRINT:'idle_max':'${space1}Max\:%5.1lf%%\\l' ";
}
// If metrics like cpu_user and wio are not present we are likely not collecting them on this
// host therefore we should not attempt to build anything and will likely end up with a broken
// image. To avoid that we'll make an empty image
if ( !file_exists("$rrd_dir/cpu_wio.rrd") && !file_exists("$rrd_dir/cpu_user.rrd") )
$rrdtool_graph[ 'series' ] = 'HRULE:1#FFCC33:"No matching metrics detected"';
else
$rrdtool_graph[ 'series' ] = $series;
return $rrdtool_graph;
}
?>
自定义?_report.json可以参考
view配置对应的json文件内支持的语法如下 :
Key: Value
view_name: Name of the view, which must be unique.
view_type: Standard or Regex. Regex view allows you to specify regex to match hosts.
items: An array of hashes describing which metrics should be part of the view.
hostname: Hostname of the host that we want metric/graph displayed.
metric: Name of the metric, such as load_one.
graph: Graph name, such as cpu_report or load_report. You can use metric or graph keys but not both.
aggregate_graph: If this value exists and is set to true, the item defines an aggregate graph.
This item needs a hash of regular expressions and a description.
warning: (Optional) Adds a vertical yellow line to provide visual cue for a warning state.
critical: (Optional) Adds a vertical red line to provide visual cue for a critical state.
例子 :
# cd /data01/web/ganglia-web/conf
[root@db-172-16-3-221 conf]# ll
-rw-r--r-- 1 nobody 1000 58 Jan 6 2014 view_default.json
[root@db-172-16-3-221 conf]# cat view_default.json
{"view_name":"default","items":[],"view_type":"standard"}
view_default.json是一个没有列表的配置文件,
我们修改一下它的配置 :
{
"view_name":"default",
"items":[
{ "aggregate_graph":"true",
"host_regex":[
{"regex":".*"} # 因为我这里只有一台主机, 所以暂且这样吧
],
"metric_regex":[
{"regex":"^load.*"}
],
"graph_type":"line",
"title":"Location Web Servers load"
}
],
"view_type":"standard"
}
修改后, 立即生效.
[root@db-172-16-3-221 conf]# vi view_digoal.json
{
"view_name":"digoal",
"items":[
{ "aggregate_graph":"true",
"host_regex":[
{"regex":".*"}
],
"metric_regex":[
{"regex":"^cpu.*"}
],
"graph_type":"line",
"title":"Cpu"
},
{ "aggregate_graph":"true",
"host_regex":[
{"regex":".*"}
],
"metric_regex":[
{"regex":"^mem.*"}
],
"graph_type":"line",
"title":"Mem"
}
],
"view_type":"standard"
}
这里同样说明了gmond hostname和metric name的命名规则重要性.