Browse Source

日志rollback展示

xueli.xue 8 years ago
parent
commit
ae26cb0c5d

BIN
doc/images/qq群-一个xxl同学进了58.png View File


+ 30 - 30
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java View File

7
 import com.xxl.job.admin.dao.IXxlJobInfoDao;
7
 import com.xxl.job.admin.dao.IXxlJobInfoDao;
8
 import com.xxl.job.admin.dao.IXxlJobLogDao;
8
 import com.xxl.job.admin.dao.IXxlJobLogDao;
9
 import com.xxl.job.core.biz.ExecutorBiz;
9
 import com.xxl.job.core.biz.ExecutorBiz;
10
+import com.xxl.job.core.biz.model.LogResult;
10
 import com.xxl.job.core.biz.model.ReturnT;
11
 import com.xxl.job.core.biz.model.ReturnT;
11
 import com.xxl.job.core.rpc.netcom.NetComClientProxy;
12
 import com.xxl.job.core.rpc.netcom.NetComClientProxy;
12
 import org.apache.commons.lang.StringUtils;
13
 import org.apache.commons.lang.StringUtils;
92
 	    maps.put("data", list);  					// 分页列表
93
 	    maps.put("data", list);  					// 分页列表
93
 		return maps;
94
 		return maps;
94
 	}
95
 	}
95
-	
96
-	@RequestMapping("/logDetail")
97
-	@ResponseBody
98
-	public ReturnT<String> logDetail(int id){
96
+
97
+	@RequestMapping("/logDetailPage")
98
+	public String logDetailPage(int id, Model model){
99
+
99
 		// base check
100
 		// base check
100
-		XxlJobLog log = xxlJobLogDao.load(id);
101
-		if (log == null) {
102
-			return new ReturnT<String>(500, "查看执行日志失败: 参数异常");
103
-		}
104
-		if (ReturnT.SUCCESS_CODE != log.getTriggerCode()) {
105
-			return new ReturnT<String>(500, "查看执行日志失败: 任务发起调度失败,无法查看执行日志");
101
+		ReturnT<String> logStatue = ReturnT.SUCCESS;
102
+		XxlJobLog jobLog = xxlJobLogDao.load(id);
103
+		if (jobLog == null) {
104
+			logStatue = new ReturnT<String>(ReturnT.FAIL_CODE, "查看执行日志失败: 日志ID非法");
105
+		} else {
106
+			if (ReturnT.SUCCESS_CODE != jobLog.getTriggerCode()) {
107
+				logStatue = new ReturnT<String>(ReturnT.FAIL_CODE, "查看执行日志失败: 任务发起调度失败,无法查看执行日志");
108
+			}
109
+
110
+			model.addAttribute("executorAddress", jobLog.getExecutorAddress());
111
+			model.addAttribute("triggerTime", jobLog.getTriggerTime().getTime());
112
+			model.addAttribute("logId", jobLog.getId());
106
 		}
113
 		}
107
-		
108
-		// trigger id, trigger time
109
-		ExecutorBiz executorBiz = null;
114
+
115
+		model.addAttribute("logStatue", logStatue);
116
+		return "joblog/logdetail";
117
+	}
118
+
119
+	@RequestMapping("/logDetailCat")
120
+	@ResponseBody
121
+	public ReturnT<LogResult> logDetailCat(String executorAddress, long triggerTime, int logId, int fromLineNum){
110
 		try {
122
 		try {
111
-			executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, log.getExecutorAddress()).getObject();
123
+			ExecutorBiz executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, executorAddress).getObject();
124
+			ReturnT<LogResult> logResult = executorBiz.log(triggerTime, logId, fromLineNum);
125
+			return logResult;
112
 		} catch (Exception e) {
126
 		} catch (Exception e) {
113
 			e.printStackTrace();
127
 			e.printStackTrace();
114
-			return new ReturnT<String>(500, e.getMessage());
115
-		}
116
-		ReturnT<String> logResult = executorBiz.log(log.getTriggerTime().getTime(), id);
117
-
118
-		if (ReturnT.SUCCESS_CODE == logResult.getCode()) {
119
-			return new ReturnT<String>(logResult.getMsg());
120
-		} else {
121
-			return new ReturnT<String>(500, "查看执行日志失败: " + logResult.getMsg());
128
+			return new ReturnT<LogResult>(ReturnT.FAIL_CODE, e.getMessage());
122
 		}
129
 		}
