ganglia自定义图表

http://blog.163.com/digoal@126/blog/static/1638770402014815105622529/

上一篇简单的将了一些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, ?表示视图名, 必须唯一.

 

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是一个没有列表的配置文件, 
ganglia gweb customize views - 德哥@Digoal - PostgreSQL research
我们修改一下它的配置 : 

 

{
  "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"
}
修改后, 立即生效.
ganglia gweb customize views - 德哥@Digoal - PostgreSQL research
例如再新增一个view_digoal.json

 

[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"
}
ganglia gweb customize views - 德哥@Digoal - PostgreSQL research
这里同样说明了gmond hostname和metric name的命名规则重要性.
 
 
http://blog.csdn.net/cloudeep/article/details/5669295

Ganglia 扩展之 Python 实现方法

                                                                                  --作者:Terry,Schubert

1.      Ganglia 简介

Ganglia 是 UC Berkeley 发起的一个开源监视项目,设计用于测量数以千计的节点。每台计算机都运行一个收集和发送度量数据(如处理器速度、内存使用量等)的名为  gmond  的守护进程。它将从操作系统和指定主机中收集。接收所有度量数据的主机可以显示这些数据并且可以将这些数据的精简表单传递到层次结构中。正因为有这种层次结构模式,才使得 Ganglia 可以实现良好的扩展。 gmond  带来的系统负载非常少,这使得它成为在集群中各台计算机上运行的一段代码,而不会影响用户性能。

 

所有这些数据收集会多次影响节点性能。网络中的 “ 抖动( Jitter ) ” 发生在大量小消息同时出现时。我们发现通过将节点时钟保持一致,就可以避免这个问题。

 

2.      Ganglia 扩展能力

基本 Ganglia 安装已经给我们提供了大量有用信息。使用 Ganglia 的插件将给我们提供两种添加更多功能的方法:

  • 通过添加带内( in-band )插件。
  • 通过添加一些其他来源的带外( out-of-band )欺骗。

Ganglia 安装启动部分参照文档尾部的参考资料,本文档主要讲解 Ganglia 扩展方法的带内 Python 插件实现。

 

3.      系统准备

实验环境:

l  机器:

n  机型: DELL OPTIPLEX 755

n  操作系统: Linux 2.6.18-164.15.1.el5.centos.plus #1 SMP Wed Mar 17 19:54:20 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

n  内存: 2G

 

l  Ganglia 部署环境

n  Ganglia 根目录: /usr/local/ganglia/                   $GANGLIA_ROOT

n  Ganglia 配置文件目录: /etc/ganglia/                 $GANGLIA_CONF

n  Ganglia RRDTool 目录: /var/lib/ganglia/rrds/       $GANGLIA_RRDS

n  Ganglia html 目录: /var/www/html/ganglia/   $GANGLIA_WEB

为了方便描述,将采用 $GANGLIA_*** 代表相关环境。

 

如果安装成功,可发现 $GANGLIA_ROOT/lib64/ganglia/modpython.so ,该文件是 Ganglia Python 扩展的动态库文件,若不存在,则无法支持 python 扩展。

4.      Python 扩展的实现

1)     实例描述

我们以实现一个 random_module , random 模块中有两个 metric : random1 和 random2 。我们限定 random的取值为 [RandMin,RandomMax], 其中 random1+random2 互补,即

random2 = RandomMin + RandomMax - random1

 

2)     需要做的工作

为实现该模块需要做的工作如下:

l  修改配置文件,添加扩展的模块

l  编写扩展模块 Python 代码

l  增加扩展模块的统计表(可省略)

 

3)     修改配置文件

l  gmond.conf 文件

修改 $GANGLIA_CONF/gmond.conf 文件,操作如下:

 

*********************** Start ****************************

modules {

      …..

  module {

    name = "sys_module"

    path = "modsys.so"

  }

 

  /* 添加 python 主模块 */

  module {

    name = "python_module"

 

/* 动态库路径, 完整路径为   $GANGLIA_ROOT/lib64/ganglia/modpython.so */

    path = "modpython.so"  

 

/*  Python 扩展模块代码存放目录,不存在则创建 */

    params="/etc/ganglia/python_modules/"

 

}

  }

 

include ('/etc/ganglia/conf.d/*.conf')

/* /etc/ganglia/conf.d/ 为 python 扩展模块配置文件存放目录,不存在则创建, gmond 启动时,会 load 所有的配置文件和 python 模块代码

  */

include ('/etc/ganglia/conf.d/*.pyconf')

….

*********************** End ****************************

 

我们将用 $GANGLIA_PY_CODE 和 $GANGLIA_PY_CONF 来表示 Python 扩展模块的代码和配置文件存放的目录

 

l  random_module.pyconf 文件

vi $GANGLIA_PY_CONF/random_module.pyconf

random_module.pyconf 内容如下:

*********************** Start ****************************

modules {

  module {

  /*  模块名 $PY_MODULE ,创建 Python 文件路径为 $GANGLIA_PY_CODE/$PY_MODULE.py */

    name = "random_module"

language = "python"

/* 参数列表,所有的参数作为一个 dict( 即 map) 传给 python 脚本的 metric_init(params) 函数。

   本例中, metric_init 调用时, params={“RandomMax”:”10”,”RandomMin”:”0”}

   */

    param RandomMax{ 

        value = 10

    }

    param RandomMin{

        value = 0

    }

  }

}

 

/*  需要收集的 metric 列表,一个模块中可以扩展任意个 metric

 

本例中,我们收集的 metric 为 random1 和 random2.

Title 的内容,作为 metric 图的标题

  */

collection_group {

  /* 汇报周期

   可选参数:

collect_once – Specifies that the group of static metrics

collect_every – Collection interval (only valid for non-static)

time_threshold – Max data send interval

*/

  collect_every = 10  /* 10 s 汇报一次 */

 

  time_threshold = 50

  metric {

    name = "random1"

    title = "test random1"   /* Metric name (see “gmond –m”)  */

    value_threshold = 50  /* Metric variance threshold (send if exceeded) */

  }

  metric {

     name="random2"

     title = "test random2"

     value_threshold = 50

  }

}

*********************** End ****************************

 

4)     编写模块代码

Ganglia 模块扩展时, Python 脚本主要要实现的函数有:

l  metric_init(params): 

§  Called once at module initialization time

§  Must return a metric description dictionary or list of dictionaries

Metric definition data dictionary :

d = {      ‘name’ : ‘<your_metric_name>’,

‘ call_back’ : <call_back function>,

‘ time_max’ : int(<your_time_max>),

‘ value_type’ : ‘<string | uint | float | double>’,

‘ units’ : ’<your_units>’,

‘ slope’ : ‘<zero | positive | negative | both>’,

‘ format’ : ‘<your_format>’,

‘ description’ : ‘<your_description>’}

 

Can be a single dictionary or a list of dictionaries

Must be returned from the metric_init() function

 

§  Any other module initialization can also take place here

l  metric_handler() – may have multiple handlers

§  Metric gathering handler

§  Must return a single data value of the same type as specified in the metric_init() function

l  metric_cleanup()

§  Called once at module termination time

§  Does not return a value

vi $GANGLIA_PY_CODE /random_module.py

random_module.py 的代码如下:

*********************** Start ****************************

 

 

