Ведение журнала AWS Elastic Beanstalk с помощью python (django)
Как вы управляете журналами своих приложений в AWS эластичный бобовый стебель? Я имею в виду, вы пишете журналы приложений в какой файл? Я использую следующую конфигурацию ведения журнала в своей среде разработки, но она не работает при развертывании в AWS.
Заранее спасибо!
DEBUG_LOG_DIR = BASE_DIR + "/django_debug.log"
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
# How to format the output
'formatters': {
'standard': {
'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
'datefmt' : "%d/%b/%Y %H:%M:%S"
},
},
# Log handlers (where to go)
'handlers': {
'null': {
'level':'DEBUG',
'class':'django.utils.log.NullHandler',
},
'log_file': {
'level':'DEBUG',
'class':'logging.handlers.RotatingFileHandler',
'filename': DEBUG_LOG_DIR,
'maxBytes': 50000,
'backupCount': 2,
'formatter': 'standard',
},
'console':{
'level':'INFO',
'class':'logging.StreamHandler',
'formatter': 'standard'
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
},
},
# Loggers (where does the log come from)
'loggers': {
'repackager': {
'handlers': ['console', 'log_file'],
'level': 'DEBUG',
'propagate': True,
},
'django': {
'handlers':['console'],
'propagate': True,
'level':'WARN',
},
'django.db.backends': {
'handlers': ['console', 'log_file'],
'level': 'WARN',
'propagate': False,
},
'': {
'handlers': ['console', 'log_file'],
'level': 'DEBUG',
},
}
}
10 ответов
Хорошо, я нашел способ сделать это.
Сначала я подключился через ssh к машине ec2, затем я создал папку в /var/log с именем app_logs с пользователем root:
mkdir /var/log/app_logs
После этого я сделал следующее:
cd /var/log/
chmod g+s app_logs/
setfacl -d -m g::rw app_logs/
chown wsgi:wsgi app_logs/
Это гарантирует, что все файлы, созданные в этой папке, будут иметь владельца wsgi и будут доступны для записи для группы, к которой принадлежит файл. Мне пришлось это сделать, потому что я заметил, что файл журнала, созданный приложением django, имел root как владельца и группу владельцев, но приложение запускается через пользователя wsgi.
Наконец я изменил DEBUG_LOG_DIR на /var/log/app_logs/django_debug.log
У меня была похожая проблема, но на Elastic Beanstalk, поэтому я создал файл конфигурации (например, applogs.config) в .ebextensions
папка приложения. Это создает папку app-logs, если ее там еще нет, и устанавливает права доступа к файлу и владельца, чтобы приложение могло записывать туда свои журналы.
commands:
00_create_dir:
command: mkdir -p /var/log/app-logs
01_change_permissions:
command: chmod g+s /var/log/app-logs
02_change_owner:
command: chown wsgi:wsgi /var/log/app-logs
Наконец, в ваших настройках Django:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/var/log/app-logs/django.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
Кроме того, если вы хотите, чтобы ваш журнал был доступен из журналов beanstalk с помощью Интернета, добавьте его в свой файл в.ebextensions
files:
"/opt/elasticbeanstalk/tasks/taillogs.d/django.conf":
mode: "000755"
owner: root
group: root
content: |
/var/log/app-logs/django.log
Есть простой способ, который не требует никакой конфигурации beanstalk.
В ваших настройках django в разделе LOGGING установите обработчик, направленный в файл '/ opt / python / log / {log_file_name}'. Затем к журналам можно получить доступ через меню среды beanstalk в разделе "Журналы".
LOGGING = {
...,
'handlers': {
'logfile': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': '/opt/python/log/{log_file_name}',
},
},
'loggers': {
'debugger': {
'level': 'DEBUG',
'handlers': ['logfile'],
'propagate': False,
},
}
Это местоположение указано в документации здесь:
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.logging.html
--редактировать--
Этот ответ был первоначально написан для Amazon Linux AMI. На Amazon Linux AMI удобно использовать/opt/python/log
, потому что все файлы журналов в /opt/python/log
папка автоматически включается, когда вы запрашиваете журналы из Elastic Beanstalk. Это связано с тем, что конфигурация по умолчанию содержит задачу, расположенную в/opt/elasticbeanstalk/tasks
, который включает все файлы в /opt/python/log
. Официальный образец приложения AWS Python для AMI Amazon Linux также использует/opt/python/log
для регистрации.
Однако в Amazon Linux 2 нет/opt/python/log
папка (как указано @Oded в комментариях). Итак, что нам теперь делать?
Официальный образец приложения AWS Python для Amazon linux 2 использует /tmp
папка для ведения журнала, но пользовательские файлы журнала добавляются в /tmp
являются не включается автоматически при запросе журналов из Elastic Beanstalk. В примере приложения теперь используются настраиваемые задачи ведения журнала, расположенные в/opt/elasticbeanstalk/tasks
вложенные папки. См. Инструкции в документации. В примере источника приложения показано, как это достигается с помощью.ebextensions
:
files:
"/opt/elasticbeanstalk/tasks/bundlelogs.d/01-sample-app.conf":
content: |
/tmp/sample-app*
"/opt/elasticbeanstalk/tasks/taillogs.d/01-sample-app.conf":
content: |
/tmp/sample-app.log
Отсюда следует, что удобство использования /opt/python/log
без необходимости настраивать конфигурацию, теряется. Тем не менее, некоторые проблемы с разрешениями, описанные в исходном ответе ниже, все еще могут возникнуть.
Права доступа к файлам по умолчанию для /tmp/sample-app.log
, на тестовом экземпляре, на котором запущен пример приложения Python по умолчанию в Amazon Linux 2, со всеми настройками по умолчанию, следующие:
-rw-r--r-- 1 webapp webapp 0 Aug 7 14:24 sample-app.log
Обратите внимание, что владелец и группа теперь называются webapp
.
Обратите внимание, что само приложение теперь можно найти в /var/app/current
.
Дополнительную информацию см. В документации по миграции AWS Linux 2 и расширении платформ EB Linux.
--оригинал -
Резюме
На мой взгляд, самое простое решение - войти в /opt/python/log
папка, как было предложено bewestphal и @thierry-j (в соответствии с ответом Стива-Данлопа).
То же самое и в официальном примере приложения AWS EB Python: см.python-v1.zip
источник
Затем файл журнала будет включен автоматически, когда вы запросите журналы у EB.
Это решение работает "из коробки", без каких-либо изменений .ebextensions
, пока ты не позвонишьdjango-admin.py
(или другой код django) в вашем .ebextensions
.
Тем не менее, большинство приложений делают необходимость вызоваdjango-admin.py
в .ebextensions
, например, чтобы migrate
. Это приведет к преждевременному созданию файла журнала сroot
владелец и root
группа. Это приводит к ошибкам разрешений, потому что приложение работает какwsgi:wsgi
.
Это можно исправить, добавив новую команду в конце вашегоcontainer_commands
, чтобы удалить "преждевременный" файл журнала, например:
container_commands:
...
9999_remove_root_log_file:
command: rm /opt/python/log/django.log
ignoreErrors: true
Подробности ниже.
Задний план
На стандартной предварительно настроенной платформе Amazon Linux/Python, которая использует Apache с mod_wsgi (см. Документацию по платформе AWS),WSGIDaemonProcess
для приложения Django запускается как пользователь wsgi
и группа wsgi
(видеть /etc/httpd/conf.d/wsgi.conf
на вашем экземпляре EC2).
Кроме того, права доступа к папке по умолчанию для/opt/python/log
папка (в моем стандартном экземпляре EC2): drwxrwxr-x 3 root wsgi 4096 Mar 5 14:08 .
Это wsgi
группа имеет все разрешения (rwx
), поэтому приложение Django (группа wsgi
) может создавать там файлы журналов.
Это работает "из коробки", как демонстрирует официальный пример приложения AWS EB Python ( python-v1.zip).
Однако если вы сделаете что-нибудь в своем .ebextensions
что вызывает logging
файл-обработчик для инициализации (например, вызов django-admin.py
), он сломается.
Проблемы с разрешениями
Вот как использовать django-admin.py
в .ebextensions
нарушает права доступа к файлу журнала:
Эластичный бобовый стебель container_commands
, в .ebextensions
, выполняются как root
пользователь (см. документацию по AWS).
Если вы позвоните django-admin.py
в любом из container_commands
, например, с collectstatic
или migrate
, что приведет к инициализации обработчиков файлов журналов. Если указанный файл журнала еще не существует, в это время он будет создан сroot
владелец и root
группа.
Это означает, что приложение Django работает как часть wsgi
группа, не будет иметь разрешения на запись в файл журнала (который принадлежит root
группа).
Это приводит к ошибкам прав доступа, например: PermissionError: [Errno 13] Permission denied: '/opt/python/log/django.log'
Как воспроизвести
В следующем фрагменте кода показана проблема с разрешениями и показано, как ее исправить.
Чтобы воспроизвести проблему, добавьте эти container_commands
в чистый проект (например, следуя руководству AWS EB Django), настройте Djangosettings.py
войти в /opt/python/log/django.log
, разверните в AWS EB, затем проверьте eb-activity.log
чтобы увидеть вывод команд контейнера.
...
container_commands:
0100_show_current_user:
# show that we are running as root user
command: whoami
0200_try_to_remove_log_file:
# we need a clean slate for this example (make sure no log file owned by wsgi is present)
command: rm /opt/python/log/django.log
ignoreErrors: true
0300_break_log_file_permissions:
# this causes a new log file to be created, owned by root:root (instead of wsgi:wsgi)
command: django-admin.py
0400_show_log_file_permissions:
# prove that a log file was created by root, and show folder permissions
command: ls -la /opt/python/log
0500_fix_by_removing_log_file_after_all_django_admin_calls:
# remove the log file created by django-admin.py, to ensure that a new log file will
# be created when the server starts, owned by wsgi:wsgi
command: rm /opt/python/log/django.log
ignoreErrors: true
СУХОЙ раствор
Таким образом, нет необходимости явно связываться с разрешениями файлов / папок.
Если вы не вызываете код django в .ebextensions
, вход в /opt/python/log
работает прямо из коробки.
Если вы вызываете код django в .ebextensions
, например django-admin.py collectstatic
, просто удалите файл журнала в конце вашегоcontainer_commands
раздел.
Вот пример СУХОЙ:
В .ebextensions
config:
option_settings:
# create EB environment property for the log file path
aws:elasticbeanstalk:application:environment:
LOG_FILE_PATH: /opt/python/log/django.log
...
container_commands:
...
# django code called here, e.g. "django-admin.py collectstatic"
...
9999_remove_any_existing_django_log_files:
command: rm $LOG_FILE_PATH
ignoreErrors: true
И в settings.py
:
...
# get log path from environment variable, with fallback for local development
log_file_path = os.getenv('LOG_FILE_PATH', 'local.log')
# use this as 'filename' for the file handler, as described in the other answers
...
Этот ответ относится только к Amazon Linux 2 . Для тех, кто еще не выполнил миграцию , см. Мой старый ответ для Amazon Linux AMI.
Задний план
Официальное AWS Python выборки приложения для Amazon Linux 2 использует папку для регистрации.
Однако пользовательские файлы журналов добавлены в
/tmp
являются не включается автоматически при запросе журналов из Elastic Beanstalk. Чтобы включить пользовательские файлы журнала, нам нужно создать задачи ведения журнала в подпапках
/opt/elasticbeanstalk/tasks
на экземпляре EC2. См. Инструкции в документации.
Пример приложения ( источник ) выполняет это с помощью
.ebextensions
. Однако в документации по миграции AWS Linux 2 предлагается использовать
.platform
вместо этого крючки:
Мы рекомендуем использовать обработчики платформы для запуска пользовательского кода в экземплярах вашей среды. Вы по-прежнему можете использовать команды и команды контейнера в файлах конфигурации .ebextensions, но с ними не так просто работать. Например, написание командных сценариев внутри файла YAML может быть обременительным и трудным для тестирования.
Это имеет дополнительное преимущество, заключающееся в том, что выходные данные хуков платформы собираются в отдельном файле журнала, а именно.
/var/log/eb-hooks.log
, что немного упрощает отладку.
Настройка DRY logging для базового приложения Django в Amazon Linux 2
Уровень журнала и путь к журналу определяются в одном месте, как свойства среды Elastic Beanstalk, например, в
.ebextensions/options.config
:
option_settings:
aws:elasticbeanstalk:application:environment:
LOG_LEVEL: INFO
LOG_FILE_PATH: /tmp/django-app.log
...
Свойство environment теперь можно использовать в хуке платформы для создания задач журналирования:
.platform/hooks/postdeploy/00_create_logging_tasks.sh
#!/bin/bash
TASKS_DIR=/opt/elasticbeanstalk/tasks
# include all app log files in bundle logs (replaces ".log" by "*")
echo "${LOG_FILE_PATH//.log/*}" > "$TASKS_DIR/bundlelogs.d/01-app-log.conf"
# include current app log file in tail logs
echo $LOG_FILE_PATH > "$TASKS_DIR/taillogs.d/01-app-log.conf"
Обратите внимание, что для крючков платформы требуется разрешение на выполнение, например
chmod +x 00_create_logging_tasks.sh
. В окнах вы можете использовать
git
как описано здесь .
Мы также используем
LOG_LEVEL
и
LOG_FILE_PATH
свойства среды в нашем Django
settings.py
:
...
# basic logging with file rotation ()
log_level = os.getenv('LOG_LEVEL', 'INFO')
handlers = dict(file={'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': os.getenv('LOG_FILE_PATH'),
'when': 'midnight',
'interval': 1,
'backupCount': 1,
'encoding': 'utf-8'})
loggers = dict(django=dict(level=log_level, handlers=['file']),
myapp=dict(level=log_level, handlers=['file']))
LOGGING = dict(version=1,
disable_existing_loggers=False,
handlers=handlers,
loggers=loggers)
...
Некоторые примечания:
Обычно мы указываем заказ
formatters
также, но я оставил их для ясности.Само приложение теперь можно найти на экземпляре EC2 в
/var/app/current
. Также см. Дополнительные сведения о расширении платформ EB Linux .Приложение теперь работает как с группой.
твой друг. См. Документы .
Мы также используем хуки платформы для запуска Django's
migrate
иcollectstatic
команды, как описано здесь . Мы еще не наблюдали проблем с правами доступа к файлам журнала.
РЕДАКТИРОВАТЬ:
Как указывает @hax0 в комментариях, проблемы с правами доступа к файлам могут возникнуть, если вы попытаетесь запустить команды на экземпляре EC2, используя SSH, после развертывания.
Например, при использовании
eb ssh
, вы вошли в систему как, но файл журнала принадлежит пользователю, и по умолчанию только владелец имеет разрешение на запись (
644
). Таким образом, при запуске
python manage.py
в виде
ec2-user
, вы получите сообщение об ошибке, в котором говорится, что он не может настроить обработчик файла журнала из-за отказа в разрешении.
Быстрый и грязный обходной путь - временно изменить права доступа к файлам , например, используя
sudo chmod 646 /tmp/django-app.log
Другой обходной путь - запустить
manage.py
как
webapp
user, например так:
sudo su - webapp <<'EOF'
source $(find /var/app/venv/*/bin/activate)
export $(/opt/elasticbeanstalk/bin/get-config --output YAML environment |
sed -r 's/: /=/' | xargs)
python3 /var/app/current/manage.py showmigrations
EOF
Как новичку в области разрешений в Linux, мне потребовалось некоторое время, чтобы заставить его работать. Обобщая приведенные выше ответы, у меня наконец сработало следующее:
logging.config
commands:
00_create_dir:
command: mkdir -p /var/log/app-logs
01_change_permissions:
command: chmod g+s /var/log/app-logs
02_change_default_owner:
command: setfacl -d -m g::rw /var/log/app-logs
03_change_owner:
command: chown wsgi:wsgi /var/log/app-logs
settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/var/log/app-logs/django.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
При этом я могу видеть журналы как отдельный раздел, используя "журналы eb", или в среде Beanstalk, раздел "журналы".
Если вы используетеgunicorn
, то вы можете использовать этот флаг:
gunicorn --access-logfile=-
Ни одно из упомянутых решений не помогло мне, поскольку я запускаю свой сервер на Amazon Linux 2
.
Проблема была не в самой конфигурации ведения журнала, а в .log
права доступа к файлам.
Это мой родственный logger.config
файл в формате.ebextensions:
commands:
01_create_log_file:
command: 'touch /var/log/django.log'
02_change_log_file_permissions:
command: 'sudo chmod ugo+rwx /var/log/django.log'
Как видите, мне пришлось решить проблему с разрешениями, просто предоставив все разрешения всем пользователям.
Это моя конфигурация регистратора Django:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/var/log/django.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
Вот мое решение для 64-битной Amazon Linux 2023/4.0.2.
commands:
00_create_dir:
command: mkdir -p /var/log/app-logs
01_change_permissions:
command: chmod g+s /var/log/app-logs
02_change_owner:
command: chown webapp:webapp /var/log/app-logs
и настройка файла журнала в Django,
'handlers': {
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
},
'logfile': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': "/var/log/app-logs/django.log",
'formatter': 'standard',
},
},
'loggers': {
'': {
'handlers': ['console', 'logfile'],
'level': 'INFO',
},
}
Убедитесь, что файл журнала имеет правильную конфигурацию владельца и группы, владельцем и группой должен быть webapp:wehapp, как показано ниже.
[ec2-user@ip-171-11-1-8 app-logs]$ ll django.log
-rw-r--r--. 1 webapp webapp 1120 Jul 29 01:08 django.log
По умолчанию в asticbeanstalk вы можете увидеть журналы ошибок django здесь.
/var/log/httpd/error_log