����JFIF��x�x����'403WebShell
403Webshell
Server IP : 78.140.185.180  /  Your IP : 216.73.216.82
Web Server : LiteSpeed
System : Linux cpanel13.v.fozzy.com 4.18.0-513.11.1.lve.el8.x86_64 #1 SMP Thu Jan 18 16:21:02 UTC 2024 x86_64
User : builderbox ( 1072)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/cloudlinux/venv/lib/python3.11/site-packages/cl_plus/collectors/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/cloudlinux/venv/lib/python3.11/site-packages/cl_plus/collectors//mysql.py
# coding=utf-8
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2020 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#
import time
import warnings
from typing import Optional, Tuple

try:
    import pymysql
except ImportError:
    pymysql = None

from clcommon.cpapi import db_access
from clcommon.cpapi.cpapiexceptions import NoDBAccessData, NotSupported
from clcommon import mysql_lib

from .collector_base import CollectorBase

# enough to collect only several times per minute, cause we rely on DB counter
MYSQL_COLLECTION_INTERVAL = 30

def _total_queries_num_request(db, query_str):
    """
    Execs passed query and returns value
    """
    with warnings.catch_warnings():
        warnings.filterwarnings('ignore', category=pymysql.Warning)
        data = db.execute_query(query_str)
    return data[0][1]


class MySQLCollector(CollectorBase):
    class DBAccess:
        def __init__(self, login: Optional[str] = None, password: Optional[str] = None):
            self.login = login
            self.password = password
            self.expire_time = time.time() + 3600

        def __eq__(self, other):
            return self.login == other.login and self.password == other.password

        def __bool__(self):
            return bool(self.login and self.password and not self.is_expired())

        def is_expired(self) -> bool:
            return time.time() > self.expire_time

    def __init__(self, _logger):
        super(MySQLCollector, self).__init__(_logger)
        self._is_mysql_error = False
        self.collection_interval = MYSQL_COLLECTION_INTERVAL
        self.access = self.DBAccess()
        self.previous_num, self.current_num = None, None
        self._aggregation_times = 0

    def init(self):
        """
        Initialize MySQL collector
        :return: None
        """
        self._aggregated_data = 0
        self._logger.info("MySQL collector init")
        self._logger.info('MySQL collector initial values: previous: %s, current: %s',
                          str(self.previous_num),
                          str(self.current_num))

    def _get_total_queries_num(self, dblogin: str, dbpass: str):
        """
        Gets total queries number via Queries variable in DB
        it is a total counter of queries made to DB

        it is used be such monitoring system as Nagios and mysqladmin returns it
        https://github.com/nagios-plugins/nagios-plugins/blob/master/plugins/check_mysql.c
        """
        if not pymysql:
            return "No MySQL client libraries installed", 0
        try:
            connector = mysql_lib.MySQLConnector(host='localhost',
                                                 user=dblogin,
                                                 passwd=dbpass,
                                                 db='mysql',
                                                 use_unicode=True,
                                                 charset='utf8')
            with connector.connect() as db:
                total = _total_queries_num_request(db, 'show global status where Variable_name = \'Questions\';')
            self._aggregation_times += 1
        # since mysql_lib is our lib, it could through different exceptions
        except Exception as e:
            return str(e), 0
        return 'OK', int(total)


    def _get_db_access(self) -> Tuple[str, str]:
        """
        Get DB access data from cpapi function. Logs error
        :return: tuple (db_root_login, db_password)
            None, None if error
        """
        if not self.access:
            try:
                access = db_access()    # {'pass': str, 'login': str}
                self.access = self.DBAccess(access['login'], access['pass'])
            except (NoDBAccessData, NotSupported, KeyError, TypeError) as e:
                # Can't retrieve data
                if not self._is_mysql_error:
                    self._logger.warn("MySQL collector: can't obtain MySQL DB access: %s", str(e))
                    self._is_mysql_error = True
        return self.access.login, self.access.password

    def aggregate_new_data(self):
        """
        Retrieve and aggregate new data
        :return None
        """
        self._get_db_access()
        if not self.access:     # access data still is not set
            return

        # New data present - aggregate
        message, total_queries = self._get_total_queries_num(self.access.login, self.access.password)

        if message == 'OK':
            self.previous_num = self.current_num
            self.current_num = total_queries

            # no previous value to compare during 1st iteration after collector is started
            if self.previous_num is not None and self.current_num is not None:

                # if mysql counter was re-set
                if self.current_num < self.previous_num:
                    self._logger.info('MySQL collector: QUERIES counter was re-set in database, '
                                      're-set collectors previous counter as well')
                    self.previous_num = 0
                self._aggregated_data += self.current_num - self.previous_num

            self._is_mysql_error = False
            return

        # Retrieve data error
        if not self._is_mysql_error:
            self._logger.error("MySQL collector can't obtain MySQL queries number: %s", message)
            self._is_mysql_error = True

    def get_averages(self):
        """
        Get collector's averages data
        :return: dict:
            { "mysql_queries_num": 16}
            or None if can't get data
        """
        mysql_queries_num = max(0, self._aggregated_data - self._aggregation_times)
        self._aggregated_data = 0
        self._aggregation_times = 0
        return {"mysql_queries_num": mysql_queries_num}

Youez - 2016 - github.com/yon3zu
LinuXploit