|
1 #!/usr/bin/perl -w
2 use strict;
3 use warnings;
4 use DBI;
5
6 ####
7 # 这里进行服务器任务管理
8 ##
9 #字符串映射函数
10 our %actions = (
11 "check" => \&pcheck,
12 "run" => \&prun,
13 "run_nohup" => \&run_nohup,
14 "kill" => \&pkill
15 );
16 our $home = "/var/www/html";
17 our $public_home = "/var/www/html/public" ;
18 our $log_home = "/var/www/html/yfcloud_admin/Public/log" ;
19
20 our $host = "XXX" ;
21 our $database = "XXX" ;
22 our $db_user = "XXX";
23 our $db_pass = "XXX";
24
25 #程序路径
26 our $ppath = "" ;
27 #程序名
28 our $pname = "" ;
29 #日志文件
30 our $log_file = "log" ;
31
32 #检测进程状态,返回PID
33 # 如果同进程不在运行,则返回空
34 sub pcheck
35 {
36 # grep 排除perl本身的进程
37 my $cmd = "ps -ef | grep " . $pname . " | grep -v grep | grep -v perl | awk '{print \$2}'";
38 my $ret = `$cmd` ;
39 chomp $ret;
40 #如果有多个进程PID,则返回第一个pid
41 if( $ret =~ /\n/ ){
42 $ret = ( split /\n/, $ret )[0] ;
43 }
44 ($ret eq "") ? print 0 : print $ret ;
45 }
46
47 #结束进程,返回成功与否
48 # 0 表示成功
49 sub pkill
50 {
51 my $cmd = "killall $pname";
52 my $ret = `$cmd`;
53 print $? ;
54 }
55
56 # 参数需要是 程序的全路径
57 # 启动进程并后台运行,并返回PID
58 # 启动进程后,需要将进程的PID及日志文件写入数据库
59 # shell输出格式如下: [1] 15758
60 sub prun
61 {
62 my $cmd = "$pname";
63 run_exec($cmd);
64 }
65
66 # 后台以nuhup方式运行
67 sub run_nohup
68 {
69 my $cmd = "nohup $pname" ;
70 run_exec($cmd);
71 }
72
73 # 命令格式如下: perl ProcessManager.pl $pname $action
74 sub main
75 {
76 umask(0);
77 #print "begin\n";
78 #这里接收参数并执行相应的操作
79 if( @ARGV < 2 )
80 {
81 print "arguments error!\nusage:perl ProcessManager.pl command action\n";
82 exit 1;
83 }
84 $pname = $ARGV[0] ; #这里使用全局变量算了 ~_~
85 my $action = $ARGV[1] ;
86 #判断操作是否合法
87 if( $actions{$action} ){
88 $actions{$action}->() ;
89 }else{
90 print "undeclare action!check you action!\n";
91 exit 1;
92 }
93 }
94
95 main();
96
97
98
99 ############
100 ##这里是一些工具函数
101 ############
102 sub gettime
103 {
104 my($sec,$min,$hour,$day,$mon,$year) = (localtime(time));
105 $mon +=1 ;
106 $day = ($day < 10 )?"0$day":$day;
107 $mon = ($mon < 10 )?"0$mon":$mon;
108 $min = ($min < 10 )?"0$min":$min;
109
110 return "$mon$day$hour$min" ;
111 }
112
113 sub run_exec
114 {
115 my $cmd = shift ;
116 #先检测文件是否存在,可执行
117 if( -x $pname ){
118 $pname =~ m#.+/(.+)# ; #获得程序名(包括后缀名)作为日志文件名称
119 # 建立程序的日志文件目录
120 my $name = $1 ;
121 mkdir "$log_home/$name" or die("cannot create dir:$name") unless ( -e "$log_home/$name" );
122 $log_file = "$log_home/$name/".gettime() ;
123 # print "log_file : $log_file\n";
124 $cmd .= " > $log_file 2>&1 &";
125 addToDB($name,$log_file);
126 my $pid = fork;
127 if (not $pid) {
128 $pid = $$;
129 print $pid ;
130 exec($cmd); #exec是异步的,执行完后就脱离perl程序了
131 }
132 }else{
133 print "$pname cannot be excuted\n";
134 exit 1;
135 }
136 }
137
138 # 将日志写入日志
139 sub addToDB
140 {
141 my ($progName,$log_file) = @_ ;
142 my $createtime = time ;
143 my $db_handle = DBI->connect("DBI:mysql:database=$database;host=$host", $db_user, $db_pass, {'RaiseError' => 1})|| die "Could not connect to database: $DBI::errstr";
144
145 my $sql = "insert into log (name,log_file,createtime) values (?,?,?)";
146 my $sth = $db_handle->prepare($sql);
147
148 $sth->execute($progName, $log_file , $createtime) or die $DBI::errstr;
149 $sth->finish();
150
151 $db_handle->disconnect();
152 }
|
|
|