让运维无忧,在实战中分析检验报告功能的实施方案

小夏 科技 更新 2024-03-08

随着大数据技术的发展和信息安全要求的提高,数据规模的不断扩大给数据运维带来了严峻的挑战。 面对海量数据带来的沉重管理压力,运维人员面临效率瓶颈,人力成本不断上升,单纯依靠扩容运维团队解决问题已不再可行。

由此可见,智能化、高效化、便捷化是运维发展的必然方向。 袋鼠云的检测报告功能就是为了实现这一目标而设计的,并提供优化的解决方案。

什么是检验报告?

检查报告是指对某个系统或设备进行全面检查,并将检查结果和建议整理成报告的过程。 检查报告通常用于评估系统或设备的健康状况和性能,并为发现问题、优化系统、提高效率和降低故障率提供参考。

本文将详细阐述检验报告的功能和实施方案,以期为有此类需求的用户提供实用参考。

自定义布局。

可以拖放报表中的面板以更改布局。

在拖拽过程中,拖拽区域受到限制,只允许拖拽同一个父级,不允许跨目录移动,不允许改变目录的级别,比如将一级目录移动到另一个一级目录,成为二级目录。

目录可以通过收缩来扩展。

可以通过收缩来扩展内容列表,收缩时隐藏所有子面板,展开时显示所有子面板。

移动目录时,子面板会跟随移动。

更改目录后,更新右侧的目录面板。

生成目录号。

右侧的目录树。

生成目录号。

支持锚点滚动。

支持扩展和收缩。

链接到左侧的报告。

数据面板。 根据日期范围获取指标数据。

以图表的形式显示指标信息。

查看详细信息并删除。

每个面板的请求设计都支持刷新请求。

面板导入。 计算目录中选择的面板数。

导入新面板时,无法销毁现有布局,新面板只能跟随旧面板。

导入已有面板时,需要对数据进行对比,如果数据发生变化,则需要再次获取最新数据。

救。 在保存之前,与布局相关的所有操作都是临时的,包括导入面板。 只有点击保存后,才会将当前数据提交到后端保存。

支持 PDF 和 Word 导出。

那么,这套检验报告功能是如何实现的呢? 下面将介绍数据结构设计、组件设计、目录、面板等。

让我们看一下使用扁平结构下的图表:

在扁平化结构中,只需要找到下一行面板即可确定子级,多级目录也是如此,但一级目录需要额外的处理。

扁平化结构实现起来相对简单,但为了满足特定需求,它限制了目录的拖拽。 限制目录需要面板的清晰层次结构,很明显,树结构可以非常恰当地清晰地描述数据层次结构。

它不同于传统的组件编程。 该实现将呈现和数据处理分为两部分:

React 组件:主要负责页面渲染。

class :负责数据的处理。

dashboardmodel

class dashboardmodel
panelmodel

class panelmodel
每个仪表盘组件对应一个仪表盘模型,每个面板组件对应一个面板模型。

React 组合基于类实例中的数据进行渲染。 实例一旦投入生产,就不会轻易被销毁或引用地址被更改,从而防止依赖实例数据进行渲染的 react 组件触发更新渲染。

我们需要一种方法,让我们在实例中的数据发生变化后手动触发组件的更新渲染。

组件呈现控件。

由于我们之前使用过 hooks 组件,因此与类组件不同,该组件可以通过调用 forceupdate 方法触发。

在 React18 中,有一个名为 usesyncexternalstore 的新功能,它允许我们订阅外部数据并在数据发生变化时触发组件的渲染。

实际上,usesyncexternalstore 通过在内部维护一个状态来触发组件渲染,当状态值发生变化时,会导致外部组件渲染。

考虑到这一点,我们简单地实现了一个触发组件渲染的 useforceupdate 方法。

export function useforceupdate()
虽然实现了 useforceupdate,但在实际使用过程中,需要在组件被销毁时删除该事件。 UseSyncExternalStore 已在内部实现,您可以直接使用它。

usesyncexternalstore(dashboard?.subscribe ??=>
要更新面板布局数据,可以使用面板映射准确定位对应的面板,并进一步调用其 UpdateGridPOS 方法进行布局更新操作。

至此,我们才刚刚完成了面板本身数据的更新,还需要执行仪表盘的 sortpanelssbygridpos 方法对所有面板进行排序。

class dashboardmodel else }// ..
面板拖动范围。

当前拖拽范围为整个仪表盘,可随意拖拽,绿色为仪表盘的可拖拽区域,灰色为面板。 如下:

如果需要限制,需要将其更改为结构,如下图所示:

在原来的基础上,将目录划分为多个单元,绿色为整体可移动区域,黄色为一级目录块,可在绿色区域拖拽,拖拽时可拖动整个黄色块,紫色为二级目录块,可在当前黄色区域内拖拽, 并且不能与当前黄色块分离,灰色面板只能拖拽到当前目录下。

