google analyticsの設定をしたけど、よくまだわかってないというところがあり、
Apache側のログをいい感じで集計できないかと思いました。
gooleでWebをまさぐったところ、Mezzanineのpluginではないですが、
djangoのplugin のGitHub - django-request/django-requestインストール、設定して、
MezzanineのDashboardで表示できないか試してみました。


環境情報

  • OS
    CentOS release 6.7 (Final)

  • Python Version
    Python 2.7.8

  • Package (必要そうなものだけ抜粋)
    Django (1.9.6)
    Mezzanine (4.1.0)


インストール

  • 追記(django-requestのversion情報)
    pip で インストールされた django-request のverisonは 1.4.0 になります。
    version が 今後上がれば以下の面倒なことはしなくて済むようになるかと思います。

  • 参考サイト

  • pip でインストール

    pip install django-request
    

  • settings.py#INSTALLED_APPSrequest追加する

    INSTALLED_APPS = (
        "request",
        "admin_backup",
        "clean_blog",
    

  • makemigrations実行

    python manage.py makemigrations request
    

  • WARNINGのOUTPUT

WARNINGS:
?: (mezzanine.core.W01) Please update your settings to use the TEMPLATES setting rather than the deprecated individual TEMPLATE_ settings. The latter are unsupported and correct behaviour is not guaranteed. Here's a suggestion based on on your existing configuration:

.....

Migrations for 'request':
  0001_initial.py:
    - Create model Request
こちら対処し次手順へ..(Django1.8からTemplateの書き方が変わったようです。)

  • sqlmigrate実行

    python manage.py sqlmigrate request 0001
    
    BEGIN;
    --
    -- Create model Request
    --
    CREATE TABLE "request_request" ("id" serial NOT NULL PRIMARY KEY, "response" smallint NOT NULL, "method" varchar(7) NOT NULL, "path" varchar(255) NOT NULL, "time" timestamp with time zone NOT NULL, "is_secure" boolean NOT NULL, "is_ajax" boolean NOT NULL, "ip" inet NOT NULL, "referer" varchar(255) NULL, "user_agent" varchar(255) NULL, "language" varchar(255) NULL, "user_id" integer NULL);
    ALTER TABLE "request_request" ADD CONSTRAINT "request_request_user_id_2a99fbcb_fk_auth_user_id" FOREIGN KEY ("user_id") REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED;
    CREATE INDEX "request_request_e8701ad4" ON "request_request" ("user_id");
    
    COMMIT;
    

  • migrate実行

    python manage.py migrate request 0001
    

  • settings.py#MIDDLEWARE_CLASSESrequest.middleware.RequestMiddleware追加する
    django.contrib.auth,
    django.contrib.flatpagesどちらも使用していないので、
    1要素目に追加しました。

MIDDLEWARE_CLASSES = (
    "request.middleware.RequestMiddleware",

  • Siteのドメイン名が、正しいことを確認
    ユニークビジター数とトップ参照元を計算するために使うよということらしいです。

ADMIN画面から表示してみる。

  • 管理メニューTOP インストールがうまくいくと、管理者権限のユーザーでログインすると、
    画面の左メニューにリクエストタブが表示されるようになりました。

管理メニューTOP

  • 管理メニューリンク押下で、No module named importlib エラー発生
    django-requestが、django1.9ので削除されたmoduleを参照しており、エラーになっています。
    まだ、pip対応モジュールがダウンロードできないので、直接編集して直します。

    • 参考 django-request/plugins.py at master · django-request/django-request · GitHub
      No module named importlib
      Request Method: GET
      Request URL:    ......
      Django Version: 1.9.6
      Exception Type: ImportError
      Exception Value:    
      No module named importlib
      Exception Location: /usr/local/lib/python2.7/site-packages/request/plugins.py in load, line 42
      Python Executable:  /usr/bin/python
      Python Version: 2.7.8
      Python Path:    
      ....
      
  • 対象箇所を修正 plugins.py

    class Plugins(object):
        def load(self):
            #from django.utils.importlib import import_module
            from importlib import import_module
            from django.core import exceptions
    

  • 再度動作確認

別のモジュールで同様のエラー…

No module named importlib
Request Method: GET
Request URL:    ......
Django Version: 1.9.6
Exception Type: ImportError
Exception Value:    
No module named importlib
Exception Location: /usr/local/lib/python2.7/site-packages/request/traffic.py in load, line 18
Python Executable:  /usr/bin/python
Python Version: 2.7.8
Python Path:    
....

  • 対象箇所を修正 traffic.py

class Modules(object):
    def load(self):
        #from django.utils.importlib import import_module
        from importlib import import_module
        from django.core import exceptions

  • ログの一覧表示画面
    右メニューを表示すると以下の画面が表示されます。
    ログの<wbr>一覧画面

  • JSエラーになったので、必要な静的ファイルをファイル置き場にコピー 私の環境だと、一覧画面の表示時にjsエラーになっていたので、
    必要なファイルをファイル置き場にコピーしました。

cp -R /usr/local/lib/python2.7/site-packages/request/static/request ${MEZZANINE_PROJECT_ROOT}/static
chown -R apache:apache ${MEZZANINE_PROJECT_ROOT}/static

  • リクエストを追加
    ログの一覧画面の右上リクエストを<wbr>追加クリックでこちらに移動します。
    正直これはあまり意味がない機能な気が....

リクエストを<wbr>追加

  • Request Overview ログの一覧画面の右上Overviewクリックでこちらに移動します。
    これが欲しかった機能かと思われます。

Request Overview


settings.pyの設定

django-requestでのロギングの仕方などを変更可能です。
結構たくさん設定があったので、私が変えたかったものだけ、つまんで記載します。

キー値内容デフォルト値
REQUEST_IGNORE_AJAXajaxリクエストを無視するか否かTrue 無視する
REQUEST_IGNORE_IP無視するIPアドレスNone
REQUEST_LOG_IPIPアドレスを記録する/しないを示す。しない場合IPはDEUMMYアドレスに置き換えるTrue 記録する
REQUEST_IP_DUMMYダミーIPアドレス。REQUEST_LOG_IPがFalseの際に使用する1.1.1.1
REQUEST_ANONYMOUS_IP匿名IPに変更するか否か。Trueだと4オクテット目を1にするFalse 変更しない
REQUEST_LOG_USERログインユーザー名を出力するか否か。True 出力する
REQUEST_LOG_USERログインユーザー名を出力するか否か。Falseだと名称にNoneが設定されるTrue 出力する
REQUEST_IGNORE_USERNAMEロギングしないユーザーリストNone
REQUEST_IGNORE_PATHSロギングしないURLのリストNone
REQUEST_IGNORE_PATHSロギングしないURLのリストNone
REQUEST_IGNORE_USER_AGENTS無視するユーザーエージェントのリストNone
REQUEST_TRAFFIC_MODULESロギングモジュール?グラフ表示時に使用する?種類が結構ある参考ページ 参照
REQUEST_PLUGINSロギングプラグイン?グラフ表示時に使用する?種類が結構ある参考ページ 参照
REQUEST_BASE_URLSSLや、django.contrib.sites使用しない場合設定する?‘http://%s’ % Site.objects.get_current().domain
REQUEST_ONLY_ERRORSレスポンスエラー時のみ記録するか否か。False:エラー時以外も記録する
REQUEST_VALID_METHOD_NAMES記録するHTTPメソッド(‘get’, ‘post’, ‘put’, ‘delete’, ‘head’, ‘options’, ‘trace’)
  • どれを設定するか?
    一旦以下を設定すれば、今回の用途として事足りるかと思ました。
    セキュリテイ的には、どちらの設定変更も悪かもしれないですが

    1. REQUEST_IGNORE_USERNAME : 値はBlog投稿ユーザーを設定する
    2. REQUEST_IGNORE_USER_AGENTS : 値は検索エンジンのロボット達を設定する
  • settings.pyの設定
    設定対象キー、Valueをsettings.pyに追加しました。 ロボットのユーザーレージェントと言ってもたくさんあるっぽくて、
    どこまで入れるのが良いのか、ちょっと判断できなかったので、
    以下の設定をしてしばらく様子見することにします。

REQUEST_IGNORE_USERNAME = ('user_name')
REQUEST_IGNORE_USER_AGENTS = (
    r'Googlebot',
    r'Baiduspider',
)

  • apacheを再起動して確認
    エラーと成りました

__init__() takes at most 3 arguments (10 given)
Request Method: GET
Request URL:  http://www.monotalk.xyz/ja/xyz_monotalk_admin/
Django Version: 1.9.6
Exception Type: TypeError
Exception Value:  
__init__() takes at most 3 arguments (10 given)
Exception Location: /usr/local/lib/python2.7/site-packages/request/router.py in __init__, line 24
Python Executable:  /usr/bin/python
Python Version: 2.7.8
Python Path:  
.....

対象箇所を確認した所、ライブラリのバグ?のようです。
python3でないと動作しないのじゃないのかと思います。
Github上のソース参考にして以下の通り修正しました。

# router.py
import re

# ---ADD < imprort文を追加
from django.utils.six import string_types

class RegexPattern(object):
    def __init__(self, regex, name=''):
        self.regex = re.compile(regex, re.UNICODE)
        self.name = name

    def resolve(self, string):
        match = self.regex.search(string)
        if match:
            return self.name, match.groupdict()


class patterns(object):
    def __init__(self, unknown, *args):
        self.patterns = []
        self.unknown = unknown

# ---DEL TypeErrorとなるため、記述を削除
#        for pattern in args:
#            if pattern.__class__ == str:
#                self.patterns.append(RegexPattern(pattern))
#            else:
#                self.patterns.append(RegexPattern(*pattern))
# -----------------------------------

        for pattern in args:
            if isinstance(pattern, string_types):
                self.patterns.append(RegexPattern(pattern))
            else:
                self.patterns.append(RegexPattern(*pattern))

    def resolve(self, name):
        for pattern in self.patterns:
            match = pattern.resolve(name)
            if match:
                return match
        return self.unknown

再起動後、問題なく動作することが確認できました。


purgerequestsの設定

リクエスト毎にログを記録してるのが、結構すごい容量になるはずなので、
コマンドラインのログ削除コマンドが用意されています。

pip install後にpython manage.py実行すると、
以下、管理コマンドが追加されます。

[request]
    purgerequests

  • 実行方法 ドキュメント記載がありますが、
    以下で、実行可能です。

python manage.py purgerequests 4 days

期間は、 hour(s), day(s), week(s), month(s), year(s)設定可能です。

  • OUTPUT

4日前以前のリクエスト消しても良いかを聞いてきます。
yes/no で削除する/しないを入力します。

You have requested a database reset.
This will IRREVERSIBLY DESTROY any
requests created before 4 days ago.
That is a total of 380 requests.
Are you sure you want to do this?
--noinput オプションがありこれを指定すると、
確認なしで削除しに行きます。
cron実行時は、こちらを使えとのことです。


参考サイト (ちょっとログを見たいときに参考にする)

VPS1台All in One構成だから、
scriptで気になった時に見るくらいでも良い気はします。


追記 URLにマルチバイト文字列が含まれるとエラーになる

管理画面から、URLにマルチバイト文字列を含むアクセスデータを削除しようとした際、
以下のエラーが発生しました。

UnicodeEncodeError at /ja/admin/request/request/
'ascii' codec can't encode characters in position 66-69: ordinal not in range(128)

こちら、model.py の修正が必要で、
デコレータ @python_2_unicode_compatible追加しました。

  • /usr/local/lib/python2.7/site-packages/request/models.py

from socket import gethostbyaddr

from django.db import models
from django.conf import settings
from django.contrib.auth import get_user_model
# python_2_unicode_compatible の import を追加
from django.utils.encoding import python_2_unicode_compatible                                                                                                                       
from django.utils.translation import ugettext_lazy as _

from request.managers import RequestManager
from request.utils import HTTP_STATUS_CODES, browsers, engines
from request import settings as request_settings


AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
# @python_2_unicode_compatible を追加
@python_2_unicode_compatible
class Request(models.Model):
    # Response infomation


追記 SSL環境下で使用する場合、追加で実施したこと

後日、MezzanineのSSL設定したところ、
管理画面上の折れ線グラフと、パイチャートの出力ができなくなり、
ソースをGithub最新Versionで置き換えたところ、動作しました。
実施したことを以下に記載します。

request_tag.py の置き換え

パイチャートで描画に使っている google chart api の URLが変更されています。
HTTPS/HTTP どっちでも通信可能なURLに変わっているので、それを取り込みます。

  • ディレクトリ移動

cd /usr/local/lib/python2.7/site-packages/request/templatetags

  • 念のためバックアップ

    cp request_tag.py request_tag.py.back
    

  • 最新ファイルダウンロード

    curl https://raw.githubusercontent.com/django-request/django-request/master/request/templatetags/request_admin.py > request_admin.py
    

overview.html の置き換え

折れ線グラフが描画できなくなった(折れ線出力用 JSONを吐き出すURLが404) ので、
Ajax でリクエスト送付しているソースを取り込みます。

  • ディレクトリ移動

cd /usr/local/lib/python2.7/site-packages/request/templates/admin/request/request

  • 念のためバックアップ

    cp overview.html overview.html.back
    

  • 最新ファイルダウンロード

    curl https://raw.githubusercontent.com/django-request/django-request/master/request/templates/admin/request/request/overview.html > overview.html
    

  • ファイルのdiff抜粋

request url の記述方が変わっています。

diff overview.html overview.html.back
---------------------------
31,38c34,39
<     {% if request and request.user %}
<         <div class="breadcrumbs">
<             <a href="{% url "admin:index" %}">{% trans "Home" %}</a> &rsaquo;
<             <a href="{% url "admin:app_list" "request" %}">{% trans "Request" %}</a> &rsaquo;
<             <a href="{% url "admin:request_request_changelist" %}">{% trans "Requests" %}</a> &rsaquo;
<             {% trans "Overview" %}
<         </div>
<     {% endif %}
---
>     <div class="breadcrumbs">
>         <a href="../../../">{% trans "Home" %}</a> &rsaquo;
>         <a href="../../">{% trans "Request" %}</a> &rsaquo;
>         <a href="../">{% trans "Request" %}</a> &rsaquo;
>         {% trans "Overview" %}
>     </div>
----------------------------

長くなりましたが、以上です。

コメント