mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-09-06 14:18:26 +00:00
init project
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.monitor.model;
|
||||
|
||||
import com.zfoo.monitor.util.OSUtils;
|
||||
import com.zfoo.protocol.util.IOUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.scheduler.util.TimeUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class DiskFileSystemVO implements Comparable<DiskFileSystemVO> {
|
||||
|
||||
private String name;
|
||||
|
||||
private long size;
|
||||
|
||||
private long available;
|
||||
|
||||
private long timestamp;
|
||||
|
||||
public static DiskFileSystemVO valueOf(String name, long size, long available, long timestamp) {
|
||||
var vo = new DiskFileSystemVO();
|
||||
vo.name = name;
|
||||
vo.size = size;
|
||||
vo.available = available;
|
||||
vo.timestamp = timestamp;
|
||||
return vo;
|
||||
}
|
||||
|
||||
public String pressure() {
|
||||
var usage = 1D * (size - available) / size;
|
||||
if (usage >= 0.8) {
|
||||
var tempVO = this.toGB();
|
||||
return StringUtils.format("df - 磁盘[name:{}]空间过高[size:{}GB][available:{}GB][usage:{}][{}]"
|
||||
, name, tempVO.getSize(), tempVO.getAvailable(), OSUtils.toPercent(usage), TimeUtils.timeToString(timestamp));
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(DiskFileSystemVO target) {
|
||||
if (target == null) {
|
||||
return 1;
|
||||
}
|
||||
if (!this.name.equals(target.getName())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var a = 1D * (this.size - this.available) / this.size;
|
||||
var b = 1D * (target.getSize() - target.getAvailable()) / target.getSize();
|
||||
return Double.compare(a, b);
|
||||
}
|
||||
|
||||
public DiskFileSystemVO toMB() {
|
||||
var size = this.size / IOUtils.BYTES_PER_MB;
|
||||
var available = this.available / IOUtils.BYTES_PER_MB;
|
||||
return DiskFileSystemVO.valueOf(this.name, size, available, timestamp);
|
||||
}
|
||||
|
||||
public DiskFileSystemVO toGB() {
|
||||
var size = (long) Math.ceil(1D * this.size / IOUtils.BYTES_PER_GB);
|
||||
var available = (long) Math.ceil(1D * this.available / IOUtils.BYTES_PER_GB);
|
||||
return DiskFileSystemVO.valueOf(this.name, size, available, timestamp);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public long getAvailable() {
|
||||
return available;
|
||||
}
|
||||
|
||||
public void setAvailable(long available) {
|
||||
this.available = available;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.monitor.model;
|
||||
|
||||
import com.zfoo.monitor.util.OSUtils;
|
||||
import com.zfoo.protocol.util.IOUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.scheduler.util.TimeUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class MemoryVO implements Comparable<MemoryVO> {
|
||||
|
||||
private long total;
|
||||
|
||||
private long available;
|
||||
|
||||
private long timestamp;
|
||||
|
||||
public static MemoryVO valueOf(long total, long available, long timestamp) {
|
||||
var vo = new MemoryVO();
|
||||
vo.total = total;
|
||||
vo.available = available;
|
||||
vo.timestamp = timestamp;
|
||||
return vo;
|
||||
}
|
||||
|
||||
public String pressure() {
|
||||
var usage = 1D * (total - available) / total;
|
||||
if (usage >= 0.8) {
|
||||
var tempVO = this.toGB();
|
||||
return StringUtils.format("free - 内存占用过高[total:{}GB][available:{}GB][usage:{}][{}]"
|
||||
, tempVO.getTotal(), tempVO.getAvailable(), OSUtils.toPercent(usage), TimeUtils.timeToString(timestamp));
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MemoryVO target) {
|
||||
if (target == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
var a = 1D * (this.total - this.available) / this.total;
|
||||
var b = 1D * (target.getTotal() - target.getAvailable()) / target.getTotal();
|
||||
return Double.compare(a, b);
|
||||
}
|
||||
|
||||
public MemoryVO toMB() {
|
||||
var total = this.total / IOUtils.BYTES_PER_MB;
|
||||
var available = this.available / IOUtils.BYTES_PER_MB;
|
||||
return MemoryVO.valueOf(total, available, timestamp);
|
||||
}
|
||||
|
||||
public MemoryVO toGB() {
|
||||
var total = (long) Math.ceil(1D * this.total / IOUtils.BYTES_PER_GB);
|
||||
var available = (long) Math.ceil(1D * this.available / IOUtils.BYTES_PER_GB);
|
||||
return MemoryVO.valueOf(total, available, timestamp);
|
||||
}
|
||||
|
||||
public long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public long getAvailable() {
|
||||
return available;
|
||||
}
|
||||
|
||||
public void setAvailable(long available) {
|
||||
this.available = available;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.monitor.model;
|
||||
|
||||
import com.zfoo.monitor.util.OSUtils;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.scheduler.util.TimeUtils;
|
||||
import com.zfoo.util.net.NetUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class MonitorVO {
|
||||
|
||||
private String uuid;
|
||||
|
||||
private UptimeVO uptime;
|
||||
|
||||
private List<DiskFileSystemVO> df;
|
||||
|
||||
private MemoryVO free;
|
||||
|
||||
private List<SarVO> sar;
|
||||
|
||||
public static MonitorVO valueOf(String uuid, UptimeVO uptime, List<DiskFileSystemVO> df, MemoryVO free, List<SarVO> sar) {
|
||||
var vo = new MonitorVO();
|
||||
vo.uuid = uuid;
|
||||
vo.uptime = uptime;
|
||||
vo.df = df;
|
||||
vo.free = free;
|
||||
vo.sar = sar;
|
||||
return vo;
|
||||
}
|
||||
|
||||
public List<String> toPressures() {
|
||||
var messages = new ArrayList<String>();
|
||||
|
||||
var uptimeMessage = uptime.pressure();
|
||||
if (!StringUtils.isBlank(uptimeMessage)) {
|
||||
messages.add(uptimeMessage);
|
||||
}
|
||||
|
||||
for (var fileSystem : df) {
|
||||
var dfMessage = fileSystem.pressure();
|
||||
if (!StringUtils.isBlank(dfMessage)) {
|
||||
messages.add(dfMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var freeMessage = free.pressure();
|
||||
if (!StringUtils.isBlank(freeMessage)) {
|
||||
messages.add(freeMessage);
|
||||
}
|
||||
|
||||
for (var networkIF : sar) {
|
||||
var sarMessage = networkIF.pressure();
|
||||
if (!StringUtils.isBlank(sarMessage)) {
|
||||
messages.add(sarMessage);
|
||||
}
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
var builder = new StringBuilder();
|
||||
builder.append(StringUtils.format("Server Monitor [ip:{}] [uuid:{}]", NetUtils.getLocalhostStr(), uuid));
|
||||
builder.append(FileUtils.LS);
|
||||
builder.append(StringUtils.format("1.cpu: [{}] [{}] [{}] [usage:{}] [{}]"
|
||||
, uptime.getOneMinute(), uptime.getFiveMinute(), uptime.getFiftyMinute(), OSUtils.toPercent(uptime.getUsage()), TimeUtils.timeToString(uptime.getTimestamp())));
|
||||
builder.append(FileUtils.LS);
|
||||
builder.append(StringUtils.format("2.memory: [total:{}GB] [available:{}GB] [usage:{}] [{}]"
|
||||
, free.toGB().getTotal(), free.toGB().getAvailable(), OSUtils.toPercent(1D * (free.getTotal() - free.getAvailable()) / free.getTotal()), TimeUtils.timeToString(free.getTimestamp())));
|
||||
builder.append(FileUtils.LS);
|
||||
builder.append("3.disk: ");
|
||||
builder.append(FileUtils.LS);
|
||||
df.forEach(it -> {
|
||||
builder.append(StringUtils.format(" [disk:{}] [size:{}GB] [available:{}GB] [usage:{}] [{}]"
|
||||
, it.getName(), it.toGB().getSize(), it.toGB().getAvailable(), OSUtils.toPercent(1D * (it.getSize() - it.getAvailable()) / it.getSize()), TimeUtils.timeToString(it.getTimestamp())));
|
||||
builder.append(FileUtils.LS);
|
||||
});
|
||||
builder.append("4.network:");
|
||||
builder.append(FileUtils.LS);
|
||||
sar.forEach(it -> {
|
||||
builder.append(StringUtils.format(" [interface:{}] [rxpck:{}] [txpck:{}] [rxBytes:{}] [txBytes:{}] [inErrors:{}] [outErrors:{}] [inDrops:{}] [collisions:{}] [{}]"
|
||||
, it.getName(), it.getRxpck(), it.getTxpck(), it.getRxBytes(), it.getTxBytes(), it.getInErrors(), it.getOutErrors(), it.getInDrops(), it.getCollisions(), TimeUtils.timeToString(it.getTimestamp())));
|
||||
builder.append(FileUtils.LS);
|
||||
});
|
||||
var pressures = toPressures();
|
||||
if (CollectionUtils.isNotEmpty(pressures)) {
|
||||
builder.append("summary of errors:");
|
||||
builder.append(FileUtils.LS);
|
||||
pressures.forEach(it -> builder.append(StringUtils.format(" {}", it)).append(FileUtils.LS));
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public UptimeVO getUptime() {
|
||||
return uptime;
|
||||
}
|
||||
|
||||
public void setUptime(UptimeVO uptime) {
|
||||
this.uptime = uptime;
|
||||
}
|
||||
|
||||
public List<DiskFileSystemVO> getDf() {
|
||||
return df;
|
||||
}
|
||||
|
||||
public void setDf(List<DiskFileSystemVO> df) {
|
||||
this.df = df;
|
||||
}
|
||||
|
||||
public MemoryVO getFree() {
|
||||
return free;
|
||||
}
|
||||
|
||||
public void setFree(MemoryVO free) {
|
||||
this.free = free;
|
||||
}
|
||||
|
||||
public List<SarVO> getSar() {
|
||||
return sar;
|
||||
}
|
||||
|
||||
public void setSar(List<SarVO> sar) {
|
||||
this.sar = sar;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.monitor.model;
|
||||
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.scheduler.util.TimeUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class SarVO implements Comparable<SarVO> {
|
||||
|
||||
private String name;
|
||||
|
||||
private long rxpck;
|
||||
|
||||
private long txpck;
|
||||
|
||||
private long rxBytes;
|
||||
|
||||
private long txBytes;
|
||||
|
||||
private long inErrors;
|
||||
|
||||
private long outErrors;
|
||||
|
||||
private long inDrops;
|
||||
|
||||
private long collisions;
|
||||
|
||||
private long timestamp;
|
||||
|
||||
public static SarVO valueOf(String name, long rxpck, long txpck, long rxBytes, long txBytes
|
||||
, long inErrors, long outErrors, long inDrops, long collisions, long timestamp) {
|
||||
var vo = new SarVO();
|
||||
vo.name = name;
|
||||
vo.rxpck = rxpck;
|
||||
vo.txpck = txpck;
|
||||
vo.rxBytes = rxBytes;
|
||||
vo.txBytes = txBytes;
|
||||
vo.inErrors = inErrors;
|
||||
vo.outErrors = outErrors;
|
||||
vo.inDrops = inDrops;
|
||||
vo.collisions = collisions;
|
||||
vo.timestamp = timestamp;
|
||||
return vo;
|
||||
}
|
||||
|
||||
public String pressure() {
|
||||
if (rxpck >= 5_0000) {
|
||||
return StringUtils.format("sar - 网卡流量[interface:{}] [rxpck:{}] [txpck:{}] [rxBytes:{}] [txBytes:{}] [inErrors:{}] [outErrors:{}] [inDrops:{}] [collisions:{}] [{}],性能影响:危险"
|
||||
, name, rxpck, txpck, rxBytes, txBytes, inErrors, outErrors, inDrops, collisions, TimeUtils.timeToString(timestamp));
|
||||
}
|
||||
if (inErrors > 0 || outErrors > 0 || inDrops > 0 || collisions > 0) {
|
||||
return StringUtils.format("sar - 网卡流量[interface:{}] [rxpck:{}] [txpck:{}] [rxBytes:{}] [txBytes:{}] [inErrors:{}] [outErrors:{}] [inDrops:{}] [collisions:{}] [{}],性能影响:低"
|
||||
, name, rxpck, txpck, rxBytes, txBytes, inErrors, outErrors, inDrops, collisions, TimeUtils.timeToString(timestamp));
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(SarVO target) {
|
||||
if (target == null) {
|
||||
return 1;
|
||||
}
|
||||
if (!this.name.equals(target.getName())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var a = this.rxpck + this.txpck;
|
||||
var b = target.getRxpck() + target.getTxpck();
|
||||
return Long.compare(a, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtils.format("[name:{}][rxpck:{}][txpck:{}][rxBytes:{}][txBytes:{}][inErrors:{}][outErrors:{}][inDrops:{}][collisions:{}][time:{}]"
|
||||
, name, rxpck, txpck, rxBytes, txBytes, inErrors, outErrors, inDrops, collisions, TimeUtils.timeToString(timestamp));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getRxpck() {
|
||||
return rxpck;
|
||||
}
|
||||
|
||||
public void setRxpck(long rxpck) {
|
||||
this.rxpck = rxpck;
|
||||
}
|
||||
|
||||
public long getTxpck() {
|
||||
return txpck;
|
||||
}
|
||||
|
||||
public void setTxpck(long txpck) {
|
||||
this.txpck = txpck;
|
||||
}
|
||||
|
||||
public long getRxBytes() {
|
||||
return rxBytes;
|
||||
}
|
||||
|
||||
public void setRxBytes(long rxBytes) {
|
||||
this.rxBytes = rxBytes;
|
||||
}
|
||||
|
||||
public long getTxBytes() {
|
||||
return txBytes;
|
||||
}
|
||||
|
||||
public void setTxBytes(long txBytes) {
|
||||
this.txBytes = txBytes;
|
||||
}
|
||||
|
||||
public long getInErrors() {
|
||||
return inErrors;
|
||||
}
|
||||
|
||||
public void setInErrors(long inErrors) {
|
||||
this.inErrors = inErrors;
|
||||
}
|
||||
|
||||
public long getOutErrors() {
|
||||
return outErrors;
|
||||
}
|
||||
|
||||
public void setOutErrors(long outErrors) {
|
||||
this.outErrors = outErrors;
|
||||
}
|
||||
|
||||
public long getInDrops() {
|
||||
return inDrops;
|
||||
}
|
||||
|
||||
public void setInDrops(long inDrops) {
|
||||
this.inDrops = inDrops;
|
||||
}
|
||||
|
||||
public long getCollisions() {
|
||||
return collisions;
|
||||
}
|
||||
|
||||
public void setCollisions(long collisions) {
|
||||
this.collisions = collisions;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.monitor.model;
|
||||
|
||||
import com.zfoo.monitor.util.OSUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.scheduler.util.TimeUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class UptimeVO implements Comparable<UptimeVO> {
|
||||
|
||||
private double oneMinute;
|
||||
|
||||
private double fiveMinute;
|
||||
|
||||
private double fiftyMinute;
|
||||
|
||||
private double usage;
|
||||
|
||||
private long timestamp;
|
||||
|
||||
public static UptimeVO valueOf(double oneMinute, double fiveMinute, double fiftyMinute, double usage, long timestamp) {
|
||||
var vo = new UptimeVO();
|
||||
vo.oneMinute = oneMinute;
|
||||
vo.fiveMinute = fiveMinute;
|
||||
vo.fiftyMinute = fiftyMinute;
|
||||
vo.usage = usage;
|
||||
vo.timestamp = timestamp;
|
||||
return vo;
|
||||
}
|
||||
|
||||
public String pressure() {
|
||||
var processors = OSUtils.availableProcessors();
|
||||
var one = oneMinute / processors;
|
||||
var five = fiveMinute / processors;
|
||||
var fifty = fiftyMinute / processors;
|
||||
|
||||
if (usage >= 0.8) {
|
||||
return StringUtils.format("uptime - cpu负载[{}][{}][{}][usage:{}][{}]过大,性能影响:危险"
|
||||
, oneMinute, fiveMinute, fiftyMinute, OSUtils.toPercent(usage), TimeUtils.timeToString(timestamp));
|
||||
}
|
||||
|
||||
if (one > 5 || five > 5 || fifty > 5) {
|
||||
return StringUtils.format("uptime - cpu负载[{}][{}][{}][usage:{}][{}]过大,性能影响:警告"
|
||||
, oneMinute, fiveMinute, fiftyMinute, OSUtils.toPercent(usage), TimeUtils.timeToString(timestamp));
|
||||
}
|
||||
|
||||
if (one > 4 || five > 4 || fifty > 4) {
|
||||
return StringUtils.format("uptime - cpu负载[{}][{}][{}][usage:{}][{}],性能影响:高"
|
||||
, oneMinute, fiveMinute, fiftyMinute, OSUtils.toPercent(usage), TimeUtils.timeToString(timestamp));
|
||||
}
|
||||
|
||||
if (one > 3 || five > 3 || fifty > 3) {
|
||||
return StringUtils.format("uptime - cpu负载[{}][{}][{}][usage:{}][{}],性能影响:中,考虑优化"
|
||||
, oneMinute, fiveMinute, fiftyMinute, OSUtils.toPercent(usage), TimeUtils.timeToString(timestamp));
|
||||
}
|
||||
|
||||
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(UptimeVO target) {
|
||||
if (target == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return Double.compare(this.usage, target.getUsage());
|
||||
}
|
||||
|
||||
public double getOneMinute() {
|
||||
return oneMinute;
|
||||
}
|
||||
|
||||
public void setOneMinute(double oneMinute) {
|
||||
this.oneMinute = oneMinute;
|
||||
}
|
||||
|
||||
public double getFiveMinute() {
|
||||
return fiveMinute;
|
||||
}
|
||||
|
||||
public void setFiveMinute(double fiveMinute) {
|
||||
this.fiveMinute = fiveMinute;
|
||||
}
|
||||
|
||||
public double getFiftyMinute() {
|
||||
return fiftyMinute;
|
||||
}
|
||||
|
||||
public void setFiftyMinute(double fiftyMinute) {
|
||||
this.fiftyMinute = fiftyMinute;
|
||||
}
|
||||
|
||||
public double getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
public void setUsage(double usage) {
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.monitor.util;
|
||||
|
||||
import com.zfoo.monitor.model.*;
|
||||
import com.zfoo.protocol.util.IOUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.scheduler.util.TimeUtils;
|
||||
import com.zfoo.util.security.IdUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import oshi.SystemInfo;
|
||||
import oshi.hardware.HardwareAbstractionLayer;
|
||||
import oshi.hardware.NetworkIF;
|
||||
import oshi.software.os.OperatingSystem;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Oshi库封装的工具类,通过此工具类,可获取系统、硬件相关信息
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class OSUtils {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(OSUtils.class);
|
||||
|
||||
/**
|
||||
* cpu的数量
|
||||
*/
|
||||
private static final int processors = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
/**
|
||||
* 系统信息
|
||||
*/
|
||||
private static final SystemInfo systemInfo = new SystemInfo();
|
||||
|
||||
/**
|
||||
* 硬件信息
|
||||
*/
|
||||
private static final HardwareAbstractionLayer hardware = systemInfo.getHardware();
|
||||
|
||||
/**
|
||||
* 操作系统信息
|
||||
*/
|
||||
private static final OperatingSystem os = systemInfo.getOperatingSystem();
|
||||
|
||||
/**
|
||||
* 网络信息
|
||||
*/
|
||||
private static final List<NetworkIF> networkIFs = hardware.getNetworkIFs();
|
||||
|
||||
/**
|
||||
* cpu的tick次数信息
|
||||
*/
|
||||
private static long[] ticks = hardware.getProcessor().getSystemCpuLoadTicks();
|
||||
|
||||
public static int availableProcessors() {
|
||||
return processors;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将小于0的num转为百分比,舍弃的部分将会做四舍五入
|
||||
*/
|
||||
public static String toPercent(double num) {
|
||||
if (num > 1) {
|
||||
throw new RuntimeException("转为百分比的num必须小于1");
|
||||
}
|
||||
var percentFormat = NumberFormat.getPercentInstance();
|
||||
// 最大小数位数
|
||||
percentFormat.setMaximumFractionDigits(2);
|
||||
// 最大整数位数
|
||||
percentFormat.setMaximumIntegerDigits(2);
|
||||
// 最小小数位数
|
||||
percentFormat.setMinimumFractionDigits(2);
|
||||
// 最小整数位数
|
||||
percentFormat.setMinimumIntegerDigits(2);
|
||||
// 自动转换成百分比显示
|
||||
return percentFormat.format(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对应于Linux中的uptime命令,windows中无法统计,所以在windows返回的结果默认是-1
|
||||
*/
|
||||
public static UptimeVO uptime() {
|
||||
var processor = hardware.getProcessor();
|
||||
var loads = processor.getSystemLoadAverage(3);
|
||||
var oneMinute = loads[0];
|
||||
var fiveMinute = loads[1];
|
||||
var fiftyMinute = loads[2];
|
||||
|
||||
var cpuTicks = processor.getSystemCpuLoadTicks();
|
||||
var usage = processor.getSystemCpuLoadBetweenTicks(ticks);
|
||||
|
||||
ticks = cpuTicks;
|
||||
return UptimeVO.valueOf(oneMinute, fiveMinute, fiftyMinute, usage, TimeUtils.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* 对应于Linux中的df -h命令,兼容windows
|
||||
*/
|
||||
public static List<DiskFileSystemVO> df() {
|
||||
var fileSystems = os.getFileSystem().getFileStores();
|
||||
var df = new ArrayList<DiskFileSystemVO>();
|
||||
var nameMap = new HashMap<String, Integer>();
|
||||
for (var fs : fileSystems) {
|
||||
var name = fs.getName();
|
||||
var size = fs.getTotalSpace();
|
||||
var available = fs.getFreeSpace();
|
||||
|
||||
var value = nameMap.get(name);
|
||||
if (value == null) {
|
||||
nameMap.put(name, 1);
|
||||
} else {
|
||||
name = name + value;
|
||||
nameMap.put(name, ++value);
|
||||
}
|
||||
|
||||
df.add(DiskFileSystemVO.valueOf(name, size, available, TimeUtils.now()));
|
||||
}
|
||||
return df;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对应于Linux中的free命令,兼容windows
|
||||
*/
|
||||
public static MemoryVO free() {
|
||||
var memory = hardware.getMemory();
|
||||
var total = memory.getTotal();
|
||||
var available = memory.getAvailable();
|
||||
return MemoryVO.valueOf(total, available, TimeUtils.now());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对应于Linux中的sar -n DEV 1命令,兼容windows
|
||||
*/
|
||||
public static List<SarVO> sar() {
|
||||
var sar = new ArrayList<SarVO>();
|
||||
for (var networkIF : networkIFs) {
|
||||
var name = networkIF.getDisplayName() + StringUtils.SPACE + networkIF.getName();
|
||||
var oldTimestamp = networkIF.getTimeStamp();
|
||||
var oldBytesRecv = networkIF.getBytesRecv();
|
||||
var oldBytesSent = networkIF.getBytesSent();
|
||||
var oldPacketsRecv = networkIF.getPacketsRecv();
|
||||
var oldPacketsSent = networkIF.getPacketsSent();
|
||||
var oldInErrors = networkIF.getInErrors();
|
||||
var oldOutErrors = networkIF.getOutErrors();
|
||||
var oldInDrops = networkIF.getInDrops();
|
||||
var oldCollisions = networkIF.getCollisions();
|
||||
|
||||
networkIF.updateAttributes();
|
||||
var timestamp = networkIF.getTimeStamp();
|
||||
var timeInterval = (timestamp - oldTimestamp) / 1000D;
|
||||
var rxpck = (long) Math.ceil(((networkIF.getPacketsRecv() - oldPacketsRecv) / timeInterval));
|
||||
var txpck = (long) Math.ceil((networkIF.getPacketsSent() - oldPacketsSent) / timeInterval);
|
||||
var rxBytes = (long) Math.ceil((networkIF.getBytesRecv() - oldBytesRecv) / timeInterval);
|
||||
var txBytes = (long) Math.ceil((networkIF.getBytesSent() - oldBytesSent) / timeInterval);
|
||||
var inErrors = networkIF.getInErrors() - oldInErrors;
|
||||
var outErrors = networkIF.getOutErrors() - oldOutErrors;
|
||||
var inDrops = networkIF.getInDrops() - oldInDrops;
|
||||
var collisions = networkIF.getCollisions() - oldCollisions;
|
||||
|
||||
sar.add(SarVO.valueOf(name, rxpck, txpck, rxBytes, txBytes, inErrors, outErrors, inDrops, collisions, timestamp));
|
||||
}
|
||||
return sar;
|
||||
}
|
||||
|
||||
private static UptimeVO maxUptime;
|
||||
private static Map<String, DiskFileSystemVO> maxDfMap;
|
||||
private static MemoryVO maxFree;
|
||||
private static Map<String, SarVO> maxSarMap;
|
||||
|
||||
static {
|
||||
initMonitor();
|
||||
}
|
||||
|
||||
public static void initMonitor() {
|
||||
maxUptime = uptime();
|
||||
maxDfMap = new ConcurrentHashMap<>(df().stream().collect(Collectors.toMap(key -> key.getName(), value -> value)));
|
||||
maxFree = free();
|
||||
maxSarMap = new ConcurrentHashMap<>(sar().stream().collect(Collectors.toMap(key -> key.getName(), value -> value)));
|
||||
}
|
||||
|
||||
public static MonitorVO maxMonitor() {
|
||||
var uuid = IdUtils.getUUID();
|
||||
var monitor = MonitorVO.valueOf(uuid, maxUptime, new ArrayList<>(maxDfMap.values()), maxFree, new ArrayList<>(maxSarMap.values()));
|
||||
|
||||
initMonitor();
|
||||
return monitor;
|
||||
}
|
||||
|
||||
public static MonitorVO monitor() {
|
||||
var uuid = IdUtils.getUUID();
|
||||
var uptime = uptime();
|
||||
var df = df();
|
||||
var free = free();
|
||||
var sar = sar();
|
||||
|
||||
if (uptime.compareTo(maxUptime) > 0) {
|
||||
maxUptime = uptime;
|
||||
}
|
||||
|
||||
for (var fileSystem : df) {
|
||||
var maxFileSystem = maxDfMap.get(fileSystem.getName());
|
||||
if (maxFileSystem != null && fileSystem.compareTo(maxFileSystem) > 0) {
|
||||
maxDfMap.put(fileSystem.getName(), fileSystem);
|
||||
}
|
||||
}
|
||||
|
||||
if (free.compareTo(maxFree) > 0) {
|
||||
maxFree = free;
|
||||
}
|
||||
|
||||
for (var networkIF : sar) {
|
||||
var maxNetworkIF = maxSarMap.get(networkIF.getName());
|
||||
if (maxNetworkIF != null && networkIF.compareTo(maxNetworkIF) > 0) {
|
||||
maxSarMap.put(maxNetworkIF.getName(), networkIF);
|
||||
}
|
||||
}
|
||||
|
||||
return MonitorVO.valueOf(uuid, uptime, df, free, sar);
|
||||
}
|
||||
|
||||
public static String execCommand(String command) {
|
||||
Process process = null;
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
process = new ProcessBuilder(command.split(" "))
|
||||
.redirectErrorStream(true)
|
||||
.start();
|
||||
|
||||
//取得命令结果的输出流
|
||||
inputStream = process.getInputStream();
|
||||
var bytes = IOUtils.toByteArray(inputStream);
|
||||
var result = StringUtils.bytesToString(bytes);
|
||||
|
||||
// 其他线程都等待这个线程完成
|
||||
process.waitFor();
|
||||
// 获取javac线程的退出值,0代表正常退出,非0代表异常中止
|
||||
int exitValue = process.exitValue();
|
||||
|
||||
// 返回编译是否成功
|
||||
if (exitValue != 0) {
|
||||
throw new Exception("执行命令错误,返回码:" + exitValue);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
logger.error("命令执行未知异常", e);
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
IOUtils.closeIO(inputStream);
|
||||
}
|
||||
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.monitor;
|
||||
|
||||
import com.zfoo.monitor.util.OSUtils;
|
||||
import com.zfoo.protocol.util.JsonUtils;
|
||||
import com.zfoo.util.ThreadUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import oshi.SystemInfo;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ApplicationTest {
|
||||
|
||||
/**
|
||||
* 仿Linux的uptime指令,可以用来监控cpu的负载
|
||||
*/
|
||||
@Test
|
||||
public void uptimeTest() {
|
||||
var vo = OSUtils.uptime();
|
||||
System.out.println(JsonUtils.object2String(vo));
|
||||
System.out.println(vo.pressure());
|
||||
}
|
||||
|
||||
/**
|
||||
* 仿Linux的df指令,可以用来监控硬盘容量
|
||||
*/
|
||||
@Test
|
||||
public void dfTest() {
|
||||
var df = OSUtils.df();
|
||||
df.forEach(it -> {
|
||||
System.out.println(JsonUtils.object2String(it.toGB()));
|
||||
System.out.println(it.pressure());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 仿Linux的free指令,可以用来监控内存占用
|
||||
*/
|
||||
@Test
|
||||
public void freeTest() {
|
||||
var free = OSUtils.free();
|
||||
System.out.println(JsonUtils.object2String(free.toGB()));
|
||||
System.out.println(free.pressure());
|
||||
}
|
||||
|
||||
/**
|
||||
* 仿Linux的sar指令,可以用来监控网络IO
|
||||
*/
|
||||
@Test
|
||||
public void sarTest() {
|
||||
var sar = OSUtils.sar();
|
||||
sar.forEach(it -> {
|
||||
System.out.println(JsonUtils.object2String(it));
|
||||
System.out.println(it.pressure());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu的tick大小测试
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void cpuTest() {
|
||||
var systemInfo = new SystemInfo();
|
||||
var hardware = systemInfo.getHardware();
|
||||
var os = systemInfo.getOperatingSystem();
|
||||
|
||||
while (true) {
|
||||
var oldTicks = hardware.getProcessor().getSystemCpuLoadTicks();
|
||||
ThreadUtils.sleep(1000);
|
||||
var usage = hardware.getProcessor().getSystemCpuLoadBetweenTicks(oldTicks);
|
||||
System.out.println(usage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制台指令执行测试
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void execCommandTest() {
|
||||
var str = OSUtils.execCommand("cmd /c jps");
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toPercentTest() {
|
||||
var num = 0.123456D;
|
||||
var str = OSUtils.toPercent(num);
|
||||
Assert.assertEquals(str, "12.35%");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void monitorTest() {
|
||||
var monitor = OSUtils.monitor();
|
||||
System.out.println(monitor);
|
||||
ThreadUtils.sleep(1000);
|
||||
monitor = OSUtils.monitor();
|
||||
System.out.println(monitor);
|
||||
monitor = OSUtils.maxMonitor();
|
||||
System.out.println(monitor);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user