Celery worker的日志包含问号(???)而不是正确的unicode字符

时间:2015-05-07 07:37:38

标签: python logging unicode celery

我在CentOS 6.5上使用Celery 3.1.18和Python 2.7.8。

在Celery任务模块中,我有以下代码:

# someapp/tasks.py
from celery import shared_task
from celery.utils.log import get_task_logger

logger = get_task_logger(__name__)


@shared_task()
def foo():
    logger.info('Test output: %s', u"测试中")

我使用the initd script here来运行Celery工作者。我还在/etc/default/celeryd中添加了以下设置:

CELERYD_NODES="bar"

# %N will be replaced with the first part of the nodename.
CELERYD_LOG_FILE="/var/log/celery/%N.log"

# Workers should run as an unprivileged user.
#   You need to create this user manually (or you can choose
#   a user/group combination that already exists, e.g. nobody).
CELERYD_USER="nobody"
CELERYD_GROUP="nobody"

所以我的日志文件位于/var/log/celery/bar.log

但是,一旦工作人员执行了该任务,上面的日志文件就会显示:

[2015-05-07 03:51:14,438: INFO/Worker-1/someapp.tasks.foo(...)] Test output: ???

unicode字符消失了,取而代之的是一些问号。

如何在日志文件中找回unicode字符?

1 个答案:

答案 0 :(得分:6)

您需要在启动芹菜应用程序的环境中设置LANG=zh_CN.UTF-8

如果您使用celeryd,有一种简单的方法,在CELERY_BIN="env LANG=zh_CN.UTF-8 /path/to/celery/binary

中设置/etc/default/celeryd

<强>解释

  1. Celery使用ColorFormatter进行邮件格式化,即 在celery.utils.log中定义。
  2. ColorFormatterunicode转换为str kombu.utils.encoding.safe_str
  3. kombu.utils.encoding.safe_str使用编码将unicode编码为str     在default_encoding
  4. 中定义的kombu.utils.encoding返回
  5. default_encoding返回getattr(get_default_encoding_file(), 'encoding', None) or sys.getfilesystemencoding()
  6. 此外,我没有明确找到celery set编码,所以我认为celery使用sys.getfilesystemencoding()作为编码将unicode转换为str。
  7. sys.getfilesystemencoding's manual说:

      

    在Unix上,根据nl_langinfo(CODESET)的结果,编码是用户的首选项,如果nl_langinfo(CODESET)失败,则编码是None

  8.   
  9. 因此,在芹菜进程环境中设置LANG=zh_CN.UTF8会告诉芹菜通过UTF8将unicode转换为str。
  10.