您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
打造自己的Linux服务器监控小工具
 
作者 sunfan,火龙果软件    发布于 2014-08-07
  2380  次浏览      15
 

周末在家蛮无聊的,思考人生的同时突发奇想就写一个服务器监控的小工具吧。学JAVA快1年了,刚好检验一下自己!

仔细想想呢估计作用可能也有限,毕竟外面各种监控工具也很多,初衷其实也只是练练手,加上平时比较懒,那么为了更方便的看服务器性能指标,所以就选了这个题材咯,那么就开始吧。

不过优点也是有的嘛,至少不需要在服务器端装一个脚本之类的了。

一、小工具的功能

1 能够读取服务器CPU,IO,Memory的性能指标并在页面展示出来

2 把监控的信息打印到文件,方便进行数据分析

二、准备工作

1.java开发环境、JDK1.7+、 Eclipse

2.maven环境

3.git

三、使用到的框架

前台:JS的FLOT框架

后台:SpringMVC框架

工作流程图(其实蛮简单的)

项目结构目录

四、实现代码

主要的功能类

1 LinuxService 提供服务器指令输入的服务入口

2 LinuxConnectionPool 把服务器连接对象保存起来,每一次获得请求时会先检查连接是否在池子中存在,有的话直接用,没有的话就创建一个新的

3 LinuxConnection 服务器连接对象,负责创建connection

4 LinuxSessionHandle 负责创建session并执行CMD指令最后销毁session

5 EntityBaseUtil 提供了把Linux返回的结果转换成比较适合装入实体类的方法String Transfer ListString[]

代码

1 LinuxService

package com.sunfan.monitor.service;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.sunfan.monitor.manager.pool.LinuxConnectionPool;
import com.sunfan.monitor.platform.IConnectable;
import com.sunfan.monitor.platform.linux.LinuxSessionHandle;
/**
*
* @author sunfan
*
*/
@Component
public class LinuxService {
private String defaultTopComand = "top -b -n 1";
private String defaultMpstatComand = "mpstat -P ALL";
private String defaultFreeCommand = "free -m";
private String defaultIostatCommand = "iostat -d -m";
@Autowired
private LinuxConnectionPool pool ;
@Autowired
private LinuxSessionHandle handle;
/**
* execute default command "top -b -n 1" and return String type reslut
*
* @param url server's ip
* @param user login name
* @param password login password
* @return
* @throws IOException
*/
public String topMonitor(String url,String user,String password) throws IOException{
return this.executeCommand(url, user, password, defaultTopComand);
}
/**
* execute default command "mpstat -P ALL" to get cpus performance
*
* @param url
* @param user
* @param password
* @return
* @throws IOException
*/
public String cpuMonitor(String url,String user,String password) throws IOException{
return this.executeCommand(url, user, password, defaultMpstatComand);
}
/**
* execute default command "free -m" to get memory performance
* @param url
* @param user
* @param password
* @return
* @throws IOException
*/
public String memoryMonitor(String url,String user,String password) throws IOException{
return this.executeCommand(url, user, password, defaultFreeCommand);
}
/**
* execute default command "free -m" to get memory performance
* @param url
* @param user
* @param password
* @return
* @throws IOException
*/
public String inputOutputMonitor(String url,String user,String password) throws IOException{
return this.executeCommand(url, user, password, defaultIostatCommand);
}
public String executeCommand(String url,String user,String password,String command) throws IOException{
IConnectable lc = pool.borrowObject(url,user,password);
return handle.executeCommand(lc.getConnection(),command);
}
}

2 LinuxConnectionPool

