service
/**
* 正在运行的进程
*/
private static Map<String, TaskProcess> runningProcess = new ConcurrentHashMap<String, TaskProcess>();
/**
* 查看其它机器日志
* @param instanceAddr
* @param instance
* @param logFileName
*/
public static void addAssistantTask(String instanceAddr, String instance, String logFileName, String username, String pwd){
String processName = instanceAddr + instance;
//如果没有任务则创建任务
if(!runningProcess.containsKey(processName)){
synchronized(CrtRunner.class){
if(runningProcess.containsKey(processName)){
return;
}
String jsFile = StatusSupervisor.class.getResource("/log-stg-other.js").getPath();
jsFile = jsFile.substring(1, jsFile.length());
try {
String ins = instance.replaceAll("_", "-") ;
String localLog = crtlogpath + "\\" + ins + "-" + instanceAddr + ".log";
//替换非法字符以便生成日志文件
localLog = localLog.replaceAll("@", "-");
new File(localLog).delete();
new File(localLog).createNewFile();
Process exec = Runtime.getRuntime().exec("C:\\SecureCRT\\SecureCRT.exe "
+ "/SCRIPT " + jsFile + " "
+ "/ARG " + instanceAddr + " " //机器地址
+ "/ARG " + instance + " " //实例名
+ "/ARG " + logFileName + " "
+ "/ARG " + username + " "
+ "/ARG " + pwd + " "
+ "/LOG " + localLog + " "
+ "/PASSWORD " + crtPwd + " "
+ crtUser + "@ts");
runningProcess.put(processName, new TaskProcess(exec, new LogTask(localLog)));
tasks.add(processName);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
}
/**
* 在实例上注册数据通道
* @param instanceIp 实例ip
* @param instance 实例名
* @param remoteAddr 客户端ip
* @param token
* @throws Exception
*/
public static boolean registerChannel(String instanceIp, String instance, String remoteAddr, String token) throws Exception{
TaskProcess tp = runningProcess.get(instanceIp + instance);
if(tp == null){
throw new Exception("通道已关闭, 请重新连接");
}
return tp.getTask().registerChannel(remoteAddr, token);
}
/**
* 读取数据
* @param instanceAddr
* @param instance
* @param start
* @param addr
* @param channelId
* @throws Exception
*/
public static LogTask readData(String instanceAddr, String instance, int start, String addr, String channelId, String filter) throws Exception{
TaskProcess tp = runningProcess.get(instanceAddr + instance);
if(null == tp){
throw new Exception("通道已关闭, 请重新连接");
}
return tp.getTask().readData(start, addr, channelId, filter);
}
public static class TaskProcess{
Process process;
LogTask task;
public TaskProcess(Process process, LogTask task) {
super();
this.process = process;
this.task = task;
}
public Process getProcess() {
return process;
}
public LogTask getTask() {
return task;
}
}
/**
* 通道
*
*/
private static class Channel{
private String token;
//上次活跃时间
private long lastActiveTime;
private List<String> cache = new ArrayList<String>();
public Channel(String token) {
super();
this.token = token;
this.lastActiveTime = new Date().getTime();
}
public String getToken() {
return token;
}
public boolean isOutOfDate(){
return new Date().getTime() - lastActiveTime > CHANNEL_MAX_IDLE_TIME;
}
public void addCache(String data){
this.cache.add(data);
}
public List<String> readCache(){
return cache;
}
public boolean hasValidCache(String filter){
for(String line : cache){
if(line.toLowerCase().contains(filter.toLowerCase())){
return true;
}
}
return false;
}
public void clearCache(){
this.cache.clear();
}
/**
* 刷新访问时间
*/
public void refresh(){
this.lastActiveTime = new Date().getTime();
}
}
/**
* 日志任务类
*
*/
public static class LogTask{
//保存合法的数据通道凭证, key是IP, value是通道号
Map<String, Channel> channels = new ConcurrentHashMap<String, Channel>();
//日志文件
public String logFile;
//上次访问时间
private long lastAccess = new Date().getTime();
public long startTime = new Date().getTime();
private LineNumberReader reader;
//最大行数
private int maxLine = 0;
//记录上次读取的位置
private int index;
private List<String> results;
private boolean stop = false;
/**
* 停止任务
*/
public void stop(){
stop = true;
run = false;
close();
}
public long getLastAccess() {
return lastAccess;
}
/**
* 检查channel
*/
public void checkChannel(){
for(String ip : channels.keySet()){
if(channels.get(ip).isOutOfDate()){
AuditLog.info("remove channel [" + channels.remove(ip) + "], remoteAddr: [" + ip + "]");
}
}
}
private synchronized void close() {
try {
reader.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
public boolean registerChannel(String ip, String token){
if(channels.containsKey(ip)){
return false;
}
channels.put(ip, new Channel(token));
//并发注册只能有一个人成功
return channels.get(ip).getToken().equals(token);
}
/**
* 从指定的行开始读取数据
* @param from
* @param addr
* @param channelId
* @param filter 过滤条件
* @return
* @throws Exception
*/
public synchronized LogTask readData(int from, String addr, String channelId, String filter) throws Exception{
if(!channels.containsKey(addr) || !channelId.equals(channels.get(addr).getToken())){
throw new Exception("非法通道");
}
channels.get(addr).refresh();
lastAccess = new Date().getTime();
List<String> data = new ArrayList<String>();
if(stop){
return new LogTask(0, data);
}
if(from == 0){
from = maxLine;
}
reader.setLineNumber(from);
String line = "";
try {
int begin = 0;
while(null != (line = reader.readLine()) && !stop){
from++;
if(StringUtils.isNotBlank(filter)){
//开启过滤器
if(line.contains("INFO]") || line.contains("DEBUG]")
|| line.contains("FATAL]")
|| line.contains("ERROR]")){
//新的段落
if(channels.get(addr).hasValidCache(filter)){
data.addAll(channels.get(addr).readCache());
}
channels.get(addr).clearCache();
begin++;
}
channels.get(addr).addCache(line.replaceAll("(?i)" + filter, "<label style='color:fuchsia;'>" + filter + "</label>"));
}else{
data.add(line);
begin++;
}
//单次最大读取100条,防止并发时独占reader
if(begin == 100){
break;
}
}
if(channels.get(addr).hasValidCache(filter)){
data.addAll(channels.get(addr).readCache());
channels.get(addr).clearCache();
begin++;
}
if(from > maxLine){
maxLine = from;
}
} catch (IOException e) {
e.printStackTrace();
}
return new LogTask(from, data);
}
public LogTask(int index, List<String> data) {
super();
this.index = index;
this.results = data;
}
public LogTask(String logFile) throws IOException, InterruptedException {
super();
this.logFile = logFile;
reader = new LineNumberReader(new InputStreamReader(new FileInputStream(logFile),"utf-8"));
while(null != reader.readLine()){
maxLine++;
}
}
public List<String> getResults() {
return results;
}
public int getIndex() {
return index;
}
//标识任务在run
public boolean run = true;
public boolean isRun() {
return run;
}
}