Python函数调用追踪实现代码


Posted in Python onNovember 27, 2020

对于分布式追踪,主要有以下的几个概念:

  • 追踪 Trace:就是由分布的微服务协作所支撑的一个事务。一个追踪,包含为该事务提供服务的各个服务请求。
  • 跨度 Span:Span是事务中的一个工作流,一个Span包含了时间戳,日志和标签信息。Span之间包含父子关系,或者主从(Followup)关系。
  • 跨度上下文 Span Context:跨度上下文是支撑分布式追踪的关键,它可以在调用的服务之间传递,上下文的内容包括诸如:从一个服务传递到另一个服务的时间,追踪的ID,Span的ID还有其它需要从上游服务传递到下游服务的信息。

我实现了一种简单的调用追踪。

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")

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现博客文章爬虫示例
Feb 26 Python
Python脚本实现12306火车票查询系统
Sep 30 Python
利用Python自带PIL库扩展图片大小给图片加文字描述的方法示例
Aug 08 Python
Python 比较两个数组的元素的异同方法
Aug 17 Python
python通过伪装头部数据抵抗反爬虫的实例
May 07 Python
python set集合使用方法解析
Nov 05 Python
python判断无向图环是否存在的示例
Nov 22 Python
Pycharm内置终端及远程SSH工具的使用教程图文详解
Mar 19 Python
Python中实现一行拆多行和多行并一行的示例代码
Sep 06 Python
10个python爬虫入门基础代码实例 + 1个简单的python爬虫完整实例
Dec 16 Python
Python包管理工具pip的15 个使用小技巧
May 17 Python
我对PyTorch dataloader里的shuffle=True的理解
May 20 Python
Numpy中np.max的用法及np.maximum区别
Nov 27 #Python
python 实现aes256加密
Nov 27 #Python
pandas使用函数批量处理数据(map、apply、applymap)
Nov 27 #Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
Nov 27 #Python
Python基于template实现字符串替换
Nov 27 #Python
使用Python画了一棵圣诞树的实例代码
Nov 27 #Python
python 用opencv实现霍夫线变换
Nov 27 #Python
You might like
wamp下修改mysql访问密码的解决方法
2013/05/07 PHP
php动态生成函数示例
2014/03/21 PHP
使用ob系列函数实现PHP网站页面静态化
2014/08/13 PHP
PHP积分兑换接口实例
2015/02/09 PHP
5个最佳的Javascript日期处理类库分享
2012/04/15 Javascript
分享JavaScript获取网页关闭与取消关闭的事件
2013/12/13 Javascript
cookie的secure属性详解
2015/04/08 Javascript
javascript截取字符串小结
2015/04/28 Javascript
js数组的五种迭代方法及两种归并方法(推荐)
2016/06/14 Javascript
node.js实现快速截图
2016/08/27 Javascript
jQuery Ajax全解析
2017/02/13 Javascript
js实现返回顶部效果
2017/03/10 Javascript
微信小程序页面间通信的5种方式
2017/03/31 Javascript
纯JS实现只能输入数字的简单代码
2017/06/21 Javascript
ES6中Array.includes()函数的用法
2017/09/20 Javascript
使用webpack打包koa2 框架app
2018/02/02 Javascript
angularjs实现table增加tr的方法
2018/02/27 Javascript
JS实现的透明度渐变动画效果示例
2018/04/28 Javascript
JavaScript继承定义与用法实践分析
2018/05/28 Javascript
JS函数节流和防抖之间的区分和实现详解
2019/01/11 Javascript
开源一个微信小程序仪表盘组件过程解析
2019/07/30 Javascript
vue3.0搭配.net core实现文件上传组件
2020/10/29 Javascript
[02:15]2014DOTA2国际邀请赛 专访LGD.lin小兔子是大腿
2014/07/14 DOTA
Python 列表理解及使用方法
2017/10/27 Python
matplotlib绘图实例演示标记路径
2018/01/23 Python
Python3实现将本地JSON大数据文件写入MySQL数据库的方法
2018/06/13 Python
Python中的list与tuple集合区别解析
2019/10/12 Python
Python如何优雅删除字符列表空字符及None元素
2020/06/25 Python
基于Python实现下载网易音乐代码实例
2020/08/10 Python
html5实现完美兼容各大浏览器的播放器
2014/12/26 HTML / CSS
俄罗斯运动鞋商店:Sneakerhead
2018/05/10 全球购物
法国设计制造的扫帚和刷子:Andrée Jardin
2018/12/06 全球购物
心理健康教育制度
2014/01/27 职场文书
校园文明倡议书
2014/05/16 职场文书
感恩教育月活动总结
2014/07/07 职场文书
导游词之张家口
2019/12/13 职场文书