123
 	}
130
 	}
124
-	
125
-	@RequestMapping("/logDetailPage")
126
-	public String logDetailPage(int id, Model model){
127
-		ReturnT<String> data = logDetail(id);
128
-		model.addAttribute("result", data);
129
-		return "joblog/logdetail";
130
-	}
131
-	
131
+
132
 	@RequestMapping("/logKill")
132
 	@RequestMapping("/logKill")
133
 	@ResponseBody
133
 	@ResponseBody
134
 	public ReturnT<String> logKill(int id){
134
 	public ReturnT<String> logKill(int id){

+ 94 - 6
xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/logdetail.ftl View File

1
-<body style="color:white;background-color:black;" >
2
-<pre>
3
-<br>
4
-<#if result.code == 200>${result.content}
5
-<#else>${result.msg}</#if>
6
-</pre>
1
+<!DOCTYPE html>
2
+<html>
3
+<head>
4
+    <title>任务调度中心</title>
5
+<#import "/common/common.macro.ftl" as netCommon>
6
+<@netCommon.commonStyle />
7
+    <style type="text/css">
8
+        .logConsolePre {
9
+            font-size:12px;
10
+            width: 100%;
11
+            height: 100%;
12
+            /*bottom: 0;
13
+            top: 0px;*/
14
+            position: absolute;
15
+            /*color:white;background-color:black*/
16
+        }
17
+        .logConsoleRunning {
18
+            font-size: 20px;
19
+            margin-top: 7px;
20
+        }
21
+    </style>
22
+</head>
23
+<body class="skin-blue fixed layout-top-nav">
24
+
25
+<div class="wrapper">
26
+
27
+    <header class="main-header">
28
+        <nav class="navbar navbar-static-top">
29
+            <div class="container">
30
+            <#-- icon -->
31
+                <div class="navbar-header">
32
+                    <a href="../../index2.html" class="navbar-brand"><b>日志</b>Console</a>
33
+                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse">
34
+                        <i class="fa fa-bars"></i>
35
+                    </button>
36
+                </div>
37
+
38
+                <#-- left nav -->
39
+                <div class="collapse navbar-collapse pull-left" id="navbar-collapse">
40
+                    <ul class="nav navbar-nav">
41
+                        <#--<li class="active" ><a href="javascript:;">任务:<span class="sr-only">(current)</span></a></li>-->
42
+                    </ul>
43
+                </div>
44
+
45
+                <#-- right nav -->
46
+                <div class="navbar-custom-menu">
47
+                    <ul class="nav navbar-nav">
48
+                        <li>
49
+                            <a href="javascript:window.location.reload();" >
50
+                                <i class="fa fa-fw fa-refresh" ></i>
51
+                                刷新
52
+                            </a>
53
+                        </li>
54
+                    </ul>
55
+                </div>
56
+
57
+            </div>
58
+        </nav>
59
+    </header>
60
+
61
+    <div class="content-wrapper" >
62
+        <pre class="logConsolePre"><div id="logConsole"></div><li class="fa fa-refresh fa-spin logConsoleRunning" ></li></pre>
63
+    </div>
64
+
65
+</div>
66
+
67
+<@netCommon.commonScript />
68
+<script>
69
+
70
+    // 参数
71
+    var running = true;     // 允许运行
72
+    var executorAddress;
73
+    var triggerTime;
74
+    var logId;
75
+
76
+    // init
77
+    <#if logStatue.code == 200>
78
+        running = true;
79
+        $('.logConsoleRunning').show();
80
+
81
+        executorAddress = '${executorAddress}';
82
+        triggerTime = '${triggerTime}';
83
+        logId = '${logId}';
84
+    <#else>
85
+        running = false;
86
+        $('.logConsoleRunning').hide();
87
+
88
+        $('.logConsole').append('${logStatue.msg}');
89
+    </#if>
90
+
91
+</script>
92
+<script src="${request.contextPath}/static/js/logdetail.index.1.js"></script>
93
+
7
 </body>
94
 </body>
95
+</html>

+ 78 - 0
xxl-job-admin/src/main/webapp/static/js/logdetail.index.1.js View File

1
+$(function() {
2
+
3
+	// valid
4
+	if (!running) {
5
+		return;
6
+	}
7
+
8
+	// 加载日志
9
+	var fromLineNum = 0;
10
+	var pullFailCount = 0;
11
+	function pullLog() {
12
+
13
+		// pullFailCount, max=20
14
+		if (pullFailCount >= 20) {
15
+			console.log("pullLog fail-count limit");
16
+			running = false;
17
+		}
18
+
19
+		// valid
20
+		if (!running) {
21
+			$('.logConsoleRunning').hide();
22
+			logRun = window.clearInterval(logRun)
23
+			return;
24
+		}
25
+
26
+		// load
27
+		console.log("pullLog, fromLineNum:" + fromLineNum);
28
+		$.ajax({
29
+			type : 'POST',
30
+			async: false,   // async, avoid js invoke pagelist before jobId data init
31
+			url : base_url + '/joblog/logDetailCat',
32
+			data : {
33
+				"executorAddress":executorAddress,
34
+				"triggerTime":triggerTime,
35
+				"logId":logId,
36
+				"fromLineNum":fromLineNum
37
+			},
38
+			dataType : "json",
39
+			success : function(data){
40
+				pullFailCount++;
41
+				if (data.code == 200) {
42
+					if (!data.content) {
43
+						console.log('pullLog fail');
44
+						return;
45
+					}
46
+					if (fromLineNum != data.content.fromLineNum) {
47
+						console.log('pullLog fromLineNum not match');
48
+						return;
49
+					}
50
+					if (fromLineNum == (data.content.toLineNum + 1) ) {
51
+						console.log('pullLog already line-end');
52
+						return;
53
+					}
54
+
55
+					// append
56
+					fromLineNum = data.content.toLineNum + 1;
57
+					$('#logConsole').append(data.content.logContent);
58
+					pullFailCount = 0;
59
+
60
+					// valid end
61
+					if (data.content.end) {
62
+						running = false;
63
+						console.log("pullLog already file-end");
64
+					}
65
+				} else {
66
+					ComAlertTec.show(data.msg);
67
+				}
68
+			}
69
+		});
70
+	}
71
+
72
+	// 周期运行
73
+	pullLog();
74
+	var logRun = setInterval(function () {
75
+		pullLog()
76
+	}, 3000);
77
+
78
+});

+ 3 - 1
xxl-job-core/src/main/java/com/xxl/job/core/biz/ExecutorBiz.java View File

1
 package com.xxl.job.core.biz;
1
 package com.xxl.job.core.biz;
2
 
2
 
3
+import com.xxl.job.core.biz.model.LogResult;
3
 import com.xxl.job.core.biz.model.ReturnT;
4
 import com.xxl.job.core.biz.model.ReturnT;
4
 import com.xxl.job.core.biz.model.TriggerParam;
5
 import com.xxl.job.core.biz.model.TriggerParam;
5
 
6
 
25
      * log
26
      * log
26
      * @param logDateTim
27
      * @param logDateTim
27
      * @param logId
28
      * @param logId
29
+     * @param fromLineNum
28
      * @return
30
      * @return
29
      */
31
      */
30
-    public ReturnT<String> log(long logDateTim, int logId);
32
+    public ReturnT<LogResult> log(long logDateTim, int logId, int fromLineNum);
31
 
33
 
32
     /**
34
     /**
33
      * run
35
      * run

+ 4 - 3
xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java View File

1
 package com.xxl.job.core.biz.impl;
1
 package com.xxl.job.core.biz.impl;
2
 
2
 
3
 import com.xxl.job.core.biz.ExecutorBiz;
3
 import com.xxl.job.core.biz.ExecutorBiz;
4
+import com.xxl.job.core.biz.model.LogResult;
4
 import com.xxl.job.core.biz.model.ReturnT;
5
 import com.xxl.job.core.biz.model.ReturnT;
5
 import com.xxl.job.core.biz.model.TriggerParam;
6
 import com.xxl.job.core.biz.model.TriggerParam;
6
 import com.xxl.job.core.executor.XxlJobExecutor;
7
 import com.xxl.job.core.executor.XxlJobExecutor;
42
     }
43
     }
43
 
44
 
44
     @Override
45
     @Override
45
-    public ReturnT<String> log(long logDateTim, int logId) {
46
+    public ReturnT<LogResult> log(long logDateTim, int logId, int fromLineNum) {
46
         // log filename: yyyy-MM-dd/9999.log
47
         // log filename: yyyy-MM-dd/9999.log
47
         String logFileName = XxlJobFileAppender.makeLogFileName(new Date(logDateTim), logId);
48
         String logFileName = XxlJobFileAppender.makeLogFileName(new Date(logDateTim), logId);
48
 
49
 
49
-        String logConteng = XxlJobFileAppender.readLog(logFileName);
50
-        return new ReturnT<String>(ReturnT.SUCCESS_CODE, logConteng);
50
+        LogResult logResult = XxlJobFileAppender.readLog(logFileName, fromLineNum);
51
+        return new ReturnT<LogResult>(logResult);
51
     }
52
     }
52
 
53
 
53
     @Override
54
     @Override

+ 47 - 0
xxl-job-core/src/main/java/com/xxl/job/core/biz/model/LogResult.java View File

1
+package com.xxl.job.core.biz.model;
2
+
3
+import java.io.Serializable;
4
+
5
+/**
6
+ * Created by xuxueli on 17/3/23.
7
+ */
8
+public class LogResult implements Serializable {
9
+    private static final long serialVersionUID = 42L;
10
+
11
+    private int fromLineNum;
12
+    private int toLineNum;
13
+    private String logContent;
14
+    private boolean isEnd;
15
+
16
+    public int getFromLineNum() {
17
+        return fromLineNum;
18
+    }
19
+
20
+    public void setFromLineNum(int fromLineNum) {
21
+        this.fromLineNum = fromLineNum;
22
+    }
23
+
24
+    public int getToLineNum() {
25
+        return toLineNum;
26
+    }
27
+
28
+    public void setToLineNum(int toLineNum) {
29
+        this.toLineNum = toLineNum;
30
+    }
31
+
32
+    public String getLogContent() {
33
+        return logContent;
34
+    }
35
+
36
+    public void setLogContent(String logContent) {
37
+        this.logContent = logContent;
38
+    }
39
+
40
+    public boolean isEnd() {
41
+        return isEnd;
42
+    }
43
+
44
+    public void setEnd(boolean end) {
45
+        isEnd = end;
46
+    }
47
+}

+ 46 - 53
xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java View File

1
 package com.xxl.job.core.log;
1
 package com.xxl.job.core.log;
2
 
2
 
3
+import com.xxl.job.core.biz.model.LogResult;
3
 import org.apache.log4j.AppenderSkeleton;
4
 import org.apache.log4j.AppenderSkeleton;
4
 import org.apache.log4j.Layout;
5
 import org.apache.log4j.Layout;
5
 import org.apache.log4j.spi.LoggingEvent;
6
 import org.apache.log4j.spi.LoggingEvent;
117
 	 * @param logFileName
118
 	 * @param logFileName
118
 	 * @return log content
119
 	 * @return log content
119
 	 */
120
 	 */
120
-	public static String readLog(String logFileName ){
121
+	public static LogResult readLog(String logFileName, int fromLineNum){
121
 
122
 
123
+		// valid log file
122
 		if (logFileName==null || logFileName.trim().length()==0) {
124
 		if (logFileName==null || logFileName.trim().length()==0) {
123
 			return null;
125
 			return null;
124
 		}
126
 		}
127
 		if (!logFile.exists()) {
129
 		if (!logFile.exists()) {
128
 			return null;
130
 			return null;
129
 		}
131
 		}
130
-		
131
-		String logData = readLines(logFile);
132
-		return logData;
133
-	}
134
-	
135
-	/**
136
-	 * read log data
137
-	 * @param logFile
138
-	 * @return log line content
139
-	 */
140
-	public static String readLines(File logFile){
141
-		BufferedReader reader = null;
132
+
133
+		// read file
134
+		StringBuffer logContentBuffer = new StringBuffer();
135
+		int toLineNum = 0;
136
+		LineNumberReader reader = null;
142
 		try {
137
 		try {
143
-			reader = new BufferedReader(new InputStreamReader(new FileInputStream(logFile), "utf-8"));
144
-			if (reader != null) {
145
-				StringBuilder sb = new StringBuilder();
146
-				String line = null;
147
-				while ((line = reader.readLine()) != null) {
148
-					sb.append(line).append("\n");
138
+			reader = new LineNumberReader(new FileReader(logFile));
139
+			String line = null;
140
+
141
+			while ((line = reader.readLine())!=null) {
142
+				toLineNum++;
143
+				if (reader.getLineNumber() >= fromLineNum) {
144
+					logContentBuffer.append(line).append("\n");
149
 				}
145
 				}
150
-				return sb.toString();
151
 			}
146
 			}
152
 		} catch (IOException e) {
147
 		} catch (IOException e) {
153
 			e.printStackTrace();
148
 			e.printStackTrace();
159
 					e.printStackTrace();
154
 					e.printStackTrace();
160
 				}
155
 				}
161
 			}
156
 			}
162
-		} 
163
-		return null;
157
+		}
158
+
159
+		// result
160
+		LogResult logResult = new LogResult();
161
+		logResult.setFromLineNum(fromLineNum);
162
+		logResult.setToLineNum(toLineNum);
163
+		logResult.setLogContent(logContentBuffer.toString());
164
+		logResult.setEnd(false);
165
+		return logResult;
166
+
167
+		/*
168
+        // it will return the number of characters actually skipped
169
+        reader.skip(Long.MAX_VALUE);
170
+        int maxLineNum = reader.getLineNumber();
171
+        maxLineNum++;	// 最大行号
172
+        */
164
 	}