[python] view plaincopy
 
  1. import random  
  2. random_max = 100  
  3. random_min = 0  
  4. v = 0  
  5. def random1_handler(name):  
  6.         global v,random_max,random_min  
  7.         v = random.randint(random_min,random_max)  
  8.         return v  
  9. def random2_handler(name):  
  10.         global v,random_max,random_min  
  11.         return random_min+random_max-v  
  12. def metric_init(params):  
  13.         global random_max,random_min  
  14.         if params:  
  15.                 if params.has_key("RandomMin"):  
  16.                         random_min = int(params["RandomMin"])  
  17.                 if params.has_key("RandomMax"):  
  18.                         random_max = int(params["RandomMax"])  
  19.         tmp = {'name':'random1','call_back':random1_handler,  
  20.                 'value_type':'uint','units':'usage',  
  21.                 'slope':'both','format':'%u',  
  22.                 'description':'test random plugin',  
  23.                 'groups':'random'}  
  24.         descriptors = [tmp]  
  25.         tmp1 = {'name':'random2','call_back':random2_handler,  
  26.                 'value_type':'uint','units':'usage',  
  27.                 'slope':'both','format':'%u',  
  28.                 'description':'test subs plugin',  
  29.                 'groups':'random'}  
  30.         descriptors.append(tmp1)  
  31.         return descriptors  
  32. def metric_cleanup():  
  33.         pass  
  34. if __name__=='__main__':  
  35.         descriptors = metric_init(None)  
  36.         for d in descriptors:  
  37.                 print "value for %s is %d"%(d['name'],d['call_back'](d['name']))  
  

 

*********************** End ****************************

 

 

完成以上步骤后,重启 gmond ,就可以在 web 界面的节点视图上看到新添的 random1 和 random2 的统计图表

 

截图如下:

 

  

5)     增加统计表

通过以上扩展,我们增加了自定义的 metric ,这些 metric 各自以图表的形式展现,为了方便查找问题,需要将若干 metric 结合起来,显示在同一个表中,这时我们就需要增加相应的统计表展现。该部分实现仅需修改 Ganglia 的web 代码。这里,我们以扩展的 random 模块作为例子,将 random1 和 random2 两个 metric 画在同一张表中。

 

$GANGLIA_WEB 目录文件组及相关文件说明见附录 1.

 

为此我们需要做的工作:

l  修改 $GANGLIA_WEB/conf.php 文件,添加要显示的统计表名称 $GRAPH_NAME ,本例中为“ random ”;

l  编写 $GANGLIA_WEB/graph.d/{$GRAPH_NAME}_report.php 文件,并实现函数:

function graph_{$GRAPH_NAME}_report ( &$rrdtool_graph )

l  重启 httpd 服务。

a)     修改 $GANGLIA_WEB/conf.php 文件

Vi $GANGLIA_WEB/conf.php

************************* Start **********************

 

#

# Colors for the load ranks.

#

$load_colors = array(

   "100+" => "ff634f",

   "75-100" =>"ffa15e",

   "50-75" => "ffde5e",

   "25-50" => "caff98",

   "0-25" => "e2ecff",

   "down" => "515151"

);

 

#

# 添加我们自定义 metric 的颜色,也可以在 random_report.php 中定义

# Colors for the random report graph

#

$random1_color = "0000FF";

$random2_color = "FF0000";

#

# Default metric

#

$default_metric = "load_one";

 

#

# Optional summary graphs

#

#$optional_graphs = array('packet');

# 需要添加的统计表名

$optional_graphs = array('random');

************************ End *************************

 

b)     编写 $GANGLIA_WEB/graph.d/random_report.php 文件

我们可以参考 $GANGLIA_WEB/graph.d/ 目录下已经实现的内容。

 

Vi $GANGLIA_WEB/graph.d/random_report.php

************************ Start  *************************

 

 

[php] view plaincopy
 
  1. <?php  
  2. function graph_random_report ( &$rrdtool_graph ) {  
  3.     global $context,     //声明全局变量  
  4.            $random1_color,  
  5.            $random2_color,  
  6.            $hostname,  
  7.            $range,  
  8.            $rrd_dir,    // 即$GANGLIA_RRDS  
  9.            $size;  
  10.     //  
  11.    // You *MUST* set at least the 'title', 'vertical-label', and 'series' variables.  
  12.     // Otherwise, the graph *will not work*.  
  13.     //  
  14.     $title = 'random';     
  15.     if ($context != 'host') {  //判断是否为节点视图  
  16.        $rrdtool_graph['title']  = $title;  // 设置图表的标题  
  17.     } else {  
  18.        $rrdtool_graph['title']  = "$hostname $title last $range";  
  19.     }  
  20.     $rrdtool_graph['vertical-label'] = 'usage'; // Y坐标标题  
  21.     $rrdtool_graph['height']        += $size == 'medium' ? 28 : 0 ;   // Fudge to account for number of lines in the chart legend  
  22.     $rrdtool_graph['upper-limit']    = '10';  
  23.     $rrdtool_graph['lower-limit']    = '0';  
  24.     $rrdtool_graph['extras']         = '--rigid';  
  25.     if($context != "host" ) {  
  26.         $series = "DEF:'num_nodes'='${rrd_dir}/cpu_user.rrd':'num':AVERAGE "  
  27.             . "DEF:'random1'='${rrd_dir}/random1.rrd':'sum':AVERAGE"  
  28.             . "CDEF:'crandom1'=random1,num_nodes,/ "  
  29.             . "DEF:'random2'='${rrd_dir}/random2.rrd':'sum':AVERAGE"  
  30.             . "CDEF:'crandom2'=random2,num_nodes,/ "  
  31.             . "LINE2:'crandom1'#$random1_color:'random1' "  
  32.             . "LINE2:'crandom2'#$random2_color:'random2' ";  
  33.     }  
  34.     else  
  35.     {  
  36.         $series = "DEF:'random1'='${rrd_dir}/random1.rrd':'sum':AVERAGE "  
  37.             . "DEF:'random2'='${rrd_dir}/random2.rrd':'sum':AVERAGE"  
  38.             . "LINE2:'random1'#$random1_color:'random1' "  
  39.             . "LINE2:'random2'#$random2_color:'random2' ";  
  40.     }  
  41.     // We have everything now, so add it to the array, and go on our way.  
  42.     $rrdtool_graph['series'] = $series;  
  43.     return $rrdtool_graph;  
  44. }  
  45. ?>  

 

************************ End *************************

 

摘录《 Custom Graphs in Ganglia 3.1.x 》,相关说明如下:

 



 

  • Set values for the following hash keys:

$rrdtool_graph['title']

This will be used as the "title" of the graph.

$rrdtool_graph['vertical_label']

