Почему f.write () в файле Python на сервере не работает? - PullRequest
0 голосов
/ 24 ноября 2018

У меня есть приложение Python, которое работает локально, но на сервере что-то идет не так.
Так что я должен сделать некоторую отладку в сеансе SSH.
Журналы сервера говорят мне, что что-то идет не так в utils/do_something.py.
Я создал utils/log (права 777), куда должны идти значения отладки.

do_something.py выглядит так:

import os
parent_folder = os.path.dirname(__file__)
log_file = os.path.join(parent_folder, 'log')

def do_something(arg1, arg2):

    print('XXX')
    f = open(log_file, 'a')
    f.write('XXX\n')

    stuff = goes.wrong

Загрузка страницы вызывает do_something для запуска (что подтверждается журналами ошибок).Локально ожидаемый XXX появляется в консоли и в файле журнала.Но на сервере ничего не происходит.

Я создал второй файл utils/blah.py:

print('BLAH')

import os
parent_folder = os.path.dirname(__file__)
log_file = os.path.join(parent_folder, 'log')
f = open(log_file, 'a')
f.write('BLAH\n')

Когда я запускаю его с python blah.py, появляется ожидаемое BLAH в консоли и в лог-файле.

Меня не волнует разница между локальным и рабочим сервером.
Но я бы хотел понять разницу между do_something.py и blah.py.

Есть ли лучший способ отладки в сеансе SSH?

Я работаю в virtualenv в среде mod_wsgi 4.6.5/Python3.7 на сервере Webfaction.
Некоторые подробности об этом можно увидеть в этом вопросе на форуме Webfaction.


Редактировать 1: На сервере print, кажется,все равно обескураживайтесь.
(См. Куда идут дела, когда я «печатаю» их из моего приложения Django? )
Но для меня важно f.write().Я просто добавил print для сравнения.

Редактировать 2: То же самое, когда я использую модуль регистрации.Он работает, когда я запускаю blah.py, но при загрузке страницы ничего не происходит do_something.

Редактировать 3: Я попробовал то же самое с более простым приложением, и в результатеТо же самое.
Я добавил запись в систему views.py:

from django.http import HttpResponse
import os

parent_folder = os.path.dirname(__file__)
log_file = os.path.join(parent_folder, 'log')

def home_view(request):
    f = open(log_file, 'a')
    f.write('XXX\n')
    return HttpResponse("Hello from home view.")

Локально это записывает XXX в файл журнала при каждой загрузке страницы.Но не на сервере.
В журнале сервера нет ошибок.


Использование модуля logging: Я не уверен, почему это не сработало, но сейчас работает.

import os
import logging

parent_folder = os.path.dirname(__file__)
log_file = os.path.join(parent_folder, 'log')
logging.basicConfig(filename=log_file, level=logging.DEBUG)
logging.debug('This works.')

Возможно, я использовалэто с filename='log' вместо filename=log_file.Локально первый создает файл журнала в корневой папке.Но на сервере он уже должен существовать.

Права на запись : Кажется, стоит упомянуть, что touch log дал мне файл, который я не мог записать, и не имея sudo, я не смогиспользуйте chmod.Поэтому я использовал трюк install -b -m 777 /dev/null log.

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Вы можете проверить привилегии в папке utils и в любых родительских папках.Много раз http-сервер будет работать как пользователь «nobody», у которого есть практически права zip.Таким образом, если сама папка utils также не имеет прав 0777, это может создать проблему.Вы также можете захотеть поместить f.write в блок try ... Кроме того, чтобы вы могли специально отследить ошибку и создать более полезное / информативное сообщение об ошибке.Best.

0 голосов
/ 24 ноября 2018

Похоже, что вы никогда не закрываете файл явно после записи, поэтому вывод, вероятно, буферизуется.Ваш сервер и ваш локальный компьютер могут иметь разные настройки в отношении буферизации файлов, что объясняет различия, которые вы испытываете.

Если вы хотите открывать, писать и закрывать файл, менеджеры контекста Python являютсяЛучший способ сделать это:

def home_view(request):
    with open(log_file, 'a') as f:
        f.write('XXX\n')
    return HttpResponse("Hello from home view.")
...