package com.sunfan.monitor.manager.pool;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.sunfan.monitor.manager.IConnectionPool;
import com.sunfan.monitor.platform.IConnectable;
import com.sunfan.monitor.platform.linux.LinuxConnection;
/**
*
* @author sunfan
*
*/
@Component
public class LinuxConnectionPool implements IConnectionPool {
private Logger logger = LoggerFactory.getLogger(getClass());
private Map<String, IConnectable> connectionPool = new HashMap<String, IConnectable>();
/**
* save connecion in the connectionPool,if conn is already exist return
* false else return true
*
* @param conn
* @return
*/
public synchronized Boolean saveObject(IConnectable conn) {
String key = rewardConnectionKey(conn);
if (isExist(key)) {
logger.info("this key{} has already exist", key);
return false;
}
connectionPool.put(key, conn);
return true;
}
/**
* borrow connection object in the connect-pool
*
* @param key
* @return
*/
public IConnectable borrowObject(String key) {
if (!isExist(key)) {
throw new IllegalArgumentException("key not found:" + key);
}
return connectionPool.get(key);
}
public IConnectable borrowObject(String url,String user,String password){
String key = this.rewardConnectionKey(url, user, password);
if (!isExist(key)){
try {
LinuxConnection connect = new LinuxConnection(url, user, password);
connectionPool.put(key, connect);
return connect;
} catch (IOException e) {
throw new RuntimeException("connection error"+url,e);
}
}else {
return connectionPool.get(key);
}
}
/**
* borrow connection object in the connect-pool if the connection hasn't in
* the connectionPool return null,else return connect object
*
* @param conn
* @return
*/
public IConnectable borrowObject(IConnectable conn) {
String key = rewardConnectionKey(conn);
return borrowObject(key);
}
/**
* close single connection in the connection-pool and close/release of this
* connection
*
* @param conn
* @throws IOException
*/
public void remove(IConnectable conn) throws IOException {
String key = rewardConnectionKey(conn);
remove(key);
}
/**
* close single connection in the connection-pool and close/release of this
* connection
*
* @param conn
* @throws IOException
*/
public synchronized void remove(String key) throws IOException {
if (!isExist(key)) {
throw new IllegalArgumentException(key + "is not exist");
}
connectionPool.get(key).close();
connectionPool.remove(key);
}
/**
* delete every connection in the connection-pool and also close/release of
* all connection
*
* @throws IOException
*/
public void clear() throws IOException {
for (String keyString : connectionPool.keySet()) {
connectionPool.get(keyString).close();
}
connectionPool.clear();
}
/**
* according to the connection to generate key if the connecion is not equal
* null return url/usr/password
*
* @param conn
* @return
*/
public String rewardConnectionKey(IConnectable conn) {
return conn.getUrl() + "/" + conn.getUser() + "/" + conn.getPassword();
}
public String rewardConnectionKey(String url, String user, String password) {
return url + "/" + user + "/" + password;
}
/**
* To confirm whether the connectionPool has this key if already has return
* true else return false
*
* @param key
* @return
*/
public Boolean isExist(String key) {
return connectionPool.containsKey(key);
}
}

 3 LinuxConnection