This will set the label for the Y-axis on the chart (there is no corresponding X-axis key, since it is always "time.)

$rrdtool_graph['series']

Commands to actually generate the  rrdtool   graph are here. This is a string variable, so care must be taken to properly format and space each command. Developers may find it useful to create a temporary array and  push()  commands into it, then  implode()   them into a single string.

  • Set other variables as desired. Setting the "upper-limit" and "lower-limit" keys can be useful to clamp a chart to a fixed range in the Y-axis. For example, if you are monitoring a percentage, and always want the low and high values to be 0 and 100, respectively. This can also be used to ignore values outside the norm that would otherwise cause rrdtool to chose an inappropriate range; basically, cheap spike removal.
  • The most difficult part of generating the graph is properly setting the  $rrdtool_graph['series']  value. It is suggested that you experiment first on the command line, using rrdtool directly, then convert that into a set of PHP statements. The PHP code can be as simple or complicated as required.
  • There are many variables are pre-defined and available for use in custom graphs. Users are encouraged to make use of these, although changing the values inside the report PHP file is  notrecommended. Variables are imported into the scope of the PHP file using the  global   PHP function (yes, it's ugly, we know). A list of the more commonly used variables is:

$context   (e.g. "host", "cluster", "meta", etc)

$cpu_*_color   (see list in conf.php)

$hostname   (set to the current hostname, as known to gmetad)

$load_one_color

$range   (time range of the graph, usually "hour", "week", "month", or "year")

$load_colors   (assoc. array that stores colors for the CPU report. Valid keys are: "down", "0-25", "25-50", "50-75", "75-100", "100+")

$rrd_dir   (Appropriate filesystem directory for the RRD file in question. Different contexts (host/cluster/meta) will be handled correctly.  Use this   instead of hardcoding paths to RRD files.)

$mem_*_color   (similar to  $cpu_*color, above)

$size   (Current size of the graph, usually "small", "medium", "large", etc)

$strip_domainname   (should the "shortname" of the host be used, instead of the FQDN?)

  • Penultimately, any value in the  $rrdtool_graph['extras']   key will be passed, verbaitim, to rrdtool after all other keys, but before various data definition, calculation, graphing and printing elements. This key is essentially a way for the developer to add any other rrdtool options that are desired, and make a last-ditch effort to override other settings.
  • And lastly, the $rrdtool_graph variable should be the return value of the function; Ganglia will take care of the rest!

 


#rrdtool_graph_keys?

  • Keys present in the $rrdtool_graph associative array.

A list of keys in $rrdtool_graph that are used:

    $series (string: holds the meat of the rrdgraph definition. REQUIRED!)   

//见参考文档 《RRD 数据库及RRDTool 简介》

    $title           (string: title of the report. REQUIRED!) 
$vertical_label (label for Y-Axis. REQUIRED!)

$start (string: Start time of the graph, can usually be
left alone)
$end (string: End time of the graph, also can usually be
left alone)

$width (strings: Width and height of *graph*, the actual image
$height will be slightly larger due to text elements
and padding. These are normally set
automatically, depending on the graph size
chosen from the web UI)

$upper-limit (strings: Maximum and minimum Y-value for the graph.
$lower-limit RRDTool normally will auto-scale the Y min
and max to fit the data. You may override
this by setting these variables to specific
limits. The default value is a null string,
which will force the auto-scale behavior)

$color (array: Sets one or more chart colors. Usually used
for setting the background color of the chart.
Valid array keys are BACK, CANVAS, SHADEA,
SHADEB, FONT, FRAME and ARROW. Usually,
only BACK is set, and only rarely at that.)

$extras (Any other custom rrdtool commands can be added to this
variable. For example, setting a different --base
value or use a --logarithmic scale)


做完以上操作,重启 httpd ,操作如下:
 

 

Service httpd restart

 

我们可以在 cluster 视图中看到 random 统计图表,截图如下:

 

 

 

但在节点视图上看不到该图表,尽管 $GANGLIA_WEB/graph.d/random_report.php 中针对集群视图和节点视图都做了处理。

 

6)     Ganglia 自定义 Web 模板

检查 web 执行流程,我们发现 $GANGLIA_WEB/host_view.php 以及 $GANGLIA_WEB/ templates/default/host_view.tpl 中均没有自定义统计表显示的代码。为了保证默认模板不变,我们建立新的模板目录 $GANGLIA_WEB/ templates/onest, 并将 default 的内容拷贝到该目录下。

 

a)     修改 $GANGLIA_WEB/host_view.php

在文件尾部 “ $tpl->printToScreen(); ” 语句前,添加如下代码:

// 添加自定义统计表信息

if (!isset($optional_graphs))

        $optional_graphs = array();

foreach ($optional_graphs as $g) {

        $tpl->newBlock('optional_graphs');

        $tpl->assign('name',$g);

        $tpl->assign("cluster_url", $cluster_url);

        $tpl->assign("graphargs", "h=$hostname&amp;$get_metric_string&amp;st=$cluster[LOCALTIME]");

        $tpl->gotoBlock('_ROOT');

}

 

该部分是通过替换 $GANGLIA_WEB/ templates/onest/host_view.tpl 的 optional_graphs 模块实现的。

 

b)     修改 $GANGLIA_WEB/ templates/onest/host_view.tpl

**************** Start ****************************

…….

<A HREF="./graph.php?g=network_report&z=large&c={cluster_url}&{graphargs}">

<IMG BORDER=0 ALT="{cluster_url} NETWORK"

   SRC="./graph.php?g=network_report&z=medium&c={cluster_url}&{graphargs}">

</A>

<A HREF="./graph.php?g=packet_report&z=large&c={cluster_url}&{graphargs}">

<IMG BORDER=0 ALT="{cluster_url} PACKETS"

   SRC="./graph.php?g=packet_report&z=medium&c={cluster_url}&{graphargs}">

</A>

<!-- START BLOCK : optional_graphs -->

<A HREF="./graph.php?g={name}_report&z=large&c={cluster_url}&{graphargs}">

<IMG BORDER=0 ALT="{cluster_url} {name}"

    SRC="./graph.php?g={name}_report&z=medium&c={cluster_url}&{graphargs}">

</A>

<!-- END BLOCK : optional_graphs -->

…..

************************* End ****************************

以上修改中,在节点视图中增加了网络包统计表以及自定义统计表

 

c)      修改 $GANGLIA_WEB/conf.php

修改 $template_name 参数 , 让其指向我们的模板目录

**************** Start ****************************

<?php

# $Id: conf.php.in 1688 2008-08-15 12:34:40Z carenas $

#

# Gmetad-webfrontend version. Used to check for updates.

#

include_once "./version.php";

 

#

# The name of the directory in "./templates" which contains the

# templates that you want to use. Templates are like a skin for the

# site that can alter its look and feel.

#

$template_name = "onest";

…..

************************* End ****************************

 

d)     重启 httpd 服务

执行命令: service httpd restart ,这样我们就可以在节点视图,看到节点的 random 统计了。

截图如下:

 

 

e)     自定义显示

如果不喜欢 Ganglia 显示界面,我们可以修改 $GANGLIA_WEB/ templates /$template_name 目录中相应的模板文件

 

 

 

附录 1 :

 

$GANGLIA_WEB

|-- AUTHORS

|-- COPYING

|-- Makefile.am

|-- auth.php

|-- class.TemplatePower.inc.php

|-- cluster_legend.html

|-- cluster_view.php           // 集群视图

|-- conf.php

|-- conf.php.in      // 配置文件初始模板

|-- footer.php      // 脚注

|-- functions.php

|-- ganglia.php

|-- get_context.php   // 解析视图类型

|-- get_ganglia.php  

|-- graph.d              // 存放绘图脚本, metric 以及统计图表

|   |-- cpu_report.php

|   |-- load_report.php

