编写守护脚本需要注意的的两个问题

本文介绍了如何在crontab中定时运行脚本,并通过ps命令监控特定进程,确保其正常运行。重点提及了使用'nohup'命令在进程挂掉后自动重启,并强调了在脚本前加载.bash_profile的重要性。
1、在crontab里定时运行脚本,脚本名称和路径里不要包含被守护的进程名,否则在判断进程数的时候会比预想的多。另外,最好使用“ps -ef|grep -w”而不是“ps -ef|grep ”, -w 是整字匹配。
2、进程挂掉之后再拉起用到了nohup,需要在脚本前加一句“source ~/.bash_profile”。碰到两个地方的服务器没加这一句导致nohup失效。可能nohup对环境变量有要求。

以下是我部署在一台服务器上的守护脚本:
crontab:
  1. #进程守护脚本
  2. */5 * * * * bash /home/greenet_check/moniter.sh >>/home/greenet_check/moniter.log
复制代码
脚本:
  1. #!/bin/bash
  2. ## ==========================================================================
  3. ## Copyright (c)  Shenzhen *** Communication Co.,Ltd. All rights reserved.
  4. ##
  5. ##  进程守护脚本(进程不在时邮件告警、自动拉起、压缩core文件)
  6. ##
  7. ##  Written by linl 2012-03-27
  8. ##

  9. source ~/.bash_profile

  10. PROCNAME=radius
  11. BINPATH=/home/radius/bin
  12. MAILADDR=moniter@126.com

  13. echo -n "[`date +"%Y-%m-%d %H:%M:%S"`] "

  14. let PROCNUM=$(ps -ef|grep -w ${PROCNAME}|grep -vw grep|wc -l)
  15. if [ "$PROCNUM" -le "0" ];then
  16.     echo -n "[ERROR] "
  17.     mail -s "告警! ${PROCNAME}挂了" ${MAILADDR} <. -- -f ${HOSTNAME}@moniter.com -F moniter
  18.     cd ${BINPATH}
  19.     nohup ./${PROCNAME} >/dev/null &
  20.     gzip core.*
  21. else
  22.     echo -n "[OK]    "
  23. fi
  24. echo -e "proc name is \"${PROCNAME}\"  proc num is ${PROCNUM}"
