Django保存整个请求进行统计,有什么可用的?

发布于 2024-10-31 16:05:42 字数 240 浏览 1 评论 0原文

我想保存可用于统计的所有内容,例如引荐来源网址、操作系统、浏览器等。有哪些可用的以及存储它们的最佳方式是什么?

这仅对项目中的 1 个应用程序(1 个页面)很重要,其他页面将使用一些标准分析产品,例如 google 分析。

我查看了 django-tracking,但这似乎有点过分了,因为我只想在 1 个视图上使用它。理想的情况是,将整个请求对象传递给 TaskQue 并稍后进行处理。因此,用户首先被重定向,分析处理将在幕后完成。

I want to save everything that can be used for statistics, such as referrer, os, browser etc. What is available and what's the best way to store it?

This is only important for 1 application (1 page) in the project, the other pages some standard analytics product will be used such as google analytics.

I had a look at django-tracking, but it seems this is overkill as I only want to use it on 1 view. The ideal situation would be, passing the whole request object to a TaskQue and do the processing later. So the user is redirected first and the analytics processing will be done behind the scenes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

归属感 2024-11-07 16:05:42

我们使用一些简单的中间件..下面是摘录。您可以修改它以直接在视图中使用。

class WebRequest(models.Model):
    time = models.DateTimeField(auto_now_add=True)
    host = models.CharField(max_length=1000)
    path = models.CharField(max_length=1000)
    method = models.CharField(max_length=50)
    uri = models.CharField(max_length=2000)
    status_code = models.IntegerField()
    user_agent = models.CharField(max_length=1000,blank=True,null=True)
    remote_addr = models.IPAddressField()
    remote_addr_fwd = models.IPAddressField(blank=True,null=True)
    meta = models.TextField()
    cookies = models.TextField(blank=True,null=True)
    get = models.TextField(blank=True,null=True)
    post = models.TextField(blank=True,null=True)
    raw_post = models.TextField(blank=True,null=True)
    is_secure = models.BooleanField()
    is_ajax = models.BooleanField()
    user = models.ForeignKey(User,blank=True,null=True)

def dumps(value):
    return json.dumps(value,default=lambda o:None)

class WebRequestMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        setattr(request,'hide_post',view_kwargs.pop('hide_post',False))


    def process_response(self, request, response):

        if request.path.endswith('/favicon.ico'):
            return response

        if type(response) == HttpResponsePermanentRedirect and settings.APPEND_SLASH:
            new_location = response.get('location',None)
            content_length = response.get('content-length',None)

            if new_location and content_length is '0':
                new_parsed = urlparse(new_location)

                old = (('http','https')[request.is_secure()], request.get_host(), '{0}/'.format(request.path), request.META['QUERY_STRING'])
                new = (new_parsed.scheme, new_parsed.netloc, new_parsed.path, new_parsed.query)

                if old == new:
                    #dont log - it's just adding a /
                    return response
        try:
            self.save(request, response)
        except Exception as e:
            print >> sys.stderr, "Error saving request log", e

        return response

    def save(self, request, response):
        if hasattr(request, 'user'):
            user = request.user if type(request.user) == User else None
        else:
            user = None

        meta = request.META.copy()
        meta.pop('QUERY_STRING',None)
        meta.pop('HTTP_COOKIE',None)
        remote_addr_fwd = None

        if 'HTTP_X_FORWARDED_FOR' in meta:
            remote_addr_fwd = meta['HTTP_X_FORWARDED_FOR'].split(",")[0].strip()
            if remote_addr_fwd == meta['HTTP_X_FORWARDED_FOR']:
                meta.pop('HTTP_X_FORWARDED_FOR')

        post = None
        uri = request.build_absolute_uri()
        if request.POST and uri != '/login/':
            post = dumps(request.POST)

        models.WebRequest(
            host = request.get_host(),
            path = request.path,
            method = request.method,
            uri = request.build_absolute_uri(),
            status_code = response.status_code,
            user_agent = meta.pop('HTTP_USER_AGENT',None),
            remote_addr = meta.pop('REMOTE_ADDR',None),
            remote_addr_fwd = remote_addr_fwd,
            meta = None if not meta else dumps(meta),
            cookies = None if not request.COOKIES else dumps(request.COOKIES),
            get = None if not request.GET else dumps(request.GET),
            post = None if (not request.POST or getattr(request,'hide_post') == True) else dumps(request.POST),
            raw_post = None if getattr(request,'hide_post') else request.raw_post_data,
            is_secure = request.is_secure(),
            is_ajax = request.is_ajax(),
            user = user
        ).save()

We use some simple middleware.. below is an excerpt. You can modify it to use directly within a view.

