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

Roc*_*ite 0 python unicode logging 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"???")
Run Code Online (Sandbox Code Playgroud)

在这里使用initd脚本来运行Celery worker.我还将以下设置放入/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"
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

WKP*_*lus 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. ColorFormatter转换unicodestr使用 kombu.utils.encoding.safe_str.
  3. kombu.utils.encoding.safe_str使用default_encoding定义的编码返回将unicode编码为strkombu.utils.encoding
  4. default_encoding 回报 getattr(get_default_encoding_file(), 'encoding', None) or sys.getfilesystemencoding()
  5. 此外,我没有明确地找到celery set编码,所以我认为celery sys.getfilesystemencoding()用作将unicode转换为str的编码.
  6. sys.getfilesystemencoding的手册说:

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

  7. 因此,LANG=zh_CN.UTF8在芹菜过程环境中设置告诉芹菜通过UTF8将unicode转换为str.