質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.41%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

uWSGI

uWSGIは、PythonでWebサービスを動かすアプリケーションサーバの一つです。WSGI(Web Server Gateway Interface)アプリケーションコンテナの一種で、WSGIに則ったDjangoやFlaskなどで動かすことができます。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

237閲覧

Djangoから出力されるログをログローテーションしたい

nemui_

総合スコア1

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

uWSGI

uWSGIは、PythonでWebサービスを動かすアプリケーションサーバの一つです。WSGI(Web Server Gateway Interface)アプリケーションコンテナの一種で、WSGIに則ったDjangoやFlaskなどで動かすことができます。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2023/10/27 08:05

編集2023/10/27 08:10

実現したいこと

Django・uWSGI・nginx・LINUX環境でDjangoから出力されるログをログローテーションしたい。

前提

Django・uWSGI・nginx・LINUX環境でWebアプリを作成しています。
Djangoから出力されるログを日付ごとにまとめようと設定ファイルを以下のように設定しました。

settings.py

1 'handlers': { 2 'file': { 3 'level': 'INFO', 4 'class': 'logging.handlers.TimedRotatingFileHandler', 5 'filename': '{}/log/app_name/app.log'\ 6 .format(os.path.dirname(__file__)), 7 'formatter': 'production', 8 'when': 'MIDNIGHT' 9 }, 10 },

発生している問題

ただ実際に動作を確認してみると、uWSGIを起動した日時を基準に、常に同じファイル名を生成する形でローテートしてしまいます。
例:2023/10/27にuWSGIを起動した場合、28日にログを出力しても29日にログを出力しても、前日分が必ずapp.log.2023-10-27に上書きされてしまい一昨日以前のログがすべて消えてしまいます。

試したこと

loggingのローテートを使用しない以下のパターンを試してみましたが、同様に日付が変わってもuWSGIの起動日名のログファイルapp_2023-10-27.logに書き続ける結果となりました。

settings.py

1 'handlers': { 2 'file': { 3 'level': 'INFO', 4 'class': 'logging.FileHandler', 5 'filename': '{}/log/app_name/app_{}.log'\ 6 .format(os.path.dirname(__file__), datetime.now().date()), 7 'formatter': 'production' 8 }, 9 },

その他はTimedRotatingFileHandlerのinterval,backupCount等を設定したりwhenをMなどに変えて細かい動きを見てみましたが特に変化はありません。

補足情報

以下にuWSGIの実行時設定を記載します。(実行方法はuwsgi_app.serviceのExecStartを利用した方法を採用しています。)

uwsgi_app.service

1ExecStart=/home/app_home/.venv/bin/uwsgi \ 2 --http=:8888 \ 3 --processes=30 \ 4 --module=mysite.wsgi \ 5 --socket=/home/app_home/mysite/mysite/uwsgi.sock \ 6 --pidfile=/home/app_home/mysite/mysite/uwsgi.pid \ 7 --home=/home/app_home/.venv \ 8 --master \ 9 --vacuum

利用バージョン

Django 4.2.5
uWSGI 2.0.18-debian
nginx 1.18.0 (Ubuntu)
LINUX 5.15.0-1041-azure
Python 3.8.10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dameo

2023/10/28 16:17

その書き方だとsettings.pyを実行した際にファイル名が決まって一生変わらない気がします。 uWSGIの設定でdjangoが複数で動く(processes/threadsを1にしない)と同じファイルを書き込みに行って破綻しちゃいますが、まずはlogging.handlers.TimedRotatingFileHandlerを使ったサンプルコードを置いておきます。(要bash&docker) mkdir -p html/static python cat >python/uwsgi_django.ini <<EOF [uwsgi] socket = :3031 chdir=/home/python/mysite module=mysite.wsgi:application master=True processes=1 workers=1 pidfile=/tmp/project-master.pid vacuum=True max-requests=5000 home=/home/python/env ;daemonize=/var/log/uwsgi/mysite.log EOF cat >docker-compose.yml <<EOF version: '3' services: python: image: python:3.8 volumes: - ./python:/home/python - ./html:/var/www/html command: /home/python/env/bin/uwsgi --ini /home/python/uwsgi_django.ini nginx: image: nginx:1.18 volumes: - ./html:/var/www/html # - ./default.conf:/etc/nginx/conf.d/default.conf ports: - 80:80 EOF docker compose up -d docker compose run -T --rm python bash <<EOF cd /home/python python -m venv env . env/bin/activate pip install -U pip setuptools pip install uwsgi==2.0.18 django==4.2.5 django-admin startproject mysite cd mysite patch -p1 <<EOF2 diff --git a/mysite/settings.py b/mysite/settings.py index f3e1d05..34ebf8e 100644 --- a/mysite/settings.py +++ b/mysite/settings.py @@ -23,9 +23,9 @@ BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = 'django-insecure-j74jgz=@l#2uxpj$+^y&)ouzpc6-nmbrqgi++vhr!_bcac2un(' # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = False -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ['*'] # Application definition @@ -116,8 +116,31 @@ USE_TZ = True # https://docs.djangoproject.com/en/4.2/howto/static-files/ STATIC_URL = 'static/' +STATIC_ROOT = '/var/www/html/static/' # Default primary key field type # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +LOGGING = { + "version": 1, + "disable_existing_loggers": False, + "handlers": { + "file": { + "level": "DEBUG", + "class": "logging.handlers.TimedRotatingFileHandler", + "when": "S", + "interval": 10, + "backupCount": 20, + "filename": "/home/python/mysite/debug.log", + }, + }, + "loggers": { + "django": { + "handlers": ["file"], + "level": "DEBUG", + "propagate": True, + }, + }, +} EOF2 python manage.py collectstatic deactivate exit EOF docker compose cp nginx:/etc/nginx/conf.d/default.conf ./default.conf docker compose down patch -p1 <<EOF diff -up a/default.conf b/default.conf --- a/default.conf 2023-10-29 00:50:35.000000000 +0900 +++ b/default.conf 2023-10-29 00:55:18.103250149 +0900 @@ -6,10 +6,14 @@ server { #charset koi8-r; #access_log /var/log/nginx/host.access.log main; - location / { - root /usr/share/nginx/html; + location /static { + root /var/www/html; index index.html index.htm; } + location / { + include uwsgi_params; + uwsgi_pass python:3031; + } #error_page 404 /404.html; EOF cat docker-compose.yml | sed 's/^#//' > docker-compose.yml.new mv docker-compose.yml.new docker-compose.yml docker compose up -d for i in `seq 199`;do sleep 0.1 wget 'http://localhost/' -O - done docker compose logs ls -lAF python/mysite/debug.log* cat python/mysite/debug.log* | wc docker compose down
nemui_

