最近一直在看dancer,发现真心好用,之前在看mojo,搞了好久没有搞懂.只能怪自己太挫了.

作为练手就写了一套简易的监控系统,主要是利用net::ssh2模块监控AIX服务器的CPU,IO负载,还有磁盘空间.当然如果你是linux/unix作为监控服务器简易使用net::ssh:perl 或者使用SNMP来获取服务器信息.

在lib下添加

login.pm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package  login;
use  Dancer  ':syntax' ;
use  Net::SSH2;
use  Data::Dumper;
$| = 1;
prefix  '/monitor' ;
my  $envMon  = {
     NST => {
         '192.168.1.100'  => [  'user' 'passwd'  ],
         '192.168.1.101'  => [  'user' 'passwd'  ],
           '192.168.1.102'  => [  'user' 'passwd'  ],
    },
     UAT => {
        '192.168.1.103'  => [  'user' 'passwd'  ],
        '192.168.1.104'  => [  'user' 'passwd'  ],
     }
};
sub  mon {
     my  $host $user $passwd $env  ) =  @_ ;
     my  @monArr ;
     my  $monOut ;
     my  $ssh2  = Net::SSH2->new();
     my  $row ;
     $ssh2 -> connect ( "$host" ) or  die  "$!" ;
     if  $ssh2 ->auth_password(  "$user" "$passwd"  ) ) {
         my  $chan  $ssh2 ->channel();
         # $chan->blocking(1);
         $chan ->shell();
         #monitor memory useage
   这款是监控内存,因为linux/unix内存机制都是有多少用多少,所以就去掉了
         # print $chan "svmon -G\n";
         #
         # while(<$chan>){
         # if(/^memory\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)/){
         # push @{$monOut->{'memory'}},sprintf"%0.2f",$2/$1*100;
         # }
         #}
         #monitor disk data
         print  $chan  "df -g\n" ;
         while  (< $chan >) {
             if  (/^\S+\s+([\d.]+)\s+([\d.]+)\s+(\d+)%\s+[^\/]+(\S+)$/) {
                 # push @monArr, $3, $1, $2;
                 if  ( $3 > 80 ) {
                     push  @{  $monOut ->{ 'disk' } }, $4, $1, $2,
                         '<div class="jindu_r"><div style="width:'
                       . $3 .  '%">'
                       . $3
                       '%</div></div>' ;
                     ++ $row ;
                 }
#以下是根据自己需要,如果想监控所有硬盘就去掉注释,我这块只监控大于80%已用空间
         #else{
         # push @{$monOut->{'disk'}},$4,$1,$2,
         # '<div class="jindu_g"><div style="width:'.$3.'%">'.$3.'%</div></div>';
         #}
             }
         }
         unless  defined  @{  $monOut ->{ 'disk' } } ) {
             push  @{  $monOut ->{ 'disk' } },  'normal' 'normal' 'normal' 'normal' ;
             $row  = 1;
         }
         # monitor cpu data
         print  $chan  "iostat\n" ;
         while  (< $chan >) {
             if  (/^\s+\S+\s+\S+\s+(\S+)\s+(\S+)\s+(\S+)\s+([\d.]+)/) {
                 push  @{  $monOut ->{ 'cpu' } }, $1, $2, $3, $4;
             }
         }
         $monOut ->{ 'ip' } =  $host ;
         $monOut ->{ 'env' } =  $env ;
         $monOut ->{ 'row' } =  $row ;
     }
     $monOut ;
}
get  '/login'  =>  sub  {
     template  'login'  => { table =>  'login'  };
};
#登陆页面,这里直接用明文了,根据自己需要可以加密为md5,当然也可以保存在数据库中
post  '/login'  =>  sub  {
     if  ( params->{username} eq  'test'  && params->{password} eq  'test'  ) {
         session user => params->{username};
         redirect params->{path};
     }
     else  {
         redirect  '/monitor/login' ;
     }
};
get  '/logout'  =>  sub  {
     session->destroy;
     redirect  '/monitor/login' ;
};
get  '/:env'  =>  sub  {
     if  ( session( 'user' ) ) {
         my  $monitorOut ;
         my  $env  = params->{env};
         $env  uc ( $env );
         if  defined  $envMon ->{ $env } ) {
             for  keys  %{  $envMon ->{ $env } } ) {
                 push  @ $monitorOut ,
                   mon(
                     $_ ,
                     $envMon ->{ $env }->{ $_ }[0],
                     $envMon ->{ $env }->{ $_ }[1],  $env
                   );
             }
       
             template  'monitor'  => { table =>  $monitorOut  };
             #template 'monitor' => {table => '2'};
         }
     }
         else  {
             template  'monitor'  => { table =>
'<a href="/monitor/login" style="color: #fff">Please Login!</a>'
             };
         }
    
};
get  '/' sub  {
     if  ( session( 'user' ) ) {
         template  'monitor'  => {};
     }
     else  {
         template  'monitor'  => { table =>
               '<a href="monitor/login" style="color: #fff">Please Login!</a>'  };
     }
};
1;

