AWS Elastic Beanstalk使用Python(django)进行日志记录

j7dteeu8  于 2023-08-08  发布在  Go
关注(0)|答案(9)|浏览(145)

如何在AWS Elastic Beanstalk中管理应用程序日志?您将应用程序日志写入哪个文件?
我在开发环境中使用以下日志记录配置,但在AWS中部署时,这不起作用。

  1. DEBUG_LOG_DIR = BASE_DIR + "/django_debug.log"
  2. LOGGING = {
  3. 'version': 1,
  4. 'disable_existing_loggers': True,
  5. # How to format the output
  6. 'formatters': {
  7. 'standard': {
  8. 'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
  9. 'datefmt' : "%d/%b/%Y %H:%M:%S"
  10. },
  11. },
  12. # Log handlers (where to go)
  13. 'handlers': {
  14. 'null': {
  15. 'level':'DEBUG',
  16. 'class':'django.utils.log.NullHandler',
  17. },
  18. 'log_file': {
  19. 'level':'DEBUG',
  20. 'class':'logging.handlers.RotatingFileHandler',
  21. 'filename': DEBUG_LOG_DIR,
  22. 'maxBytes': 50000,
  23. 'backupCount': 2,
  24. 'formatter': 'standard',
  25. },
  26. 'console':{
  27. 'level':'INFO',
  28. 'class':'logging.StreamHandler',
  29. 'formatter': 'standard'
  30. },
  31. 'mail_admins': {
  32. 'level': 'ERROR',
  33. 'class': 'django.utils.log.AdminEmailHandler',
  34. },
  35. },
  36. # Loggers (where does the log come from)
  37. 'loggers': {
  38. 'repackager': {
  39. 'handlers': ['console', 'log_file'],
  40. 'level': 'DEBUG',
  41. 'propagate': True,
  42. },
  43. 'django': {
  44. 'handlers':['console'],
  45. 'propagate': True,
  46. 'level':'WARN',
  47. },
  48. 'django.db.backends': {
  49. 'handlers': ['console', 'log_file'],
  50. 'level': 'WARN',
  51. 'propagate': False,
  52. },
  53. '': {
  54. 'handlers': ['console', 'log_file'],
  55. 'level': 'DEBUG',
  56. },
  57. }
  58. }

字符串

mec1mxoz

mec1mxoz1#

我在Elastic Beanstalk上遇到了类似的问题,所以我创建了一个配置文件(e.g. applogs.config)在应用程序的.ebextensions文件夹中。如果app-logs文件夹不存在,则会创建该文件夹,并设置文件权限和所有者,以便应用可以在其中写入日志。

  1. commands:
  2. 00_create_dir:
  3. command: mkdir -p /var/log/app-logs
  4. 01_change_permissions:
  5. command: chmod g+s /var/log/app-logs
  6. 02_change_owner:
  7. command: chown wsgi:wsgi /var/log/app-logs

字符串
最后,在Django设置中:

  1. LOGGING = {
  2. 'version': 1,
  3. 'disable_existing_loggers': False,
  4. 'handlers': {
  5. 'file': {
  6. 'level': 'DEBUG',
  7. 'class': 'logging.FileHandler',
  8. 'filename': '/var/log/app-logs/django.log',
  9. },
  10. },
  11. 'loggers': {
  12. 'django': {
  13. 'handlers': ['file'],
  14. 'level': 'DEBUG',
  15. 'propagate': True,
  16. },
  17. },
  18. }


有条件地,如果您希望您的日志可以通过web从beanstalk日志访问,请将其添加到.ebextensions中的文件中

  1. files:
  2. "/opt/elasticbeanstalk/tasks/taillogs.d/django.conf":
  3. mode: "000755"
  4. owner: root
  5. group: root
  6. content: |
  7. /var/log/app-logs/django.log

展开查看全部
wz3gfoph

wz3gfoph2#

好吧,我想到了一个办法。
首先,我通过ssh连接到ec2机器,然后我在/var/log中创建了一个名为app_logs的文件夹:

  1. mkdir /var/log/app_logs

字符串
之后,我做了以下工作:

  1. cd /var/log/
  2. chmod g+s app_logs/
  3. setfacl -d -m g::rw app_logs/
  4. chown wsgi:wsgi app_logs/


这样可以确保在此文件夹中创建的所有文件都将wsgi作为所有者,并且对于文件所属的组来说都是可写的。我不得不这样做,因为我注意到django应用程序创建的日志文件有root作为所有者和所有者组,但是应用程序通过wsgi用户运行。
最后我把DEBUG_LOG_DIR改为/var/log/app_logs/django_debug. log

展开查看全部
ilmyapht

