package com.sohu.cache.client.service.impl; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sohu.cache.client.service.ClientReportExceptionService; import com.sohu.cache.client.service.ClientReportInstanceService; import com.sohu.cache.dao.AppClientExceptionStatDao; import com.sohu.cache.dao.AppClientVersionDao; import com.sohu.cache.entity.AppClientExceptionStat; import com.sohu.cache.entity.AppClientVersion; import com.sohu.cache.entity.ClientInstanceException; import com.sohu.cache.entity.InstanceInfo; import com.sohu.cache.web.util.Page; import com.sohu.tv.jedis.stat.constant.ClientReportConstant; import com.sohu.tv.jedis.stat.enums.ClientCollectDataTypeEnum; import com.sohu.tv.jedis.stat.enums.ClientExceptionType; import com.sohu.tv.jedis.stat.model.ClientReportBean; /** * 客户端上报异常service * * @author leifu * @Date 2015年1月19日 * @Time 上午10:02:32 */ public class ClientReportExceptionServiceImpl implements ClientReportExceptionService { private final Logger logger = LoggerFactory.getLogger(ClientReportExceptionServiceImpl.class); /** * 客户端异常操作 */ private AppClientExceptionStatDao appClientExceptionStatDao; /** * host:port与instanceInfo简单缓存 */ private ClientReportInstanceService clientReportInstanceService; /** * 客户端ip,版本查询 */ private AppClientVersionDao appClientVersionDao; @Override public List<AppClientExceptionStat> getAppExceptionList(Long appId, long startTime, long endTime, int type, String clientIp, Page page) { try { return appClientExceptionStatDao.getAppExceptionList(appId, startTime, endTime, type, clientIp, page); } catch (Exception e) { logger.error(e.getMessage(), e); return Collections.emptyList(); } } @Override public int getAppExceptionCount(Long appId, long startTime, long endTime, int type, String clientIp) { try { return appClientExceptionStatDao.getAppExceptionCount(appId, startTime, endTime, type, clientIp); } catch (Exception e) { logger.error(e.getMessage(), e); return 0; } } @Override public List<ClientInstanceException> getInstanceExceptionStat(String ip, long collectTime) { try { return appClientExceptionStatDao.getInstanceExceptionStat(ip, collectTime); } catch (Exception e) { logger.error(e.getMessage(), e); return Collections.emptyList(); } } @Override public void batchSave(ClientReportBean clientReportBean) { try { // 1.client上报 final String clientIp = clientReportBean.getClientIp(); final long collectTime = clientReportBean.getCollectTime(); final long reportTime = clientReportBean.getReportTimeStamp(); final List<Map<String, Object>> datas = clientReportBean.getDatas(); if (datas == null || datas.isEmpty()) { logger.warn("datas field {} is empty", clientReportBean); return; } // 2.结果集 List<AppClientExceptionStat> appClientExceptionStatList = new ArrayList<AppClientExceptionStat>(); // 3.解析 for (Map<String, Object> map : datas) { Integer clientDataType = MapUtils.getInteger(map, ClientReportConstant.CLIENT_DATA_TYPE, -1); ClientCollectDataTypeEnum clientCollectDataTypeEnum = ClientCollectDataTypeEnum.MAP.get(clientDataType); if (clientCollectDataTypeEnum == null) { continue; } if (ClientCollectDataTypeEnum.EXCEPTION_TYPE.equals(clientCollectDataTypeEnum)) { AppClientExceptionStat appClientExceptionStat = generate(clientIp, collectTime, reportTime, map); if (appClientExceptionStat != null) { appClientExceptionStatList.add(appClientExceptionStat); } } } // 4.批量保存 if (CollectionUtils.isNotEmpty(appClientExceptionStatList)) { appClientExceptionStatDao.batchSave(appClientExceptionStatList); } } catch (Exception e) { logger.error(e.getMessage(), e); } } private AppClientExceptionStat generate(String clientIp, long collectTime, long reportTime, Map<String, Object> map) { // 异常信息 String exceptionClass = MapUtils.getString(map, ClientReportConstant.EXCEPTION_CLASS, ""); Long exceptionCount = MapUtils.getLong(map, ClientReportConstant.EXCEPTION_COUNT, 0L); int exceptionType = MapUtils.getInteger(map, ClientReportConstant.EXCEPTION_TYPE, ClientExceptionType.REDIS_TYPE.getType()); String host = null; Integer port = null; Integer instanceId = null; long appId; if (ClientExceptionType.REDIS_TYPE.getType() == exceptionType) { // 实例host:port String hostPort = MapUtils.getString(map, ClientReportConstant.EXCEPTION_HOST_PORT, ""); if (StringUtils.isEmpty(hostPort)) { logger.warn("hostPort is empty", hostPort); return null; } int index = hostPort.indexOf(":"); if (index <= 0) { logger.warn("hostPort {} format is wrong", hostPort); return null; } host = hostPort.substring(0, index); port = NumberUtils.toInt(hostPort.substring(index + 1)); // 实例信息 InstanceInfo instanceInfo = clientReportInstanceService.getInstanceInfoByHostPort(host, port); if (instanceInfo == null) { // logger.warn("instanceInfo is empty, host is {}, port is {}", host, port); return null; } // 实例id instanceId = instanceInfo.getId(); // 应用id appId = instanceInfo.getAppId(); } else { List<AppClientVersion> appClientVersion = appClientVersionDao.getByClientIp(clientIp); if (CollectionUtils.isNotEmpty(appClientVersion)) { appId = appClientVersion.get(0).getAppId(); } else { appId = 0; } } // 组装AppClientExceptionStat AppClientExceptionStat stat = new AppClientExceptionStat(); stat.setAppId(appId); stat.setClientIp(clientIp); stat.setReportTime(new Date(reportTime)); stat.setCollectTime(collectTime); stat.setCreateTime(new Date()); stat.setExceptionClass(exceptionClass); stat.setExceptionCount(exceptionCount); stat.setInstanceHost(host); stat.setInstancePort(port); stat.setInstanceId(instanceId); stat.setType(exceptionType); return stat; } public void setAppClientExceptionStatDao(AppClientExceptionStatDao appClientExceptionStatDao) { this.appClientExceptionStatDao = appClientExceptionStatDao; } public void setAppClientVersionDao(AppClientVersionDao appClientVersionDao) { this.appClientVersionDao = appClientVersionDao; } public void setClientReportInstanceService(ClientReportInstanceService clientReportInstanceService) { this.clientReportInstanceService = clientReportInstanceService; } }