需要在原有数据结构的基础上进行转换:

class panelmodel
面板的进口设计。

后端返回的数据是一棵带有**级别的树,我们得到后,维护成三个map:modulemap、dashboardmap和panelmap。

import from 'react';export interface module export interface dashboard export interface panel type expr = ;export const dashboardcontext = createcontext();
当我们渲染一个模块时,我们会遍历 modulemap 并通过模块内的仪表板信息找到辅助目录。

选择辅助目录后,通过辅助目录仪表板的面板找到相关面板,并将其渲染到右侧区域。

对于这 3 个地图的操作,维护在 usehandledata,导出:

面板选择回填。 

进入面板管理时,我们需要回填选中的面板,可以通过gets**emodel获取当前检测报告的信息,并将对应的选定信息存储在selectpanel中。

现在我们只需要更改选择面板中的值即可选择相应的面板。

面板检查重置。

直接遍历仪表板地图并重置每个 SelectPanels。

dashboardmap.foreach((dashboard) => )
面板插入。

选择面板后,插入所选面板时有几种情况:

这次还选择了检测报告的原始面板,插入时会对比数据,如果数据发生变化,需要根据最新的数据源信息进行请求和渲染。

如果这次没有选择检查报告的原始面板,则在插入时需要删除未选择的面板。

插入新选定的面板时,该面板将插入到相应目录的末尾。

添加新面板需要,类似于目录收缩,但需要:

目录收缩仅适用于一个目录,而插入仅适用于整个目录。

目录收缩是直接从子节点向上冒泡,而插入是从根节点开始向下,插入完成后,根据最新的目录数据更新布局。

class dashboardmodel ** 将当前数据与传入数据进行对比,以传入数据为标准,按当前顺序进行修改 * param panels * updatepanels(panels: paneldata)return false;  }panelmap.foreach((panel) => )addpanel(paneldata: any) )resetdashboardgridpos(panels: panelmodel = this.panels) else const gridpos = ; panel.updategridpos();sumh += h; }return sumh; }class panelmodel this.restoremodel(panel); if (this.dashboard) this.needrequest &&this.forceupdate();
小组请求。

needrequest 控制面板是否需要发出请求,如果为 true,则下次面板渲染时会请求请求,并且请求的处理也放在 PanelModel 中。

import from '../../components/useparams';class panelmodel as params; }request = ()=> ;fetchdata = async (params: params) => ;fetch = async (params: params) => }
我们的数据渲染组件一般是深层次的,请求时需要时间间隔等外部参数,使用全局变量来维护这些参数。 上层组件使用 change 来修改参数,数据渲染组件根据抛出的参数发出请求。

export let params: params = ;function useparams() as params; }return ;}export default useparams;
面板刷新。

从根节点向下搜索,找到叶节点,并触发相应的请求。

class dashboardmodel );class panelmodel else }rerequest()
删除面板。

对于面板的删除,我们只需要在对应的 dashboard 下进行删除,删除后会改变当前的 dashboard 高度,这与下面的目录收缩相同。

class dashboardmodel ** 基于传入面板的过滤器 * 参数面板 要过滤的面板数组 * 返回过滤的面板 * filterpanelsbypanels(panels: panelmodel) 。
保存面板。

与后端沟通后,当前检测报告的数据结构由前端维护,最后给后端一个字符串。 获取当前面板数据,并使用 json 进行转换。

从面板获取信息的过程从根节点开始,遍历到叶节点,然后从叶节点开始,逐层返回,这就是回溯的过程。

class dashboardmodel // ..最终保存所需的属性,其他属性不需要 const persistedproperties: = ; class panelmodel ; for (const property in this) model.panels = this.dashboard?.gets**emodel() return model; }// ..
面板详细信息显示。

在查看面板时,可以修改时间等,这些操作会影响实例中的数据,因此需要在细节中区分原始数据和数据。

通过重新生成原始面板数据的 panelmodel 实例,对此实例的任何操作都不会影响原始数据。

const model = panel.gets**emodel();const newpanel = new panelmodel();创建一个新实例 seteditpanel(newpanel); 设置为详细信息
在DOM上,详情页面是绝对定位的,上面覆盖着检验报告。

目录会缩小和扩展。

维护“目录”面板的折叠属性,以控制面板的隐藏显示。

类 PanelModel 组件呈现
当您缩小和展开目录时,您将更改其高度,现在您需要将此更改的高度同步到下一级的仪表板。

下一个级别需要做的是我们如何控制目录。 如下所示,控制第一个辅助目录的收缩:

当面板发生变化时,需要通知父面板进行相应的操作。

添加 top 以获取父实例。

class dashboardmodel this.panels = [.this.panels];顶级仪表板容器没有 top thistop?.changeheight(h); this.forceupdate();// ..class panelmodel ** param h changed height * changeheight(h: number) ) change the height of the own panel thistop.togglepanelheight(this, h);触发父项更改此项forceupdate();// ..
组织流程和冒泡类型,一直到顶级仪表板。 展开的宫缩也是如此。

