1
2
3
4 package gboat2.base.logging.action;
5
6 import gboat2.base.core.annotation.Domain;
7 import gboat2.base.core.annotation.Module;
8 import gboat2.base.core.annotation.Preference;
9 import gboat2.base.core.logging.BusinessLogEntry;
10 import gboat2.base.core.web.BaseActionSupport;
11 import gboat2.base.core.web.JsonResultSupport;
12
13 import java.io.BufferedReader;
14 import java.io.File;
15 import java.io.FileInputStream;
16 import java.io.FileNotFoundException;
17 import java.io.FileOutputStream;
18 import java.io.FileReader;
19 import java.io.IOException;
20 import java.io.OutputStream;
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23 import java.util.Properties;
24
25 import org.apache.commons.lang3.StringUtils;
26 import org.apache.log4j.LogManager;
27 import org.apache.log4j.PropertyConfigurator;
28 import org.apache.log4j.helpers.Loader;
29 import org.apache.log4j.helpers.LogLog;
30 import org.apache.log4j.spi.LoggerRepository;
31 import org.apache.struts2.convention.annotation.ParentPackage;
32 import org.apache.struts2.convention.annotation.Result;
33 import org.apache.struts2.convention.annotation.ResultPath;
34 import org.apache.struts2.convention.annotation.Results;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38
39
40
41
42 @Preference("/系统配置/日志配置")
43 @Results(value = { @Result(name = "success", location = "/content/index.vm"), @Result(name = "list", location = "/content/index-list.vm") })
44 @ParentPackage(value = "log")
45 @Domain(value = BusinessLogEntry.class)
46 @ResultPath("/content")
47 @Module(name = "日志配置管理", desc = "配置日志的记录级别")
48 public class LogConfigAction extends BaseActionSupport {
49
50
51 private static final long serialVersionUID = 1L;
52
53 private static Logger logger = LoggerFactory.getLogger(LogConfigAction.class.getName());
54
55 private static final String BR = "\r\n";
56
57
58
59
60 public final static String WEB_APP_ROOT = System.getProperty("webapp.gboat2.root");
61
62
63
64
65 public final static String BUSI_LOG_CONFIG_LOCATION = "WEB-INF/config/businessLog.properties";
66
67
68
69
70 public final static String SYS_LOG_CONFIG_LOCATION = "WEB-INF/config/log4j.properties";
71
72
73
74
75 public final static String SYS_LOG_DIRECTORY = "WEB-INF/config";
76
77
78
79
80 public final static String LOG4J_FILENAME = "log4j.properties";
81
82
83 public final static String BUSINESS_LEVEL = "business.level";
84
85
86 public final static String LOG4J_ROOTLOGGER = "log4j.rootLogger";
87
88 private String businessLevel;
89
90 private String systemLogRootLevel;
91
92 private String properties;
93
94 public String getProperties() {
95 return properties;
96 }
97
98 public void setProperties(String properties) {
99 this.properties = properties;
100 }
101
102 public String getBusinessLevel() {
103 return businessLevel;
104 }
105
106 public void setBusinessLevel(String businessLevel) {
107 this.businessLevel = businessLevel;
108 }
109
110 public String getSystemLogRootLevel() {
111 return systemLogRootLevel;
112 }
113
114 public void setSystemLogRootLevel(String systemLogRootLevel) {
115 this.systemLogRootLevel = systemLogRootLevel;
116 }
117
118
119
120
121 public String execute() {
122
123 setDefaultRootLevel();
124
125 setDefaultValueToPage();
126
127 return null;
128 }
129
130
131
132
133
134
135 public String properties() throws IOException {
136 setProperties(readFromFile(getSystemLogRealPath()));
137
138
139
140
141
142
143
144
145
146
147 return null;
148 }
149
150
151
152
153
154
155 public String saveLog4jConfig() throws IOException {
156
157 writeToFile(getProperties());
158
159 JsonResultSupport.output(JsonResultSupport.wrap(true));
160
161 return null;
162 }
163
164
165
166
167
168 private void setDefaultValueToPage() {
169
170
171
172
173
174
175
176
177
178 }
179
180 private String getBusinessLogRealPath() {
181 checkWebAppRootKeyExist();
182 return WEB_APP_ROOT + BUSI_LOG_CONFIG_LOCATION;
183 }
184
185 private void checkWebAppRootKeyExist() {
186 if (WEB_APP_ROOT == null) {
187 LogLog.warn("can't get web app root,please add context param into web.xml like below:");
188 LogLog.warn("<context-param><param-name>webAppRootKey</param-name><param-value>webapp.gboat2.root</param-value></context-param>");
189 }
190 }
191
192 private String getSystemLogRealPath() {
193 checkWebAppRootKeyExist();
194 return WEB_APP_ROOT + SYS_LOG_CONFIG_LOCATION;
195 }
196
197
198
199
200
201
202
203
204
205
206 public String apply() throws IOException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
207
208 try {
209 Properties busiProps = loadProperties(getBusinessLogRealPath());
210 Properties sysProps = loadProperties(getSystemLogRealPath());
211
212
213 setProperties(readFromFile(getSystemLogRealPath()));
214
215
216 busiProps.put(BUSINESS_LEVEL, getBusinessLevel());
217 storeProperties(busiProps, getBusinessLogRealPath());
218
219 writeToFile(getProperties());
220
221
222 reBundleConfigLog4jProperies(sysProps);
223
224
225 reRuntimeEnvConfigLog4jProperties();
226
227 } catch (FileNotFoundException e) {
228
229 LogLog.warn(" log properties don't not exist ,please check ");
230 JsonResultSupport.output(JsonResultSupport.wrap(false));
231 return null;
232 } catch (IOException e) {
233
234 JsonResultSupport.output(JsonResultSupport.wrap(false));
235 LogLog.warn(" log properties don't not exist ,please check ");
236 return null;
237 } catch (ClassNotFoundException e) {
238 LogLog.warn(" log properties don't not exist ,please check ");
239
240 } catch (Exception e) {
241 LogLog.warn(" log properties don't not exist ,please check ");
242
243 }
244
245 JsonResultSupport.output(JsonResultSupport.wrap(true));
246
247 return null;
248 }
249
250
251
252
253
254
255
256
257
258 @SuppressWarnings("unchecked")
259 private void reRuntimeEnvConfigLog4jProperties() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
260 InvocationTargetException, InstantiationException {
261 Class<?> propertyConfigurator = Loader.loadClass(PropertyConfigurator.class.getName());
262 Class<?> loggerRepository = Loader.loadClass(LoggerRepository.class.getName());
263 Class<?> logManager = Loader.loadClass(LogManager.class.getName());
264 Method getLoggerRepository = logManager.getMethod("getLoggerRepository");
265 Class[] paramTypes = new Class[] { String.class, loggerRepository };
266 Object[] params = new Object[] { getSystemLogRealPath(), getLoggerRepository.invoke(null) };
267 Method doConfigure = propertyConfigurator.getMethod("doConfigure", paramTypes);
268 doConfigure.invoke(propertyConfigurator.newInstance(), params);
269 }
270
271
272
273
274
275 private void reBundleConfigLog4jProperies(Properties props) {
276
277 LogManager.resetConfiguration();
278 LogManager.shutdown();
279 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
280 Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
281 PropertyConfigurator.configure(props);
282 Thread.currentThread().setContextClassLoader(contextClassLoader);
283 logger.debug("gboat2 bundle log apply successful.");
284
285 }
286
287
288
289
290
291 private void setDefaultRootLevel() {
292
293 try {
294 Properties busiProps = loadProperties(getBusinessLogRealPath());
295 String level = (String) busiProps.get(BUSINESS_LEVEL);
296 if (StringUtils.isEmpty(level)) {
297 setBusinessLevel("DEBUG");
298 } else {
299 setBusinessLevel(level.toUpperCase());
300 }
301 } catch (FileNotFoundException e) {
302 LogLog.warn(" no business log level could be found for Gboat2. ");
303 LogLog.warn(" businessLog.properties not found ,Gboat2 use default level DEBUG . ");
304 LogLog.warn(" adding businessLog.properties in directory of WEB-INF/config can change business log behavior . ");
305 LogLog.warn(" the Content as follows:business.level=DEBUG;business.level=INFO;business.level=WARN;business.level=ERROR . ");
306 } catch (IOException e) {
307 LogLog.warn(" gboat2 use default level DEBUG ");
308 }
309
310
311 try {
312 Properties sysProps = loadProperties(getSystemLogRealPath());
313 String level = (String) sysProps.get(LOG4J_ROOTLOGGER);
314 if (StringUtils.isEmpty(level)) {
315 setBusinessLevel("DEBUG");
316 } else {
317 String[] split = level.split(",");
318 setSystemLogRootLevel(split[0].toUpperCase());
319 }
320 } catch (FileNotFoundException e) {
321 LogLog.warn(" No appenders could be found for Gboat2. ");
322 LogLog.warn(" Please initialize the log4j system properly. ");
323 LogLog.warn(" Please add log4j.properties in the directory: WEB-INF/config. ");
324 } catch (IOException e) {
325 LogLog.warn(" log4j.properties don't load. ");
326 }
327
328 }
329
330
331
332
333
334
335
336 private Properties loadProperties(String path) throws IOException {
337 Properties props = new Properties();
338 FileInputStream logStream;
339 logStream = new FileInputStream(path);
340 props.load(logStream);
341
342 logStream.close();
343 return props;
344 }
345
346
347
348
349
350
351
352
353 private Properties storeProperties(Properties props, String path) throws IOException {
354 FileOutputStream logOutStream;
355 logOutStream = new FileOutputStream(path);
356 props.store(logOutStream, "存储成功");
357 logOutStream.close();
358 return props;
359 }
360
361
362
363
364
365
366 private String readFromFile(String fileName) {
367 try {
368 File file = new File(fileName);
369 BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
370 StringBuilder stringBuilder = new StringBuilder();
371 int content;
372 while ((content = bufferedReader.read()) != -1) {
373 stringBuilder.append((char) content);
374 }
375
376 bufferedReader.close();
377
378 return stringBuilder.toString();
379 } catch (FileNotFoundException e) {
380
381 e.printStackTrace();
382 return null;
383 } catch (IOException e) {
384
385 e.printStackTrace();
386 return null;
387 }
388 }
389
390
391
392
393
394
395 private void writeToFile(String content) throws IOException {
396 if (StringUtils.isEmpty(content))
397 return;
398 String path = WEB_APP_ROOT + SYS_LOG_DIRECTORY;
399 File fileDir = new File(path);
400 if (!fileDir.exists()) {
401 boolean mkdirs = fileDir.mkdirs();
402 if (!mkdirs) {
403 throw new RuntimeException(" create directory {" + path + "} fail ");
404 }
405 } else if (!fileDir.isDirectory()) {
406 throw new RuntimeException(path + " should be directory");
407 }
408
409 File f = new File(fileDir, LOG4J_FILENAME);
410
411
412 OutputStream out = null;
413 try {
414 out = new FileOutputStream(f);
415
416
417 String[] split = content.split(BR);
418 if (split.length == 1) {
419 String[] temp = content.split("\n");
420 if (temp.length >= 1) {
421 split = temp;
422 }
423 }
424 if (split == null) {
425 out.close();
426 return;
427 }
428 for (int i = 0; i < split.length; i++) {
429 String lineContent = split[i];
430 if (!StringUtils.isEmpty(lineContent)) {
431 if (lineContent.indexOf("log4j.rootLogger") >= 0) {
432 if (!StringUtils.isEmpty(getSystemLogRootLevel())) {
433 String afterEqual = lineContent.substring(lineContent.indexOf("=") + 1);
434 String[] appenders = afterEqual.split(",");
435 StringBuffer appenderStrings = new StringBuffer();
436 if (appenders.length >= 2) {
437 for (int j = 1; j < appenders.length; j++) {
438 appenderStrings = appenderStrings.append(appenders[j]);
439 if (j < appenders.length - 1) {
440 appenderStrings = appenderStrings.append(",");
441 }
442 }
443 }
444 if ("".equals(appenderStrings.toString())) {
445 lineContent = "log4j.rootLogger = " + getSystemLogRootLevel();
446 } else
447 lineContent = "log4j.rootLogger = " + getSystemLogRootLevel() + "," + appenderStrings;
448 }
449 }
450 }
451 out.write(lineContent.getBytes());
452 out.write('\r');
453 out.write('\n');
454 }
455
456 out.close();
457 } catch (FileNotFoundException e) {
458
459 e.printStackTrace();
460 } catch (IOException e) {
461
462 e.printStackTrace();
463 }
464 }
465
466 }