Python如何实现函数调用追踪

最近使用了分布式追踪系列:OpenTracing与Jaeger那些,日常的话可能很难使用,我实现了一种简单的调用追踪。

import uuid
import os
import time


l = []
class Recorder(object):
    def __init__(self,servername,root_span = None):
        if root_span == None:
            self.__span = Span(servername)
        else:
            self.__span = Span(servername,root_span)

    #上下文管理器
    def __enter__(self):
        return self.__span

    # 退出方法中,用来实现善后处理工作
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.__span.record()
        self.__span.record_save(self.__span.span)


class Span(object):
    def __init__(self,servername,root_span = None):
        self.servername = servername
        self.span = self.newspan()
        if root_span != None:
            root_span.dic['child_span'] = self.span
            self.span["root_span_flag"] = False

    def newspan(self):
        self.dic = {
            "spanid": uuid.uuid4().int,
            "servername": self.servername,
            "location": "",
            "ip": "",
            "durationtime": 0,
            "starttime": time.time(),
            "endtime":0,
            "tag": "",
            "log": "",
            "root_span_flag":True,
            "child_span": ""
        }
        return self.dic

    def record_save(self, span):
        currenttracer = {"id": span["spanid"], "data": span}
        print(currenttracer)
        l.append(currenttracer)

    def record(self):
        self.span["servername"] = self.servername
        self.span["location"] = os.getcwd() + "." + self.servername
        self.span["endtime"] = time.time()
        self.span["durationtime"] = self.span["endtime"] - self.span["starttime"]

    def setspantag(self,tag):
        self.span["tag"] = tag

    def setspanlog(self,log):
        self.span["log"] = log

# 连续调用
with Recorder('server1') as span:
    time.sleep(1)
    span.setspantag("test")
    #调用server1方法
    print("server1")
    with Recorder('server2',span) as span1:
        time.sleep(2)
        # 调用server2方法
        print("server2")
        with Recorder('server3',span1) as span2:
            time.sleep(0.5)
            # 调用server3方法
            print("server3")

#单独调用记录
with Recorder('server4') as span_test1:
    time.sleep(1.5)
    print("server4")

with Recorder('server5') as span_test2:
    time.sleep(2)
    print("server5")

运行结果:

server1
server2
server3
{'id': 224716339449765695394515303164364012192, 'data': {'spanid': 224716339449765695394515303164364012192, 'servername': 'server3', 'location': 'D:\python_protest\protest\trace\trace_main.server3', 'ip': '', 'durationtime': 0.5004403591156006, 'starttime': 1598947338.0551107, 'endtime': 1598947338.555551, 'tag': '', 'log': '', 'root_span_flag': False, 'child_span': None}}
{'id': 254736847532758359233387151739984206570, 'data': {'spanid': 254736847532758359233387151739984206570, 'servername': 'server2', 'location': 'D:\python_protest\protest\trace\trace_main.server2', 'ip': '', 'durationtime': 2.501264810562134, 'starttime': 1598947336.0542862, 'endtime': 1598947338.555551, 'tag': '', 'log': '', 'root_span_flag': False, 'child_span': {'spanid': 224716339449765695394515303164364012192, 'servername': 'server3', 'location': 'D:\python_protest\protest\trace\trace_main.server3', 'ip': '', 'durationtime': 0.5004403591156006, 'starttime': 1598947338.0551107, 'endtime': 1598947338.555551, 'tag': '', 'log': '', 'root_span_flag': False, 'child_span': None}}}
{'id': 91028031631192607088457781914309166266, 'data': {'spanid': 91028031631192607088457781914309166266, 'servername': 'server1', 'location': 'D:\python_protest\protest\trace\trace_main.server1', 'ip': '', 'durationtime': 3.5021069049835205, 'starttime': 1598947335.0534441, 'endtime': 1598947338.555551, 'tag': 'test', 'log': '', 'root_span_flag': True, 'child_span': {'spanid': 254736847532758359233387151739984206570, 'servername': 'server2', 'location': 'D:\python_protest\protest\trace\trace_main.server2', 'ip': '', 'durationtime': 2.501264810562134, 'starttime': 1598947336.0542862, 'endtime': 1598947338.555551, 'tag': '', 'log': '', 'root_span_flag': False, 'child_span': {'spanid': 224716339449765695394515303164364012192, 'servername': 'server3', 'location': 'D:\python_protest\protest\trace\trace_main.server3', 'ip': '', 'durationtime': 0.5004403591156006, 'starttime': 1598947338.0551107, 'endtime': 1598947338.555551, 'tag': '', 'log': '', 'root_span_flag': False, 'child_span': None}}}}
server4
{'id': 103171729522922437998918618387133480096, 'data': {'spanid': 103171729522922437998918618387133480096, 'servername': 'server4', 'location': 'D:\python_protest\protest\trace\trace_main.server4', 'ip': '', 'durationtime': 1.5001769065856934, 'starttime': 1598947338.555551, 'endtime': 1598947340.055728, 'tag': '', 'log': '', 'root_span_flag': True, 'child_span': None}}
server5
{'id': 320091321623887285825256878422834254741, 'data': {'spanid': 320091321623887285825256878422834254741, 'servername': 'server5', 'location': 'D:\python_protest\protest\trace\trace_main.server5', 'ip': '', 'durationtime': 2.0005736351013184, 'starttime': 1598947340.055728, 'endtime': 1598947342.0563016, 'tag': '', 'log': '', 'root_span_flag': True, 'child_span': None}}

