生成日志系统和监控

背景:已知某后台服务将日志存放在本地硬盘的日志文件中,该服务也支持代码热更新,并在完成热更新后输出一条日志。我们需要对服务日志进行监控,以确保文件热更新后的错误能被第一时间发现。

我们提供 Python 程序模拟(https://pastebin.com/pZH8wruC,密码pWXRFeSpwU)上述行为,该程序会不断生成日志,并输出到日志文件 1.log 中,日志格式参考源码。

要求:
1、使用 Python 或者 Shell 对上述日志进行检测,检测方式可以是常驻进程实时检测,也可以通过系统定时任务(需要说明如何配置)定时检测日志;
2、当检测到热更新日志时(以"load file:"开头,具体格式参考源码),对错误日志(error级别)进行分类统计(分类按照日志内容进行);
3、如果热更新后1分钟内某一类别的错误日志比热更新前1分钟内的量级更多(增加50%),则在另一个文件 2.log 中记录相关日志(附带该量级超标的日志内容、热更新前后的量级信息)。
 

//这是链接里面的代码# 日志生成用例# - 程序随机地生成 info 和 error 级别日志# - 每隔一段时间产生热更新日志# - 模拟热更新后出现更多的错误日志import osimport timeimport randomimport loggingdef init_logging():logger = logging.getLogger()logger.setLevel(logging.INFO)logger_format = logging.Formatter("[%(asctime)s][%(levelname)s][%(module)s:%(funcName)s:%(lineno)d] %(message)s")logger_console = logging.StreamHandler()logger_console.setLevel(logging.INFO)logger_console.setFormatter(logger_format)logger.addHandler(logger_console)logger_file = logging.FileHandler("1.log")logger_file.setLevel(logging.INFO)logger_file.setFormatter(logger_format)logger.addHandler(logger_file)STAGE_CONFIG = {"normal": {"duration": "70±10","info_base_prob": 0.01,"info_add_prob": 0,"error_base_prob": 0.01,"error_add_prob": 0,},"after_hotreload": {"duration": "80±20","info_base_prob": 0.1,"info_add_prob": 0.1,"error_base_prob": 0.1,"error_add_prob": 0.2,}}INFO_LOG_TEMPLATE = ["session connected","session closed","player login","player registered","player logout","buy item flow","sell item flow",]ERROR_LOG_TEMPLATE = ["function %d error occur","player login failed","incorrect password","establish connection failed","bad arguments",]INFO_HOTRELOAD_TEMPLATE = ["load file: %d.lua .......... [ok]"]def random_stage_time(duration):pos = duration.find('±')base_time = int(duration[:pos])offset_time = int(duration[pos + 1:])return base_time + (random.random() * 2 - 1) * offset_timedef random_select(l):e = random.choice(l)if e.find('%') >= 0:r = random.randint(0, 10)return e % rreturn eclass App:def __init__(self):self._stage = Noneself._stage_time = 0self._timer = 0self._init_state("normal")def _init_state(self, stage):self._stage = stageself._stage_time = random_stage_time(STAGE_CONFIG[stage]["duration"])self._timer = 0def on_tick(self, elapsed_time):self._timer += elapsed_timeif self._timer >= self._stage_time:if self._stage == "normal":logging.info(random_select(INFO_HOTRELOAD_TEMPLATE))self._init_state("after_hotreload")elif self._stage == "after_hotreload":self._init_state("normal")log_add_strength = 1 - min(1.0, (self._stage_time - self._timer) / self._stage_time)log_info_prob = STAGE_CONFIG[self._stage]["info_base_prob"] + \log_add_strength * STAGE_CONFIG[self._stage]["info_add_prob"]log_err_prob = STAGE_CONFIG[self._stage]["error_base_prob"] + \log_add_strength * STAGE_CONFIG[self._stage]["error_add_prob"]if random.random() < log_info_prob:logging.info(random_select(INFO_LOG_TEMPLATE))if random.random() < log_err_prob:logging.error(random_select(ERROR_LOG_TEMPLATE))def main():init_logging()app = App()last_time = time.time()while True:now_time = time.time()app.on_tick(now_time - last_time)last_time = now_timetime.sleep(0.01)if __name__ == "__main__":main()

解决方法:

为了使用Python来实现上述要求,我们可以编写一个Python脚本来处理日志文件的读取、解析、分类统计以及比较热更新前后的错误日志数量。同时,我们将使用系统定时任务(如Linux下的cron)来定期运行这个Python脚本。

步骤 1: 编写Python脚本

首先,我们需要编写一个Python脚本来处理日志文件。这个脚本将需要能够:

  1. 读取日志文件。
  2. 检测热更新日志(以"load file:"开头)。
  3. 提取错误日志并根据内容进行分类统计。
  4. 比较热更新前后的错误日志数量。
  5. 记录超标的日志内容和统计信息到另一个文件。

下面是一个简化的Python脚本示例:

import re  
import os  
from datetime import datetime, timedelta  LOG_FILE = '/path/to/your/logfile.log'  
OUTPUT_FILE = '/path/to/2.log'  
TEMP_STATS_FILE = '/tmp/stats.tmp'  # 模拟从日志文件中读取行(实际中应使用文件操作)  
def read_log_lines(file_path):  # 这里只是模拟,实际中应打开文件并逐行读取  with open(file_path, 'r') as file:  return file.readlines()  # 检测热更新并处理日志  
def process_logs():  lines = read_log_lines(LOG_FILE)  update_time = None  before_counts = {}  after_counts = {}  # 遍历日志行  for line in lines:  if line.startswith('load file:'):  # 检测到热更新,记录时间并重置计数器  update_time = datetime.strptime(line.split(' ')[-1], '%Y-%m-%d %H:%M:%S')  before_counts = {}  after_counts = {}  elif 'ERROR' in line:  # 假设每行日志包含时间和级别  log_time = datetime.strptime(re.search(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}', line).group(), '%Y-%m-%d %H:%M:%S')  error_type = re.search(r'ERROR: (.+?)(?: \[|$)', line).group(1)  if update_time and update_time - timedelta(minutes=1) <= log_time <= update_time + timedelta(minutes=1):  # 在热更新前后1分钟内  if log_time < update_time:  before_counts[error_type] = before_counts.get(error_type, 0) + 1  else:  after_counts[error_type] = after_counts.get(error_type, 0) + 1  # 比较并记录结果  for type, after_count in after_counts.items():  before_count = before_counts.get(type, 0)  if after_count > before_count * 1.5:  with open(OUTPUT_FILE, 'a') as file:  file.write(f"Error type {type} increased significantly after update:\n")  file.write(f"Before: {before_count}, After: {after_count}\n")  # 这里可以添加更多逻辑来记录具体的日志内容  # 定时任务将调用这个函数  
if __name__ == '__main__':  process_logs()

注意:上面的脚本有几个简化和假设的地方,比如直接读取整个日志文件并假设时间戳和错误类型可以直接从日志行中提取。在实际应用中,你可能需要处理更复杂的日志格式和更大的日志文件。

步骤 2: 配置Cron定时任务

接下来,你需要在Linux系统上设置Cron定时任务来定期运行这个Python脚本。

  1. 打开终端。
  2. 输入crontab -e命令来编辑当前用户的Cron任务列表。
  3. 添加一个定时任务来每分钟运行一次脚本(或者根据你的需求设置不同的频率):
    * * * * * /usr/bin/python3 /path/to/your/script.py

    注意将/usr/bin/python3替换为你的Python解释器的实际路径,/path/to/your/script.py替换为你的Python脚本的实际路径。

    保存并关闭编辑器。Cron将自动加载新的任务列表。
    现在,你的Python脚本将按照Cron任务的设置定期运行,检测日志文件中的热更新,并对错误

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/44448.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab仿真 模拟调制(上)

&#xff08;内容源自详解MATLAB&#xff0f;SIMULINK 通信系统建模与仿真 刘学勇编著第五章内容&#xff0c;有兴趣的读者请阅读原书&#xff09; 1.幅度调制 clear all ts0.0025; %信号抽样时间间隔 t0:ts:10-ts;%时间矢量 fs1/ts;%抽样频率 dffs/length(t); %fft的频率分…

国内从事人机交互的团队——浙江工业大学

一、背景 当我们选择一个新的课题后&#xff0c;需要清楚的了解从事该方向的团队都有哪些&#xff0c;这样可以及时跟踪和学习大牛团队的最新进展&#xff0c;以免自己认为的good idea&#xff0c;其实早就已经研究过了。 随着人形机器人的发展&#xff0c;机器人不仅需要在无…

人类远未触及自然规律的本质

我想知道上帝是如何创造这个世界的&#xff0c;对于这样或那样的现象我不感兴趣&#xff0c;我想知道的是他的思想&#xff0c;其余的都是细枝末节。——爱因斯坦 人类对自然规律的研究已经取得了不少进展&#xff0c;但是看起来研究清楚了原理&#xff0c;其实只是发现了更深…

【Windows】实现窗口子类化(基于远程线程注入)

目录 前言 原理解释 完整项目 相关文献 文章出处链接&#xff1a;[https://blog.csdn.net/qq_59075481/article/details/140334106] 前言 众所周知&#xff0c;DLL 注入有多种用途&#xff0c;如热修补、日志记录、子类化等。本文重点介绍使用 DLL 注入对窗口进行子类化。…

mysql中count的区别

count(1)和count(*) 从执行计划来看&#xff0c;count(1)和count(*)的效果是一样的当表的数据量大些时&#xff0c;对表分析之后&#xff0c;使用count(1)还要比使用count(*)用时多当数据量在1W以内时&#xff0c;count(1)会比count(*)的用时少&#xff0c;不过也差不多如果cou…

GOLLIE : ANNOTATION GUIDELINES IMPROVE ZERO-SHOT INFORMATION-EXTRACTION

文章目录 题目摘要引言方法实验消融 题目 Gollie&#xff1a;注释指南改进零样本信息提取 论文地址&#xff1a;https://arxiv.org/abs/2310.03668 摘要 大型语言模型 (LLM) 与指令调优相结合&#xff0c;在泛化到未见过的任务时取得了重大进展。然而&#xff0c;它们在信息提…

又上热搜!曝iPhone 16将支持40W快充

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 7月9日晚&#xff0c;微博话题“iPhone16系列或将支持40W快充”上了热搜榜&#xff0c;这已经是iPhone 16系列第N次上热搜了。 据爆料&#xff0c;iPhone 16系列充电功率将提升至40W&#xff0c;并且…

Java自己实现动态数组

数组是由一组元素&#xff08;值或变量&#xff09;组成的数据结构&#xff0c;每个元素有至少一个索引或键来标识。 数组内的元素是连续存储的&#xff0c;所以数组中元素的地址&#xff0c;可以通过其索引计算出来 空间占用 Java 中数组结构为 8 字节 markword 4 字节 cl…

米家立式学习灯怎么样?书客、米家、孩视宝三款护眼大路灯巅峰PK!

米家立式学习灯怎么样?不知从什么时候开始&#xff0c;青少年成为了近视重灾区&#xff0c;主要促成近视的原因有长时间接触电子产品、学习时的不正确姿势、不良的灯光环境等&#xff0c;除了减少电子产品的使用以及多室外活动之外&#xff0c;剩下的就是室内孩子经常学习的光…

全球首款集成GPT-4o的智能眼镜AirGo Vision:AI眼镜的未来

引言 在人工智能和大模型技术迅猛发展的今天&#xff0c;AI硬件产品逐渐走入人们的生活。继Meta Ray-Ban智能眼镜之后&#xff0c;Solos公司在最近的香港智能眼镜峰会上发布了全球首款集成GPT-4o的智能眼镜AirGo Vision。本文将深入探讨这款AI智能眼镜的功能、技术特点以及其在…

侯捷C++面向对象高级编程(下)-2-non-explicit one argument constructor

1.构造函数 构造函数: Fraction(int num, int den 1) 初始化分子和分母&#xff0c;允许指定分子 num 和可选的分母 den。默认情况下&#xff0c;分母为 1。 加法运算符重载: Fraction operator(const Fraction& f) 重载了加法运算符 。这使得两个 Fraction 对象可以通过 …

Qt 异步实现事件的定时执行 - QTimer和QThread的联合使用

异步实现事件的定时执行 - QTimer和QThread的联合使用 引言一、核心源码二、其信号和槽函数简述三、定时器及其moveToThread简述 引言 在 Qt 中&#xff0c;如果想要定时执行某些事件或函数&#xff0c;通常会使用 QTimer 类。QTimer 允许设置一个时间间隔&#xff0c;当这个时…

echarts使用自定义图形实现3D柱状图

先看下效果吧 实现思路 使用graphic创建并注册自定义图形。根据每组的数据值&#xff0c;得到一个对应的点&#xff0c;从点出发用canvas绘制一组图形&#xff0c;分别为 顶部的菱形 const CubeTop echarts.graphic.extendShape({buildPath: function (ctx, shape) {const c1…

c++ primer plus 第15章友,异常和其他,15.3.8exception 类

c primer plus 第15章友&#xff0c;异常和其他,15.3.8exception 类 15.3.8exception 类 文章目录 c primer plus 第15章友&#xff0c;异常和其他,15.3.8exception 类15.3.8exception 类1.stdexcept异常类3.空指针和 new 15.3.8exception 类 C异常的主要目的是为设计容错程序…

NVIDIA良心给显卡免费升级,只为挨更多的骂

起猛了&#xff0c;还真的以为 NVIDIA 良心发现了。 众所周知&#xff0c;英伟达对于咱们普通游戏玩家向来不屑一顾。只因为游戏业务在 NVIDIA 收入中占比较少。 在最新的 40 系显卡 RTX 4070 Ti Super 显卡中&#xff0c;NVIDIA悄悄给它来了一次核心「升级」&#xff0c;将原…

ARM学习(29)NXP 双coreMCU IMX1160学习----NorFlash 启动引脚选择

ARM学习&#xff08;28&#xff09;NXP 双coreMCU IMX1160学习----NorFlash 启动引脚选择 1、多种启动方式介绍 IMX1166 支持多组flexSPI 引脚启动&#xff0c;FlexSPI1以及FlexSPI2&#xff0c;通过boot cfg可以切换FlexSPI得实例。 每个实例又支持多组引脚&#xff0c;总共…

Subclass-balancing Contrastive Learning for Long-tailed Recognition

Subclass-balancing Contrastive Learning for Long-tailed Recognition 核心公式解析温度参数 τ \tau τ的作用公式5解析 核心公式解析 L S B C L − ∑ i 1 N ( 1 ∣ M ~ i ∣ ∑ z p ∈ M ~ i log ⁡ exp ⁡ ( z i ⋅ z p ⊤ / τ 1 ) ∑ z a ∈ V ~ i exp ⁡ ( z i ⋅ z…

LiteOS增加执行自定义源码

开发过程注意事项&#xff1a; 源码工程路径不能太长 源码工程路径不能有中文 一定要关闭360等杀毒软件&#xff0c;否则编译的打包阶段会出错 增加自定义源码的步骤: 1.创建源码目录 2. 创建源文件 新建myhello目录后&#xff0c;再此目录下再新建源文件myhello_demo.c 3. 编…

程序员学长 | PyCaret,一个超强的 python 库

本文来源公众号“程序员学长”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;PyCaret&#xff0c;一个超强的 python 库 今天给大家分享一个超强的 python 库&#xff0c;PyCaret。 https://github.com/pycaret/pycaret 简介 …

[论文笔记]RAPTOR: RECURSIVE ABSTRACTIVE PROCESSING FOR TREE-ORGANIZED RETRIEVAL

引言 今天带来又一篇RAG论文笔记&#xff1a;RAPTOR: RECURSIVE ABSTRACTIVE PROCESSING FOR TREE-ORGANIZED RETRIEVAL。 检索增强语言模型能够更好地适应世界状态的变化并融入长尾知识。然而&#xff0c;大多数现有方法只能从检索语料库中检索到短的连续文本片段&#xff0…