记一次获取linux服务器参数监控的简单实现

应用的操作系统是centos7,jdk版本是1.8.0_232,涉及到shell脚本和可执行jar包等方面功能的使用,shell脚本不具备普遍适用性,仅供参考,若要使用最好自行编写。
写好后的目录结构如下所示。run.在这里插入图片描述
其中run.sh是启动jar包的脚本文件

#!/bin/bash
`java -jar serverStatus.jar& >>temp.txt`
exit

getStat.sh是获取服务器信息的脚本文件

#!/bin/bash
TIME_INTERVAL=1

LAST_CPU_INFO=$(cat /proc/stat | grep -w cpu | awk '{print $2,$3,$4,$5,$6,$7,$8}')
LAST_SYS_IDLE=$(echo $LAST_CPU_INFO | awk '{print $4}')
LAST_TOTAL_CPU_T=$(echo $LAST_CPU_INFO | awk '{print $1+$2+$3+$4+$5+$6+$7}')
sleep ${TIME_INTERVAL}
NEXT_CPU_INFO=$(cat /proc/stat | grep -w cpu | awk '{print $2,$3,$4,$5,$6,$7,$8}')
NEXT_SYS_IDLE=$(echo $NEXT_CPU_INFO | awk '{print $4}')
NEXT_TOTAL_CPU_T=$(echo $NEXT_CPU_INFO | awk '{print $1+$2+$3+$4+$5+$6+$7}')

#系统空闲时间
SYSTEM_IDLE=`echo ${NEXT_SYS_IDLE} ${LAST_SYS_IDLE} | awk '{print $1-$2}'`
#CPU总时间
TOTAL_TIME=`echo ${NEXT_TOTAL_CPU_T} ${LAST_TOTAL_CPU_T} | awk '{print $1-$2}'`
CPU_USAGE=`echo ${SYSTEM_IDLE} ${TOTAL_TIME} | awk '{printf "%.2f", 100-$1/$2*100}'`

echo "cpu=${CPU_USAGE}%"
#系统内存
mem_use_info=(`awk '/MemTotal/{memtotal=$2}/MemAvailable/{memavailable=$2}END{printf "%.2f %.2f %.2f",memtotal/1024/1024," "(memtotal-memavailable)/1024/1024," "(memtotal-memavailable)/memtotal*100}' /proc/meminfo`)

echo totalMem=${mem_use_info[0]}G
echo usedMem=${mem_use_info[1]}G
echo usageMem=${mem_use_info[2]}%

disk_size=$(df -h ./|awk -F: '{if(NR==2) print $1}')
echo "diskSize=$disk_size"
release=$(cat /etc/redhat-release)
echo "release=$release"
runtime=$(uptime)
echo "runTime=$runtime"
hostname=`hostname`
ip=`hostname -i`
echo "hostName=$hostname"
echo "ip=$ip"
sum=0
for io in `iostat -x |awk '{if(NR>6){print $14}}'`;do
sum=`echo "$io+$sum" | bc`;
done
echo "io=$sum"

部分参数获取方式有争议,而且根据操作系统不同和linux安装的命令工具不同会出现一定差异,需要自行摸索修改echo部分的命令(或者上网百度用法)。
java项目的结构如下所示
在这里插入图片描述
getServerStatus.java类中使用ServerSocket创建socket服务器,用于接收外部socket请求(可在其他项目创建test类发送socket请求服务器数据)

package serverStatus;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class GetServerStatus {
	public static void main(String[] args){
		ServerSocket ss=null;
		try {
			ss = new ServerSocket(2333);
		} catch (IOException e) {
			e.printStackTrace();
		}
		Socket s = null;
		DataInputStream bis = null;
		DataOutputStream bos = null;
		while (true) {
			try {
				if (s==null) {
					s = ss.accept();
					s.setKeepAlive(true);
				}
				if (bis==null) {
					bis = new DataInputStream(s.getInputStream());
				}
				String mess = bis.readUTF();
				if (bos==null) {
					bos = new DataOutputStream(s.getOutputStream());
				}
				if (mess.indexOf("EOF")!=-1) {
					if (bis!=null) {
						bis.close();
						bis=null;
					}
					if (bos!=null) {
						bos.close();
						bos=null;
					}
					if (s!=null) {
						s.close();
						s=null;
					}
					continue;
				}
				Map<String, Object> map = new HashMap<String, Object>();
				if (mess.indexOf(".sh")!=-1) {//是linux系统,则执行shell脚本获取服务器信息
					String result = ShellTest.shellTest(mess);
					if (result!=null) {
						result = new String(result.getBytes("utf-8"));
						String[] split = result.split("\\n");
						for (int i = 0; i < split.length; i++) {
							String[] split2 = split[i].split("=");
							if (split2.length==2) {
								map.put(split2[0].trim(), split2[1].trim());
							}
						}
					}
				}else {//不是linux系统则默认为windows系统,执行Java命令获取服务器信息
					map = Server4J.getServerStat();
				}
				String retMsg = JsonUtils.objectToJson(map);
				bos.writeUTF(retMsg);
				bos.flush();
			} catch (IOException e) {
				try {
					if (bis!=null) {
						bis.close();
						bis=null;
					}
					if (bos!=null) {
						bos.close();
						bos=null;
					}
					if (s!=null) {
						s.close();
						s=null;
					}
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
		
	}

}

简单写了一个长连接,在发送过来的参数中包含EOF关闭标识时或出现异常时才关闭流,其余状态下处于一直连接状态(因为当时想要不断轮询获取服务器参数)。
Server4J.java是之前测试用Java的api获取服务器参数的类,但是后来发现有些东西获取不到就改用shell了,这里不用关注。
JsonUtils.java是处理json格式报文的工具类,这里也不再赘述。
ShellTest.java类是java执行getStat.sh脚本的test类,这里的传入参数是shell脚本在linux中的存放全路径,使用的是java的Runtime类。

package serverStatus;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ShellTest {

	public static String shellTest(String mess) {
		String path = mess;
		try {
			Process p = Runtime.getRuntime().exec(path);
			BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
			StringBuffer sb = new StringBuffer();
			String line = null;
			while ((line=reader.readLine())!=null) {
				sb.append(line).append("\n");
			}
			String result = sb.toString();
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		} 
		
		return null;
	}

}

至此这个demo就差不多完成了,之后自己写一个test类发送socket请求到服务器上就可以尝试获取参数了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值