|   |-- mem_report.php

|   |-- metric.php

|   |-- network_report.php

|   |-- packet_report.php

|   |-- random_report.php

|   `-- sample_report.php

|-- graph.php              // 绘图脚本调用起点文件

|-- grid_tree.php

|-- header.php

|-- host_view.php          // 节点视图

|-- index.php

|-- meta_view.php

|-- node_legend.html

|-- physical_view.php

|-- pie.php

|-- private_clusters

|-- show_node.php

|-- styles.css

|-- templates                 // 相关模板,可以修改该模板,自定义显示

|   |-- default               // 默认模板目录

|   |   |-- cluster_extra.tpl     // 集群视图扩展内容模板

|   |   |-- cluster_view.tpl     // 集群视图模板

|   |   |-- footer.tpl

|   |   |-- grid_tree.tpl

|   |   |-- header-nobanner.tpl

|   |   |-- header.tpl

|   |   |-- host_extra.tpl       // 节点视图扩展内容模板

|   |   |-- host_view.tpl       // 节点视图模板

|   |   |-- images

|   |   |   |-- cluster_0-24.jpg

|   |   |   |-- cluster_25-49.jpg

|   |   |   |-- cluster_50-74.jpg

|    |   |   |-- cluster_75-100.jpg

|   |   |   |-- cluster_overloaded.jpg

|   |   |   |-- cluster_private.jpg

|   |   |   |-- grid_0-24.jpg

|   |   |   |-- grid_25-49.jpg

|   |   |   |-- grid_50-74.jpg

|   |   |   |-- grid_75-100.jpg

|   |   |   |-- grid_overloaded.jpg

|   |   |   |-- grid_private.jpg

|   |   |   |-- logo.jpg

|   |   |   |-- node_0-24.jpg

|   |   |   |-- node_25-49.jpg

|   |   |   |-- node_50-74.jpg

|   |   |   |-- node_75-100.jpg

|   |   |   |-- node_dead.jpg

|   |   |   `-- node_overloaded.jpg

|   |   |-- meta_view.tpl

|   |   |-- node_extra.tpl

|   |   |-- physical_view.tpl

|   |   `-- show_node.tpl

|   `-- onest           // 自定义模板目录,通过 conf.php 的 $template_name 参数指定

|       |-- cluster_extra.tpl   

|       |-- cluster_view.tpl

|       |-- footer.tpl

|       |-- grid_tree.tpl

|       |-- header-nobanner.tpl

|       |-- header.tpl

|       |-- host_extra.tpl

|       |-- host_view.tpl

|       |-- images

|       |   |-- cluster_0-24.jpg

|       |   |-- cluster_25-49.jpg

|       |   |-- cluster_50-74.jpg

|       |   |-- cluster_75-100.jpg

|       |   |-- cluster_overloaded.jpg

|       |   |-- cluster_private.jpg

|       |   |-- grid_0-24.jpg

|       |   |-- grid_25-49.jpg

|       |   |-- grid_50-74.jpg

|       |   |-- grid_75-100.jpg

|       |   |-- grid_overloaded.jpg

|       |   |-- grid_private.jpg

|       |   |-- logo.jpg

|       |   |-- node_0-24.jpg

|       |   |-- node_25-49.jpg

|       |   |-- node_50-74.jpg

|       |   |-- node_75-100.jpg

|       |   |-- node_dead.jpg

|       |   `-- node_overloaded.jpg

|       |-- meta_view.tpl

|       |-- node_extra.tpl

|       |-- physical_view.tpl

|       `-- show_node.tpl

|-- version.php