在public/css/style.css最后添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.jindu_g{ position relative ; width : 200px ; border 1px  solid  #B1D632 ; padding 1px ;}
.jindu_g div{ display block ; position relative ;
background green color #333333 ;
height 20px ; line-height 20px ;
}
.jindu_g div span{ position absolute ; width 200px ;
text-align center ; font-weight bold ;
}
.jindu_r{ position relative ; width : 200px ; border 1px  solid  #B1D632 ; padding 1px ;}
.jindu_r div{ display block ; position relative ;
background red color #333333 ;
height 20px ; line-height 20px ;
}
.jindu_r div span{ position absolute ; width 200px ;
text-align center ; font-weight bold ;
}

呈现的效果为磁盘使用的进度条.


views/monitor.tt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
< head >
     < script >
         function mm(){
             var i=document.frm1.select1.selectedIndex;
             var address=document.frm1.select1.options[i].value;
             document.location.href=address;
         }
     </ script >
</ head >
<% IF session.user%>
< center >
   < form  name = "frm1" >
         < select  name = "select1"  onchange = "mm()" >
             < option  selected>请选择环境</ option >
             < option  value="<% request.uri_base %>/monitor/nst">NST环境</ option >
             < option  value="<% request.uri_base %>/monitor/uat">UAT环境</ option >
       
         </ select >
     </ form >
< table  class = "mytable" > < tr >
< th  scope = "col"  width = "5%"  rowspan = "2" >环境</ th >
< th  scope = "col"  width = "8%"  rowspan = "2"  >IP</ th >
< th  scope = "col"  width = "10%"  colspan = "4"  >CPU监控</ th >
< th  scope = "col"  width = "15%"  colspan = "4"  >磁盘空间</ th >
</ tr >
< tr >
< th  scope = "col"  width = "4%" >user</ th >
< th  scope = "col"  width = "4%" >sys</ th >
< th  scope = "col"  width = "2%" >idle</ th >
< th  scope = "col"  width = "2%" >iowait</ th >
  
< th  scope = "col"  width = "15%"  >挂载目录</ th >
< th  scope = "col"  width = "5%" >totle</ th >
< th  scope = "col"  width = "5%" >Free</ th >
< th  scope = "col"  width = "5%" >%Used</ th >
</ tr >
< tbody >
<% FOREACH k IN table %>
< tr >
< td  rowspan="<%k.row%>">
   <%k.env%>
</ td >
< td  rowspan="<%k.row%>" >
   <%k.ip%>
</ td >
      <% FOREACH memory IN k.memory%>
      < td  rowspan="<%k.row%>">
     <%memory%>%
     </ td >
     <%END%>
      <% FOREACH cpu IN k.cpu%>
   < td  rowspan="<%k.row%>">
     <%cpu%>
     </ td >
     <%END%>
     <% FOREACH fdisk IN k.disk%>
  < td  >
     <%fdisk%>
   </ td >
     <% IF loop.count % 4 == 0 %>
</ tr >
<%END%>
     <%END%>
    
<%END%>
</ tbody >
</ table >
</ center >
<%ELSE%>
< center >
<%table%>
</ center >
<%END%>

输出页面

wKiom1OO3T-hT2zvAAJTHBpG15g323.jpg

源码在附件中,中间去除了敏感信息,可能运行会有问题,只给大家提供一个思路,有什么问题可以MAIL或Q讨论