1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.app.web.admin.log;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.nio.charset.StandardCharsets;
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.nio.file.Paths;
24 import java.util.ArrayList;
25 import java.util.Base64;
26 import java.util.Date;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.stream.Stream;
31
32 import org.codelibs.core.lang.StringUtil;
33 import org.codelibs.fess.annotation.Secured;
34 import org.codelibs.fess.app.web.base.FessAdminAction;
35 import org.codelibs.fess.exception.FessSystemException;
36 import org.codelibs.fess.helper.SystemHelper;
37 import org.codelibs.fess.util.ComponentUtil;
38 import org.codelibs.fess.util.RenderDataUtil;
39 import org.lastaflute.di.exception.IORuntimeException;
40 import org.lastaflute.web.Execute;
41 import org.lastaflute.web.response.ActionResponse;
42 import org.lastaflute.web.response.HtmlResponse;
43 import org.lastaflute.web.ruts.process.ActionRuntime;
44
45
46
47
48
49 public class AdminLogAction extends FessAdminAction {
50
51 public static final String ROLE = "admin-log";
52
53 @Override
54 protected void setupHtmlData(final ActionRuntime runtime) {
55 super.setupHtmlData(runtime);
56 runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameLog()));
57 }
58
59 @Override
60 protected String getActionRole() {
61 return ROLE;
62 }
63
64 @Execute
65 @Secured({ ROLE, ROLE + VIEW })
66 public HtmlResponse index() {
67 return asIndexHtml();
68 }
69
70 @Execute
71 @Secured({ ROLE, ROLE + VIEW })
72 public ActionResponse download(final String id) {
73 final String filename = new String(Base64.getDecoder().decode(id), StandardCharsets.UTF_8).replace("..", "").replaceAll("\\s", "");
74 final String logFilePath = systemHelper.getLogFilePath();
75 if (StringUtil.isNotBlank(logFilePath) && isLogFilename(filename)) {
76 final Path path = Paths.get(logFilePath, filename);
77 return asStream(filename).contentTypeOctetStream().stream(out -> {
78 try (InputStream in = Files.newInputStream(path)) {
79 out.write(in);
80 }
81 });
82 }
83 throwValidationError(messages -> messages.addErrorsCouldNotFindLogFile(GLOBAL, filename), this::asIndexHtml);
84 return redirect(getClass());
85 }
86
87 public static List<Map<String, Object>> getLogFileItems() {
88 final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
89 final List<Map<String, Object>> logFileItems = new ArrayList<>();
90 final String logFilePath = systemHelper.getLogFilePath();
91 if (StringUtil.isNotBlank(logFilePath)) {
92 final Path logDirPath = Paths.get(logFilePath);
93 try (Stream<Path> stream = Files.list(logDirPath)) {
94 stream.filter(entry -> isLogFilename(entry.getFileName().toString())).sorted().forEach(filePath -> {
95 final Map<String, Object> map = new HashMap<>();
96 final String name = filePath.getFileName().toString();
97 map.put("id", Base64.getUrlEncoder().encodeToString(name.getBytes(StandardCharsets.UTF_8)));
98 map.put("name", name);
99 try {
100 map.put("lastModified", new Date(Files.getLastModifiedTime(filePath).toMillis()));
101 } catch (final IOException e) {
102 throw new IORuntimeException(e);
103 }
104 logFileItems.add(map);
105 });
106 } catch (final Exception e) {
107 throw new FessSystemException("Failed to access log files.", e);
108 }
109 }
110 return logFileItems;
111 }
112
113 public static boolean isLogFilename(final String name) {
114 return name.endsWith(".log") || name.endsWith(".log.gz");
115 }
116
117 private HtmlResponse asIndexHtml() {
118 return asHtml(path_AdminLog_AdminLogJsp).renderWith(data -> {
119 RenderDataUtil.register(data, "logFileItems", getLogFileItems());
120 });
121 }
122
123 }