You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

服务器端Logging功能失效,本地运行正常,求故障排查

Python+Django项目部署服务器后无法写入日志排查

我开发的Python+Django项目在本地运行时可正常收集数据并写入日志,但部署到服务器后无法完成日志写入操作。以下是项目代码片段和本地运行时的日志示例,恳请协助排查代码问题。

项目代码片段

from bravo import Bravo
from ozon import OzonAPI
from datetime import datetime
import logging
import django
import os
import sys

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

def create_log():
    t = datetime.now()
    log_directory = os.path.join(BASE_DIR, 'assets', 'logs', str(t.year), str(t.month), str(t.day))
    logfile = os.path.join(log_directory, '{}-{}-{}.log'.format(t.hour, t.minute, t.second))

    try:
        os.makedirs(log_directory, exist_ok=True)
    except Exception as e:
        print('Failed to create log directory: {}'.format(e))

    log = logging.getLogger("my_log")
    log.setLevel(logging.INFO)
    FH = logging.FileHandler(logfile, encoding='utf-8')
    basic_formatter = logging.Formatter('%(asctime)s : [%(levelname)s] : %(message)s')
    FH.setFormatter(basic_formatter)
    log.addHandler(FH)
    log.addHandler(logging.StreamHandler(sys.stdout))  # Add stream handler for console output
    log.info('Start program')
    return log, t

def main():
    log, _ = create_log()

    setting = Settings.objects.all()[0]
    if not setting.mode:
        log.info('Program mode is disabled')
        return

    t1 = datetime.utcnow()
    bravo = Bravo()
    ozon = OzonAPI("I deleted here API")

    log.info('Fetching product list from Ozon...')
    products = ozon.get_product_list()
    warehouse_id = ozon.get_warehouses()[0]['warehouse_id']

    products_for_upload = []
    for product in products:
        if product['offer_id'].startswith('BR-'):
            try:
                stock = bravo.get_product_stock(product['offer_id'][3:-2])
                log.info("{} - {}".format(product['offer_id'], stock))
                products_for_upload.append(
                    {
                        'offer_id': product['offer_id'],
                        'product_id': product['product_id'],
                        'stock': stock,
                        'warehouse_id': warehouse_id,
                    }
                )
            except Exception as e:
                log.error("{} - {}".format(product['offer_id'][3:], e))

    log.info('Updating stocks on Ozon...')
    update_result = ozon.update_stocks(products_for_upload)
    log.info(update_result)

    t2 = datetime.utcnow()
    diff = t2 - t1
    log.info('Program execution time: {} seconds'.format(diff.total_seconds()))

    return update_result

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bravoparser.settings")
    django.setup()
    from main.models import Settings

    log = logging.getLogger("my_log")
    log.setLevel(logging.INFO)
    FH = logging.FileHandler(os.path.join(BASE_DIR, 'assets', 'logs', 'main.log'), encoding='utf-8')
    basic_formatter = logging.Formatter('%(asctime)s : [%(levelname)s] : %(message)s')
    FH.setFormatter(basic_formatter)
    log.addHandler(FH)
    log.addHandler(logging.StreamHandler(sys.stdout))  # Add stream handler for console output
    log.info('Start program')

    result = main()
    log.info('Program result: {}'.format(result))

本地日志示例

2023-06-06 20:51:58,298 : [INFO] : Fetching product list from Ozon...
2023-06-06 20:52:02,911 : [INFO] : BR-195090-I - 0
2023-06-06 20:52:03,596 : [INFO] : BR-183024-I - 0
2023-06-06 20:52:04,283 : [INFO] : BR-183440-I - 0
2023-06-06 20:52:04,968 : [INFO] : BR-183441-I - 0
2023-06-06 20:52:05,671 : [INFO] : BR-183393-I - 0
2023-06-06 20:52:06,220 : [INFO] : BR-195092-I - 0
2023-06-06 20:52:06,905 : [INFO] : BR-195094-I - 0
2023-06-06 20:52:07,607 : [INFO] : BR-195093-I - 0
2023-06-06 20:52:08,309 : [INFO] : BR-195091-I - 0
2023-06-06 20:52:09,074 : [INFO] : BR-183394-I - 0

排查方向

  • 权限问题:服务器上运行项目的用户(如www-data、nginx)对assets/logs目录及子目录无读写权限。可通过以下命令检查并修复:

    # 查看目录权限
    ls -l /path/to/project/assets/logs
    # 修改目录所属用户及权限
    chown -R www-data:www-data /path/to/project/assets/logs
    chmod -R 755 /path/to/project/assets/logs
    
  • 日志重复配置冲突:代码中if __name__ == "__main__"块和create_log函数均对my_log添加Handler,服务器环境下(如uwsgi、gunicorn启动)可能因启动方式导致配置重复或未生效。建议统一日志配置,或在添加新Handler前移除已有Handler:

    log = logging.getLogger("my_log")
    log.setLevel(logging.INFO)
    # 移除已有Handler避免重复
    for handler in log.handlers[:]:
        log.removeHandler(handler)
    # 后续添加新Handler代码不变
    
  • BASE_DIR路径错误:服务器上项目路径可能与本地不一致,BASE_DIR = os.path.dirname(os.path.abspath(__file__))获取的路径可能无效。可添加打印语句确认路径:

    print(f"BASE_DIR: {BASE_DIR}")
    print(f"Log directory: {log_directory}")
    
  • 异常捕获不完整:create_log中创建目录的异常仅打印到控制台,服务器后台运行时无法查看。建议将异常写入临时文件或直接抛出:

    try:
        os.makedirs(log_directory, exist_ok=True)
    except Exception as e:
        error_msg = f'Failed to create log directory: {e}'
        print(error_msg)
        # 写入临时文件记录错误
        with open('/tmp/log_error.txt', 'a', encoding='utf-8') as f:
            f.write(f"{datetime.now()}: {error_msg}\n")
        raise e
    
  • 时区差异问题:datetime.now()使用本地时间,服务器时区可能与本地不同,导致日志目录路径不符合预期。可检查服务器时区,或改用UTC时间创建目录。

内容的提问来源于stack exchange,提问作者Darnoob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:23:13