log

本文主要讲述如何抓取python脚本产生的log。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import logging

# 将logging专有化,避免和引用第三方模块的logging冲突。
logger = logging.getLogger(‘test’)
logger.setLevel(logging.INFO)

# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('/tmp/test.log')

# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()

# 定义handler的输出格式formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)

# 将定义好的console日志handler添加到logger
logger.addHandler(fh)
logger.addHandler(ch)

# 记录日志
logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

注意,在这种方法下print信息应该不会被logging抓取到。

有时候,我们希望抓取xgb运行过程中的精度反馈信息,可以采用子进程的方法进行抓取。子进程print在console的信息都可以被父进程抓取到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 将子进程信息抓取到文件
with open(log_path,'ab') as log_file:
process = subprocess.Popen(cmd, stdout=log_file, stderr=subprocess.STDOUT)

# 将子进程信息实时抓取到内存
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in iter(process.stdout.readline, b''):
print(line)

# 等待进程结束,不然block。用于防止直接运行下方codes
process.wait()

# 另一种写法(好像并没有什么差别。同事用的,我更倾向上一种)
while process.poll() is None:
time.sleep(1)

有时,我们希望子进程信息直接输出到控制台(这可能只是表象,具体是怎样的机制或说该怎样表述不清楚。。),那么可以直接调用

1
2
3
subprocess.call(cmd)
# or
subprocess.Popen(cmd)

当子进程本身也包含子进程时,我们也可以用以上方法使log汇总到最上层子进程上面,然后根据具体需求在父进程代码中选择相应的方法进行处理。