package com.sunfan.monitor.platform.linux;
import java.io.Closeable;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sunfan.monitor.platform.IConnectable;
import com.trilead.ssh2.Connection;
import com.trilead.ssh2.ConnectionInfo;
/**
*
* @author sunfan
*
*/
public class LinuxConnection implements IConnectable, Closeable {
Logger log = LoggerFactory.getLogger(LinuxConnection.class);
private String url, user, password;
private Connection connection;
/**
* init server's connect
*
* @param url
* @param user
* @param password
* @throws IOException
*/
public LinuxConnection(String url, String user, String password) throws IOException{
this.url = url;
this.user = user;
this.password = password;
this.connection = createConnection();
}
/**
* this method will establish connection unless username or password
* incorrect and remote server is not find
*
* @return connection
* @throws IOException
*/
private Connection createConnection() throws IOException {
connection = new Connection(url);
ConnectionInfo info = connection.connect(); // establish connection
if (false == connection.authenticateWithPassword(user, password)){
log.error("connect server failed,please check the username and password. " + this.user + " " + this.password);
throw new IllegalArgumentException("connection remote server fail");
}
return connection;
}
/**
* close connection
*/
@Override
public void close() throws IOException {
if (connection != null)
this.connection.close();
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Connection getConnection() {
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
}

4 LinuxSessionHandle

package com.sunfan.monitor.platform.linux;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.sunfan.monitor.platform.IMonitorable;
import com.trilead.ssh2.Connection;
import com.trilead.ssh2.Session;
import com.trilead.ssh2.StreamGobbler;
/**
*
* @author sunfan
*
*/
@Component
public class LinuxSessionHandle implements IMonitorable,Closeable{
Logger logger = LoggerFactory.getLogger(LinuxSessionHandle.class);
private Session session;
/**
* open session then execute commands on remote server and return the result of it
* @param command
* @return String
* @throws IOException
*/
public synchronized String executeCommand(Connection conn,String command) throws IOException {
String str="";
try {
session = conn.openSession();
session.execCommand(command);
str = this.read().toString();
} catch (Exception e) {
session.ping();
throw new IOException("session exception",e);
}
finally{
close();
}
return str;
}
/**
* read the result of remote server execute commands
* @return
* @throws IOException
*/
private StringBuffer read() throws IOException{
InputStream stdout = new StreamGobbler(session.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
String tempString = null;
// readLine()每次调用都默认会读一行
StringBuffer str = new StringBuffer();
while ((tempString = br.readLine()) != null) {
str.append(tempString+"\r\n");
}
br.close();
return str;
}
/**
* close session
*/
@Override
public void close() throws IOException {
if (this.session != null) this.session.close();
}
}
5 EntityBaseUtil
package com.sunfan.monitor.entity.util;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author sunfan
*
*/
public class EntityBaseUtil {
/**change String result to List<String> result by split "\r\n"
* remove the content above flag
* to transfer List<String> ---> list<String[]> by .split("\\s{1,}")
* @param result
* @param flag
* @return
*/
public List<String[]> transferListofStringArray(String result,String flag){
List<String> resList = this.transferList(result);
List<String> contentList = this.removeResultHead(resList,flag);
return this.transferArrayOfList(contentList);
}
/**
* change String result to List<String> result by split "\r\n"
* @param result
* @return List<String>
*/
public List<String> transferList(String result){
String[] strs = result.split("\r\n");
List<String> list = new ArrayList<String>();
for(String s:strs){
list.add(s);
}
return list;
}
/**remove the content above flag
*
* @return List<String>
*/
public List<String> removeResultHead(List<String> resultList,String flag){
List<String> contentList = new ArrayList<String>();
contentList.addAll(resultList);
for(String res:resultList){
if(res.contains(flag)){
break;
}
contentList.remove(res);
}
return contentList;
}
/**to transfer List<String> ---> list<String[]> by .split("\\s{1,}")
*
* @param contentList
* @return List<String[]>
*/
public List<String[]> transferArrayOfList(List<String> contentList){
List<String[]> contentLists =new ArrayList<>();
for(String content:contentList){
contentLists.add(content.split("\\s{1,}"));
}
return contentLists;
}
/**get result of reference by title
*
* @param head data of reference title
* @param title reference title
* @param infos data of each reference
* @return String result of reference by title ,if title is not matched ,return " "
*/
public String resolveValueByTagName(List<String> head,String[] infos,String title){
if(head.indexOf(title)>0){
return infos[head.indexOf(title)];
}
return "";
}
}

五、测试

这个小工具耗时2个周末终于搞定了,感谢大家的观看,写的不好或者欠缺考虑的地方请@我,谢谢各位老师。

如果喜欢请点一下推荐哦,谢谢!

源码地址:https://github.com/sunfan1988/sunfan

六 将来的扩展

1 把日志功能完善

2 按照今后的需求把性能监控器逐个配置上去,基本上只要改一下controller和JSP页面就可以了。

   
2380 次浏览       15
相关文章 相关文档 相关课程



深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
最新课程计划
信息架构建模(基于UML+EA)3-21[北京]
软件架构设计师 3-21[北京]
图数据库与知识图谱 3-25[北京]
业务架构设计 4-11[北京]
SysML和EA系统设计与建模 4-22[北京]
DoDAF规范、模型与实例 5-23[北京]

基于模型的整车电子电气架构设计
嵌入式设备上的 Linux 系统开发
Linux 的并发可管理工作队列
ARM嵌入式系统的问题总结分析
嵌入式系统设计与实例开发
WinCE6.0的EBOOT概要
更多...   


UML +RoseRealtime+嵌入式
C++嵌入式系统开发
嵌入式白盒测试
手机软件测试
嵌入式软件测试
嵌入式操作系统VxWorks


中国航空 嵌入式C高质量编程
使用EA和UML进行嵌入式系统分析设计
基于SysML和EA的嵌入式系统建模
上海汽车 嵌入式软件架构设计
北京 嵌入式C高质量编程
北京 高质高效嵌入式开发
Nagra linux内核与设备驱动原理
更多...