File size: 10,608 Bytes
3a5cf48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# coding: utf-8
# -------------------------------------------------------------------
# 宝塔Linux面板
# -------------------------------------------------------------------
# Copyright (c) 2015-2018 宝塔软件(http:#bt.cn) All rights reserved.
# -------------------------------------------------------------------
# Author: hwliang <hwl@bt.cn>
# -------------------------------------------------------------------

# ------------------------------
# Apache管理模块
# ------------------------------
import public, os, re, shutil, math, psutil, time

os.chdir("/www/server/panel")


class apache:
    setupPath = '/www/server'
    apachedefaultfile = "%s/apache/conf/extra/httpd-default.conf" % (setupPath)
    apachempmfile = "%s/apache/conf/extra/httpd-mpm.conf" % (setupPath)
    apachedefaultfile_backup = '/tmp/apdefault_file_bk.conf'
    apachempmfile_backup = '/tmp/apmpm_file_bk.conf'

    def GetProcessCpuPercent(self, i, process_cpu):
        try:
            pp = psutil.Process(i)
            if pp.name() not in process_cpu.keys():
                process_cpu[pp.name()] = float(pp.cpu_percent(interval=0.1))
            process_cpu[pp.name()] += float(pp.cpu_percent(interval=0.1))
        except:
            pass

    def GetApacheStatus(self):
        process_cpu = {}
        apacheconf = "%s/apache/conf/httpd.conf" % (self.setupPath)
        confcontent = public.readFile(apacheconf)
        if not confcontent:
            return public.returnMsg(False, "获取配置文件错误")
        rep = "#Include conf/extra/httpd-info.conf"
        if re.search(rep, confcontent):
            confcontent = re.sub(rep, "Include conf/extra/httpd-info.conf", confcontent)
            public.writeFile(apacheconf, confcontent)
            public.serviceReload()
        result = public.HttpGet('http://127.0.0.1/server-status?auto')
        try:
            workermen = int(
                public.ExecShell("ps aux|grep httpd|grep 'start'|awk '{memsum+=$6};END {print memsum}'")[0]) / 1024
        except:
            return public.returnMsg(False, "获取内存错误")
        for proc in psutil.process_iter():
            if proc.name() == "httpd":
                self.GetProcessCpuPercent(proc.pid, process_cpu)
        time.sleep(0.5)

        data = {}
        # 计算启动时间
        try:
            Uptime = re.search("ServerUptimeSeconds:\s+(.*)", result)
        except TypeError:
            return public.returnMsg(False, "获取启动时间错误")

        if not Uptime:
            return public.returnMsg(False, "获取启动时间错误")
        Uptime = int(Uptime.group(1))
        min = Uptime / 60
        hours = min / 60
        days = math.floor(hours / 24)
        hours = math.floor(hours - (days * 24))
        min = math.floor(min - (days * 60 * 24) - (hours * 60))

        # 格式化重启时间
        restarttime = re.search("RestartTime:\s+(.*)", result)
        if not restarttime:
            return public.returnMsg(False, "获取重启时间错误")
        restarttime = restarttime.group(1)
        rep = "\w+,\s([\w-]+)\s([\d\:]+)\s\w+"
        date = re.search(rep, restarttime)
        if not date:
            return public.returnMsg(False, "获取日期错误")
        date = date.group(1)
        timedetail = re.search(rep, restarttime)
        if not timedetail:
            return public.returnMsg(False, "获取时间详情错误")
        timedetail = timedetail.group(2)
        monthen = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
        n = 0
        for m in monthen:
            if m in date:
                date = re.sub(m, str(n + 1), date)
            n += 1
        date = date.split("-")
        date = "%s-%s-%s" % (date[2], date[1], date[0])

        reqpersec = re.search("ReqPerSec:\s+(.*)", result)
        if not reqpersec:
            return public.returnMsg(False, "获取 reqpersec  错误")
        reqpersec = reqpersec.group(1)
        if re.match("^\.", reqpersec):
            reqpersec = "%s%s" % (0, reqpersec)
        data["RestartTime"] = "%s %s" % (date, timedetail)
        data["UpTime"] = "%s day %s hour %s minute" % (str(int(days)), str(int(hours)), str(int(min)))
        total_acc = re.search("Total Accesses:\s+(\d+)", result)
        if not total_acc:
            return public.returnMsg(False, "获取 TotalAccesses 错误")
        data["TotalAccesses"] = total_acc.group(1)
        total_kb = re.search("Total kBytes:\s+(\d+)", result)
        if not total_kb:
            return public.returnMsg(False, "获取 TotalKBytes 错误")
        data["TotalKBytes"] = total_kb.group(1)
        data["ReqPerSec"] = round(float(reqpersec), 2)
        busywork = re.search("BusyWorkers:\s+(\d+)", result)
        if not busywork:
            return public.returnMsg(False, "获取 BusyWorkers 错误")
        data["BusyWorkers"] = busywork.group(1)
        idlework = re.search("IdleWorkers:\s+(\d+)", result)
        if not idlework:
            return public.returnMsg(False, "获取 IdleWorkers 错误")
        data["IdleWorkers"] = idlework.group(1)
        data["workercpu"] = round(float(process_cpu["httpd"]), 2)
        data["workermem"] = "%s%s" % (int(workermen), "MB")
        return data

    def GetApacheValue(self):
        apachedefaultcontent = public.readFile(self.apachedefaultfile)
        apachempmcontent = public.readFile(self.apachempmfile)
        if not apachempmcontent:
            return public.returnMsg(False, "没有找到 /www/server/apache/conf/extra/httpd-mpm.conf 配置")
        if not "mpm_event_module" in apachempmcontent:
            return public.returnMsg(False,
                                    "没有找到 mpm_event_module 配置或 /www/server/apache/conf/extra/httpd-mpm.conf 配置为空")
        apachempmcontent = re.search("\<IfModule mpm_event_module\>(\n|.)+?\</IfModule\>", apachempmcontent).group()
        ps = ["秒,请求超时时间", "保持连接", "秒,连接超时时间", "单次连接最大请求数"]
        gets = ["Timeout", "KeepAlive", "KeepAliveTimeout", "MaxKeepAliveRequests"]
        if public.get_webserver() == 'apache':
            shutil.copyfile(self.apachedefaultfile, self.apachedefaultfile_backup)
            shutil.copyfile(self.apachempmfile, self.apachempmfile_backup)
        conflist = []
        n = 0
        for i in gets:
            rep = "(%s)\s+(\w+)" % i
            k = re.search(rep, apachedefaultcontent)
            if not k:
                return public.returnMsg(False,"获取 key {} 失败,请检查配置文件中/www/server/apache/conf/extra/httpd-mpm.conf的{}配置是否正常".format(k,i))
            k = k.group(1)
            v = re.search(rep, apachedefaultcontent)
            if not v:
                return public.returnMsg(False,"获取 value {} 失败,请检查配置文件中/www/server/apache/conf/extra/httpd-mpm.conf的{}配置是否正常".format(v,i))
            v = v.group(2)
            psstr = ps[n]
            kv = {"name": k, "value": v, "ps": psstr}
            conflist.append(kv)
            n += 1

        ps = ["启动时默认进程数", "最大空闲线程数", "可用于处理请求峰值的最小空闲线程数", "每个子进程创建的线程数",
              "将同时处理的最大连接数", "限制单个子服务在生命周期内处理的连接数"]
        gets = ["StartServers", "MaxSpareThreads", "MinSpareThreads", "ThreadsPerChild", "MaxRequestWorkers",
                "MaxConnectionsPerChild"]
        n = 0
        for i in gets:
            rep = "(%s)\s+(\w+)" % i
            k = re.search(rep, apachempmcontent)
            if not k:
                return public.returnMsg(False,"获取 key {} 失败,请检查配置文件中/www/server/apache/conf/extra/httpd-mpm.conf的{}配置是否正常".format(k,i))
            k = k.group(1)
            v = re.search(rep, apachempmcontent)
            if not v:
                return public.returnMsg(False,"获取 value {} 失败,请检查配置文件中/www/server/apache/conf/extra/httpd-mpm.conf的{}配置是否正常".format(v,i))
            v = v.group(2)
            psstr = ps[n]
            kv = {"name": k, "value": v, "ps": psstr}
            conflist.append(kv)
            n += 1
        return (conflist)

    def SetApacheValue(self, get):
        apachedefaultcontent = public.readFile(self.apachedefaultfile)
        apachempmcontent = public.readFile(self.apachempmfile)
        if not "mpm_event_module" in apachempmcontent:
            return public.returnMsg(False,
                                    "没有找到 mpm_event_module 配置或 /www/server/apache/conf/extra/httpd-mpm.conf 配置为空")
        allow_fields = ["Timeout", "KeepAlive", "KeepAliveTimeout", "MaxKeepAliveRequests", "StartServers",
                        "MaxSpareThreads", "MinSpareThreads", "ThreadsPerChild", "MaxRequestWorkers",
                        "MaxConnectionsPerChild"]

        for _k in allow_fields:
            val = get.get(_k)
            if _k == "KeepAlive":
                if not val in ['On', 'Off']:
                    return public.returnMsg(False, f'参数值错误({_k})')
            if _k != "KeepAlive":
                try:
                    val = int(float(val))
                    if val < 0: raise ValueError()
                    val = str(val)
                except Exception as e:
                    return public.returnMsg(False, f'{_k} 参数值错误,请输入正整数。')

            _kv = (_k, val)
            rep = f"{_k}\s+\w+"
            if re.search(rep, apachedefaultcontent):
                newconf = "%s %s" % _kv
                apachedefaultcontent = re.sub(rep, newconf, apachedefaultcontent)
            elif re.search(rep, apachempmcontent):
                newconf = "%s\t\t\t%s" % _kv
                apachempmcontent = re.sub(rep, newconf, apachempmcontent)
        public.writeFile(self.apachedefaultfile, apachedefaultcontent)
        public.writeFile(self.apachempmfile, apachempmcontent)
        isError = public.checkWebConfig()
        if (isError != True):
            shutil.copyfile(self.apachedefaultfile_backup, self.apachedefaultfile)
            shutil.copyfile(self.apachempmfile_backup, self.apachempmfile)
            return public.returnMsg(False, 'ERROR: 配置出错<br><a style="color:red;">' + isError.replace("\n",
                                                                                                         '<br>') + '</a>')
        public.serviceReload()
        return public.returnMsg(True, '设置成功')