关于下一步,会使用redis存储其结果,并进行相应的输出分析。

修过不能追踪同级调用的问题

import uuid
import os
import time


l = []
class Recorder(object):
    def __init__(self,servername,root_span = None):
        if root_span == None:
            self.__span = Span(servername)
        else:
            self.__span = Span(servername,root_span)

    #上下文管理器
    def __enter__(self):
        return self.__span

    # 退出方法中,用来实现善后处理工作
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.__span.record()
        self.__span.record_save(self.__span.span)


class Span(object):
    def __init__(self,servername,root_span = None):
        self.servername = servername
        self.span = self.newspan()
        if root_span != None:
            root_span.dic['child_span'].append(self.span)
            self.span["root_span_flag"] = False

    def newspan(self):
        self.dic = {
            "spanid": uuid.uuid4().int,
            "servername": self.servername,
            "location": "",
            "ip": "",
            "durationtime": 0,
            "starttime": time.time(),
            "endtime":0,
            "tag": "",
            "log": "",
            "root_span_flag":True,
            "child_span": []
        }
        return self.dic

    def record_save(self, span):
        currenttracer = {"id": span["spanid"], "data": span}
        print(currenttracer)
        l.append(currenttracer)

    def record(self):
        self.span["servername"] = self.servername
        self.span["location"] = os.getcwd() + "." + self.servername
        self.span["endtime"] = time.time()
        self.span["durationtime"] = self.span["endtime"] - self.span["starttime"]

    def setspantag(self,tag):
        self.span["tag"] = tag

    def setspanlog(self,log):
        self.span["log"] = log



# 连续调用
with Recorder('server1') as span:
    time.sleep(1)
    span.setspantag("test")
    #调用server1方法
    print("server1")
    with Recorder('server2',span) as span1:
        time.sleep(2)
        # 调用server2方法
        print("server2")
        with Recorder('server3',span1) as span2:
            time.sleep(0.5)
            # 调用server3方法
            print("server3")


# 并级连续调用
# with Recorder('server1') as span1:
#     time.sleep(1)
#     span1.setspantag("test")
#     #调用server1方法
#     print("server1")
#     with Recorder('server2',span1) as span2:
#         time.sleep(2)
#         # 调用server2方法
#         print("server2")
#     with Recorder('server3',span1) as span3:
#         time.sleep(0.5)
#         # 调用server3方法
#         print("server3")

# #单独调用记录
# with Recorder('server4') as span_test1:
#     time.sleep(1.5)
#     print("server4")
#
# with Recorder('server5') as span_test2:
#     time.sleep(2)
#     print("server5")
原文地址:https://www.cnblogs.com/-wenli/p/13596771.html