复制代码
moniter@126.com仅是举例,非真实邮箱。有些邮箱不能作为邮件告警的接收邮箱,126邮箱可以,可能是sendmail所发邮件格式不够规范导致的吧,没仔细研究。
<think> 我们被要求使用Python脚本计算两个关键字之间CPU负载。这里的“两个关键字之间”可能指的是在一段时间内的CPU负载,即从第一个关键字出现到第二个关键字出现的时间段内的CPU负载。 根据引用[1],我们可以使用os模块来获取系统的负载情况。但是,更常见的做法是使用`psutil`库来获取CPU的使用情况,因为它跨平台且易于使用。 思路: 1. 我们需要监控从第一个关键字出现到第二个关键字出现这段时间内的CPU使用率。 2. 我们可以通过记录第一个关键字出现的时间点,然后持续监控CPU使用率,直到第二个关键字出现,然后计算这段时间内的平均CPU负载。 步骤: a. 安装psutil库(如果尚未安装):`pip install psutil` b. 编写脚本,在检测到第一个关键字时开始记录CPU使用率,在检测到第二个关键字时停止记录。 c. 计算这段时间内的平均CPU负载。 但是,这里有一个问题:关键字如何出现?我们可能需要监控日志文件或其他输出?题目没有明确说明。假设我们监控的是标准输入(例如从管道输入)或者日志文件。 我们可以这样设计: - 脚本实时读取输入(可以是文件或标准输入流),每读取一行就检查是否包含关键字。 - 当包含第一个关键字时,开始记录CPU使用率(每隔一段时间取样一次,比如每秒)。 - 当包含第二个关键字时,停止记录,并计算平均CPU负载。 另一种情况:我们可能不是在监控日志,而是通过其他方式触发关键字(例如,用户按键盘),但这种情况较少见。我们假设是监控文本流。 具体实现步骤: 1. 导入必要的模块:`psutil`,`time`,`sys`(用于标准输入)或文件操作。 2. 设置两个关键字,例如`start_keyword`和`end_keyword`。 3. 初始化变量:`start_time`记录开始时间,`cpu_readings`列表用于存储每次取样的CPU使用率。 4. 循环读取输入(按行读取): - 如果读取到`start_keyword`,则开始一个循环,在循环中每隔一定时间(例如1秒)获取一次CPU使用率(`psutil.cpu_percent(interval=None)`),并记录到`cpu_readings`中,同时继续检查输入(我们需要非阻塞读取?或者另开线程?)。 5. 但是,由于在循环中等待CPU取样时可能会阻塞,导致无法及时读取到结束关键字,因此我们需要使用多线程或者异步方式。 另一种设计(简化): 我们可以在检测到开始关键字后,记录开始时间,然后开始记录CPU使用率到文件(或内存),同时继续读取输入,当读到结束关键字时,停止记录,并计算从开始时间到结束时间内的平均CPU使用率。 然而,由于读取输入和记录CPU使用率是并行的,我们可以这样: 主线程:读取输入,遇到开始关键字,启动一个后台线程来记录CPU使用率;遇到结束关键字,设置一个标志通知后台线程停止。 具体代码结构: 使用一个全局标志来控制后台线程的停止。 步骤: 1. 定义两个关键字。 2. 定义一个全局变量`monitoring`,初始为False。 3. 主线程读取输入(从stdin或文件),每行检查: - 如果包含开始关键字,且`monitoring`为False,则设置`monitoring`为True,并启动后台线程(该线程每隔一秒记录CPU使用率)。 - 如果包含结束关键字,且`monitoring`为True,则设置`monitoring`为False,并等待后台线程结束,然后计算平均值。 4. 后台线程函数:在`monitoring`为True时,循环执行:记录当前CPU使用率(使用`psutil.cpu_percent(interval=1)`,这里间隔1秒,会阻塞1秒),然后记录。注意:当`monitoring`被设为False时,线程退出。 但是注意:在后台线程中,我们使用1秒间隔,那么每次获取的是过去1秒内的平均CPU使用率。这样,我们记录的是每秒的CPU使用率,然后计算平均值。 代码示例: 注意:由于psutil.cpu_percent(interval=1)会阻塞1秒,所以我们的后台线程每次循环大约1秒。同时,我们需要在主线程中设置一个停止标志,并在停止时等待当前循环结束。 由于全局变量的线程安全问题,我们使用`threading.Event`来控制。 我们使用两个事件: - `start_event`:用于通知开始(这里我们可以不需要,直接用一个标志) - `stop_event`:用于通知停止 实际上,我们只需要一个停止事件(`stop_flag`)即可,后台线程循环检查这个标志。 具体代码: 注意:这个脚本需要持续运行,直到遇到结束关键字。 由于我们可能需要从标准输入读取,所以使用`sys.stdin`。 以下是代码: </think># 使用Python计算两个关键字之间的CPU负载 要计算两个关键字之间时间段的CPU负载,我们可以结合Python的`psutil`库和日志监控功能来实现。下面是一个完整的解决方案: ## 实现原理 1. 监控系统日志或应用程序日志,检测特定关键字出现的时间点 2. 使用`psutil`库获取CPU使用率数据 3. 计算两个关键字之间时间段的平均CPU负载 ## 完整代码实现 ```python import psutil import time import re import threading from collections import deque class CPULoadMonitor: def __init__(self, keyword_start, keyword_end): """ 初始化CPU负载监控器 :param keyword_start: 开始关键字 :param keyword_end: 结束关键字 """ self.keyword_start = keyword_start self.keyword_end = keyword_end self.cpu_readings = deque(maxlen=10000) # 存储CPU读数 self.monitoring = False self.start_time = None self.end_time = None self.avg_load = None def start_monitoring(self): """开始监控CPU负载""" self.monitoring = True monitor_thread = threading.Thread(target=self._monitor_cpu) monitor_thread.daemon = True monitor_thread.start() def _monitor_cpu(self): """后台线程:持续监控CPU使用率""" while True: if self.monitoring: # 获取当前时间戳和CPU使用率 timestamp = time.time() cpu_percent = psutil.cpu_percent(interval=0.1) self.cpu_readings.append((timestamp, cpu_percent)) time.sleep(0.1) def process_log_line(self, line): """ 处理日志行,检测关键字 :param line: 日志行内容 """ if re.search(self.keyword_start, line): self._handle_start_keyword() elif re.search(self.keyword_end, line): self._handle_end_keyword() def _handle_start_keyword(self): """处理开始关键字""" if not self.monitoring: print(f"检测到开始关键字: {self.keyword_start}") self.start_time = time.time() self.start_monitoring() def _handle_end_keyword(self): """处理结束关键字""" if self.monitoring: print(f"检测到结束关键字: {self.keyword_end}") self.end_time = time.time() self.monitoring = False self._calculate_avg_load() def _calculate_avg_load(self): """计算两个关键字之间的平均CPU负载""" if not self.start_time or not self.end_time: return # 筛选在时间范围内的CPU读数 relevant_readings = [ load for ts, load in self.cpu_readings if self.start_time <= ts <= self.end_time ] if relevant_readings: self.avg_load = sum(relevant_readings) / len(relevant_readings) print(f"\n在两个关键字之间的CPU负载统计:") print(f"开始时间: {time.ctime(self.start_time)}") print(f"结束时间: {time.ctime(self.end_time)}") print(f"持续时间: {self.end_time - self.start_time:.2f} 秒") print(f"平均CPU负载: {self.avg_load:.2f}%") else: print("未找到在两个关键字之间的CPU读数") # 使用示例 if __name__ == "__main__": # 设置监控的关键字 monitor = CPULoadMonitor( keyword_start="启动任务", # 第一次出现的关键字 keyword_end="任务完成" # 第二次出现的关键字 ) # 模拟日志输入 - 实际应用中应替换为真实日志源 print("模拟日志输入...") log_lines = [ "系统启动...", "初始化完成", "开始处理数据...", "启动任务", # 第一个关键字 "处理数据中...", "CPU使用率升高...", "任务完成", # 第二个关键字 "清理资源..." ] # 处理日志行 for line in log_lines: print(f"处理日志: {line}") monitor.process_log_line(line) time.sleep(1) # 模拟日志间隔 ``` ## 使用说明 1. **初始化监控器**: ```python monitor = CPULoadMonitor(keyword_start="启动任务", keyword_end="任务完成") ``` 2. **处理日志行**: ```python # 对于每个日志行 monitor.process_log_line(log_line) ``` 3. **获取结果**: ```python # 当检测到结束关键字后,平均负载存储在avg_load属性中 avg_load = monitor.avg_load ``` ## 关键技术与解释 1. **CPU监控技术**: - 使用`psutil.cpu_percent()`实时获取CPU使用率[^1] - 设置`interval=0.1`实现高精度采样 - 后台线程持续收集数据,避免阻塞主程序 2. **日志处理技术**: - 使用正则表达式匹配关键字 - 处理开始关键字时启动监控 - 处理结束关键字时停止监控并计算结果 3. **数据结构优化**: - 使用`deque`存储CPU读数,高效处理大量数据 - 时间戳与CPU负载成对存储,便于时间范围筛选 4. **多线程应用**: - 监控线程独立运行,不影响日志处理 - 使用守护线程确保程序退出时线程终止[^2] ## 实际应用场景 1. **性能测试**:测量特定操作期间的CPU负载 ```python monitor = CPULoadMonitor("开始压力测试", "结束压力测试") ``` 2. **批处理监控**:跟踪批处理作业的资源消耗 ```python monitor = CPULoadMonitor("批处理开始", "批处理结束") ``` 3. **微服务分析**:分析服务调用的资源开销 ```python monitor = CPULoadMonitor("API调用开始", "API调用结束") ``` ## 高级扩展功能 1. **多核分析**: ```python # 获取每个核心的负载 per_cpu = psutil.cpu_percent(interval=0.1, percpu=True) ``` 2. **历史数据保存**: ```python # 将CPU读数保存到CSV with open('cpu_load.csv', 'w') as f: f.write("timestamp,cpu_load\n") for ts, load in self.cpu_readings: f.write(f"{ts},{load}\n") ``` 3. **实时可视化**: ```python # 使用matplotlib实时绘制CPU负载 import matplotlib.pyplot as plt plt.plot(timestamps, cpu_loads) plt.xlabel('时间') plt.ylabel('CPU负载 (%)') plt.title('两个关键字之间CPU负载变化') plt.show() ``` ## 注意事项 1. 确保有足够的权限访问系统性能数据 2. 根据实际需求调整采样频率(interval参数) 3. 对于长时间监控,考虑实现数据滚动存储,避免内存溢出 4. 在生产环境中,建议添加异常处理机制 这个解决方案提供了灵活的关键字检测和精确的CPU负载计算,可用于各种性能分析和监控场景[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值