Файловый менеджер - Редактировать - /opt/imh-python/lib/python3.9/site-packages/fpmstatus/fpm.py
Ðазад
# vim: set ts=4 sw=4 expandtab syntax=python: """ fpmstatus.fpm FPM pool status parser @author J. Hipps <jacobh@inmotionhosting.com> """ import os import logging import json import socket from glob import glob from configparser import SafeConfigParser from urllib.parse import splitport from pathlib import Path import arrow from fpmstatus.util import * from fpmstatus.fcgi import FCGIApp from fpmstatus import __version__ logger = logging.getLogger('fpmstatus') def fetch_pools(phpver=None): """ Fetch list of pools If @phpver is defined, only return EA4 pools for that version """ logger.info("Enumerating pools for all FPM masters...") conftype = None if os.path.exists('/etc/php/fpm/pool.d'): # Standard Debian pcs = glob('/etc/php/fpm/pool.d/*.conf') conftype = 'debian' logger.debug("Got %d pools from /etc/php/fpm/pool.d", len(pcs)) elif os.path.exists('/etc/php-fpm.d'): # Standard RHEL pcs = glob('/etc/php-fpm.d/*.conf') conftype = 'rhel' logger.debug("Got %d pools from /etc/php-fpm.d", len(pcs)) elif os.path.exists('/etc/systemd/system/supervisord-fpm.service'): # Ngxconf supervisord-fpm pcs = glob('/opt/ngxconf/phpfpm/conf.d/*.conf') conftype = 'ngxconf' logger.debug("Got %d pools from /opt/ngxconf/phpfpm/conf.d", len(pcs)) elif len(glob('/opt/cpanel/ea-php*/root/etc/php-fpm.d')): # cPanel EA4 conftype = 'cpanel' if phpver: pcs = glob('/opt/cpanel/%s/root/etc/php-fpm.d/*.conf' % (phpver)) logger.debug("Got %d pools for %s", len(pcs), phpver) else: pcs = glob('/opt/cpanel/*/root/etc/php-fpm.d/*.conf') logger.debug("Got %d pools for all PHP versions", len(pcs)) elif len(glob('/opt/alt/php-fpm*/usr/etc/php-fpm.d/users/*.conf')): # CWP conftype = 'cwp' if phpver: pcs = glob('/opt/alt/%s/usr/etc/php-fpm.d/users/*.conf' % (phpver)) logger.debug("Got %d pools for %s", len(pcs), phpver) else: pcs = glob('/opt/alt/php-fpm*/usr/etc/php-fpm.d/users/*.conf') logger.debug("Got %d pools for all PHP versions", len(pcs)) else: logger.error("No FPM installation detected. Aborting.") return None if len(pcs) == 0: logger.error("No FPM pools detected. Aborting.") return None tglobal = {} pools = {} for tconf in pcs: cparse = SafeConfigParser() if tconf.endswith('/nobody.conf'): # prevents enumeration of the nobody pool in CWP continue try: with open(tconf, 'r') as f: cparse.readfp(f) except Exception as e: logger.error("Failed to parse %s: %s", tconf, str(e)) continue for tsec in cparse.sections(): if tsec == 'global': tglobal = dict(cparse.items('global')) else: pools[tsec] = dict(cparse.items(tsec)) pools[tsec]['_confpath'] = tconf pools[tsec]['_vhost'] = tsec.replace('_', '.') if conftype == 'ngxconf': try: pools[tsec]['_masterid'] = os.path.splitext(os.path.basename(tconf))[0] pools[tsec]['_masterlog'] = tglobal.get('error_log') except: pools[tsec]['_masterid'] = None pools[tsec]['_masterlog'] = None pass logger.debug("Found pool %s [listen=%s]", tsec, pools[tsec].get('listen')) return pools def get_pool_status(psock, uri='/status', timeout=1.0): """ Get pool status from @socket via FastCGI """ socket.setdefaulttimeout(timeout) # Determine if psock is unix or tcp socket try: shost, sport = splitport(psock) except Exception as e: logger.error("Failed to parse socket path [%s]: %s", psock, str(e)) return None try: if sport is not None: fc = FCGIApp(host=shost, port=int(sport)) else: fc = FCGIApp(psock) fenv = { 'REQUEST_METHOD': "GET", 'REQUEST_URI': uri, 'SCRIPT_NAME': uri, 'SCRIPT_FILENAME': uri, 'QUERY_STRING': "full&json", 'DOCUMENT_ROOT': "/", 'GATEWAY_INTERFACE': "CGI/1.1", 'SERVER_SOFTWARE': "fpmstatus/" + __version__, 'REMOTE_ADDR': "127.0.0.1", 'REMOTE_PORT': "0", 'SERVER_ADDR': "127.0.0.1", 'SERVER_PORT': "0", 'SERVER_NAME': "localhost", 'CONTENT_TYPE': "", 'CONTENT_LENGTH': "0" } resp = fc(fenv) except Exception as e: logger.error("Failed to read from socket %s: %s", psock, str(e)) return None pstat = {} try: if resp[2].startswith(b'File not found'): logger.error("Received 404 when requesting /status. Check FPM pool configuration for %s", psock) return None sraw = json.loads(resp[2]) except Exception as e: logger.error("Failed to parse JSON response from %s:%s: %s", psock, uri, str(e)) return None for tkey, tval in sraw.items(): nkey = tkey.replace(' ', '_') if nkey == 'start_time': pstat[nkey] = arrow.get(tval).to('local').int_timestamp elif nkey == 'processes': procs = tval pstat[nkey] = [] for tproc in procs: tpx = {} for pkey, pval in tproc.items(): npkey = pkey.replace(' ', '_') if npkey == 'script': tpx[npkey] = None if pval == '-' else os.path.realpath(pval) elif npkey == 'start_time': tpx[npkey] = arrow.get(pval).to('local').int_timestamp elif npkey == 'request_duration': tpx[npkey] = float(pval) / 1000000.0 else: tpx[npkey] = pval pstat[nkey].append(tpx) else: pstat[nkey] = tval logger.debug("Got repsonse for pool %s:\n%s", psock, pstat) return pstat def get_domain_pool(domname): """ Get pool by domain @domname """ poolname = domname.replace('.', '_') plist = fetch_pools() logger.info("Fetching status of pool %s...", poolname) pdata = plist.get(poolname) if pdata is None: logger.error("No pool for domain %s found on server", domname) return None pstat = get_pool_status(pdata['listen']) if pstat is None: logger.error("Failed to retrieve pool status for %s", domname) return None else: pstat['_config'] = pdata return pstat def get_user_pools(username): """ Get all pools for user @username """ ustat = [] plist = fetch_pools() logger.info("Fetching status of pools owned by %s...", username) for tpool in filter(lambda x: x.get('user', '') == username, plist.values()): pstat = get_pool_status(tpool['listen']) if pstat is None: logger.warning("Failed to retrieve pool status for %s", tpool.get('pool', '<unknown>')) continue else: pstat['_config'] = tpool ustat.append(pstat) logger.debug("Got %d pools for user %s", len(ustat), username) return ustat def get_pool_by_name(poolname): """ Get pool named @poolname """ plist = fetch_pools() logger.info("Fetching status of %s pool...", poolname) tpool = plist.get(poolname) if tpool is None: logger.error("No pool named '%s'", poolname) return None pstat = get_pool_status(tpool['listen']) if pstat is None: logger.warning("Failed to retrieve pool status for %s", poolname) return None else: pstat['_config'] = tpool return pstat def get_all_pools(): """ Fetch status for ALL pools on the server """ ustat = [] plist = fetch_pools() logger.info("Fetching status of all %d pools...", len(plist)) for pname, tpool in plist.items(): pstat = get_pool_status(tpool['listen']) if pstat is None: logger.warning("Failed to retrieve pool status for %s", tpool.get('pool', '<unknown>')) continue else: pstat['_config'] = tpool ustat.append(pstat) return ustat
| ver. 1.1 | |
.
| PHP 8.3.30 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка