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

 LiangChao 发布于 2023-01-12 16:44

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

我想知道获得用户统计信息(例如每个用户的请求数)的最佳方法是什么?考虑到基础架构可能会扩展到多个服务器。

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

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

1 个回答
  • 首先:您可能会发现drf-tracking是一个有用的项目,但是它将对每个请求的响应存储在数据库中,我们发现这有点疯狂。

    相反,我们为此开发的解决方案是一个mixin,它大量借鉴了 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查询以一个请求而不是六个请求命中服务器。

    它使用排序集来跟踪您的API中使用最多的端点,以及哪些用户使用API​​最多。

    它每天在您的缓存中创建一些新密钥-可能有更好的方法来执行此操作,但我找不到任何密钥。

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

    2023-01-12 16:46 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有