呈现目录的右侧。

锚点序列号。

锚点使用锚点 + id 来选择组件。

序数是按渲染生成的。

渲染使用发布-订阅方法进行管理。

每当仪表盘更改布局时,都需要同步更新目录右侧,任何面板都可能需要触发目录右侧进行更新。

如果我们以在实例中维护相应组件的渲染事件为例,则存在两个问题:

需要做区分,比如刷新面板时,不需要触发右侧目录的渲染。

每个面板如何订阅右侧目录中的呈现事件。

最后,采用发布-订阅者模型来管理事件。

class eventemitter ;** 订阅 * 参数事件 * 参数 fn 订阅事件** 返回 * on(event: string, fn: (=> void) { ** 取消订阅 * 参数事件 订阅事件 * 参数 fn 订阅事件** 返回 * off(event: string, fn: (=> void) { ** publish * 参数事件 订阅事件 * 参数参数 额外参数 * 返回 * emit(event: string, ..)arg: any)eventemitter.emit(this.key);触发面板的订阅事件事件发射器emit(global);触发顶级订阅事件,包括对右侧目录的更新
PDF 导出由 html2canvas + jspdf 实现。 需要注意的是,当PDF太长时,内容区域可能会被拆分。 我们需要手动计算面板的高度,是否超过当前文档,如果超过当前文档,我们需要提前划分,添加到下一页,并尽可能地拆分目录面板和数据面板。

Word 导出是通过 html-docx-js 实现的,它需要保留目录的结构,并且可以在面板下添加摘要,这需要我们单独转换每个面板。

实现的思路是按照面板遍历,找到目录面板就是插入带有 h1 和 h2 标签的面板,如果是数据面板,在数据面板中维护一个 ref 属性,这样我们就可以获取当前面板的 dom 信息,按照这个进行转换, 并以 base64 格式使用(word 仅支持 base64 插入)。

当前版本的检查报告仍处于起步阶段,尚未达到最终形式,但随着我们不断迭代和升级,我们将逐步添加包括摘要描述在内的一些功能。

采用当前方法后,如果以后需要调整UI界面,只需要修改相关的UI组件,如添加饼图、**等。 对于数据交互级别的更改,只需转到 dashboardmodel 和 panelmodel 即可进行必要的更新。 此外,我们可以针对特定场景灵活提取特殊类,确保整个迭代过程更加模块化和高效。

相似文章

    2023 确定性运营白皮书 让运营成为智能世界转型的加速器

    今天分享的是O M行业研究报告 确定性运维 稳定可靠篇,让运维成为智能世界转型的加速器 报告由华为云制作 研究报告内容摘要如下 稳定性和可靠性 的主要挑战。随着业务的快速迭代和敏捷发展,传统运维面临软件快速上线的挑战,模糊了运维与研发的界限,业务上线速度与现网稳定性之间的矛盾难以调和。华为云将这些挑...

    智能运维:未来运维的革命

    随着科学技术的进步,特别是人工智能和大数据技术的发展,传统的运维方式逐渐演变为智能运维方式。智能运维,利用机器学习 数据分析等技术,实现IT系统的自动化管理和维护,不仅提高了运维效率,还降低了人为失误的风险。智能运维的核心在于高质量的维护和自动化处理。通过持续监控系统状态,智能运维能够解决潜在问题并...

    传统IT运维管理与云运维对比分析

    在追求高效稳定的IT系统运行中,运维管理起着至关重要的作用。传统的IT运维管理依赖于物理服务器和人工操作,而云运维则依靠云计算技术提供更灵活 更自动化的服务。本文将从成本 效率 可靠性等方面对这两种模型进行比较。首先,从成本角度来看,传统的IT运维需要大量的初始投资,包括硬件采购 维护和运营成本。相...

    维谛技术 (Vertiv) 的户外电源产品让您无后顾之忧地享受户外生活

    随着人们对户外活动的热爱与日俱增,对电力的需求也在增加 维谛技术 Vertiv 的户外电源产品,以其卓越的性能和专业的服务,成为户外活动和应急救援领域的明星,让您无忧享受户外生活。.性能卓越,享受户外生活。维谛技术 Vertiv 的户外电源产品采用先进的锂电池技术,具有容量大 能量密度高 充电快等特...

    传统运维与智能运维性能对比

    随着信息技术的飞速发展,运维管理作为保证系统稳定运行的关键环节,直接关系到企业IT系统的健康。传统的运维依赖于人工处理大量的监控 维护和故障处理任务,但智能运维管理 IOM 的兴起标志着运维管理进入了一个新时代。首先,在效率方面,智能运营利用人工智能 AI 和机器学习 ML 等自动化工具和技术来实现...