173
 	}
165
-	
174
+
166
 	/**
175
 	/**
167
-	 * read data from line num
176
+	 * read log data
168
 	 * @param logFile
177
 	 * @param logFile
169
-	 * @param fromLineNum
170
-	 * @return log content
171
-	 * @throws Exception
178
+	 * @return log line content
172
 	 */
179
 	 */
173
-	public static String readLinesFrom(File logFile, int fromLineNum) {  
174
-        LineNumberReader reader = null;
180
+	public static String readLines(File logFile){
181
+		BufferedReader reader = null;
175
 		try {
182
 		try {
176
-			reader = new LineNumberReader(new FileReader(logFile));
177
-			
178
-			// sBuffer
179
-	        StringBuffer sBuffer = new StringBuffer();
180
-	    	String line = null;
181
-	    	int maxLineNum = 0;
182
-	    	while ((line = reader.readLine())!=null) {
183
-	    		maxLineNum++;
184
-	    		if (reader.getLineNumber() >= fromLineNum) {
185
-	    			sBuffer.append(line).append("\n");
183
+			reader = new BufferedReader(new InputStreamReader(new FileInputStream(logFile), "utf-8"));
184
+			if (reader != null) {
185
+				StringBuilder sb = new StringBuilder();
186
+				String line = null;
187
+				while ((line = reader.readLine()) != null) {
188
+					sb.append(line).append("\n");
186
 				}
189
 				}
190
+				return sb.toString();
187
 			}
191
 			}
188
-	    	
189
-	    	System.out.println("maxLineNum : " + maxLineNum);
190
-	    	return sBuffer.toString();
191
 		} catch (IOException e) {
192
 		} catch (IOException e) {
192
 			e.printStackTrace();
193
 			e.printStackTrace();
193
 		} finally {
194
 		} finally {
198
 					e.printStackTrace();
199
 					e.printStackTrace();
199
 				}
200
 				}
200
 			}
201
 			}
201
-		}
202
-		
202
+		} 
203
 		return null;
203
 		return null;
204
-		
205
-        /*
206
-        // it will return the number of characters actually skipped
207
-        reader.skip(Long.MAX_VALUE);	
208
-        int maxLineNum = reader.getLineNumber();  
209
-        maxLineNum++;	// 最大行号
210
-        */
211
-    }
212
-	
204
+	}
205
+
213
 }
206
 }