美文网首页
Python 探针实现原理

Python 探针实现原理

作者: hugoren | 来源:发表于2018-05-22 11:35 被阅读0次

本文将简单讲述一下 Python 探针的实现原理。 同时为了验证这个原理,我们也会一起来实现一个简单的统计指定函数执行时间的探针程序。

探针的实现主要涉及以下几个知识点:

  • sys.meta_path
  • sitecustomize.py
  • sys.meta_path
    sys.meta_path这个简单的来说就是可以实现 import hook 的功能, 当执行 import 相关的操作时,会触发 sys.meta_path 列表中定义的对象。 关于 sys.meta_path 更详细的资料请查阅 python 文档中 sys.meta_path 相关内容以及 PEP 0302 。

sys.meta_path 中的对象需要实现一个 find_module 方法, 这个 find_module 方法返回 None 或一个实现了 load_module 方法的对象 (代码可以从 github 上下载 part1) :

import sys


class MetaPathFinder:

    def find_module(self, fullname, path=None):
        print('find_module {}'.format(fullname))
        return MetaPathLoader()


class MetaPathLoader:

    def load_module(self, fullname):
        print('load_module {}'.format(fullname))
        sys.modules[fullname] = sys
        return sys

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

if __name__ == '__main__':
    import http
    print(http)
    print(http.version_info)

load_module 方法返回一个 module 对象,这个对象就是 import 的 module 对象了。 比如我上面那样就把 http 替换为 sys 这个 module 了。

$ python meta_path1.py
find_module http
load_module http
<module 'sys' (built-in)>
sys.version_info(major=3, minor=5, micro=1, releaselevel='final', serial=0)

通过 sys.meta_path 我们就可以实现 import hook 的功能: 当 import 预定的 module 时,对这个 module 里的对象来个狸猫换太子, 从而实现获取函数或方法的执行时间等探测信息。

上面说到了狸猫换太子,那么怎么对一个对象进行狸猫换太子的操作呢? 对于函数对象,我们可以使用装饰器的方式来替换函数对象(代码可以从 github 上下载 part2) :

import functools
import time


def func_wrapper(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print('start func')
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print('spent {}s'.format(end - start))
        return result
    return wrapper


def sleep(n):
    time.sleep(n)
    return n

if __name__ == '__main__':
    func = func_wrapper(sleep)
    print(func(3))
image.png

我们的 import hook 是 hook.py:

import functools
import importlib
import sys
import time

_hook_modules = {'hello'}


class MetaPathFinder:

    def find_module(self, fullname, path=None):
        print('find_module {}'.format(fullname))
        if fullname in _hook_modules:
            return MetaPathLoader()


class MetaPathLoader:

    def load_module(self, fullname):
        print('load_module {}'.format(fullname))
        # ``sys.modules`` 中保存的是已经导入过的 module
        if fullname in sys.modules:
            return sys.modules[fullname]

        # 先从 sys.meta_path 中删除自定义的 finder
        # 防止下面执行 import_module 的时候再次触发此 finder
        # 从而出现递归调用的问题
        finder = sys.meta_path.pop(0)
        # 导入 module
        module = importlib.import_module(fullname)

        module_hook(fullname, module)

        sys.meta_path.insert(0, finder)
        return module

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


def module_hook(fullname, module):
    if fullname == 'hello':
        module.sleep = func_wrapper(module.sleep)


def func_wrapper(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print('start func')
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print('spent {}s'.format(end - start))
        return result
    return wrapper
image.png image.png image.png image.png

实现一个agent

import os
import sys

current_dir = os.path.dirname(os.path.realpath(__file__))
boot_dir = os.path.join(current_dir, 'bootstrap')


def main():
    args = sys.argv[1:]
    os.environ['PYTHONPATH'] = boot_dir
    # 执行后面的 python 程序命令
    # sys.executable 是 python 解释器程序的绝对路径 ``which python``
    # >>> sys.executable
    # '/usr/local/var/pyenv/versions/3.5.1/bin/python3.5'
    os.execl(sys.executable, sys.executable, *args)

if __name__ == '__main__':
    main()

转自:
https://mozillazg.com/2016/04/apm-python-agent-principle.html

相关文章

  • Python 探针实现原理

    sys.meta_path sitecustomize.py agent 本文将简单讲述一下 Python 探针的...

  • 基于Android手机AP的WIFI探针开发

    1. 开发原理 先上一张WIFI探针的原理图 图中的术语请看我的文章WIFI探针简介。 2. 应用开发流程图

  • 基因芯片与基因测序的差异?

    1.检测原理 基因芯片的测序原理是杂交测序方法,即通过与一组已知序列的核酸探针杂交进行核酸序列测定的方法。由于探针...

  • wifi探针原理

    文章图片上传不正常,如需文档,可联系微信:1017429387 目录 1 安装... 4 1.1 配置探针... ...

  • WIFI探针原理

    WIFI 探针原理:WIFI 是基于IEEE802.11a/b/g/n 协议,在标准协议中,定义了AP(无线接入点...

  • Python控制电脑远程开机

    本文目标 远程开机原理 Python 远程开机代码实现 Python 关机说明 Python 开机 关于用程序来开...

  • LRU Cache的原理和python的实现

    LRU Cache的原理和python的实现 LRU的原理 LRU(Least Recently Used)即最近...

  • softmax回归

    算法原理 算法原理 造轮子python 算法实现 https://blog.csdn.net/u012328159...

  • WiFi探针的工作原理

    WiFi探针的工作原理?要深入了解WiFi探针技术,首先先认识WiFi使用的网络协议,WiFi采用的是IEEE80...

  • Apriori 算法的研究

    Aprioir 算法的原理和实现 1、Apriori 算法介绍(Python 实现) 地址:http://www....

网友评论

      本文标题:Python 探针实现原理

      本文链接:https://www.haomeiwen.com/subject/qpdhjftx.html