`-- version.php.in

 

 

参考资料:

 

1)        《 Custom Graphs in Ganglia 3.1.x 》

http://sourceforge.net/apps/trac/ganglia/wiki/Custom_graphs

 

2)        《 Ganglia Monitoring Tool 》

http://www.slideshare.net/sudhirpg/ganglia-monitoring-tool

 

3)        《针对 ganglia3.1.1 开发自定义的模块》

http://yaoweibin2008.blog.163.com/blog/static/11031392009085410345/

 

4)        《 Ganglia 和 Nagios ,第 1 部分 :  用 Ganglia 监视企业集群》

http://www.ibm.com/developerworks/cn/linux/l-ganglia-nagios-1/

 

5)        PHP 语法参考

http://www.w3school.com.cn/php/php_looping.asp

 

6)        RRD 数据库及 RRDTool  简介

http://linux.chinaunix.net/salon/200712/files/RRD_RRDTool_xa.pdf

 

 

http://www.seotcs.com/blog/1304.html

作为一个大型网站的监控,是一个涉及到各个方面的系统工作。要做好全面的web监控工作,其实不是那么容易的,作为Web的监控,笔者认为,应该包含以下几个方面:

1,服务器基础资源的监控。服务器基础资源的监控,包括服务器的内存、cpu以及磁盘等的使用监控。

内存使用监控

这些基础资源的监控,意义是十分明显的,可以及时发现占资源的程序并尽快修复,也可以及时发现硬件资源的瓶颈,便于技术人员在第一时间将硬件进行扩充和升级。

2,web服务器的监控。web服务器的监控,主要是访问请求的监控,例如,httpd并发链接数的监控,平均响应时间等。

3,web数据库的监控。包含数据库进程资源的使用,频繁使用的sql的展示,耗资源的前几位的sql语句等。一般各大数据库服务商都带有监控的功能,例如oracle、mysql等。

4,应用服务器的监控。可以针对Web Services等的监控,监控一些重要api的调用情况,调用次数,单位时间内调用的频率等。

5,网络流量的监控。带宽的占用分析,也是相当重要的。网络流量的监控,可以及时发现异常流量的情况,例如DDOS的攻击,这样的流量攻击通过流量的监控,就可以及时发现并进行处理,避免网站因为流量攻击而瘫痪。

当然,监控虽然复杂,网络上也是有不少好用的开源工具可供下载使用的,下面来介绍一些重量级的开源监控工具。

服务器监控工具举例

1,Ganglia。

Ganglia是一个跨平台可扩展的,高性能计算系统下的分布式监控系统,它是UC Berkeley 发起的一个开源监视项目,设计用于测量数以千计的节点。每台计算机都运行一个收集和发送度量数据(如处理器速度、内存使用量等)的名为 gmond 的守护进程。它将从操作系统和指定主机中收集。接收所有度量数据的主机可以显示这些数据并且可以将这些数据的精简表单传递到层次结构中。正因为有这种层次结构模式,才使得 Ganglia 可以实现良好的扩展。gmond 带来的系统负载非常少,这使得它成为在集群中各台计算机上运行的一段代码,而不会影响用户性能。

2,Munin。

Munin是通过客户端-服务器架构收集数据并将其图形化的工具。Munin允许你跟踪你的主机的运行记录,就是所谓的‘节点’,然后将它们发送到中央服务器,随后你就能在这里以图像形式展示它们。

3,Cacti。

Cacti在英文中的意思是仙人掌的意思,Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具。它通过snmpget来获取数据,使用 RRDtool绘画图形,你可以不需要了解RRDtool复杂的参数。Cacti提供了非常强大的数据和用户管理功能,可以指定每一个用户能查看树状结构、host以及任何一张图,还可以与LDAP结合进行用户验证,同时也能自己增加模板,功能非常强大完善。

4,Nagios。

Nagios是一个强大的监控系统,号称IT架构监控中的行业标准。它可以让企业及时鉴别和解决IT设施中的问题,功能也是非常强大,主要表现在以下几个方面:

1)监控网络服务的方方面面(SMTP, POP3, HTTP, NNTP, ICMP, SNMP, FTP, SSH);

2)监控主机资源(cpu负载,磁盘使用情况,系统日志等);

3)服务等监视的并发处理;

4)各种预警通知功能 (通过手机短信,email或其他用户自定义方法);

5)可指定自定义的事件处理控制器;

6)可选的基于浏览器的WEB界面以方便系统管理人员查看网络状态,各种系统问题,以及日志等

7)可以通过手机查看系统监控信息

总结一下,web监控的意义如此之大,所以是需要企业花大力气去关注和重视的,幸好监控的工具也是非常多,这就需要web技术或运维人员去了解和学习这些工具,以便为web的监控工作作出更多贡献。

 

http://www.haodaima.net/art/1186169

Ganglia监控系统--自定义插件

2011/12/30 17:49:42
 
 

   当在运营的环境中使用ganglia后,你可能不在满足ganglia自身提供插件,需要根据特定的需求描述特定服务性能数据。接下来,我完整完成一个自定义插件的Hello World,以后翻阅。

   我使用python编写插件,测试环境是ubuntu10.04+x86_64

 

基础环境准备

apt-get install ganglia-monitor

在/etc/ganglia/中创建conf.d目录

在conf.d目录中创建modpython.conf,其内容如下:

modules {
module {
name = "python_module"
path = "/usr/lib/ganglia/modpython.so"
params = "/usr/lib/ganglia/python_modules"
}
}

include('/etc/ganglia/conf.d/*.pyconf')

cd /usr/lib/ganglia目录,在其中创建python_modules目录,日后自行编写的python脚本都是需要放置在python_modules中。

到此,基础的环境准备已经完成。

 

自定义插件

其实自定义插件分为两步,第一步编写python脚本,第二步是向gmond注册此脚本

(1)第一步编写python脚本

脚本中需要包含如下三个函数:

metric_init(params):

  •  Called once at module initialization time
  • Must return a metric description dictionary or list of dictionaries

Metric definition data dictionary :

d = {    

‘name’ : ‘<your_metric_name>’,

‘ call_back’ : <call_back function>,

‘ time_max’ : int(<your_time_max>),

‘ value_type’ : ‘<string | uint | float | double>’,

‘ units’ : ’<your_units>’,

‘ slope’ : ‘<zero | positive | negative | both>’,

‘ format’ : ‘<your_format>’,

‘ description’ : ‘<your_description>’

}

Can be a single dictionary or a list of dictionaries,Must be returned from the metric_init() function

metric_handler(): – may have multiple handlers

  • Metric gathering handler
  • Must return a single data value of the same type as specified in the metric_init() function

metric_cleanup()

  • Called once at module termination time
  • Does not return a value

举个简单的例子来说明下,进入上面提到的python_modules目录中,创建如test123.py

#!/usr/bin/env python
import random
def get_foo_count(name):
return random.randrange(23, 90) + 5

def metric_init(params):
'''''metric'''
global descriptors

d1 = {
'name': 'test_count',
'call_back': get_foo_count,
'time_max': 90, #调度时间间隔
'value_type': 'uint',
'units': 'C',
'slope': 'both',
'format': '%u',
'description': 'Number of test',
'groups': 'test_group'
}
descriptors = [d1]
return descriptors

def metric_cleanup():
pass

if __name__ == '__main__':
metric_init({})
for d in descriptors:
v = d['call_back'](d['name'])
print 'value for %s is %u' % (d['name'], v)

(2)注册编写的脚本

cd /etc/ganglia/conf.d/

创建test123.pyconf,其内容如下:

modules {

module {

name = "test123"

language = "python"

}

}


collection_group {

collect_every = 10

time_threshold = 50

metric {

name = "test_count"

title = "test data" /* Metric name (see “gmond –m”) */

value_threshold = 50 /* Metric variance threshold (send if exceeded) */

}

}


重新启动gmond,在web界面就应该能够看到对应的图表。

 

说明

可能在构建的过程中遇到权限相关的问题,在调试的时候也可以使用 tail -f /var/log/syslog,帮助解决问题

http://dudushunai2008like.lofter.com/post/373687_1082aea

【ganglia】 ganglia扩展之gmetric and Python实现方法

来自:bkeep

1 概述 Ganglia 扩展能力:

使用 Ganglia 的插件将给我们提供两种添加更多功能的方法:

方法一:通过添加带内(in-band)插件。gmetric命令

方法二:通过添加一些其他来源的带外(out-of-band)欺骗。

         c或者python接口来实现

 

说明:hadoop使用metric2插件另外研究研究。

 

2 gmetric命令详解 2.1 示例1:

#gmetric -n test_string -v 'hello value' -t string -d 10 -c /etc/ganglia/gmond.conf.bkeep -S '2.2.2.2:web'

解说:-n '指标名' -v 指标值 -t 数据类型 -u '单位' -d 指标的存活时间 -c 指定ganglia配置文件 -S伪装客户端信息2.2.2.2代表ip地址,web代表主机名。

【ganglia】 ganglia扩展之gmetric and Python实现方法 - bkeep - bkeep

  

2.2 示例2:

#gmetric -n bkeepUse -v 10 -t int32 -u '% test' -d 10 -S '2.2.2.2:web'

【ganglia】 ganglia扩展之gmetric and Python实现方法 - bkeep - bkeep

  

2.3 gmetric语法:

#gmetric --help

gmetric 3.1.2

 

Purpose:

  The Ganglia Metric Client (gmetric) announces a metric

  on the list of defined send channels defined in a configuration file

 

Usage: gmetric [OPTIONS]...

 

  -h, --help          Print help and exit

  -V, --version       Print version and exit

  -c, --conf=STRING   The configuration file to use for finding send channels 

                        (default='/etc/ganglia/gmond.conf')

  -n, --name=STRING   Name of the metric

  -v, --value=STRING  Value of the metric

  -t, --type=STRING   Either

                        string|int8|uint8|int16|uint16|int32|uint32|float|double

  -u, --units=STRING  Unit of measure for the value e.g. Kilobytes, Celcius 

                        (default='')

  -s, --slope=STRING  Either zero|positive|negative|both  (default='both')

  -x, --tmax=INT      The maximum time in seconds between gmetric calls 

                        (default='60')

  -d, --dmax=INT      The lifetime in seconds of this metric  (default='0')

  -S, --spoof=STRING  IP address and name of host/device (colon separated) we

                        are spoofing  (default='')

  -H, --heartbeat     spoof a heartbeat message (use with spoof option)

 

 

3 python插件扩展ganglia 3.1 首先安装gangliapython模块,即modpython.so

安装包:

#rpm -qf /usr/lib64/ganglia/modpython.so

ganglia-gmond-python-3.1.2-5.el5

 

安装后的文件位置:

[root@inc-dw-hadoop-3 /usr/lib64/ganglia]

#ls

modcpu.so   modload.so  modmulticpu.so  modproc.so    modsys.so

moddisk.so  modmem.so   modnet.so       modpython.so  python_modules

 

3.2 配置gmond.conf,添加扩展的模块

1,vi /etc/ganglia/gmond.conf

#如果没有下面这句,请添加

include ('/etc/ganglia/conf.d/*.conf')

 

2,创建modpython.conf文件

vi /etc/ganglia/conf.d/modpython.conf  

# The modules section describes the module

#  that should be loaded.

#   name - module name

#   path - load path of the .so

#   params - path to the directory where mod_python

#             should look for python metric modules

modules {

  module {

    name = "python_module"  #python主模块

    path = "modpython.so"  #动态库路径

    params = "/usr/lib64/ganglia/python_modules"  #指定我们编写的python脚本放置位置

  }

}

include ('/etc/ganglia/conf.d/*.pyconf')  #该目录下只能有一个文件包含此配置,否则会造成死循环。把机器搞死。

 

3.3 实战之开发python模块 3.3.1 实验环境

进程                  机器

------------            -----------------------------

gmond               inc-dw-hadoop-3

gmetad             dw-ganglia-3

httpd                  dw-ganglia-3

3.3.2 创建random_module.pyconf模块配置文件:

注意:请区别于modpython.conf;自定义python模块配置文件只针对自己开发的模块。

[root@inc-dw-hadoop-3 /etc/ganglia/conf.d]

#cat random_module.pyconf

modules {

  module {

         #模块名,该文件存放于params = "/usr/lib64/ganglia/python_modules"指定的路径下

    name = "random_module"

         #声明使用python语言

    language = "python"

         #参数列表,所有的参数作为一个dict(即map)传给python脚本的metric_init(params)函数。

  #本例中,metric_init调用时,params={“RandomMax”:”10”,”RandomMin”:”0”}

    param RandomMax{

        value = 10

    }

    param RandomMin{

        value = 0

    }

  }

}

 

#需要收集的metric列表,一个模块中可以扩展任意个metric

collection_group {

  collect_every = 10

  time_threshold = 50  #最大发送间隔

  metric {

    name = "random1"          #metric在模块中的名字

    title = "test random1"             #图形界面上显示的标题

    value_threshold = 50

  }

  metric {

     name="random2"

     title = "test random2"

     value_threshold = 50

  }

}

 

3.3.3 编写random_module.py模块:

具体采集那些信息?有什么语法规定吗?仔细读下面的例子就能发现。

#cd /usr/lib64/ganglia/python_modules/

#vi random_module.py

import random 

random_max = 100 

random_min = 0 

v = 0 

def random1_handler(name): 

        global v,random_max,random_min 

        v = random.randint(random_min,random_max) 

        return v 

def random2_handler(name): 

        global v,random_max,random_min 

        return random_min+random_max-v 

def metric_init(params): 

        global random_max,random_min 

        if params: 

                if params.has_key("RandomMin"): 

                        random_min = int(params["RandomMin"]) 

                if params.has_key("RandomMax"): 

                        random_max = int(params["RandomMax"]) 

        tmp = {'name':'random1','call_back':random1_handler, 

                'value_type':'uint','units':'usage', 

                'slope':'both','format':'%u', 

                'description':'test random plugin', 

                'groups':'random'} 

        descriptors = [tmp] 

        tmp1 = {'name':'random2','call_back':random2_handler, 

                'value_type':'uint','units':'usage', 

                'slope':'both','format':'%u', 

                'description':'test subs plugin', 

                'groups':'random'} 

        descriptors.append(tmp1) 

        return descriptors 

def metric_cleanup(): 

        pass 

if __name__=='__main__': 

        descriptors = metric_init(None) 

        for d in descriptors: 

                print "value for %s is %d"%(d['name'],d['call_back'](d['name']))

 

3.3.4 metric开发接口:

Ganglia模块扩展时,Python脚本主要要实现的函数有:

metric_init(params):

?  Called once at module initialization time

?  Must return a metric description dictionary or list of dictionaries

 

Metric definition data dictionary 

d = {‘name’ : ‘<your_metric_name>’,

'call_back’ : <call_back function>,

'time_max’ : int(<your_time_max>),

'value_type’ : ‘<string | uint | float | double>’,

'units’ : ’<your_units>’,

'slope’ : ‘<zero | positive | negative | both>’,

'format’ : ‘<your_format>’,

'description’ : ‘<your_description>’}

 

Can be a single dictionary or a list of dictionaries

Must be returned from the metric_init() function

 

?  Any other module initialization can also take place here

?  metric_handler() – may have multiple handlers

?  Metric gathering handler

?  Must return a single data value of the same type as specified in the metric_init() function

?  metric_cleanup()

?  Called once at module termination time

?  Does not return a value

 

3.3.5 random_module.py输出效果图:

完成以上步骤后,重启gmond ,就可以在 web 界面的节点视图上看到新添的 random1 和 random2 的统计图表

 

【ganglia】 ganglia扩展之gmetric and Python实现方法 - bkeep - bkeep

  

3.4实战之增加统计表(将多条曲线画在一张图上) 3.4.1 思路

思路:根据url得知关键字---->ganglia web 目录底下去搜索相关文件---->模仿即可。

说明:memory和network模版不一样,需要分别模仿。

 

【ganglia】 ganglia扩展之gmetric and Python实现方法 - bkeep - bkeep

  

[root@dw-ganglia-3 /usr/share/ganglia]

# grep "network_report" * -r

get_context.php:   "network_report" => 1,

graph.php:$graph = isset($_GET["g"]) && in_array( $_GET['g'], array( 'cpu_report', 'mem_report', 'load_report', 'network_report', 'packet_report' ) ) ?

graph.php:      else if ($graph == "network_report")

templates/default/host_view.tpl:<A HREF="./graph.php?g=network_report&z=large&c={cluster_url}&{graphargs}">

templates/default/host_view.tpl:   SRC="./graph.php?g=network_report&z=medium&c={cluster_url}&{graphargs}">

templates/default/cluster_view.tpl:<A HREF="./graph.php?g=network_report&amp;z=large&amp;{graph_args}">

templates/default/cluster_view.tpl:    SRC="./graph.php?g=network_report&amp;z=medium&amp;{graph_args}">

3.4.2编辑get_context.php

[root@dw-ganglia-3 /usr/share/ganglia]

#vi get_context.php

#add by bkeep

$reports = array(

   "load_report" => "load_one",

   "cpu_report" => 1,

   "mem_report" => 1,

   "network_report" => 1,

   "random_report" => 1,

   "packet_report" => 1

 

3.4.3编辑graph.php

这里演示了增加random曲线,后面会演示增加多条曲线的方法

[root@dw-ganglia-3 /usr/share/ganglia]

#vi graph.php

#$graph = isset($_GET["g"]) && in_array( $_GET['g'], array( 'cpu_report', 'mem_report', 'load_report', 'network_re

port', 'packet_report' ) ) ?

#modify by bkeep

$graph = isset($_GET["g"]) && in_array( $_GET['g'], array( 'cpu_report', 'mem_report', 'load_report', 'network_rep

ort', 'packet_report' ,'random_report') ) ?

 

# add by bkeep

      #else if ($graph == "network_report")

      else if ($graph == "random_report")

         {

            $fudge = $fudge_2;

            #$style = "Network";

            $style = "Random";

 

            $lower_limit = "--lower-limit 0 --rigid";

            $extras = "--base 1024";

            $vertical_label = "--vertical-label 'Bytes/sec'";

 

            #$series = "DEF:'bytes_in'='${rrd_dir}/bytes_in.rrd':'sum':AVERAGE "

            $series = "DEF:'random1'='${rrd_dir}/random1.rrd':'sum':AVERAGE "

               #."DEF:'bytes_out'='${rrd_dir}/bytes_out.rrd':'sum':AVERAGE "

               ."DEF:'random2'='${rrd_dir}/random2.rrd':'sum':AVERAGE "

               #."LINE2:'bytes_in'#$mem_cached_color:'In' "

               ."LINE2:'random1'#$mem_cached_color:'In' "

               #."LINE2:'bytes_out'#$mem_used_color:'Out' ";                                     

               ."LINE2:'random2'#$mem_used_color:'Out' "; 

         }

 

3.4.4编辑templates/default/host_view.tpl

[root@dw-ganglia-3 /usr/share/ganglia]

#vi templates/default/host_view.tpl

<A HREF="./graph.php?g=network_report&z=large&c={cluster_url}&{graphargs}">

<IMG BORDER=0 ALT="{cluster_url} NETWORK"

   SRC="./graph.php?g=network_report&z=medium&c={cluster_url}&{graphargs}">

</A>

<!--add by bkeep -->

<A HREF="./graph.php?g=random_report&z=large&c={cluster_url}&{graphargs}">

<IMG BORDER=0 ALT="{cluster_url} NETWORK"

   SRC="./graph.php?g=random_report&z=medium&c={cluster_url}&{graphargs}">

</A>

 

3.4.5编辑templates/default/cluster_view.tpl

[root@dw-ganglia-3 /usr/share/ganglia]

#vi templates/default/cluster_view.tpl

<A HREF="./graph.php?g=network_report&amp;z=large&amp;{graph_args}">

<IMG BORDER=0 ALT="{cluster} NETWORK"

    SRC="./graph.php?g=network_report&amp;z=medium&amp;{graph_args}">

</A>

<!-- add by bkeep -->

<A HREF="./graph.php?g=random_report&amp;z=large&amp;{graph_args}">

<IMG BORDER=0 ALT="{cluster} NETWORK"

    SRC="./graph.php?g=random_report&amp;z=medium&amp;{graph_args}">

</A>

 

3.4.6添加多条曲线

vi /usr/share/ganglia/graph.php

# add by bkeep

      #else if ($graph == "network_report")

      else if ($graph == "random_report")

         {

            $fudge = $fudge_2;

            #$style = "Network";

            $style = "Random";

 

            $lower_limit = "--lower-limit 0 --rigid";

            $extras = "--base 1024";

            $vertical_label = "--vertical-label 'Bytes/sec'";

            #$series = "DEF:'bytes_in'='${rrd_dir}/bytes_in.rrd':'sum':AVERAGE "

            $series = "DEF:'random1'='${rrd_dir}/random1.rrd':'sum':AVERAGE "

               #."DEF:'bytes_out'='${rrd_dir}/bytes_out.rrd':'sum':AVERAGE "

               ."DEF:'random2'='${rrd_dir}/random2.rrd':'sum':AVERAGE " 

               ."DEF:'bytes_out'='${rrd_dir}/bytes_out.rrd':'sum':AVERAGE "

               ."DEF:'bytes_in'='${rrd_dir}/bytes_in.rrd':'sum':AVERAGE "  #定义一个样式

               #."LINE2:'bytes_in'#$mem_cached_color:'In' "  

               ."LINE2:'random1'#$mem_cached_color:'randmon1' "  

               #."LINE2:'bytes_out'#$mem_used_color:'Out' ";

               ."LINE2:'random2'#$mem_used_color:'random2' "

               ."LINE2:'bytes_out'#$mem_used_color:'bytes_out' "

               ."LINE2:'bytes_in'#$cpu_nice_color:'bytes_in' ";   #定义颜色

         }    

 

看看效果图,四条曲线。

 

【ganglia】 ganglia扩展之gmetric and Python实现方法 - bkeep - bkeep

  

 

 

 

 
 
 
http://segmentfault.com/q/1010000000116157

系统的服务器多了,独立运行的服务进程多了,服务进程间的通讯多了,该做那些监控,该怎么监控?有没有什么成熟的思想想法?
监控是不是可以分为2个方面:1)系统级别的监控(cpu,memory,io,disk,net),服务是否存活
2)应用级别(各子系统业务相关异常监控)
具体的,怎么来实现这个监控,做到一个可灵活配置、扩展的插件式监控平台?感觉还是比较棘手

综合了大家的回答,打算先这么做:
1:Nagios作为CPU、内存、硬盘等各个基本非业务的监控
2:各个业务模块做自己相关的监控:服务异常监控、服务统计信息等
1)服务异常信息通过mq异步的发送给监控主服务器,由监控主服务器统一处理
2)服务统计信息先在本地模块内存汇总,然后定时间隔的发送给监控主服务器进行持久化等相关处理

6 个回答

6
采纳
Ajian 1.4k 2012年09月06日 回答 · 2012年09月07日 更新

`以下都是自己想到什么写什么
监控从方向来分为: 系统级别监控和业务逻辑层监控。一般的开源软件都是面向系统软件级别的监控, 不可能会有业务逻辑的监控; 业务逻辑的监控因为不同的应用而不同, 这个需要程序员预留接口可以进行监控, 运维是可以提需求的。
监控从功能上分为: 报警监控和性能监控。 报警监控,就像大家说的nagios是非常好的开源软件, 其实nagios提供的也是一种监控的框架, 所以他比较的灵活; 性能监控, 主要是用来查看变化趋势, 可以更好的找到问题, 或者提早发现问题, 有时候因为报警的阀值是需要不断的调整才能到最佳状态,像cacti和ganglia
监控的选择 一般要看你的服务器分布:
如果是分布式的机房, 机房很多, 那么对集中监控和处理要求比较高, ganglia本身就有分布式特性, 是第一选择; nagios需要再做些插件的优化和结构调整才能更好的支持分布式的需求. 因为分布式面临的问题是集中管理和可靠性, 可靠性: 网络传输可能出现的问题都要避免监控,才能让监控准确; 集中管理: 才可以减少工作量
如果是集中的, 在量很大的情况下还是建议使用ganglia, 如果小其它的很多监控都可以选择, 报警监控还是用nagios, 好像很少有他这样灵活的工具, 但一定要将配置改成最适合自己环境的, 并且最简单和快速的配置 需要自己制定一些规则会比较好。
如果说要监控配合的外围工具: 像短信报警 邮件 都需要自己做些工具会比较好 ,都是为了保证报警的可靠性 监控前期一定要多关注是否跟上了需求 要做很多的调整 不是说搭建了就万事大吉了.

