每个用户请求的Django Rest Framework指标

时间:2014-05-29 11:59:19

标签: django nginx django-rest-framework

我目前正在使用Django Rest Framework,uwsgi nginx和memcached进行Api构建。

我想知道获取用户统计信息的最佳方式是什么,例如每个用户的请求数量?考虑到基础设施可能会扩展到多个服务器。

是否有办法确定响应是从缓存还是从应用程序检索?

我正在考虑处理Nginx日志以按用户分隔请求并应用所有计算。

2 个答案:

答案 0 :(得分:5)

首先:您可能find drf-tracking to be a useful project,但它会将响应存储到数据库中的每个请求中,我们发现这种请求有点疯狂。

我们开发的解决方案是一个混合,它从drf-tracking大量借用,但只记录统计信息。该解决方案使用我们的缓存服务器(Redis),因此速度非常快。

如果您已经在使用Redis,那么下载非常简单:

class LoggingMixin(object):
    """Log requests to Redis

    This draws inspiration from the code that can be found at: https://github.com/aschn/drf-tracking/blob/master/rest_framework_tracking/mixins.py

    The big distinctions, however, are that this code uses Redis for greater
    speed, and that it logs significantly less information.

    We want to know:
     - How many queries in last X days, total?
     - How many queries ever, total?
     - How many queries total made by user X?
     - How many queries per day made by user X?
    """

    def initial(self, request, *args, **kwargs):
        super(LoggingMixin, self).initial(request, *args, **kwargs)

        d = date.today().isoformat()
        user = request.user
        endpoint = request.resolver_match.url_name

        r = redis.StrictRedis(
            host=settings.REDIS_HOST,
            port=settings.REDIS_PORT,
            db=settings.REDIS_DATABASES['STATS'],
        )
        pipe = r.pipeline()

        # Global and daily tallies for all URLs.
        pipe.incr('api:v3.count')
        pipe.incr('api:v3.d:%s.count' % d)

        # Use a sorted set to store the user stats, with the score representing
        # the number of queries the user made total or on a given day.
        pipe.zincrby('api:v3.user.counts', user.pk)
        pipe.zincrby('api:v3.user.d:%s.counts' % d, user.pk)

        # Use a sorted set to store all the endpoints with score representing
        # the number of queries the endpoint received total or on a given day.
        pipe.zincrby('api:v3.endpoint.counts', endpoint)
        pipe.zincrby('api:v3.endpoint.d:%s.counts' % d, endpoint)

        pipe.execute()

将它放在项目中的某个位置,然后将mixin添加到各种视图中,如下所示:

class ThingViewSet(LoggingMixin, viewsets.ModelViewSet):
    # More stuff here.

关于班级的一些注意事项:

  • 它使用Redis管道使所有Redis查询都使用一个请求而不是六个请求命中服务器。
  • 它使用Sorted Sets来跟踪API中使用最多的端点以及哪些用户最多使用API​​。
  • 它每天在缓存中创建一些新密钥 - 可能有更好的方法来执行此操作,但我找不到任何密钥。

这应该是记录API的一个相当灵活的起点。

答案 1 :(得分:0)

我通常做的是我有一个集中式缓存服务器(Redis),我使用我需要的所有自定义计算或字段记录所有请求。然后,您可以构建自己的仪表板。

OR

使用Elasticsearch公司的Logstash。做得很好,可以节省您的时间并且非常好。我会说试一试http://michael.bouvy.net/blog/en/2013/11/19/collect-visualize-your-logs-logstash-elasticsearch-redis-kibana/