翼度科技»论坛 云主机 LINUX 查看内容

logging 模块因权限问题写入日志失败

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
哈喽大家好,我是咸鱼
今天跟大家分享一个使用 Python 的 logging 模块写入日志文件时遇到的权限问题,不知道你们有没有遇到过
1.案例现象

今天上班的时候手机短信收到了 zabbix 告警,但是发现了不对劲的地方:微信没有收到告警信息,按理说短信跟微信应该是同时收到告警信息的
咸鱼这边的 zabbix 是通过一个 python 脚本实现连接微信接口并向微信发送告警消息
上 zabbix 看看 action log

发现 zabbix 发送告警到微信的操作执行失败了,报错如下:
  1. Traceback (most recent call last):
  2.   File "/home/zabbix/alert.py", line 24, in <module>
  3.     logger = create_logger(log_path)
  4.   File "/home/zabbix/alert.py", line 10, in create_logger
  5.     file_handler = logging.FileHandler(log_path)
  6.   File "/usr/lib64/python3.9/lib/python3.9/logging/__init__.py", line 1142, in __init__
  7.     StreamHandler.__init__(self, self._open())
  8.   File "/usr/lib64/python3.9/lib/python3.9/logging/__init__.py", line 1171, in _open
  9.     return open(self.baseFilename, self.mode, encoding=self.encoding,
  10. PermissionError: [Errno 13] Permission denied: '/var/log/myapp/myapp_20230525.log'
复制代码
2.定位问题

在开始定位前先介绍一下 zabbix 发送告警信息到微信的流程:

  • zabbix 调用 /home/zabbix/alert.py 脚本实现告警信息发送到微信
  • /home/zabbix/alert.py 脚本的大体逻辑就是首先通过 logging 模块将告警内容写进本地日志,然后返回一个 logger 对象
  • 再将 logger 对象以及其他参数传进 send_msg 函数里面,将告警信息发送到微信端
python 脚本 alert.py中创建并写入日志文件的代码如下:
  1. import logging
  2. import time
  3. ...
  4. ...
  5. def create_logger(log_path):
  6.     # 创建一个 logger 对象
  7.     logger = logging.getLogger(__name__)
  8.     logger.setLevel(logging.DEBUG)
  9.     # 创建一个文件处理器,将日志写入指定的文件中
  10.     file_handler = logging.FileHandler(log_path)
  11.     file_handler.setLevel(logging.DEBUG)
  12.     # 创建一个格式化器,定义日志的格式
  13.     formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
  14.     file_handler.setFormatter(formatter)
  15.     # 将文件处理器添加到 logger 对象中
  16.     logger.addHandler(file_handler)
  17.     return logger
  18. if __name__ == '__main__':
  19.     log_path = '/var/log/myapp/myapp_%s.log' % time.strftime('%Y%m%d', time.localtime())
  20.     logger = create_logger(log_path)
  21.         ...
复制代码
看报错信息里面有 PermissionError ,首先定位到应该是权限问题
看下这个日志文件的信息
  1. [root@localhost /var/log/myapp]# ll /var/log/myapp/myapp_20230525.log
  2. -rw-r--r-- 1 root root 300 5月  25 14:09 /var/log/myapp/myapp_20230525.log
复制代码
可以看到属主属组都是 root,其他用户只有读的权限
我们再来看一下 zabbix 进程
  1. [root@localhost /var/log/myapp]# ps -ef | grep [z]abbix
  2. zabbix    31076      1  0 3月16 ?       00:00:00 /usr/sbin/zabbix_server -c /etc/zabbix/zabbix_server.conf
复制代码
可以看到 zabbix 进程是 zabbix 用户启动的,因为 /var/log/myapp/myapp_20230525.log 的权限是644且属主属组都是 root
所以说 zabbix 用户调用 alert.py 脚本时发现写入日志因为没有权限而失败,导致脚本运行崩溃
3.排查问题

到这里基本就能知道是什么原因了,但是还有一点疑问:只有 /var/log/myapp/myapp_20230525.log 这个日志的属主属组都是 root ,其余日志文件都是 zabbix
我们知道,在 Python 的 logging 模块中,日志文件的属主是由操作系统的文件系统决定的,而不是由 logging 模块本身决定。当使用 logging 模块创建日志文件时,它会使用操作系统提供的默认文件创建方式
这意味着日志文件的属主将取决于当前运行 Python 程序的用户或进程的权限和身份。
看样子应该是有人使用 root 用户执行过这个 python 脚本,导致生成的这个日志文件 myapp_20230525.log 属主是 root,后面等 zabbix 自己去执行这个脚本(zabbix 用户)的时候发现没有权限写东西进 myapp_20230525.log 里面,这才导致微信收不了告警信息
后面拷打了一下同事(其实是执行了 history 命令看操作记录 )才知道昨晚同事在终端上手动跑了一下这个 python 脚本,又因为默认登录用户是 root,导致生成的日志文件属主属组都是 root
如何解决:修改一下日志文件的属主属组即可
  1. chown zabbix.zabbix /var/log/myapp/myapp_20230525.log
复制代码
来源:https://www.cnblogs.com/edisonfish/p/17452538.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具