运行日志功能改造心得

网友投稿 519 2022-10-28

运行日志功能改造心得

运行日志功能改造心得

UMC通过控制k8s集群中的容器控制公司产品,在进行控制之前要能监视产品的动态。在实例监视中原有的运行日志功能只能显示一个容器的运行日志,而产品在k8s集群中可能拥有多个容器,会产生日志信息显示不完整且不方便对比的问题,需要对运行日志功能进行改造升级。从前期思路和知识要点的确认到编写设计再到功能实现和功能完善,本篇文档将对整个过程进行详细介绍。

1.前期准备

在进行功能改造之前,我们首先要确定设计运行日志的改造思路;其次思路确定后需要补充知识,对需要用到的知识进行大体了解;最后撰写设计,明确如何改造功能。

1.1总体思路

修改功能的大致过程就是总体思路,也就是说,在改造之前要想到修改功能需要使用哪些以前功能中就有的内容,根据功能中已有内容思考还需要添加哪些没有的内容,最后将这些想法清晰的分步写出来。

2.利用容器的心跳时间查看是否存在该容器,并判断出所有容器ID中正在运行的容器ID。

3.如同一页面中显示多个日志,需要根据容器ID的数量将页面划分区域。

4.利用WebSocket获取容器的实时信息,并显示在不同区域中。

1.2知识补充

根据总体思路学习改造功能的过程中可能会使用的知识点如下:

1.使用BootStrap中网格系统划分区域,网格系统可以根据class自动划分,最多划分12列

2.WebSocket 是 HTML5 提供的一种在单个 TCP 连接上进行全双工通讯的协议,使用WebSocket获取日志信息方法如下:

