Oracle监听日志分析
moboyou 2025-04-09 13:40 24 浏览
1.把监听日志和脚本放到一个目录
yuyuz-mac:analyze-listenerlog yuyuz$ pwd
/Users/yuyuz/python/analyze-listenerlog
yuyuz-mac:analyze-listenerlog yuyuz$ ls
listener.log lsnrlog.py
2.执行脚本
yuyuz-mac:analyze-listenerlog yuyuz$ python lsnrlog.py
提取到的成功时间戳数量: 1920
提取到的失败时间戳数量: 15081
提取到的总时间戳数量: 17001
HTML 文件生成成功
yuyuz-mac:analyze-listenerlog yuyuz$ ls
connection_analysis.html listener.log lsnrlog.py
3.查看结果
支持区域放大/查看数据/线图柱图切换
4.代码
import re
from datetime import datetime
from pyecharts import options as opts
from pyecharts.charts import Line, Page
def parse_log(log_text):
"""
解析日志文本,提取包含CONNECT_DATA字段行的时间戳、SERVICE、HOST和IP,并区分成功和失败连接
:param log_text: 日志文本
:return: 成功时间戳列表、失败时间戳列表、总时间戳列表、SERVICE信息列表、HOST信息列表、IP信息列表
"""
success_timestamps = []
failure_timestamps = []
total_timestamps = []
services = []
hosts = []
ips = []
pattern = r'(\d{2}-[A-Z]{3}-\d{4} \d{2}:\d{2}:\d{2})|(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})'
service_pattern = r'SERVICE_NAME=(\w+)'
host_pattern = r'HOST=(\w+)'
ip_pattern = r'HOST=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
for line in log_text.split('\n'):
if 'CONNECT_DATA' in line:
match = re.search(pattern, line)
if match:
timestamp_str = match.group(0)
try:
if '-' in timestamp_str[0:3]:
timestamp = datetime.strptime(timestamp_str, '%d-%b-%Y %H:%M:%S')
else:
timestamp = datetime.strptime(timestamp_str, '%Y-%m-%dT%H:%M:%S')
total_timestamps.append(timestamp)
if line.strip().endswith('0'):
success_timestamps.append(timestamp)
else:
failure_timestamps.append(timestamp)
service_match = re.search(service_pattern, line)
host_match = re.search(host_pattern, line)
ip_match = re.search(ip_pattern, line)
service = service_match.group(1) if service_match else None
host = host_match.group(1) if host_match else None
ip = ip_match.group(1) if ip_match else None
services.append((timestamp, service))
hosts.append((timestamp, host))
ips.append((timestamp, ip))
except ValueError:
print(f"无法解析时间戳: {timestamp_str}")
print(f"提取到的成功时间戳数量: {len(success_timestamps)}")
print(f"提取到的失败时间戳数量: {len(failure_timestamps)}")
print(f"提取到的总时间戳数量: {len(total_timestamps)}")
return success_timestamps, failure_timestamps, total_timestamps, services, hosts, ips
def count_connections(timestamps, interval):
"""
统计不同时间间隔的连接数
:param timestamps: 时间戳列表
:param interval: 时间间隔,如 'H' 表示小时,'T' 表示分钟,'S' 表示秒
:return: 时间间隔和对应的连接数
"""
counts = {}
for timestamp in timestamps:
if interval == 'H':
key = timestamp.replace(minute=0, second=0, microsecond=0).strftime('%Y-%m-%d %H:00:00')
elif interval == 'T':
key = timestamp.replace(second=0, microsecond=0).strftime('%Y-%m-%d %H:%M:00')
elif interval == 'S':
key = timestamp.replace(microsecond=0).strftime('%Y-%m-%d %H:%M:%S')
if key in counts:
counts[key] += 1
else:
counts[key] = 1
return sorted(counts.items())
def count_by_attribute(data, interval, attribute):
"""
按指定属性统计不同时间间隔的连接数
:param data: 包含时间戳和属性的元组列表
:param interval: 时间间隔,如 'H' 表示小时,'T' 表示分钟,'S' 表示秒
:param attribute: 属性名称
:return: 以属性为键,时间间隔和对应连接数为值的字典
"""
counts = {}
for timestamp, attr in data:
if attr is None:
continue
if interval == 'H':
key = timestamp.replace(minute=0, second=0, microsecond=0).strftime('%Y-%m-%d %H:00:00')
elif interval == 'T':
key = timestamp.replace(second=0, microsecond=0).strftime('%Y-%m-%d %H:%M:00')
elif interval == 'S':
key = timestamp.replace(microsecond=0).strftime('%Y-%m-%d %H:%M:%S')
if attr not in counts:
counts[attr] = {}
if key in counts[attr]:
counts[attr][key] += 1
else:
counts[attr][key] = 1
for attr in counts:
counts[attr] = sorted(counts[attr].items())
return counts
def create_line_chart(success_data, failure_data, total_data, interval):
"""
创建线图
:param success_data: 成功连接的时间间隔和对应的连接数
:param failure_data: 失败连接的时间间隔和对应的连接数
:param total_data: 总连接的时间间隔和对应的连接数
:param interval: 时间间隔,如 '小时','分钟','秒'
:return: 线图对象
"""
x_data = sorted(set([item[0] for item in success_data + failure_data + total_data]))
success_y_data = [next((item[1] for item in success_data if item[0] == x), 0) for x in x_data]
failure_y_data = [next((item[1] for item in failure_data if item[0] == x), 0) for x in x_data]
total_y_data = [next((item[1] for item in total_data if item[0] == x), 0) for x in x_data]
line = (
Line(init_opts=opts.InitOpts(bg_color="#f5f5f5", width="100%"))
.add_xaxis(x_data)
.add_yaxis(
series_name=f"成功连接总数/{interval}",
y_axis=success_y_data,
label_opts=opts.LabelOpts(is_show=False),
linestyle_opts=opts.LineStyleOpts(width=2, color="#228B22"),
symbol="circle",
symbol_size=6,
itemstyle_opts=opts.ItemStyleOpts(color="#228B22")
)
.add_yaxis(
series_name=f"失败连接总数/{interval}",
y_axis=failure_y_data,
label_opts=opts.LabelOpts(is_show=False),
linestyle_opts=opts.LineStyleOpts(width=2, color="#FF0000"),
symbol="circle",
symbol_size=6,
itemstyle_opts=opts.ItemStyleOpts(color="#FF0000")
)
.add_yaxis(
series_name=f"总连接数/{interval}",
y_axis=total_y_data,
label_opts=opts.LabelOpts(is_show=False),
linestyle_opts=opts.LineStyleOpts(width=2, color="#FF6347"),
symbol="circle",
symbol_size=6,
itemstyle_opts=opts.ItemStyleOpts(color="#FF6347")
)
.set_global_opts(
title_opts=opts.TitleOpts(
title=f"连接情况统计/{interval}",
title_textstyle_opts=opts.TextStyleOpts(font_size=20, color="#333")
),
toolbox_opts=opts.ToolboxOpts(is_show=True),
xaxis_opts=opts.AxisOpts(
name=interval,
axislabel_opts=opts.LabelOpts(rotate=45, font_size=12, color="#666"),
name_textstyle_opts=opts.TextStyleOpts(font_size=14, color="#333")
),
yaxis_opts=opts.AxisOpts(
name="连接数",
axislabel_opts=opts.LabelOpts(font_size=12, color="#666"),
name_textstyle_opts=opts.TextStyleOpts(font_size=14, color="#333")
),
tooltip_opts=opts.TooltipOpts(trigger="axis"),
legend_opts=opts.LegendOpts(
type_="scroll",
orient="vertical",
pos_left="right",
pos_top="middle",
textstyle_opts=opts.TextStyleOpts(font_size=8, color="#333")
)
)
)
return line
def create_attribute_line_chart(counts, interval, attribute):
"""
创建按属性统计的线图
:param counts: 以属性为键,时间间隔和对应连接数为值的字典
:param interval: 时间间隔,如 '小时','分钟','秒'
:param attribute: 属性名称
:return: 线图对象
"""
all_x_data = set()
for data in counts.values():
for x, _ in data:
all_x_data.add(x)
x_data = sorted(all_x_data)
line = Line(init_opts=opts.InitOpts(bg_color="#f5f5f5", width="100%"))
line.add_xaxis(x_data)
for attr, data in counts.items():
y_data = [next((item[1] for item in data if item[0] == x), 0) for x in x_data]
line.add_yaxis(
series_name=f"{attr}/{interval}",
y_axis=y_data,
label_opts=opts.LabelOpts(is_show=False),
linestyle_opts=opts.LineStyleOpts(width=2),
symbol="circle",
symbol_size=6
)
line.set_global_opts(
title_opts=opts.TitleOpts(
title=f"{attribute} 连接情况统计/{interval}",
title_textstyle_opts=opts.TextStyleOpts(font_size=20, color="#333")
),
toolbox_opts=opts.ToolboxOpts(is_show=True),
xaxis_opts=opts.AxisOpts(
name=interval,
axislabel_opts=opts.LabelOpts(rotate=45, font_size=12, color="#666"),
name_textstyle_opts=opts.TextStyleOpts(font_size=14, color="#333")
),
yaxis_opts=opts.AxisOpts(
name="连接数",
axislabel_opts=opts.LabelOpts(font_size=12, color="#666"),
name_textstyle_opts=opts.TextStyleOpts(font_size=14, color="#333")
),
tooltip_opts=opts.TooltipOpts(trigger="axis"),
legend_opts=opts.LegendOpts(
type_="scroll",
orient="vertical",
pos_left="right",
pos_top="middle",
textstyle_opts=opts.TextStyleOpts(font_size=8, color="#333")
)
)
return line
def main():
"""
主函数,从文件读取日志并生成包含多个线图的网页
"""
try:
with open('listener.log', 'r', encoding='utf-8') as file:
log_text = file.read()
success_timestamps, failure_timestamps, total_timestamps, services, hosts, ips = parse_log(log_text)
# 统计每小时、每分钟、每秒的成功、失败和总连接数
intervals = ['H', 'T', 'S']
interval_names = ['小时', '分钟', '秒']
page = Page()
for interval, interval_name in zip(intervals, interval_names):
hourly_success_data = count_connections(success_timestamps, interval)
hourly_failure_data = count_connections(failure_timestamps, interval)
hourly_total_data = count_connections(total_timestamps, interval)
hourly_chart = create_line_chart(hourly_success_data, hourly_failure_data, hourly_total_data, interval_name)
page.add(hourly_chart)
# 按SERVICE、HOST、IP统计并绘制线图
attributes = [('SERVICE', services), ('HOST', hosts), ('IP', ips)]
for attribute_name, attribute_data in attributes:
for interval, interval_name in zip(intervals, interval_names):
counts = count_by_attribute(attribute_data, interval, attribute_name)
chart = create_attribute_line_chart(counts, interval_name, attribute_name)
page.add(chart)
page.render("connection_analysis.html")
# 添加版权信息到 HTML 文件
copyright_info = '声明:仅用作兴趣爱好和测试使用,请勿商用,不承担任何商业责任。--张宇--'
with open('connection_analysis.html', 'a', encoding='utf-8') as f:
f.write(copyright_info)
print("HTML 文件生成成功")
except FileNotFoundError:
print("未找到 listener.log 文件,请确保文件存在。")
except Exception as e:
print(f"发生错误: {e}")
if __name__ == "__main__":
main()
- 上一篇:数据库中常用的数值函数
- 下一篇:DTrace 和 strace 概述
相关推荐
- 电子EI会议!投稿进度查
-
今天为大家推荐一个高性价比的电子类EI会议——IEEE电子与通信工程国际会议(ICECE2024)会议号:IEEE#62199截稿时间:2024年3月25日召开时间与地点:2024年8月15...
- 最“稳重”的滤波算法-中位值滤波算法的思想原理及C代码实现
-
在信号处理和图像处理领域,滤波算法是一类用于去除噪声、平滑信号或提取特定特征的关键技术。中位值滤波算法是一种常用的非线性滤波方法,它通过取一组数据的中位值来有效减小噪声,保留信号的有用特征,所以是最稳...
- 实际工程项目中是怎么用卡尔曼滤波的?
-
就是直接使用呀!个人认为,卡尔曼滤波有三个个关键点,一个是测量,一个是预测,一个是加权测量:通过传感器,获取传感器数据即可!预测:基于模型来进行数据预测;那么问题来了,如何建模?有难有易。加权:主要就...
- 我拿导弹公式算桃花,结果把自己炸成了烟花
-
第一章:学术圈混成“顶流”,全靠学生们把我写成段子最近总有人问我:“老师,您研究导弹飞行轨迹二十年,咋还顺带研究起月老红绳的抛物线了?”我扶了扶眼镜,深沉答道:“同志,导弹和爱情的本质都是动力学问题—...
- 如何更好地理解神经网络的正向传播?我们需要从「矩阵乘法」入手
-
图:pixabay原文来源:medium作者:MattRoss「机器人圈」编译:嗯~阿童木呀、多啦A亮介绍我为什么要写这篇文章呢?主要是因为我在构建神经网络的过程中遇到了一个令人沮丧的bug,最终迫...
- 电力系统EI会议·权威期刊推荐!
-
高录用率EI会议推荐:ICPSG2025(会议号:CFP25J66-PWR)截稿时间:2025年3月15日召开时间与地点:2025年8月18-20日·新加坡论文集上线:会后3个月内提交至S...
- EI论文写作全流程指南
-
推荐期刊《AppliedEnergy》是新能源领域权威EI/SCI双检索期刊,专注能源创新技术应用。刊号:ISSN0306-2619|CN11-2107/TK影响因子:11.2(最新数...
- JMSE投稿遇坑 实验结果被推翻
-
期刊基础信息刊号:ISSN2077-1312全称:JournalofMarineScienceandEngineering影响因子:3.7(最新JCR数据)分区:中科院3区JCRQ2(...
- 斩获国际特等奖!兰理工数学建模团队为百年校庆献礼
-
近日,2019年美国大学生数学建模竞赛(MCM-ICM)成绩正式公布。兰州理工大学数学建模团队再创佳绩,分别获得国际特等奖(OutstandingWinner)1项、一等奖(Meritorious...
- 省气象台开展人员大培训岗位大练兵学习活动
-
5月9日,省气象台组织开展首次基于Matlab编程语言的数值模式解释应用培训,为促进研究性业务发展,积极开展“人员大培训、岗位大练兵”学习活动起到了积极作用。此次培训基于实际业务需求,着眼高原天气特色...
- 嵌入式软件培训
-
培训效果:通过系统性的培训学习,理论与实践相结合,可以胜任相关方向的开发工作。承诺:七大块专业培训,可以任意选择其中感兴趣的内容进行针对性地学习,每期培训2个月,当期没学会,可免费学习一期。本培训内容...
- 轧机支承辊用重载中低速圆柱滚子轴承滚子修形探讨
-
摘 要:探讨了轧机支承辊用重载中低速圆柱滚子轴承滚子修形的理论和方法,确定关键自变量。使用Romax软件在特定载荷工况条件下对轴承进行数值模拟分析,确定关键量的取值范围。关键词:轧机;圆柱滚子轴承;滚...
- 数学建模EI刊,如何避雷?
-
---权威EI会议推荐会议名称:国际应用数学与工程建模大会(ICAMEM)截稿时间:2025年4月20日召开时间/地点:2025年8月15日-17日·新加坡论文集上线:会后2个月内由Sp...
- 制造工艺误差,三维共轭齿面怎样影响,双圆弧驱动的性能?
-
文/扶苏秘史编辑/扶苏秘史在现代工程领域,高效、精确的传动系统对于机械装置的性能和可靠性至关重要,谐波传动作为一种创新的机械传动方式,以其独特的特性在精密机械领域引起了广泛关注。在谐波传动的进一步优化...
- 测绘EI会议——超详细解析
-
【推荐会议】会议名称:国际测绘与地理信息工程大会(ICGGE)会议编号:71035截稿时间:2025年3月20日召开时间/地点:2025年8月15-17日·德国慕尼黑论文集上线:会后2个...
- 一周热门
- 最近发表
- 标签列表
-
- curseforge官网网址 (16)
- 外键约束 oracle (36)
- oracle的row number (32)
- 唯一索引 oracle (34)
- oracle in 表变量 (28)
- oracle导出dmp导出 (28)
- oracle 数据导出导入 (16)
- oracle两个表 (20)
- oracle 数据库 使用 (12)
- 启动oracle的监听服务 (13)
- oracle 数据库 字符集 (20)
- powerdesigner oracle (13)
- oracle修改端口 (15)
- 左连接 oracle (15)
- oracle 标准版 (13)
- oracle 转义字符 (14)
- asp 连接 oracle (12)
- oracle安装补丁 (19)
- matlab三维图 (12)
- matlab归一化 (16)
- matlab求解方程 (13)
- matlab坐标轴刻度设置 (12)
- matlab脚本 (14)
- matlab多项式拟合 (13)
- matlab阶跃函数 (14)