ilmyapht3#

有一种简单的方法不需要任何beanstalk配置。
在你的django设置中,在LOGGING下设置一个指向文件**'/opt/python/log/{log_file_name}'**的处理程序。然后可以通过beanstalk环境菜单中的“Logs”访问日志。

  1. LOGGING = {
  2. ...,
  3. 'handlers': {
  4. 'logfile': {
  5. 'level': 'DEBUG',
  6. 'class': 'logging.handlers.RotatingFileHandler',
  7. 'filename': '/opt/python/log/{log_file_name}',
  8. },
  9. },
  10. 'loggers': {
  11. 'debugger': {
  12. 'level': 'DEBUG',
  13. 'handlers': ['logfile'],
  14. 'propagate': False,
  15. },
  16. }

字符串
此位置在此处的文档中说明:
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.logging.html#health-logs-instancelocation

展开查看全部
guykilcj

guykilcj4#

--编辑--
这个答案最初是为Amazon Linux AMI编写的,它现在已经达到了end-of-life
为了让事情清晰和分开,我写了一个new answer for Amazon Linux 2
--原创答案--

摘要

在我看来,最简单的解决方案是登录到/opt/python/log文件夹,正如bewestphal和@thierry-j(在steve-dunlop's answer下)所建议的那样。
这也是官方AWS EB Python * 示例应用程序 * 的功能:参见python-v1.zip
当您向EB请求日志时,日志文件将自动包含在内。
这个解决方案是开箱即用的,无需对.ebextensions进行任何修改,只要你不.ebextensions中调用django-admin.py(或其他django代码)。
但是,大多数应用
确实**需要在.ebextensions中调用django-admin.py,例如:为了migrate。这将导致创建日志文件 * 过早 *,包含root所有者和root组。这会导致权限错误,因为应用程序以wsgi:wsgi运行。
这个问题可以通过在container_commands的末尾 * 添加一个新命令来修复,以删除“过早”的日志文件,例如:

  1. container_commands:
  2. ...
  3. 9999_remove_root_log_file:
  4. command: rm /opt/python/log/django.log
  5. ignoreErrors: true

字符串
详情见下文。

后台

在一个标准的预配置Amazon Linux/Python平台上,使用Apache和mod_wsgi(参见AWS platform docs),Django应用程序的WSGIDaemonProcess以用户wsgi和组wsgi的身份运行(参见EC2示例上的/etc/httpd/conf.d/wsgi.conf)。
此外,/opt/python/log文件夹的 default 文件夹权限(在我的标准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),它就会中断。

权限问题

以下是在.ebextensions中使用django-admin.py会破坏日志文件权限的方法:
.ebextensions中,Elastic Beanstalk container_commandsroot用户的身份执行(请参阅aws docs)。
如果您在任何container_commands中调用django-admin.py,例如使用collectstaticmigrate,这将导致日志文件处理程序被初始化。如果指定的日志文件尚不存在,则此时将创建该日志文件,并具有root所有者和root组。
这意味着Django应用程序作为wsgi组的一部分运行,将没有权限写入日志文件(属于root组)。
这会导致权限错误,例如:PermissionError: [Errno 13] Permission denied: '/opt/python/log/django.log'

如何复制

下面的代码片段说明了权限问题并说明如何修复它。
要重现问题,请将这些container_commands添加到干净的项目中(例如在AWS EB Django tutorial之后),配置Django settings.py以登录到/opt/python/log/django.log,部署到AWS EB,然后检查eb-activity.log以查看容器命令的输出。

  1. ...
  2. container_commands:
  3. 0100_show_current_user:
  4. # show that we are running as root user
  5. command: whoami
  6. 0200_try_to_remove_log_file:
  7. # we need a clean slate for this example (make sure no log file owned by wsgi is present)
  8. command: rm /opt/python/log/django.log
  9. ignoreErrors: true
  10. 0300_break_log_file_permissions:
  11. # this causes a new log file to be created, owned by root:root (instead of wsgi:wsgi)
  12. command: django-admin.py
  13. 0400_show_log_file_permissions:
  14. # prove that a log file was created by root, and show folder permissions
  15. command: ls -la /opt/python/log
  16. 0500_fix_by_removing_log_file_after_all_django_admin_calls:
  17. # remove the log file created by django-admin.py, to ensure that a new log file will
  18. # be created when the server starts, owned by wsgi:wsgi
  19. command: rm /opt/python/log/django.log
  20. ignoreErrors: true

干燥溶液

所以,* 没有必要显式地混淆文件/文件夹权限 *。
如果你没有在.ebextensions中调用django代码,那么登录到/opt/python/log就可以了,开箱即用。
如果你在.ebextensions中调用django代码,例如:django-admin.py collectstatic,只需删除container_commands部分末尾的日志文件 * 即可。
注意:如果要记录文件以在部署之间持久存在,请仅在这些文件归root所有时才删除这些文件。
下面是一个DRY示例:
.ebextensions配置中:

  1. option_settings:
  2. # create EB environment property for the log file path
  3. aws:elasticbeanstalk:application:environment:
  4. LOG_FILE_PATH: /opt/python/log/django.log
  5. ...
  6. container_commands:
  7. ...
  8. # django code called here, e.g. "django-admin.py collectstatic"
  9. ...
  10. 9999_remove_any_existing_django_log_files:
  11. command: rm $LOG_FILE_PATH
  12. ignoreErrors: true


settings.py

  1. ...
  2. # get log path from environment variable, with fallback for local development
  3. log_file_path = os.getenv('LOG_FILE_PATH', 'local.log')
  4. # use this as 'filename' for the file handler, as described in the other answers
  5. ...

展开查看全部
kupeojn6

kupeojn65#

此答案仅适用于Amazon Linux 2。对于那些没有迁移yet的人,请看我的old answer for Amazon Linux AMI

后台

official AWS Python sample-application forAmazon linux 2使用/tmp文件夹进行日志记录。
但是,从Elastic Beanstalk请求日志时,不会自动包含添加到/tmp的自定义日志文件。要包含自定义日志文件,我们需要在EC2示例的/opt/elasticbeanstalk/tasks子文件夹中创建日志任务。参见文档中的说明。
示例应用程序(source)使用.ebextensions实现了这一点。然而,AWS Linux 2 migration docs建议我们应该使用.platform钩子:
我们建议使用平台钩子在您的环境示例上运行自定义代码。您仍然可以在.ebextensions配置文件中使用命令和容器命令,但它们不那么容易使用。例如,在YAML文件中编写命令脚本可能很麻烦,并且难以测试。
这还有一个额外的优点,即平台钩子的输出被收集在一个单独的日志文件中,即。/var/log/eb-hooks.log,这使得调试更容易一些。

Amazon Linux 2**上Django基本应用的DRY日志设置

日志级别和日志路径被定义在 * 一个 * 地方,作为Elastic Beanstalk环境属性,例如在.ebextensions/options.config中:

  1. option_settings:
  2. aws:elasticbeanstalk:application:environment:
  3. LOG_LEVEL: INFO
  4. DJANGO_LOG_FILE_PATH: /tmp/django-app.log
  5. ...

字符串
DJANGO_LOG_FILE_PATH环境属性现在可以在平台钩子中用于创建日志记录任务:

.platform/hooks/postdeploy/020_create_logging_tasks.sh

  1. #!/bin/bash
  2. TASKS_DIR=/opt/elasticbeanstalk/tasks
  3. # include all app log files in bundle logs (replaces ".log" by "*")
  4. echo "${DJANGO_LOG_FILE_PATH//.log/*}" > "$TASKS_DIR/bundlelogs.d/01-app-log.conf"
  5. # include current app log file in tail logs
  6. echo $DJANGO_LOG_FILE_PATH > "$TASKS_DIR/taillogs.d/01-app-log.conf"


注意,平台钩子需要执行权限,例如chmod +x 020_create_logging_tasks.sh。在windows上,您可以使用git,如here所述。
为了防止权限问题,我们使用另一个平台钩子来确保日志文件始终归webapp所有。注意这个钩子在logging-tasks钩子之前运行:

.platform/hooks/postdeploy/010_create_log_file.sh

  1. #!/bin/bash
  2. if test -f "$DJANGO_LOG_FILE_PATH";
  3. then
  4. echo "$DJANGO_LOG_FILE_PATH exists"
  5. else
  6. # create log file
  7. touch $DJANGO_LOG_FILE_PATH
  8. fi
  9. # set log file owner (we are currently "root", but the app runs as "webapp")
  10. chown webapp:webapp $DJANGO_LOG_FILE_PATH


我们还在Django设置中使用了LOG_LEVELDJANGO_LOG_FILE_PATH环境属性:

settings.py

  1. ...
  2. # basic logging with file rotation ()
  3. log_level = os.getenv('LOG_LEVEL', 'INFO')
  4. handlers = dict(file={'class': 'logging.handlers.TimedRotatingFileHandler',
  5. 'filename': os.getenv('DJANGO_LOG_FILE_PATH'),
  6. 'when': 'midnight',
  7. 'interval': 1,
  8. 'backupCount': 1,
  9. 'encoding': 'utf-8'})
  10. loggers = dict(django=dict(level=log_level, handlers=['file']),
  11. myapp=dict(level=log_level, handlers=['file']))
  12. LOGGING = dict(version=1,
  13. disable_existing_loggers=False,
  14. handlers=handlers,
  15. loggers=loggers)
  16. ...


一些注解:

  • 我们通常也指定自定义formatters,但为了清楚起见,我省略了这些。
  • 现在可以在/var/app/current中的EC2示例上找到应用程序本身。更多详细信息,请参阅扩展EB Linux平台。
  • 该应用程序现在以webapp的形式运行,并具有组webapp
  • eb ssh是你的朋友。参见docs
  • 我们还使用平台钩子来运行Django的migratecollectstatic命令,如here所述。

编辑:
正如@hax0在评论中指出的,如果 * 您尝试在EC2示例上使用SSH运行manage.py命令,* 部署后 *,可能会出现文件权限问题。
例如,使用eb ssh时,您以ec2-user身份登录,但日志文件归webapp用户所有,默认情况下,只有所有者有写权限(644)。因此,当以ec2-user的形式运行python manage.py时,您将收到一个错误,说明它无法配置日志文件处理程序,因为权限被拒绝。
一个快速而肮脏的解决方法是 * 临时 * 更改文件权限,例如:使用

  1. sudo chmod 646 /tmp/django-app.log


另一种解决方法是以webapp用户的身份运行manage.py,例如:

  1. sudo su - webapp <<'EOF'
  2. source $(find /var/app/venv/*/bin/activate)
  3. export $(/opt/elasticbeanstalk/bin/get-config --output YAML environment |
  4. sed -r 's/: /=/' | xargs)
  5. python3 /var/app/current/manage.py showmigrations
  6. EOF

展开查看全部
bjg7j2ky

bjg7j2ky6#

作为一个linux权限方面的初学者,我花了一些时间才让它工作起来。总结以上给出的答案,以下最终对我起了作用:
logging.config

  1. commands:
  2. 00_create_dir:
  3. command: mkdir -p /var/log/app-logs
  4. 01_change_permissions:
  5. command: chmod g+s /var/log/app-logs
  6. 02_change_default_owner:
  7. command: setfacl -d -m g::rw /var/log/app-logs
  8. 03_change_owner:
  9. command: chown wsgi:wsgi /var/log/app-logs

字符串
settings.py

  1. LOGGING = {
  2. 'version': 1,
  3. 'disable_existing_loggers': False,
  4. 'handlers': {
  5. 'file': {
  6. 'level': 'DEBUG',
  7. 'class': 'logging.FileHandler',
  8. 'filename': '/var/log/app-logs/django.log',
  9. },
  10. },
  11. 'loggers': {
  12. 'django': {
  13. 'handlers': ['file'],
  14. 'level': 'DEBUG',
  15. 'propagate': True,
  16. },
  17. },
  18. }


这样我就可以使用'eb logs'将日志作为一个单独的部分或者在Beanstalk环境中的“logs”部分来查看日志。

展开查看全部
laximzn5

laximzn57#

如果你使用gunicorn,那么你可以使用这个标志:

  1. gunicorn --access-logfile=-

字符串

t3psigkw

t3psigkw8#

以下是我在64位Amazon Linux 2023/4.0.2上的解决方案

  1. commands:
  2. 00_create_dir:
  3. command: mkdir -p /var/log/app-logs
  4. 01_change_permissions:
  5. command: chmod g+s /var/log/app-logs
  6. 02_change_owner:
  7. command: chown webapp:webapp /var/log/app-logs

字符串
以及Django中的日志文件设置,

  1. 'handlers': {
  2. 'console': {
  3. 'level': 'INFO',
  4. 'class': 'logging.StreamHandler',
  5. },
  6. 'logfile': {
  7. 'level': 'INFO',
  8. 'class': 'logging.handlers.RotatingFileHandler',
  9. 'filename': "/var/log/app-logs/django.log",
  10. 'formatter': 'standard',
  11. },
  12. },
  13. 'loggers': {
  14. '': {
  15. 'handlers': ['console', 'logfile'],
  16. 'level': 'INFO',
  17. },
  18. }


确保日志文件具有正确的所有权和组配置,所有者和组应该是webapp:wehapp,如下所示

  1. [ec2-user@ip-171-11-1-8 app-logs]$ ll django.log
  2. -rw-r--r--. 1 webapp webapp 1120 Jul 29 01:08 django.log

展开查看全部
sbtkgmzw

sbtkgmzw9#

默认情况下,在elasticbeanstalk中,您可以在这里看到django错误日志。

  1. /var/log/httpd/error_log

字符串

相关问题