• 技术文章 >Python技术 >Python基础教程

    python如何制作探针模块

    小妮浅浅小妮浅浅2021-09-25 09:33:59原创3118

    1、涉及aiomysql模块,在MetaPathFinder.find_module中只需要处理aiomysql模块。

    其他先忽略,然后确定需要替换aiomysql的功能。从业务上来说,一般我们只需要cursor.execute、cursor.fetchone、cursor.fetchall、cursor.executemany这些主要操作。

    2、先cursor.execute的源代码(其他同理),调用self.nextset的方法。

    完成上一个请求的数据,然后合并sql语句,最后通过self._query查询。

    实例

    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

    import importlib

    import time

    import sys

    from functools import wraps

      

    from typing import cast, Any, Callable, Optional, Tuple, TYPE_CHECKING

    from types import ModuleType

    if TYPE_CHECKING:

        import aiomysql

      

      

    def func_wrapper(func: Callable):

        @wraps(func)

        async def wrapper(*args, **kwargs) -> Any:

            start: float = time.time()

            func_result: Any = await func(*args, **kwargs)

            end: float = time.time()

      

            # 根据_query可以知道, 第一格参数是self, 第二个参数是sql

            self: aiomysql.Cursor = args[0]

            sql: str = args[1]

            # 通过self,我们可以拿到其他的数据

            db: str = self._connection.db

            user: str = self._connection.user

            host: str = self._connection.host

            port: str = self._connection.port

            execute_result: Tuple[Tuple] = self._rows

            # 可以根据自己定义的agent把数据发送到指定的平台, 然后我们就可以在平台上看到对应的数据或进行监控了,

            # 这里只是打印一部分数据出来

            print({

                "sql": sql,

                "db": db,

                "user": user,

                "host": host,

                "port": port,

                "result": execute_result,

                "speed time": end - start

            })

            return func_result

        return cast(Callable, wrapper)

      

      

    class MetaPathFinder:

      

        @staticmethod

        def find_module(fullname: str, path: Optional[str] = None) -> Optional["MetaPathLoader"]:

            if fullname == 'aiomysql':

                # 只有aiomysql才进行hook

                return MetaPathLoader()

            else:

                return None

      

      

    class MetaPathLoader:

      

        @staticmethod

        def load_module(fullname: str):

            if fullname in sys.modules:

                return sys.modules[fullname]

            # 防止递归调用

            finder: "MetaPathFinder" = sys.meta_path.pop(0)

            # 导入 module

            module: ModuleType = importlib.import_module(fullname)

            # 针对_query进行hook

            module.Cursor._query = func_wrapper(module.Cursor._query)

            sys.meta_path.insert(0, finder)

            return module

      

      

    async def test_mysql() -> None:

        import aiomysql

        pool: aiomysql.Pool = await aiomysql.create_pool(

            host='127.0.0.1', port=3306, user='root', password='123123', db='mysql'

        )

        async with pool.acquire() as conn:

            async with conn.cursor() as cur:

                await cur.execute("SELECT 42;")

                (r,) = await cur.fetchone()

                assert r == 42

        pool.close()

        await pool.wait_closed()

      

    if __name__ == '__main__':

        sys.meta_path.insert(0, MetaPathFinder())

        import asyncio

      

        asyncio.run(test_mysql())

      

    # 输出示例:

    # 可以看出sql语句与我们输入的一样, db, user, host, port等参数也是, 还能知道执行的结果和运行时间

    # {'sql': 'SELECT 42;', 'db': 'mysql', 'user': 'root', 'host': '127.0.0.1', 'port': 3306, 'result': ((42,),), 'speed time': 0.00045609474182128906}

    以上就是python制作探针模块的方法,希望对大家有所帮助。更多Python学习指路:python基础教程

    本文教程操作环境:windows7系统、Python 3.9.1,DELL G3电脑。

    专题推荐:python探针
    上一篇:python探针如何实现 下一篇:python poetry如何创建项目

    相关文章推荐

    • python三种导入模块的方式• python查找计算函数的整理• python填充压缩的函数总结• python分割拼接函数的介绍• python判断字符串函数的归纳• python如何实现图像等比缩放• python setup和teardown的使用• python绘制散点图的两种方法• python用plt.pie绘制饼图• python Axes3D绘制3D图形• python raise触发异常的实现• python链表法的优缺点• python有序Dict的原理• python探针如何实现

    全部评论我要评论

    © 2021 Python学习网 苏ICP备2021003149号-1

  • 取消发布评论
  • 

    Python学习网