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_APPS
にrequest
を追加する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
-
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_CLASSES
にrequest.middleware.RequestMiddleware
を追加する
django.contrib.auth
,
django.contrib.flatpages
どちらも使用していないので、
1要素目に追加しました。
MIDDLEWARE_CLASSES = (
"request.middleware.RequestMiddleware",
- Siteのドメイン名が、正しいことを確認
ユニークビジター数とトップ参照元を計算するために使うよということらしいです。
ADMIN画面から表示してみる。
- 管理メニュー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: ....
- 参考
django-request/plugins.py at master · django-request/django-request · GitHub
-
対象箇所を修正 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
-
ログの一覧表示画面
右メニューを表示すると以下の画面が表示されます。
-
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
- リクエストを追加
ログの一覧画面の右上リクエストを追加
クリックでこちらに移動します。
正直これはあまり意味がない機能な気が....
- Request Overview
ログの一覧画面の右上
Overview
クリックでこちらに移動します。
これが欲しかった機能かと思われます。
settings.pyの設定
django-requestでのロギングの仕方などを変更可能です。
結構たくさん設定があったので、私が変えたかったものだけ、つまんで記載します。
- 参考ページ
-
プロパティ値の説明
キー値 | 内容 | デフォルト値 |
---|---|---|
REQUEST_IGNORE_AJAX | ajaxリクエストを無視するか否か | True 無視する |
REQUEST_IGNORE_IP | 無視するIPアドレス | None |
REQUEST_LOG_IP | IPアドレスを記録する/しないを示す。しない場合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_URL | SSLや、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’) |
-
どれを設定するか?
一旦以下を設定すれば、今回の用途として事足りるかと思ました。
セキュリテイ的には、どちらの設定変更も悪かもしれないですが…- REQUEST_IGNORE_USERNAME : 値はBlog投稿ユーザーを設定する
- 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で気になった時に見るくらいでも良い気はします。
-
アクセスログをBashのワンライナーで解析
-
Pythonで解析する
追記 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> ›
< <a href="{% url "admin:app_list" "request" %}">{% trans "Request" %}</a> ›
< <a href="{% url "admin:request_request_changelist" %}">{% trans "Requests" %}</a> ›
< {% trans "Overview" %}
< </div>
< {% endif %}
---
> <div class="breadcrumbs">
> <a href="../../../">{% trans "Home" %}</a> ›
> <a href="../../">{% trans "Request" %}</a> ›
> <a href="../">{% trans "Request" %}</a> ›
> {% trans "Overview" %}
> </div>
----------------------------
長くなりましたが、以上です。
コメント