评下你的做法
综合了大家的回答,打算先这么做:
1:Nagios作为CPU、内存、硬盘等各个基本非业务的监控
#其实nagios也可以监控业务逻辑 主要是首先要知道要监控哪些业务逻辑 再程序方面是否有相应的接口 如果没有是否可以做 再自己写一些相应的脚本 nagios和ganglia都可以很方便的写脚本。最关键的还是监控需求和程序的支持情况
2:各个业务模块做自己相关的监控:服务异常监控、服务统计信息等
1)服务异常信息通过mq异步的发送给监控主服务器,由监控主服务器统一处理
#你应该说的是自己写监控再通过队列发送给主服务,如果是同机房当然还是写nagios的插件会比较好,这样是统一管理,而只需要写插件; 如果是机房是分布的,可以考虑nagios之间的消息传递写一些脚本完成,自己写的话是时间问题和管理上不统一的麻烦。
2)服务统计信息先在本地模块内存汇总,然后定时间隔的发送给监控主服务器进行持久化等相关处理
#这一部分我建议是分成两部分: 第一部分是服务器基本信息, 像cpu 内存 硬盘 这些不会变化的可以间隔很长时间, 其实ganglia默认就有系统硬件的所有信息, 只是如果想放到表格里面对比就差些了; 反而对于系统用户 磁盘容量 各种配置文件 如计划任务 打开的服务 自启动的内容可以定时的执行和收集, 这个应该属于备份了, 但如果所有的配置集中处理之后,像使用puppet或者其它配置工作,这些都不需要做了。
我这有个服务器信息收集的 是适合自己用的 [Shell]服务器信息收集与整理输出wiki和excel http://www.ohlinux.com/archives/824/`