2023/10/30 00:49

コメントいただきありがとうございます。 浅学で申し訳ないのですが、本回答の本質はどの部分になりますでしょうか? setting.pyの修正が主題なのかと思いましたが、前提で記載の通り元々はlogging.handlers.TimedRotatingFileHandlerを使用しようとしていたので特に変更はないように感じました。 提示いただいたその他の変更箇所でDjangoのログローテーションに影響があるという事でしょうか?
dameo

2023/10/30 01:18

試したことに書いてあった「logging.FileHandler」の記述で変化すると思ったのかなと思ったんだけど、TimedRotatingFileHandlerを使ってたんですね。これを使えばとりあえずローテーションしようとはし始めるよって伝えるつもりでした。質問者へのコメント意図はそれがメインです。ただ、他の人が試せない条件だと現象が追えないので、現象を再現させられる最小限のコードを提示し、質問者にその提供を促すことも大事な目的です。 TimedRotatingFileHandlerを使ってるのであれば、記載したように、 > uWSGIの設定でdjangoが複数で動く(processes/threadsを1にしない)と同じファイルを書き込みに行って破綻しちゃいますが、 の条件に当てはまってるので、破綻しちゃってるのかと思います。上のshell scriptでも簡単に試せますよ。
nemui_

2023/10/31 00:21

なるほど、ご丁寧にご教示いただきありがとうございます。 uWSGIの設定値についてといただいたscriptでもう少し試してみます。
dameo

2023/10/31 00:57 編集

ちょっと試したらprocessとworkerの同時指定は禁止(無効?)らしいので、片方で指定してください。
guest

回答1

0

自己解決

結論

しばらく時間が空いてしまいましたが、本件解決しましたので解決方法を記載します。

まず結論から申し上げますと以下サイトを参考にlogging.handlers.SysLogHandlerを使用したログローテートを採用しました。
参考: https://gist.github.com/mjnaderi/083862078422325bdc2ba809bc63eba1

SysLogHandler採用の経緯

元々使う予定だったlogging.handlers.TimedRotatingFileHandlerlogging.FileHandlerでは多重起動のログ出力に対応していないという事が調査過程で分かりました。(uWSGIのprocess/workerを1にしないといけない)
ただ弊プログラムでは多重起動がどうしても必要だったためlogging.handlers.SysLogHandlerを使用するに至りました。

解決策

基本的には結論に書きましたサイト通りなのですが、一部変更点がありますのでそこだけ記載します。

/etc/logrotate.d/mydjangoproject

/var/log/mydjangoproject/apps.log { daily missingok rotate 1000 compress delaycompress notifempty dateext dateyesterday dateformat .%Y-%m-%d extension .log postrotate # ここから下3行を追加しました。 /bin/systemctl restart rsyslog endscript }

postrotate ~ endscriptを追加した経緯なのですが、SysLogHandlerを利用しても相変わらずログローテートが起きず、前の日付ログに書き込み続けるという事象が起きていました。ただ/bin/systemctl restart rsyslog(シスログ設定を更新するコマンド)を実行すると新しいログファイルに書き込んでくれることが分かったので、力業で解決した感じです。
正直この解決手段はあまりいただけていないのは自覚しているのでもっと良い案あればご意見求めたいところです。

投稿2023/12/15 03:02

nemui_

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nemui_

2023/12/15 03:03

SysLogHandlerを利用するにあたってPythonのバージョンは3.11に変更してあります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.41%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問