关键词搜索

源码搜索 ×
×

Python 实时获取任务请求对应的Nginx日志

发布2021-08-31浏览433次

详情内容

需求描述

项目需求测试过程中,需要向Nginx服务器发送一些用例请求,然后查看对应的Nginx日志,判断是否存在特征内容,来判断任务是否执行成功。为了提升效率,需要将这一过程实现自动化。

实践环境

python教程 3.6.5

代码设计与实现

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. '''
  4. @CreateTime: 2021/06https://cdn.jxasp.com:9143/image/26 9:05
  5. @Author : shouke
  6. '''
  7. import time
  8. import threading
  9. import subprocess
  10. from collections import deque
  11. def collect_nginx_log():
  12. global nginx_log_queue
  13. global is_tasks_compete
  14. global task_status
  15. args = 'tail -0f /usr/local/openresty/nginx/logs/access.log'
  16. while task_status != 'req_log_got':
  17. with subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, universal_newlines = True) as proc:
  18. log_for_req = ''
  19. outs, errs = '', ''
  20. try:
  21. outs, errs = proc.communicate(timeout=2)
  22. except subprocess.TimeoutExpired:
  23. print('获取nginx日志超时,正在重试')
  24. proc.kill()
  25. try:
  26. outs, errs = proc.communicate(timeout=5)
  27. except subprocess.TimeoutExpired:
  28. print('获取nginx日志超时,再次超时,停止重试')
  29. break
  30. finally:
  31. for line in outs.split('\n'):
  32. flag = '\"client_ip\":\"10.118.0.77\"' # 特征
  33. if flag in line: # 查找包含特征内容的日志
  34. log_for_req += line
  35. if task_status == 'req_finished':
  36. nginx_log_queue.append(log_for_req)
  37. task_status = 'req_log_got'
  38. def run_tasks(task_list):
  39. '''
  40. 运行任务
  41. :param task_list 任务列表
  42. '''
  43. global nginx_log_queue
  44. global is_tasks_compete
  45. global task_status
  46. for task in task_list:
  47. thread = threading.Thread(target=collect_nginx_log,
  48. name="collect_nginx_log")
  49. thread.start()
  50. time.sleep(1) # 执行任务前,让收集日志线程先做好准备
  51. print('正在执行任务:%s' % task.get('name'))
  52. # 执行Nginx任务请求
  53. # ...
  54. task_status = 'req_finished'
  55. time_to_wait = 0.1
  56. while task_status != 'req_log_got': # 请求触发的nginx日志收集未完成
  57. time.sleep(time_to_wait)
  58. time_to_wait += 0.01
  59. else:# 获取到用例请求触发的nginx日志
  60. if nginx_log_queue:
  61. nginx_log = nginx_log_queue.popleft()
  62. task_status = 'req_ready'
  63. # 解析日志
  64. # do something here
  65. # ...
  66. else:
  67. print('存储请求日志的队列为空')
  68. # do something here
  69. # ...
  70. if __name__ == '__main__':
  71. nginx_log_queue = deque()
  72. is_tasks_compete = False # 所有任务是否执行完成
  73. task_status = 'req_ready' # req_ready,req_finished,req_log_got # 存放执行次任务任务的一些状态
  74. print('###########################任务开始###########################')
  75. tast_list = [{'name':'test_task', 'other':'...'}]
  76. run_tasks(tast_list)
  77. is_tasks_compete = True
  78. current_active_thread_num = len(threading.enumerate())
  79. while current_active_thread_num != 1:
  80. time.sleep(2)
  81. current_active_thread_num = len(threading.enumerate())
  82. print('###########################任务完成###########################')

注意:

1、上述代码为啥不一步到位,直接 tail -0f /usr/local/openresty/nginx/logs/access.log | grep "特征内容"呢?这是因为这样做无法获取到Nginx的日志

2、实践时发现,第一次执行proc.communicate(timeout=2)获取日志时,总是无法获取,会超时,需要二次获取,并且timeout设置太小时(实践时尝试过设置为1秒),也会导致第二次执行时无法获取Nginx日志。

作者:授客
本文版权归原作者所有,仅供学习参考之用,转载请注明出处:,未经作者允许请务必保留此段声明!


作者:授客

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载