4
周健_MediaV 61 2012年09月05日 回答

应该监控任意两个模块之间的连接,不管你是用tcp/udp,还是thrift或者其他什么rpc server,都应该在client端记录success/fail/timeout的QPS以及latency,而在server端记录qps。
写一个监控的类库,不复杂的,有个全局的map,然后有个线程每秒能够进行计数,并把相应的数字通过一些网络接口暴露出来,这样就可以和各种Nagios/Zabbix等来集成了。
还有一个经验是每个服务最好能够注册到一个内部的Name Service中,比如Zookeeper,这样就不用把上下游的信息作为配置信息搞来搞去了。

1
tangsty_116203 18 2012年09月05日 回答 · 2012年09月05日 更新

服务器数量不太大时,比如小于200台,建议试试Nagios Nagios监控系统的CPU、内存、硬盘等各个基本面都很方便。监控自己的服务也很容易,组合些插件、写点简单的脚本啥的就能做到。

如果服务器数量很多,超过1000台。高效采集这些信息就是个复杂的事情,想想每秒钟要有多少数据往你的监控服务器传送就有点头疼了。这就需要自己精心设计下拓扑结构、写不少代码。当然,也能利用已有的开源框架做到这些信息采集。

1
蛙蛙王子 17 2014年05月26日 回答