class WebRequest(models.Model):
    time = models.DateTimeField(auto_now_add=True)
    host = models.CharField(max_length=1000)
    path = models.CharField(max_length=1000)
    method = models.CharField(max_length=50)
    uri = models.CharField(max_length=2000)
    status_code = models.IntegerField()
    user_agent = models.CharField(max_length=1000,blank=True,null=True)
    remote_addr = models.IPAddressField()
    remote_addr_fwd = models.IPAddressField(blank=True,null=True)
    meta = models.TextField()
    cookies = models.TextField(blank=True,null=True)
    get = models.TextField(blank=True,null=True)
    post = models.TextField(blank=True,null=True)
    raw_post = models.TextField(blank=True,null=True)
    is_secure = models.BooleanField()
    is_ajax = models.BooleanField()
    user = models.ForeignKey(User,blank=True,null=True)

def dumps(value):
    return json.dumps(value,default=lambda o:None)

class WebRequestMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        setattr(request,'hide_post',view_kwargs.pop('hide_post',False))


    def process_response(self, request, response):

        if request.path.endswith('/favicon.ico'):
            return response

        if type(response) == HttpResponsePermanentRedirect and settings.APPEND_SLASH:
            new_location = response.get('location',None)
            content_length = response.get('content-length',None)

            if new_location and content_length is '0':
                new_parsed = urlparse(new_location)

                old = (('http','https')[request.is_secure()], request.get_host(), '{0}/'.format(request.path), request.META['QUERY_STRING'])
                new = (new_parsed.scheme, new_parsed.netloc, new_parsed.path, new_parsed.query)

                if old == new:
                    #dont log - it's just adding a /
                    return response
        try:
            self.save(request, response)
        except Exception as e:
            print >> sys.stderr, "Error saving request log", e

        return response

    def save(self, request, response):
        if hasattr(request, 'user'):
            user = request.user if type(request.user) == User else None
        else:
            user = None

        meta = request.META.copy()
        meta.pop('QUERY_STRING',None)
        meta.pop('HTTP_COOKIE',None)
        remote_addr_fwd = None

        if 'HTTP_X_FORWARDED_FOR' in meta:
            remote_addr_fwd = meta['HTTP_X_FORWARDED_FOR'].split(",")[0].strip()
            if remote_addr_fwd == meta['HTTP_X_FORWARDED_FOR']:
                meta.pop('HTTP_X_FORWARDED_FOR')

        post = None
        uri = request.build_absolute_uri()
        if request.POST and uri != '/login/':
            post = dumps(request.POST)

        models.WebRequest(
            host = request.get_host(),
            path = request.path,
            method = request.method,
            uri = request.build_absolute_uri(),
            status_code = response.status_code,
            user_agent = meta.pop('HTTP_USER_AGENT',None),
            remote_addr = meta.pop('REMOTE_ADDR',None),
            remote_addr_fwd = remote_addr_fwd,
            meta = None if not meta else dumps(meta),
            cookies = None if not request.COOKIES else dumps(request.COOKIES),
            get = None if not request.GET else dumps(request.GET),
            post = None if (not request.POST or getattr(request,'hide_post') == True) else dumps(request.POST),
            raw_post = None if getattr(request,'hide_post') else request.raw_post_data,
            is_secure = request.is_secure(),
            is_ajax = request.is_ajax(),
            user = user
        ).save()
阳光下的泡沫是彩色的 2024-11-07 16:05:42

只需手动从请求中提取它即可。

该文档概述了可以从请求对象中提取的大量信息。

例如,标头存储在 request.META 中,GET 参数存储在 request.GET 中,等等。
http://docs.djangoproject.com/ en/dev/ref/request-response/#django.http.HttpRequest.META

存储它的最佳方式是什么?取决于你在做什么。记录它,将其存储在数据库中,将其发送到其他地方......你说的是统计数据,所以数据库听起来是一个放置它的好地方,因为它很容易查询。

Just manually pull it from the request.

The docs outlines a lot of the info that can be pulled from the request object.

For example, headers are stored in request.META, GET params in request.GET, etc.
http://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

What's the best way to store it? Depends what you're doing. Log it, store it in a DB, send it somewhere else... You say for statistics, so a database sounds like a good place to put this as it's easy to query.

笑忘罢 2024-11-07 16:05:42

扩展 Josh 的答案,如果您使用 postgres 作为后端,则可以使用 JSONField 来发布数据。它将有助于直接处理 json 而不是手动加载它。

阅读更多: https://docs.djangoproject.com/ en/2.0/ref/contrib/postgres/fields/#jsonfield

你可以这样做

from django.contrib.postgres.fields import JSONField

class WebRequest(models.Model):
    post = JSONField(default=dict)

Extension to Josh answer, you could use JSONField for post data if you are using postgres as your backend. It will help in dealing with json directly rather than loading it manually.

read more: https://docs.djangoproject.com/en/2.0/ref/contrib/postgres/fields/#jsonfield

you could do something like this

from django.contrib.postgres.fields import JSONField

class WebRequest(models.Model):
    post = JSONField(default=dict)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文