package com.jjt.biz.service.impl; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.jjt.biz.domain.*; import com.jjt.biz.mapper.BizObjMetricsMapper; import com.jjt.biz.service.*; import com.jjt.common.utils.DateUtils; import com.jjt.common.utils.IntervalUtil; import com.jjt.common.utils.StringUtils; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; /** * 业务对象指标Service业务层处理 * * @author jjt * @date 2024-08-09 */ @Service public class BizObjMetricsServiceImpl implements IBizObjMetricsService { @Resource private BizObjMetricsMapper bizObjMetricsMapper; @Resource private IMetricsTplDetailService detailService; @Resource private IBizObjPpService ppService; @Resource private IBizObjService objService; @Resource private IBizObjAppService appService; @Resource private IPinpointService pinpointService; @Resource private IPrometheusService prometheusService; @Resource private IBizObjTplService objTplService; @Resource private SqlSessionFactory factory; @Resource private IAlarmRecordService alarmRecordService; /** * 查询业务对象指标 * * @param objMetricsId 业务对象指标主键 * @return 业务对象指标 */ @Override public BizObjMetrics selectBizObjMetricsByObjMetricsId(Long objMetricsId) { return bizObjMetricsMapper.selectBizObjMetricsByObjMetricsId(objMetricsId); } /** * 查询业务对象指标列表 * * @param bizObjMetrics 业务对象指标 * @return 业务对象指标 */ @Override public List selectBizObjMetricsList(BizObjMetrics bizObjMetrics) { return bizObjMetricsMapper.selectBizObjMetricsList(bizObjMetrics); } /** * 新增业务对象指标 * * @param bizObjMetrics 业务对象指标 * @return 结果 */ @Override public int insertBizObjMetrics(BizObjMetrics bizObjMetrics) { bizObjMetrics.setCreateTime(DateUtils.getNowDate()); return bizObjMetricsMapper.insertBizObjMetrics(bizObjMetrics); } /** * 修改业务对象指标 * * @param bizObjMetrics 业务对象指标 * @return 结果 */ @Override public int updateBizObjMetrics(BizObjMetrics bizObjMetrics) { //插入数据记录表 bizObjMetrics.setUpdateTime(DateUtils.getNowDate()); return bizObjMetricsMapper.updateBizObjMetrics(bizObjMetrics); } /** * 批量删除业务对象指标 * * @param objMetricsIds 需要删除的业务对象指标主键 * @return 结果 */ @Override public int deleteBizObjMetricsByObjMetricsIds(Long[] objMetricsIds) { return bizObjMetricsMapper.deleteBizObjMetricsByObjMetricsIds(objMetricsIds); } /** * 删除业务对象指标信息 * * @param objMetricsId 业务对象指标主键 * @return 结果 */ @Override public int deleteBizObjMetricsByObjMetricsId(Long objMetricsId) { return bizObjMetricsMapper.deleteBizObjMetricsByObjMetricsId(objMetricsId); } /** * 选择指标,除去当前对象已选择的 * * @param objId 对象ID * @return 结果 */ @Override public List selectMetricsDefList(Long objId) { return bizObjMetricsMapper.selectMetricsDefList(objId); } /** * 添加指标 * * @param objId 对象ID * @param metricsIds 指标IDS * @return 结果 */ @Override public int insertMetricsDetails(Long objId, Long[] metricsIds) { BizObj obj = objService.selectBizObjByObjId(objId); String suffix = "/" + obj.getObjAddr() + ":" + obj.getObjPort(); return bizObjMetricsMapper.insertMetricsDetails(objId, suffix, metricsIds); } /** * 通过objId查询列表 * * @param objId 对象ID * @return 结果 */ @Override public List selectBizObjMetricsListByObjId(Long objId) { BizObjMetrics obj = new BizObjMetrics(); obj.setObjId(objId); return selectBizObjMetricsList(obj); } /** * 通过对象和模板ID删除指标 * * @param objId 对象ID * @param tplId 模板ID */ @Override public void delete(Long objId, Long tplId) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("obj_id", objId); wrapper.eq("tpl_id", tplId); bizObjMetricsMapper.delete(wrapper); } /** * 通过模板ID批量插入指标 * * @param objId 对象ID * * @param tplId 模板ID */ @Override public void insertBatch(Long objId, Long tplId) { BizObj obj = objService.selectBizObjByObjId(objId); MetricsTplDetail query = new MetricsTplDetail(); query.setTplId(tplId); List list = detailService.selectMetricsTplDetailList(query); List objMetrics = new ArrayList<>(); list.forEach(d -> { if ("1".equals(d.getMetricsDef().getMetricsType()) && !d.getMetricsDef().getMetricsCode().startsWith("pp.jvm.")) { //如果是pinpoint,并且不是jvm参数 // 1.获取对象pinpoint组成 List pps = ppService.selectBizObjPpListByObjId(objId); for (BizObjPp pp : pps) { BizObjMetrics ms = new BizObjMetrics(); ms.setObjId(objId); ms.setTplId(tplId); ms.setMetricsId(d.getMetricsId()); ms.setMetricsName(pp.getPpName() + "/" + d.getMetricsDef().getMetricsName()); ms.setMetricsCode(pp.getPpName() + "/" + d.getMetricsCode()); ms.setAlarmLow(d.getAlarmLow()); ms.setAlarmMid(d.getAlarmMid()); ms.setAlarmHigh(d.getAlarmHigh()); objMetrics.add(ms); } } else { BizObjMetrics ms = new BizObjMetrics(); ms.setObjId(objId); ms.setTplId(tplId); ms.setMetricsId(d.getMetricsId()); ms.setMetricsName(d.getMetricsDef().getMetricsName() + "/" + obj.getObjAddr() + ":" + obj.getObjPort()); ms.setMetricsCode(d.getMetricsCode()); ms.setAlarmLow(d.getAlarmLow()); ms.setAlarmMid(d.getAlarmMid()); ms.setAlarmHigh(d.getAlarmHigh()); objMetrics.add(ms); } }); try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) { BizObjMetricsMapper mapper = sqlSession.getMapper(BizObjMetricsMapper.class); objMetrics.forEach(mapper::insertBizObjMetrics); sqlSession.commit(); } } /** * 根据模板指标修改 * * @param detail 模板指标 */ @Override public void update(MetricsTplDetail detail) { BizObjMetrics om = new BizObjMetrics(); om.setMetricsId(detail.getMetricsId()); om.setTplId(detail.getTplId()); List list = selectBizObjMetricsList(om); if (list.size() > 0) { //如果有则更新,没有则插入 UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.set("alarm_low", detail.getAlarmLow()); updateWrapper.set("alarm_mid", detail.getAlarmMid()); updateWrapper.set("alarm_high", detail.getAlarmHigh()); bizObjMetricsMapper.update(om, updateWrapper); } else { om.setAlarmLow(detail.getAlarmLow()); om.setAlarmMid(detail.getAlarmMid()); om.setAlarmHigh(detail.getAlarmHigh()); insertBizObjMetrics(om); } } /** * 根据模板指标删除 * * @param detail 模板指标 */ @Override public void del(MetricsTplDetail detail) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("metrics_id", detail.getMetricsId()); wrapper.eq("tpl_id", detail.getTplId()); bizObjMetricsMapper.delete(wrapper); } /** * 根据objId获取指标值 * * @param objId 对象ID */ @Override public void pinpointMetricsValue(Long objId) { BizObj bizObj = objService.selectBizObjByObjId(objId); if ("1".equals(bizObj.getObjType())) { // 获取应用程序的code BizObjApp app = appService.selectBizObjAppByAppId(bizObj.getAppId()); String appName = app.getAppCode(); LocalDateTime endTime = LocalDateTime.now(); LocalDateTime startTime = endTime.minusDays(2); //TODO 暂时取2天的值,不然难得搞 Map appMap = pinpointService.getApps(); String appType = appMap.get(appName); // 获取监控数据 Float tps = pinpointService.tps(appName, startTime, endTime); int openFiles = pinpointService.openFile(appName, startTime, endTime); Map jvmInfo = pinpointService.jvmMemory(appName, startTime, endTime); float heapUsage = (float) jvmInfo.get("usage"); int gcCount = (int) jvmInfo.get("gc"); JSONObject linkData = pinpointService.link(appName, appType, startTime, endTime); JSONArray nodeDataArray = linkData.getJSONObject("applicationMapData").getJSONArray("nodeDataArray"); List pinpointVOList = new ArrayList<>(); for (int i = 0; i < nodeDataArray.size(); i++) { JSONObject obj = nodeDataArray.getJSONObject(i); PinpointVO vo = new PinpointVO(obj); if (vo.getApplicationName().equals(appName)) { bizObj.setAccessTimes(vo.getTot()); objService.updateBizObj(bizObj); } else { pinpointVOList.add(vo); } } // 1.更新 BIZ_OBJ_PP 表 updateBizObjPpTable(objId, pinpointVOList); // 2.更新业务对象指标表 updateBizObjMetrics(objId, tps, openFiles, heapUsage, gcCount, pinpointVOList); } } /** * 根据objId获取prometheus指标值 * * @param objId 对象ID */ @Override public void prometheusMetricsValue(Long objId) { List mList = getAllMetricsForObjIdList(objId); List metricsToUpdate = new ArrayList<>(); mList.stream().filter(om -> !"1".equals(om.getMetricsDef().getMetricsType())).forEach(om -> { //非pinpoint Float value = prometheusService.query(om.getDataExp()); String alarmLevel = getAlarmLevel(value, om); if (alarmLevel != null) { insertAlarm(om, alarmLevel); } om.setDValue(BigDecimal.valueOf(value)); metricsToUpdate.add(om); }); // 更新所有需要更新的BizObjMetrics对象 metricsToUpdate.forEach(this::updateBizObjMetrics); } /** * 获取告警等级 * * @param value 值 * @param bizObjMetrics 指标对象 * @return */ private String getAlarmLevel(Float value, BizObjMetrics bizObjMetrics) { if (StringUtils.isNotEmpty(bizObjMetrics.getAlarmLow()) && IntervalUtil.inNumRange(value, bizObjMetrics.getAlarmLow())) { return "low"; } else if (StringUtils.isNotEmpty(bizObjMetrics.getAlarmMid()) && IntervalUtil.inNumRange(value, bizObjMetrics.getAlarmMid())) { return "mid"; } else if (StringUtils.isNotEmpty(bizObjMetrics.getAlarmHigh()) && IntervalUtil.inNumRange(value, bizObjMetrics.getAlarmHigh())) { return "high"; } return null; } /** * 添加告警记录 * * @param om 指标对象 * @param alarmLevel 告警等级 */ private void insertAlarm(BizObjMetrics om, String alarmLevel) { AlarmRecord record = new AlarmRecord(); record.setObjId(om.getObjId()); record.setObjMetricsId(om.getObjMetricsId()); record.setAlarmLevel(alarmLevel); alarmRecordService.insertAlarmRecord(record); } /** * 更新BIZ_OBJ_PP * * @param objId 对象ID * @param pinpointVOList PP组成 */ private void updateBizObjPpTable(Long objId, List pinpointVOList) { List existingPpList = ppService.selectBizObjPpListByObjId(objId); Set existingNames = existingPpList.stream() .map(BizObjPp::getPpName) .collect(Collectors.toSet()); pinpointVOList.stream() .filter(vo -> !existingNames.contains(vo.getApplicationName())) .forEach(vo -> { BizObjPp pp = new BizObjPp(); pp.setObjId(objId); pp.setPpKey(vo.getKey()); pp.setPpName(vo.getApplicationName()); pp.setPpType(vo.getCategory()); ppService.insertBizObjPp(pp); // 根据模板更新业务对象指标表 updateBizObjMetricsFromTemplate(objId, pp); existingPpList.add(pp); }); } /** * 根据模板更新业务对象指标表 * * @param objId 对象ID * @param pp pp对象 */ private void updateBizObjMetricsFromTemplate(Long objId, BizObjPp pp) { List templateList = objTplService.selectTplList4objId(objId); templateList.forEach(template -> insertOrUpdateMetricsFromTemplate(objId, template.getTplId(), pp)); } /** * 更新模板中的pinpoint指标到业务对象指标 * * @param objId 对象ID * @param tplId 模板ID * @param pp pinpoint组成 */ private void insertOrUpdateMetricsFromTemplate(Long objId, Long tplId, BizObjPp pp) { MetricsTplDetail query = new MetricsTplDetail(); query.setTplId(tplId); List list = detailService.selectMetricsTplDetailList(query); List objMetrics = new ArrayList<>(); list.forEach(d -> { if ("1".equals(d.getMetricsDef().getMetricsType()) && !d.getMetricsDef().getMetricsCode().startsWith("pp.jvm.")) { //如果是pinpoint,需要 // 1.获取对象pinpoint组成 BizObjMetrics ms = new BizObjMetrics(); ms.setObjId(objId); ms.setTplId(tplId); ms.setMetricsId(d.getMetricsId()); ms.setMetricsName(pp.getPpName() + "/" + d.getMetricsDef().getMetricsName()); ms.setMetricsCode(pp.getPpName() + "/" + d.getMetricsCode()); if (pp.getPpType().equals("REDIS")) { //redis需要将1s换成100ms 3s换成300ms 5s换成500ms if (d.getMetricsCode().endsWith("1s")) { ms.setMetricsName(ms.getMetricsName().replace("1s", "100ms")); ms.setMetricsCode(ms.getMetricsCode().replace("1s", "100ms")); } if (d.getMetricsCode().endsWith("3s")) { ms.setMetricsName(ms.getMetricsName().replace("3s", "300ms")); ms.setMetricsCode(ms.getMetricsCode().replace("3s", "300ms")); } if (d.getMetricsCode().endsWith("5s")) { ms.setMetricsName(ms.getMetricsName().replace("5s", "500ms")); ms.setMetricsCode(ms.getMetricsCode().replace("5s", "500ms")); } } ms.setAlarmLow(d.getAlarmLow()); ms.setAlarmMid(d.getAlarmMid()); ms.setAlarmHigh(d.getAlarmHigh()); objMetrics.add(ms); } }); bizObjMetricsMapper.batchInsert(objMetrics); } /** * 更新指标 * * @param objId 对象ID * @param tps 系统压力 * @param openFiles 打开文件数量 * @param heapUsage 堆内存使用率 * @param gcCount gc次数 * @param pinpointVOList 链路列表数据 */ private void updateBizObjMetrics(Long objId, Float tps, int openFiles, float heapUsage, int gcCount, List pinpointVOList) { updateJvmMetrics(objId, tps, heapUsage, openFiles, gcCount); updateLinkMetrics(objId, pinpointVOList); } /** * 更新jvm指标 * * @param objId 对象ID * @param tps 系统压力 * @param openFiles 打开文件数量 * @param heapUsage 堆内存使用率 * @param gcCount gc次数 */ private void updateJvmMetrics(Long objId, Float tps, float heapUsage, int openFiles, int gcCount) { BizObjMetrics jvmMetrics = new BizObjMetrics(); jvmMetrics.setObjId(objId); jvmMetrics.setMetricsCode("pp.jvm."); List omList = selectBizObjMetricsList(jvmMetrics); updateMetricsValues(omList, "tps", BigDecimal.valueOf(tps)); updateMetricsValues(omList, "heap.usage", BigDecimal.valueOf(heapUsage)); updateMetricsValues(omList, "open", BigDecimal.valueOf(openFiles)); updateMetricsValues(omList, "gc", BigDecimal.valueOf(gcCount)); } /** * jvg指标更新 * * @param omList jvm指标列表 * @param metricSuffix 指标后缀 * @param value 值 */ private void updateMetricsValues(List omList, String metricSuffix, BigDecimal value) { omList.stream() .filter(om -> om.getMetricsCode().endsWith(metricSuffix)) .forEach(om -> { String alarmLevel = getAlarmLevel(value.floatValue(), om); if (alarmLevel != null) { insertAlarm(om, alarmLevel); } om.setDValue(value); updateBizObjMetrics(om); }); } /** * 更新链路指标 * * @param objId 对象ID * @param pinpointVOList 链路列表 */ private void updateLinkMetrics(Long objId, List pinpointVOList) { Map metricsMap = getAllMetricsForObjId(objId); pinpointVOList.forEach(vo -> updateMetricsValues(metricsMap, vo)); } /** * 更新指标 * * @param metricsMap 指标map * @param vo pp链路对象 */ private void updateMetricsValues(Map metricsMap, PinpointVO vo) { metricsMap.values().stream() .filter(om -> om.getMetricsCode().startsWith(vo.getApplicationName() + "/")) .forEach(om -> { updateMetric(om, "pp.1s", vo.getTime1s()); updateMetric(om, "pp.3s", vo.getTime3s()); updateMetric(om, "pp.5s", vo.getTime5s()); updateMetric(om, "pp.100ms", vo.getTime100ms()); updateMetric(om, "pp.300ms", vo.getTime300ms()); updateMetric(om, "pp.500ms", vo.getTime500ms()); updateMetric(om, "pp.tot", vo.getTot()); updateMetric(om, "pp.sum", vo.getSum()); updateMetric(om, "pp.max", vo.getMax()); updateMetric(om, "pp.avg", vo.getAvg()); updateMetric(om, "pp.slow", vo.getSlow()); updateMetric(om, "pp.error", vo.getError()); }); } /** * 调用更新方法 * * @param om 对象 * @param suffix 前缘 * @param value 值 */ private void updateMetric(BizObjMetrics om, String suffix, Number value) { if (om.getMetricsCode().endsWith(suffix) && value != null) { om.setDValue(BigDecimal.valueOf(value.doubleValue())); updateBizObjMetrics(om); } } /** * 获取所有指标对象,并以code转换成map * * @param objId 对象ID * @return map */ private Map getAllMetricsForObjId(Long objId) { return getAllMetricsForObjIdList(objId).stream() .collect(Collectors.toMap(BizObjMetrics::getMetricsCode, Function.identity())); } /** * 根据对象ID获取所有指标 * * @param objId 对象ID * @return */ private List getAllMetricsForObjIdList(Long objId) { BizObjMetrics search = new BizObjMetrics(); search.setObjId(objId); return selectBizObjMetricsList(search); } }