主要分系统监控和业务监控两类吧

系统监控就是每台主机的CPU,内存,网络带宽等使用情况,以及Mysql, Redis, Nginx等服务的核心指标等,这是比较基本的监控,必须得有,如果这块监控做的好,生产环境可以提前发现很多问题,防患于未然。

业务监控就是业务相关的指标,如某API每秒调用次数,每分钟该API的平均响应时间,服务的在线人数,甚至一些运营相关的数据,如七日留存率啦,每日新增用户,每日流失用户等。这些数据也很重要,他是你整个业务的晴雨表,为你做一些重要决策提供依据。

对于系统监控,有很多开源软件可以拿来用,如比较出名的ngios,cacti,zabbix等,部署都比较复杂,客户端要部agent,还得装一个center用来收集,存储展现数据,还有好多插件需要维护。但有一个比较简单的东西是collectd,它自带了各种插件,如系统CPU,磁盘利用率,mysql,nginx,redix等常用服务都可
以进行监控,而且自动给你推荐了要监控哪些指标。安装很方便,基本上./configuration && make && make install就可以了。

对于业务监控,肯定是需要自己写代码上报业务数据的,现在比较流行的方案是statsd+graphite,比较轻量级,而且有很多语言的sdk,可以很轻松把各种指标监控起来。

大多监控体系都差不多,如下

  1. 每台机器上安装一个agent,用来采集本机的性能数据,服务数据
  2. 每台机器部署的业务,根据一个sdk,向center提交本业务相关的数据
  3. 每个agent可以动态的按需求加载一些插件,以便监控新的指标
  4. 一般一个机房内有一个center用来收集各agent和各业务上报的指标
  5. center要把采集到的指标数据进行存储,归档,压缩,一般用rrd database
  6. center还得有一个web界面来查看各个指标的历史图表,甚至要有各种视图和dashborad来显示一组相关的指标。
  7. center还要每天把用户自定义的几个关键的指标生产报表发给运维或者相关人员。
  8. center还需要保存各种告警规则,如某个指标连续几次超过某个阈值产生告警,或者波动超过某个范围产生告警,或者某个指标超过多长时间没有上报数据产生告警
  9. center还要进行各种告警的收敛,如同类告警的合并,临时屏蔽某类告警,防止因为网络抖动引起大量告警等,没有这些运维人员会淹没在各种告警声中。
  10. center要以各种方式将告警发送给运维人员,如短信,邮件,微信,语音等。
  11. center还要对每次告警进行回顾,统计,分析,得出每个系统的薄弱点,可用率,在线时间,稳定性等。

所以说,自己搭建一套完善可靠的监控体系,挺不容易的,需要投入大量的人力和精力去开发和维护。

现在国外也有一些专门做运维外包的厂商,center托管在给他们,免去了很大的工作量,剩下的agent和plugin还是得自己安装,但这就简单了,反正有很多可以做批量部署的运维工具。

比较出名的有NewRelic,StatHat,hostedgraphite,可以去了解一下,基本上就是安装个agent就可以向它们的center上报数据了,或者是利用他们的Sdk提交一些自定义数据,他们负责存储,展现,告警方面的事情,节省很多人力。

国内的话,也有人做类似的事情,如DNSPod的D监控最近推出了自定义监控的功能,兼容graphite的上报接口,你自己部署个collectd就可以把各种系统监控指标监控起来了,如果要做业务监控,graphite也有各种语言的sdk。graphite本身开源,周边工具和软件也特别多,能满足很多的需求。

相关链接:

DNSPod D监控:https://monitor.dnspod.cn/#/monitors
New Relic: http://newrelic.com/
Hosted Graphite: https://www.hostedgraphite.com/
Stat Hat: http://www.stathat.com/
collectd: https://collectd.org/
graphite: http://graphite.wikidot.com/
statsd: https://github.com/etsy/statsd/

0
大盗贼 500 2012年09月05日 回答

监控这个事,一定是因系统而定的。首先,你要对你系统中的各个服务做排序,出故障的概率,出现故障对整个系统的影响。
一般来说是,哪里最容易出问题就监控哪里。哪里出了问题,对系统的影响最大,就监控哪里。

具体的,每一个服务都应该有自己的容灾措施,最差也会有错误报告,对这些错误报告做监控是一种方式。
对于存在通讯的不同设备,做心跳,是一个传统方式。
其他的,还有各种措施,真的是要视具体情况而定

 
 
 
 
http://www.zhihu.com/question/19636141

IT管理员常用的管理、运维工具有哪些?修改

用来做网络监控、资产管理等。修改
按票数排序按时间排序

14 个回答

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 
 
 
 
 
 
posted @ 2015-02-04 17:12  陳聽溪  阅读(484)  评论(0)    收藏  举报