django-zipkin 是一个用于记录和向Zipkin发送消息的 Django 中间件和 API
项目描述
django-zipkin 是一个用于记录和向 Zipkin 发送消息的中间件和 API。为什么要使用它?参见 http://twitter.github.io/zipkin/
“收集跟踪信息可以帮助开发者更深入地了解某些请求在分布式系统中的性能。假设我们遇到了用户请求超时的问题。我们可以查找超时的跟踪请求,并在 Web UI 中显示它们。我们将能够快速找到负责添加意外响应时间的服务。如果该服务已充分注释,我们还可以找到该服务中问题发生的地方。”
支持的版本
Python: 2.6, 2.7(当前Python Thrift版本不支持Python 3)
Django: 1.3 - 1.7
入门指南
安装库
pip install django-zipkin
将中间件添加到已安装中间件列表中
MIDDLEWARE_CLASSES = ('...',
'django_zipkin.middleware.ZipkinMiddleware',
'...')
设置服务将使用的名称以识别自身。这将在Zipkin中显示为服务名称。
ZIPKIN_SERVICE_NAME = 'awesome-service'
django-zipkin现在将数据记录为与Zipkin收集器兼容的数据到名为zipkin的记录器。
获取数据到Zipkin
从这里开始,如何将消息发送到Zipkin取决于您。以下是在Prezi中我们这样做的方式
我们使用django-zipkin在每个服务中配置日志记录,以将来自zipkin记录器的日志消息发送到本地运行的Scribe实例,并将其分类为zipkin。
Scribe实例被配置为将zipkin分类直接转发到Zipkin收集器。这很有用,因为Scribe会在收集器(或通往它的网络)关闭时缓存消息。
另一个替代方案可能是将日志记录到syslog,并使用Scribe提供的scribe_apache将数据发送到Zipkin(可能通过本地Scribe服务器)。
记录注解
django-zipkin为每个请求创建一个span。它自动添加许多注解(见下文)。您也可以从代码的任何地方添加自己的注解
from django_zipkin.api import api as zipkin_api
zipkin_api.record_event('MySQL: "SELECT * FROM auth_users"', duration=15000) # Note duration is in microseconds, as defined by Zipkin
zipkin_api.record_key_value('Cache misses', 15) # You can use string, int, long and bool values
传播跟踪信息
为了识别哪些span属于同一个跟踪,一些信息必须在与服务之间的调用中传递。在客户端和服务器端,django-zipkin提供用于此目的的设施。中间件自动读取Zipkin文档中描述的跟踪传播HTTP头(点击查看)。为了将数据传播到出站请求,提供了一个返回正确HTTP头字典的函数
from django_zipkin.api import api as zipkin_api
headers = zipkin_api.get_headers_for_downstream_request()
# During a request returns something like this:
{'X-B3-Sampled': 'false', 'X-B3-TraceId': 'b059fb34103a46f7', 'X-B3-Flags': '0', 'X-B3-SpanId': 'a42f4f3a045c54a5'}
自动生成的注解
sr和ss注解由中间件自动添加。以下二进制(键值)注解也添加了
注解 |
示例值 |
添加条件 |
---|---|---|
http.uri |
/api/v1/login |
始终 |
http.statuscode |
200 |
始终 |
django.view.func_name |
login |
始终 |
django.view.class |
AuthView |
如果视图函数是视图类的方法 |
django.view.args |
('oauth') |
始终 |
django.view.kwargs |
{"next": "/index"} |
始终 |
django.url_name |
myapp.views.login |
始终 |
django.tastypie.resource_name |
user |
如果请求由Tastypie(特别是当视图获取关键字参数resource_name)服务 |
添加cs和cr(客户端发送和客户端接收)注解的责任在于您使用的任何客户端。
注意事项
中间件顺序
如果位于django-zipkin之上的中间件返回响应,那么django-zipkin的请求处理部分将永远不会被调用,从而导致内部状态不一致。在这种情况下,您的自定义注解和大多数自动添加的注解将丢失,时间信息将不正确。将添加一个附加注解,其值为:No ZipkinData in thread local store. This can happen if process_request didn't run due to a previous middleware returning a response. Timing information is invalid.
视图包装器
如果你的视图被包裹(例如使用装饰器)而没有使用 functools.wraps 装饰器,那么 django-zipkin 将无法检索视图名称。在这种情况下,django.view.func_name 将是包装函数的函数名称。这是你自己的代码中想要避免的事情。
一个例子是 Tastypie:在 Tastypie 服务的请求中,django.view.func_name 将始终是 wrapper。在 Tastypie 服务的请求中,将添加注释 django.tastypie.resource_name,其中包含 Tastypie 资源名称,而 django.url_name 将是有用的,如 api_dispatch_list。
Zipkin UI 与 JSON 注释值对比
django.view.kwargs 注释的值是一个 JSON 字符串,以便于自动化处理。不幸的是,这使得 UI 显示的值是 [object Object]。有关此问题的最新进展,请参阅 Zipkin 问题 #410。如果您想在 Web UI 中找到值,可以打开页面源代码并搜索 django.view.kwargs。
自定义
您可以通过以下设置值自定义 django-zipkin 的工作方式。它们定义在 django_zipkin/defaults.py 中。
设置变量
ZIPKIN_SERVICE_NAME:默认 None。将在 Zipkin 中显示的服务名称(发送的 Thrift 对象中的 service_name 值)。
ZIPKIN_LOGGER_NAME:默认 'zipkin'。使用 Python 日志系统发送 Zipkin 消息时使用的日志记录器名称。
ZIPKIN_DATA_STORE_CLASS:默认 'django_zipkin.data_store.ThreadLocalDataStore'。django-zipkin 需要将一些数据从请求处理器传递到响应处理器。这些相同的数据需要从用户代码的任何地方都可以访问。此实现的默认方法是使用线程局部存储。gevent 和 greenlet 对其进行猴子补丁,因此即使在 gunicorn 和类似环境中,此实现也能正常工作。您可以提供自己的实现 - 它需要实现 django_zipkin.data_store.BaseDataStore 的方法。
ZIPKIN_ID_GENERATOR_CLASS:默认 'django_zipkin.id_generator.SimpleIdGenerator'。如果从传入的请求中没有获取到,则用于生成 span 和 trace id 的类。
Configglue
configglue 支持通过 django_zipkin.schema 提供;您可以将它包含到自己的模式中,如下所示
from django_zipkin.schema import DjangoZipkinSection
class MySchema(...):
...
class zipkin(DjangoZipkinSection):
pass
黑客
有关指南,请参阅 CONTRIBUTING.md。
您可以从以下开始对 django-zipkin 进行修改
git clone https://github.com/prezi/django-zipkin.git
cd django-zipkin
git remote rename origin upstream
virtualenv virtualenv
. virtualenv/bin/activate
pip install django
python setup.py test