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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: logging 模块因权限问题写入日志失

哈喽大家好,我是咸鱼

今天跟大家分享一个使用 Python 的 logging 模块写入日志文件时遇到的权限问题,不知道你们有没有遇到过

1.案例现象

今天上班的时候手机短信收到了 zabbix 告警,但是发现了不对劲的地方:微信没有收到告警信息,按理说短信跟微信应该是同时收到告警信息的

咸鱼这边的 zabbix 是通过一个 python 脚本实现连接微信接口并向微信发送告警消息

上 zabbix 看看 action log
image-20230525141321185.png
发现 zabbix 发送告警到微信的操作执行失败了,报错如下:

Traceback (most recent call last):
  File "/home/zabbix/alert.py", line 24, in <module>
    logger = create_logger(log_path)
  File "/home/zabbix/alert.py", line 10, in create_logger
    file_handler = logging.FileHandler(log_path)
  File "/usr/lib64/python3.9/lib/python3.9/logging/__init__.py", line 1142, in __init__
    StreamHandler.__init__(self, self._open())
  File "/usr/lib64/python3.9/lib/python3.9/logging/__init__.py", line 1171, in _open
    return open(self.baseFilename, self.mode, encoding=self.encoding,
PermissionError: [Errno 13] Permission denied: '/var/log/myapp/myapp_20230525.log'

2.定位问题

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

  1. zabbix 调用 /home/zabbix/alert.py 脚本实现告警信息发送到微信
  2. /home/zabbix/alert.py 脚本的大体逻辑就是首先通过 logging 模块将告警内容写进本地日志,然后返回一个 logger 对象
  3. 再将 logger 对象以及其他参数传进 send_msg 函数里面,将告警信息发送到微信端

python 脚本 alert.py中创建并写入日志文件的代码如下:

import logging
import time
...

...
def create_logger(log_path):
    # 创建一个 logger 对象
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)

    # 创建一个文件处理器,将日志写入指定的文件中
    file_handler = logging.FileHandler(log_path)
    file_handler.setLevel(logging.DEBUG)

    # 创建一个格式化器,定义日志的格式
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    file_handler.setFormatter(formatter)

    # 将文件处理器添加到 logger 对象中
    logger.addHandler(file_handler)

    return logger

if __name__ == '__main__':
    log_path = '/var/log/myapp/myapp_%s.log' % time.strftime('%Y%m%d', time.localtime())
    logger = create_logger(log_path)
    ...

看报错信息里面有 PermissionError ,首先定位到应该是权限问题

看下这个日志文件的信息

[root@localhost /var/log/myapp]# ll /var/log/myapp/myapp_20230525.log
-rw-r--r-- 1 root root 300 5月  25 14:09 /var/log/myapp/myapp_20230525.log

可以看到属主属组都是 root,其他用户只有读的权限

我们再来看一下 zabbix 进程

[root@localhost /var/log/myapp]# ps -ef | grep [z]abbix
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

如何解决:修改一下日志文件的属主属组即可

chown zabbix.zabbix /var/log/myapp/myapp_20230525.log
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2月前
|
Prometheus Cloud Native Go
Golang语言之Prometheus的日志模块使用案例
这篇文章是关于如何在Golang语言项目中使用Prometheus的日志模块的案例,包括源代码编写、编译和测试步骤。
48 3
Golang语言之Prometheus的日志模块使用案例
|
2月前
|
Shell Python
salt自定义模块内使用日志例子
salt自定义模块内使用日志例子
logging 日志 模块
logging 日志 模块
|
3月前
|
Go 开发者
【应用服务 App Service】App Service发生错误请求时,如何查看IIS Freb日志,从中得知错误所发生的模块,请求中所携带的Header信息
【应用服务 App Service】App Service发生错误请求时,如何查看IIS Freb日志,从中得知错误所发生的模块,请求中所携带的Header信息
|
3月前
|
数据挖掘 语音技术
3D-Speaker说话人任务的开源项目问题之语义说话人信息模块在说话人日志系统中的问题如何解决
3D-Speaker说话人任务的开源项目问题之语义说话人信息模块在说话人日志系统中的问题如何解决
|
3月前
|
存储 监控 Java
|
3天前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
71 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
29天前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
178 3
|
29天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1607 14
|
25天前
|
Python
log日志学习
【10月更文挑战第9天】 python处理log打印模块log的使用和介绍
25 0