从零到日志采集索引可视化、监控报警、rpc trace跟踪-系统上下线监控
来源:互联网 发布:vb中对象的属性 编辑:程序博客网 时间:2024/05/09 15:30
github开源 欢迎一起维护~~
- 之前说到注册中心的设计,zookeeper中的节点部署如下:
- kafkaAppender初始化向zk进行app节点注册,并写入相关的信息
- kafkaAppender发生异常暂停工作会向app节点写入相关信息,以便监控系统能够实时感知并发送报警
- app正常或者异常退出后,zk中的app临时节点会消失,shutdownhook会正常运行,监控系统能够实时感知并发送报警(这里就需要我们在自定义的log appender中写好相应的hook,防止对接系统无法正常释放资源,项目不要用kill -9 pid,应该使用kill pid)
- zk中有永久节点用来记录app的最近一次部署信息
那么我们只需要监控zk节点的变化,即可知道对接的系统上下线情况,以及内嵌的采集器是否存活,具体代码如下(curator框架和zkclient一起混用):
public class ScrollChildrenChangeListener implements PathChildrenCacheListener {
private static final Logger LOGGER = LoggerFactory.getLogger(ScrollChildrenChangeListener.class);
private RabbitmqService rabbitmqService;
private ZkClient zkClient;
private AppInfoService appInfoService;
public ScrollChildrenChangeListener(RabbitmqService rabbitmqService, ZkClient zkClient, AppInfoService appInfoService) {
this.rabbitmqService = rabbitmqService;
this.zkClient = zkClient;
this.appInfoService = appInfoService;
}
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
switch (event.getType()) {
case CHILD_ADDED:
PathChildrenCache pathChildrenCache = new PathChildrenCache(client, event.getData().getPath(), true);
pathChildrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
pathChildrenCache.getListenable().addListener(new AppChildrenChangeListener(this.rabbitmqService, this.zkClient, this.appInfoService));
LOGGER.info("app added: " + event.getData().getPath());
break;
case CHILD_REMOVED:
LOGGER.info("app removed: " + event.getData().getPath());
break;
}
}
}
private static final Logger LOGGER = LoggerFactory.getLogger(ScrollChildrenChangeListener.class);
private RabbitmqService rabbitmqService;
private ZkClient zkClient;
private AppInfoService appInfoService;
public ScrollChildrenChangeListener(RabbitmqService rabbitmqService, ZkClient zkClient, AppInfoService appInfoService) {
this.rabbitmqService = rabbitmqService;
this.zkClient = zkClient;
this.appInfoService = appInfoService;
}
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
switch (event.getType()) {
case CHILD_ADDED:
PathChildrenCache pathChildrenCache = new PathChildrenCache(client, event.getData().getPath(), true);
pathChildrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
pathChildrenCache.getListenable().addListener(new AppChildrenChangeListener(this.rabbitmqService, this.zkClient, this.appInfoService));
LOGGER.info("app added: " + event.getData().getPath());
break;
case CHILD_REMOVED:
LOGGER.info("app removed: " + event.getData().getPath());
break;
}
}
}
public class AppChildrenChangeListener implements PathChildrenCacheListener {
private static final Logger LOGGER = LoggerFactory.getLogger(AppChildrenChangeListener.class);
private RabbitmqService rabbitmqService;
private ZkClient zkClient;
private AppInfoService appInfoService;
public AppChildrenChangeListener(RabbitmqService rabbitmqService, ZkClient zkClient, AppInfoService appInfoService) {
this.rabbitmqService = rabbitmqService;
this.zkClient = zkClient;
this.appInfoService = appInfoService;
}
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
String node = Constants.EMPTY_STR;
String app = Constants.EMPTY_STR;
String host = Constants.EMPTY_STR;
String info = Constants.EMPTY_STR;
String[] datas = null;
switch (event.getType()) {
case CHILD_ADDED:
node = event.getData().getPath();
app = this.getApp(node);
host = this.getHost(node);
if (!CacheService.appHosts.contains(node)) {
datas = this.zkClient.readData(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app + Constants.SLASH + host).toString().split(Constants.SEMICOLON);
info = this.buildMsg(DateUtil.format(new Date(System.currentTimeMillis()), DateUtil.YYYYMMDDHHMMSS), app,
this.getHost(node), datas[1], Constants.APP_START);
// add to the queue
this.rabbitmqService.sendMessage(info, datas[0]);
LOGGER.info(info);
CacheService.appHosts.add(node);
this.appInfoService.add(host, app, Constants.ZK_NODE_TYPE_EPHEMERAL, LogCollectionStatus.RUNNING);
}
this.appInfoService.add(host, app, Constants.ZK_NODE_TYPE_PERSISTENT, LogCollectionStatus.HISTORY);
break;
case CHILD_REMOVED:
node = event.getData().getPath();
app = this.getApp(node);
host = this.getHost(node);
datas = this.zkClient.readData(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app + Constants.SLASH + host).toString().split(Constants.SEMICOLON);
info = this.buildMsg(DateUtil.format(new Date(System.currentTimeMillis()), DateUtil.YYYYMMDDHHMMSS), app,
this.getHost(node), datas[1], Constants.APP_STOP);
// add to the queue
this.rabbitmqService.sendMessage(info, datas[0]);
LOGGER.info(info);
if (CacheService.appHosts.contains(node)) {
CacheService.appHosts.remove(node);
this.appInfoService.delete(host, app, Constants.ZK_NODE_TYPE_EPHEMERAL);
}
break;
case CHILD_UPDATED:
node = event.getData().getPath();
datas = this.zkClient.readData(node).toString().split(Constants.SEMICOLON);
app = this.getApp(node);
host = this.getHost(node);
info = this.buildMsg(DateUtil.format(new Date(Long.parseLong(datas[0])), DateUtil.YYYYMMDDHHMMSS), app,
this.getHost(node), datas[1], Constants.APP_APPENDER_STOP);
// add to the queue
this.rabbitmqService.sendMessage(info, this.zkClient.readData(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app + Constants.SLASH + host).toString().split(Constants.SEMICOLON)[0]);
LOGGER.info(info);
this.appInfoService.update(host, app, Constants.ZK_NODE_TYPE_EPHEMERAL, LogCollectionStatus.STOPPED);
break;
}
}
/**
* 根据node获取app
* @param node
* @return
*/
private String getApp(String node) {
String tmp = node.substring(0, node.lastIndexOf(Constants.SLASH));
return this.getLast(tmp);
}
/**
* 根据node获取host
* @param node
* @return
*/
private String getHost(String node) {
return this.getLast(node);
}
/**
* 返回末尾字符串
* @param line
* @return
*/
private String getLast(String line) {
return line.substring(line.lastIndexOf(Constants.SLASH) + 1);
}
/**
* 构造报警msg
* @param time
* @param app
* @param host
* @param deploy
* @param msg
* @return
*/
private String buildMsg(String time, String app, String host, String deploy, String msg) {
AlertDto alertDto = new AlertDto(time, app, host, deploy, msg);
return alertDto.toString();
}
}
private static final Logger LOGGER = LoggerFactory.getLogger(AppChildrenChangeListener.class);
private RabbitmqService rabbitmqService;
private ZkClient zkClient;
private AppInfoService appInfoService;
public AppChildrenChangeListener(RabbitmqService rabbitmqService, ZkClient zkClient, AppInfoService appInfoService) {
this.rabbitmqService = rabbitmqService;
this.zkClient = zkClient;
this.appInfoService = appInfoService;
}
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
String node = Constants.EMPTY_STR;
String app = Constants.EMPTY_STR;
String host = Constants.EMPTY_STR;
String info = Constants.EMPTY_STR;
String[] datas = null;
switch (event.getType()) {
case CHILD_ADDED:
node = event.getData().getPath();
app = this.getApp(node);
host = this.getHost(node);
if (!CacheService.appHosts.contains(node)) {
datas = this.zkClient.readData(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app + Constants.SLASH + host).toString().split(Constants.SEMICOLON);
info = this.buildMsg(DateUtil.format(new Date(System.currentTimeMillis()), DateUtil.YYYYMMDDHHMMSS), app,
this.getHost(node), datas[1], Constants.APP_START);
// add to the queue
this.rabbitmqService.sendMessage(info, datas[0]);
LOGGER.info(info);
CacheService.appHosts.add(node);
this.appInfoService.add(host, app, Constants.ZK_NODE_TYPE_EPHEMERAL, LogCollectionStatus.RUNNING);
}
this.appInfoService.add(host, app, Constants.ZK_NODE_TYPE_PERSISTENT, LogCollectionStatus.HISTORY);
break;
case CHILD_REMOVED:
node = event.getData().getPath();
app = this.getApp(node);
host = this.getHost(node);
datas = this.zkClient.readData(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app + Constants.SLASH + host).toString().split(Constants.SEMICOLON);
info = this.buildMsg(DateUtil.format(new Date(System.currentTimeMillis()), DateUtil.YYYYMMDDHHMMSS), app,
this.getHost(node), datas[1], Constants.APP_STOP);
// add to the queue
this.rabbitmqService.sendMessage(info, datas[0]);
LOGGER.info(info);
if (CacheService.appHosts.contains(node)) {
CacheService.appHosts.remove(node);
this.appInfoService.delete(host, app, Constants.ZK_NODE_TYPE_EPHEMERAL);
}
break;
case CHILD_UPDATED:
node = event.getData().getPath();
datas = this.zkClient.readData(node).toString().split(Constants.SEMICOLON);
app = this.getApp(node);
host = this.getHost(node);
info = this.buildMsg(DateUtil.format(new Date(Long.parseLong(datas[0])), DateUtil.YYYYMMDDHHMMSS), app,
this.getHost(node), datas[1], Constants.APP_APPENDER_STOP);
// add to the queue
this.rabbitmqService.sendMessage(info, this.zkClient.readData(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app + Constants.SLASH + host).toString().split(Constants.SEMICOLON)[0]);
LOGGER.info(info);
this.appInfoService.update(host, app, Constants.ZK_NODE_TYPE_EPHEMERAL, LogCollectionStatus.STOPPED);
break;
}
}
/**
* 根据node获取app
* @param node
* @return
*/
private String getApp(String node) {
String tmp = node.substring(0, node.lastIndexOf(Constants.SLASH));
return this.getLast(tmp);
}
/**
* 根据node获取host
* @param node
* @return
*/
private String getHost(String node) {
return this.getLast(node);
}
/**
* 返回末尾字符串
* @param line
* @return
*/
private String getLast(String line) {
return line.substring(line.lastIndexOf(Constants.SLASH) + 1);
}
/**
* 构造报警msg
* @param time
* @param app
* @param host
* @param deploy
* @param msg
* @return
*/
private String buildMsg(String time, String app, String host, String deploy, String msg) {
AlertDto alertDto = new AlertDto(time, app, host, deploy, msg);
return alertDto.toString();
}
}
@Service
public class AppInfoService {
@Autowired
private ZkClient zkClient;
@Autowired
private AppInfoRepository appInfoRepository;
/**
* 保存appInfo
* @param host
* @param app
* @param type
* @param logCollectionStatus
*/
public void add(String host, String app, int type, LogCollectionStatus logCollectionStatus) {
AppInfo appInfo = new AppInfo();
AppInfoPK appInfoPK = new AppInfoPK(host, app, type);
appInfo.setAppInfoPK(appInfoPK);
appInfo.setStatus(logCollectionStatus.symbol());
if (logCollectionStatus.symbol().equals(LogCollectionStatus.HISTORY.symbol())) {
appInfo.setDeploy(this.getDeploy(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app + Constants.SLASH + host));
} else {
appInfo.setDeploy(this.getDeploy(Constants.ROOT_PATH_EPHEMERAL + Constants.SLASH + app + Constants.SLASH + host));
}
this.appInfoRepository.save(appInfo);
}
/**
* 修改记录的收集日志状态
* @param host
* @param app
* @param type
* @param logCollectionStatus
*/
public void update(String host, String app, int type, LogCollectionStatus logCollectionStatus) {
AppInfo appInfo = this.appInfoRepository.findOne(new AppInfoPK(host, app, type));
appInfo.setStatus(logCollectionStatus.symbol());
this.appInfoRepository.save(appInfo);
}
/**
* 根据host和app进行删除
* @param host
* @param app
* @param type
*/
public void delete(String host, String app, int type) {
AppInfo appInfo = this.appInfoRepository.findOne(new AppInfoPK(host, app, type));
if (null != appInfo) {
this.appInfoRepository.delete(appInfo);
}
}
/**
* 删除所有的数据
*/
public void deleteAll() {
this.appInfoRepository.deleteAll();
}
/**
* 获取app的部署位置
* @param path
* @return
*/
private String getDeploy(String path) {
String data = this.zkClient.readData(path);
return data.split(Constants.SEMICOLON)[1];
}
}
public class AppInfoService {
@Autowired
private ZkClient zkClient;
@Autowired
private AppInfoRepository appInfoRepository;
/**
* 保存appInfo
* @param host
* @param app
* @param type
* @param logCollectionStatus
*/
public void add(String host, String app, int type, LogCollectionStatus logCollectionStatus) {
AppInfo appInfo = new AppInfo();
AppInfoPK appInfoPK = new AppInfoPK(host, app, type);
appInfo.setAppInfoPK(appInfoPK);
appInfo.setStatus(logCollectionStatus.symbol());
if (logCollectionStatus.symbol().equals(LogCollectionStatus.HISTORY.symbol())) {
appInfo.setDeploy(this.getDeploy(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app + Constants.SLASH + host));
} else {
appInfo.setDeploy(this.getDeploy(Constants.ROOT_PATH_EPHEMERAL + Constants.SLASH + app + Constants.SLASH + host));
}
this.appInfoRepository.save(appInfo);
}
/**
* 修改记录的收集日志状态
* @param host
* @param app
* @param type
* @param logCollectionStatus
*/
public void update(String host, String app, int type, LogCollectionStatus logCollectionStatus) {
AppInfo appInfo = this.appInfoRepository.findOne(new AppInfoPK(host, app, type));
appInfo.setStatus(logCollectionStatus.symbol());
this.appInfoRepository.save(appInfo);
}
/**
* 根据host和app进行删除
* @param host
* @param app
* @param type
*/
public void delete(String host, String app, int type) {
AppInfo appInfo = this.appInfoRepository.findOne(new AppInfoPK(host, app, type));
if (null != appInfo) {
this.appInfoRepository.delete(appInfo);
}
}
/**
* 删除所有的数据
*/
public void deleteAll() {
this.appInfoRepository.deleteAll();
}
/**
* 获取app的部署位置
* @param path
* @return
*/
private String getDeploy(String path) {
String data = this.zkClient.readData(path);
return data.split(Constants.SEMICOLON)[1];
}
}
*/
@Service
public class AppStatusMonitorService implements InitializingBean {
@Autowired
private CuratorFramework curatorFramework;
@Autowired
private RabbitmqService rabbitmqService;
@Autowired
private ZkClient zkClient;
@Autowired
private AppInfoService appInfoService;
@Override
public void afterPropertiesSet() throws Exception {
PathChildrenCache pathChildrenCache = new PathChildrenCache(curatorFramework, Constants.ROOT_PATH_EPHEMERAL, true);
pathChildrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
pathChildrenCache.getListenable().addListener(new ScrollChildrenChangeListener(this.rabbitmqService, this.zkClient, this.appInfoService));
}
}
@Service
public class AppStatusMonitorService implements InitializingBean {
@Autowired
private CuratorFramework curatorFramework;
@Autowired
private RabbitmqService rabbitmqService;
@Autowired
private ZkClient zkClient;
@Autowired
private AppInfoService appInfoService;
@Override
public void afterPropertiesSet() throws Exception {
PathChildrenCache pathChildrenCache = new PathChildrenCache(curatorFramework, Constants.ROOT_PATH_EPHEMERAL, true);
pathChildrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
pathChildrenCache.getListenable().addListener(new ScrollChildrenChangeListener(this.rabbitmqService, this.zkClient, this.appInfoService));
}
}
@Service
public class CacheService implements InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(CacheService.class);
public static List<String> appHosts = new ArrayList<String>();
@Autowired
private CuratorFramework curatorFramework;
@Autowired
private AppInfoService appInfoService;
@Autowired
private ZkClient zkClient;
@Override
public void afterPropertiesSet() throws Exception {
// 将mysql数据进行清空
this.appInfoService.deleteAll();
List<String> apps = curatorFramework.getChildren().forPath(Constants.ROOT_PATH_EPHEMERAL);
// 启动时获取所有的节点数据, 写入本地缓存和mysql
for (String app : apps) {
List<String> hosts = curatorFramework.getChildren().forPath(Constants.ROOT_PATH_EPHEMERAL + Constants.SLASH + app);
for (String host : hosts) {
appHosts.add(Constants.ROOT_PATH_EPHEMERAL + Constants.SLASH + app + Constants.SLASH + host);
this.appInfoService.add(host, app, Constants.ZK_NODE_TYPE_EPHEMERAL, this.calLogCollectionStatus(app, host));
}
}
apps = curatorFramework.getChildren().forPath(Constants.ROOT_PATH_PERSISTENT);
for (String app : apps) {
List<String> hosts = curatorFramework.getChildren().forPath(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app);
for (String host : hosts) {
this.appInfoService.add(host, app, Constants.ZK_NODE_TYPE_PERSISTENT, LogCollectionStatus.HISTORY);
}
}
}
/**
* 根据app和host计算LogCollectionStatus
* @param app
* @param host
* @return
*/
private LogCollectionStatus calLogCollectionStatus(String app, String host) {
String[] datas = this.zkClient.readData(Constants.ROOT_PATH_EPHEMERAL + Constants.SLASH + app + Constants.SLASH + host).toString().split(Constants.SEMICOLON);
if (datas[0].equals(Constants.APPENDER_INIT_DATA)) {
return LogCollectionStatus.RUNNING;
}
return LogCollectionStatus.STOPPED;
}
}
public class CacheService implements InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(CacheService.class);
public static List<String> appHosts = new ArrayList<String>();
@Autowired
private CuratorFramework curatorFramework;
@Autowired
private AppInfoService appInfoService;
@Autowired
private ZkClient zkClient;
@Override
public void afterPropertiesSet() throws Exception {
// 将mysql数据进行清空
this.appInfoService.deleteAll();
List<String> apps = curatorFramework.getChildren().forPath(Constants.ROOT_PATH_EPHEMERAL);
// 启动时获取所有的节点数据, 写入本地缓存和mysql
for (String app : apps) {
List<String> hosts = curatorFramework.getChildren().forPath(Constants.ROOT_PATH_EPHEMERAL + Constants.SLASH + app);
for (String host : hosts) {
appHosts.add(Constants.ROOT_PATH_EPHEMERAL + Constants.SLASH + app + Constants.SLASH + host);
this.appInfoService.add(host, app, Constants.ZK_NODE_TYPE_EPHEMERAL, this.calLogCollectionStatus(app, host));
}
}
apps = curatorFramework.getChildren().forPath(Constants.ROOT_PATH_PERSISTENT);
for (String app : apps) {
List<String> hosts = curatorFramework.getChildren().forPath(Constants.ROOT_PATH_PERSISTENT + Constants.SLASH + app);
for (String host : hosts) {
this.appInfoService.add(host, app, Constants.ZK_NODE_TYPE_PERSISTENT, LogCollectionStatus.HISTORY);
}
}
}
/**
* 根据app和host计算LogCollectionStatus
* @param app
* @param host
* @return
*/
private LogCollectionStatus calLogCollectionStatus(String app, String host) {
String[] datas = this.zkClient.readData(Constants.ROOT_PATH_EPHEMERAL + Constants.SLASH + app + Constants.SLASH + host).toString().split(Constants.SEMICOLON);
if (datas[0].equals(Constants.APPENDER_INIT_DATA)) {
return LogCollectionStatus.RUNNING;
}
return LogCollectionStatus.STOPPED;
}
}
代码较为简单,不再赘述,主要就是监听zk节点的变化情况,并且将app和host信息采集进入了mysql(同时本项目进程中缓存了一份用来提高速度)。
2 0
- 从零到日志采集索引可视化、监控报警、rpc trace跟踪-系统上下线监控
- 从零到日志采集索引可视化、监控报警、rpc trace跟踪-日志索引
- 从零到日志采集索引可视化、监控报警、rpc trace跟踪-自定义日志框架
- 从零到日志采集索引可视化、监控报警、rpc trace跟踪-架构介绍
- 从零到日志采集索引可视化、监控报警、rpc trace跟踪-分布式唯一ID生成
- 从零到日志采集索引可视化、监控报警、rpc trace跟踪-日志事件、埋点设计及对接
- 服务端技术进阶(三)从架构到监控报警,支付系统的设计如何步步为营
- Perl 监控日志异常报警
- flume监控spoolDir日志到HDFS(从日志产生到hdfs上一整套)
- Netlink实现网卡上下线监控
- Netlink实现网卡上下线监控
- 代码分享,日志文件监控报警
- docker 监控报警以及日志分析
- 系统监控:msn在线机器人实时报警
- 系统监控:msn在线机器人实时报警
- 银行110自动监控报警系统解决方案
- 银行监控及报警系统解决方案
- 亿级高并发系统的监控与报警
- android项目开发首页+底部导航
- Android开发之webview的加载优化
- 数据库基础知识整理:
- JS中的call()和apply()方法
- C语言学习笔记
- 从零到日志采集索引可视化、监控报警、rpc trace跟踪-系统上下线监控
- JavaScript模拟手势翻页动作
- PX EM REM之间的区别
- python2.7中用numpy.reshape 对图像进行切割
- USACO 3.3解题思路报告
- CodeForces-149D Coloring Brackets(区间dp)
- hibernate正向生成简单教程
- 数据库表间关系
- linux驱动由浅入深系列:驱动程序的基本结构概览之一(第一个驱动程序)