<%if (pageBean.getStringValue("wsReqURL") != null){%> var websocket = null; if('WebSocket' in window){ websocket = new WebSocket("<%=pageBean.getStringValue("wsReqURL")%>"); } else{ alert('Not support websocket') } websocket.onerror = function(){ setMessageInnerHTML("error"); }; websocket.onopen = function(event){ setMessageInnerHTML("connected!"); } websocket.onmessage = function(event){ setMessageInnerHTML(event.data); } websocket.onclose = function(){ setMessageInnerHTML("closed"); } window.onbeforeunload = function(){ websocket.close(); } function setMessageInnerHTML(innerHTML){ document.getElementById('message').innerHTML += innerHTML + '
'; $('body').parent().scrollTop($('body')[0].scrollHeight); }<%}%>

1.3撰写设计

根据总体思路和补充的知识撰写设计,设计是功能改造的根本和方向。设计中至少要包含:实现思路、技术要点、实现步骤等。

实现思路是总体思路的更加具体化,要比总体思路更加细化。

技术要点是知识补充的扩展,不仅扩展知识深度,还扩充知识的广度,罗列出可能使用到的知识点。

实现步骤包括页面设计和代码设计。

页面设计要至少包括页面中的重要展示信息和功能,如图所示:

代码设计中要包含原有代码,以及在原有代码上的改造思路。原代码如下:

public ViewRenderer prepareDisplay(DataParam param){ String instanceId = param.get("containerId"); if (StringUtil.isNotNullNotEmpty(instanceId)) { CommandManager commandManager = (CommandManager)this.lookupService("commandManager"); ViewLogCommand viewLogCommand = new ViewLogCommand(); viewLogCommand.setActionType(ViewLogCommand.StartActionType); CmdRequest cmdRequest = commandManager.buildCmdRequest(viewLogCommand); commandManager.publishToCommand(instanceId, cmdRequest); String serverName = this.getRequest().getServerName(); String scheme = this.getRequest().getScheme(); int port = this.getRequest().getServerPort(); String portSyntax = this.buildPortSyntax(port); String wsReqURL = null; if ("{ wsReqURL = "ws://"+serverName+portSyntax+"/UMC/monitor/" + instanceId + "/"+ MonitorResponse.ObjectTypes.RuntimeLog; } else { wsReqURL = "wss://"+serverName+portSyntax+"/UMC/monitor/" + instanceId + "/"+ MonitorResponse.ObjectTypes.RuntimeLog; } this.setAttribute("wsReqURL", wsReqURL); this.setAttribute("containerId", instanceId); this.setAttribute("GP_CODE", param.getString("GP_CODE")); ContainerManage containerManage = this.lookupService(ContainerManage.class); DataRow holderConInfoRecord = containerManage.getHolderConInfoRecord(instanceId); this.setAttributes(holderConInfoRecord); } return new LocalRenderer(getPage()); }

原代码中获取的是单个容器ID,并且构造WebSocket所需的wsReqURL,我们只需要获取该产品的多个容器ID,并构造多个wsReqURL,使得一一对应传输到前端。

2.功能实现

功能实现是根据已有设计进行功能改造,在改造过程中,首先要确定对象,确定容器是获取当前产品节点下所有容器ID;其次划分区域,我们使用网格系统将页面划分成多个小区域,每个小区域代表一个容器;最后通过WebSockey使用wsReqURL动态获取各个容器的日志。

2.1确定容器

如果页面中同时显示多个容器的日志,则需要获取多个容器ID。

获取当前环境下所有容器的信息List containerRows = containerManage.findContainerRecords("", "", envId, "");区分不同产品的容器信息if ((gpCode.equals(productCode))) {}使用心跳时间区分运行中的容器HeartBeatResult heartBeatResult = (HeartBeatResult)commandManager.retrieveCmdResult(HeartBeatCommand.class.getSimpleName(), containerId); if (heartBeatResult != null) { long heartBeatTime = heartBeatResult.getTimestamp(); containerRow.put("CON_HEART_BEAT_TIME", DateUtil.getDateByType(DateUtil.YYMMDDHHMISS_HORIZONTAL, new Date(heartBeatTime))); } else { if ("stop".equals(containerRow.getString("CON_STATE"))) { containerRow.put("CON_STATE", "unknown"); } }

根据获取的容器ID拼接wsReqURL,一个容器ID对应一条wdReqURL。

wsReqURL = "ws://"+serverName+portSyntax+"/UMC/monitor/" + instanceId + "/"+ MonitorResponse.ObjectTypes.RuntimeLog;

2.2区域划分

由于容器数量是动态的,每个产品下的容器个数可能都不相同,所以在区域划分时不能使用静态的,需要根据容器数量创建不同数量的div。

根据容器日志的数量循环创建div,以区分不同容器<%for(int i=0;i= gpContainerLogs.size()){ break; } %> var childDiv1 = $('

'); parentDiv.append(childDiv1);}

2.3动态获取

在划分好区域后,需要根据容器ID区分不同WebSocket,WebSocket获取对应容器的日志信息。

<% if (gpContainerLogs.get(i+1).getString("wsReqURL") != null){ %> var websocket<%=i+1%> = null; if('WebSocket' in window){ websocket<%=i+1%> = new WebSocket("<%=gpContainerLogs.get(i+1).getString("wsReqURL")%>"); } else{ alert('Not support websocket') } websocket<%=i+1%>.onerror = function(){ setMessageInnerHTML<%=i+1%>("error"); }; websocket<%=i+1%>.onopen = function(event){ setMessageInnerHTML<%=i+1%>("connected!"); } websocket<%=i+1%>.onmessage = function(event){ setMessageInnerHTML<%=i+1%>(event.data); } websocket<%=i+1%>.onclose = function(){ setMessageInnerHTML<%=i+1%>("closed"); } window.onbeforeunload = function(){ websocket<%=i+1%>.close(); } function setMessageInnerHTML<%=i+1%>(innerHTML){ document.getElementById('son<%=i+1%>').innerHTML += innerHTML + '
'; $('#son<%=i+1%>').scrollTop($('#son<%=i+1%>').scrollHeight); } <%}%>

3.功能完善

在改造功能后,可能会有许多bug,需要多测试,发现其中的功能问题并完善。

3.1功能问题

测试时发现的问题如下:

1.当容器个数为奇数时,jsp页面会报错,错误描述:index超出界限异常。

3.2补充完善

当容器个数为奇数时,jsp页面报错。这个问题是因为判断奇数和偶数时,js中的判断无法限制js中的java代码,即使容器个数是奇数,也会运行偶数情况下的java代码,导致超限。在js中的java代码添加奇数和偶数判断即可。

4.心得体会

在改造运行日志的过程中,在知识方面收获了WebSocket、网格系统和动态创建页面元素的相关知识;在意识方面了解到做事要反复确认、反复修改,争取做到更好。

4.1知识收获

知识方面收获了很多,了解到WebSocket的简单使用方法和原理,以及WebSocket相对于轮询和Ajax在实时获取信息方面的优势;学会使用BootStrap的网格系统对div分区,在js和html方面多了一份积累。

4.2意识方法

意识方面,深切体会到设计在功能开发中的重要性,设计是功能开发的方向,无论做什么工作都应该先制定一个设计,避免在工作过程中走弯路;在做一项工作时要多和领导交互,避免走错方向,在时间允许的情况下多做测试和完善。

4.3工作总结

运行日志功能改造是我第一次从设计开始做的工作任务,在这次工作中收获了许多,有很多内容是我以前没有思考过的。在编写设计时就发生了准备的技术要点不充足,做到一半再去查找资料的问题,在之后的工作中还是要多思考,即使由别人写设计,也要思考设计中内容是否正确,同时在考虑问题时要发散思维,每次发散一点点到最后考虑问题时就会很全面。

本篇文档对于改造功能做简单阐述,文档的总体思路不仅适用于功能开发还适用于其他工作,不过最重要的还是在做工作量较大的工作时要先做设计,避免自己在工作过程中跑偏。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:ThinkPHP5——为API开发而设计的高性能PHP框架
下一篇:MySQL数据库性能优化
相关文章

 发表评论

暂时没有评论,来抢沙发吧~