1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.admininterface.pages;
35
36 import info.magnolia.cms.core.Path;
37 import info.magnolia.cms.core.SystemProperty;
38 import info.magnolia.module.admininterface.TemplatedMVCHandler;
39
40 import java.io.File;
41 import java.io.FileInputStream;
42 import java.io.FileNotFoundException;
43 import java.io.FileReader;
44 import java.io.IOException;
45 import java.io.LineNumberReader;
46 import java.io.PrintWriter;
47 import java.io.StringWriter;
48 import java.util.ArrayList;
49 import java.util.Collection;
50 import java.util.Iterator;
51
52 import javax.servlet.ServletOutputStream;
53 import javax.servlet.http.HttpServletRequest;
54 import javax.servlet.http.HttpServletResponse;
55
56 import org.apache.commons.io.FileUtils;
57 import org.apache.commons.io.IOUtils;
58 import org.apache.commons.io.filefilter.TrueFileFilter;
59 import org.apache.commons.io.filefilter.WildcardFileFilter;
60 import org.apache.commons.lang.StringEscapeUtils;
61 import org.apache.commons.lang.StringUtils;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64
65 public class LogViewerPage extends TemplatedMVCHandler {
66 private static final Logger log = LoggerFactory.getLogger(LogViewerPage.class);
67
68 private final static String LOGS_FOLDER_PROPERTY = "magnolia.logs.dir";
69
70 public LogViewerPage(String name, HttpServletRequest request, HttpServletResponse response) {
71 super(name, request, response);
72
73
74 String temp = SystemProperty.getProperty(LOGS_FOLDER_PROPERTY);
75 if (temp != null) {
76 logsFolder = Path.getAbsoluteFileSystemPath(temp);
77 }
78 }
79
80 private String logsFolder = "";
81
82 private String fileName = "";
83
84 private String text = "";
85
86 private Collection namesList = null;
87
88 private long maxNumLinesPerPage = 50;
89
90 private long pageNumber = 0;
91
92 private long totalPages = 0;
93
94 private long currentPosition = 0;
95
96 private long fileSizeInLines = 0;
97
98
99
100
101
102
103 public Collection getLogFiles() {
104
105 ArrayList urls = new ArrayList();
106
107 File logDir = new File(this.logsFolder);
108 Collection files = null;
109 if (logDir.exists()) {
110 files = FileUtils.listFiles(logDir, new WildcardFileFilter("*.log*"), TrueFileFilter.TRUE);
111
112 Iterator filesIterator = files.iterator();
113 String name = "";
114 while (filesIterator.hasNext()) {
115 name = ((File) filesIterator.next()).getName();
116 urls.add(name);
117 }
118 }
119 return urls;
120 }
121
122 public String refresh() {
123 displayFileContent();
124 return VIEW_SHOW;
125 }
126
127 public String next() {
128 this.currentPosition = Math.min(this.currentPosition + this.maxNumLinesPerPage, this.fileSizeInLines - 1);
129 displayFileContent();
130 return VIEW_SHOW;
131 }
132
133 public String previous() {
134 this.currentPosition = Math.max(0, this.currentPosition - this.maxNumLinesPerPage);
135 displayFileContent();
136 return VIEW_SHOW;
137 }
138
139 public String begin() {
140 this.currentPosition = 0;
141 displayFileContent();
142 return VIEW_SHOW;
143 }
144
145 public String end() {
146 if (this.fileSizeInLines > this.maxNumLinesPerPage) {
147 this.currentPosition = this.fileSizeInLines - (this.fileSizeInLines % this.maxNumLinesPerPage);
148 } else {
149 currentPosition = 0;
150 }
151 displayFileContent();
152 return VIEW_SHOW;
153 }
154
155 public String download() throws FileNotFoundException {
156
157 if (isValidPath()) {
158 File file = getFile();
159 this.getResponse().setContentType("html/text");
160 this.getResponse().setHeader("Content-Disposition", "attachment; filename=" + fileName);
161
162 FileInputStream is = new FileInputStream(file);
163 this.getResponse().setContentLength((int) file.length());
164
165 try {
166 sendUnCompressed(is, this.getResponse());
167 } catch (Exception e) {
168 log.info("File download failed [{}]: {}", fileName, e.getMessage());
169 } finally {
170 IOUtils.closeQuietly(is);
171 }
172 }
173 return "";
174 }
175
176 private void sendUnCompressed(java.io.InputStream is, HttpServletResponse res) throws Exception {
177 ServletOutputStream os = res.getOutputStream();
178 byte[] buffer = new byte[8192];
179 int read = 0;
180 while ((read = is.read(buffer)) > 0) {
181 os.write(buffer, 0, read);
182 }
183 os.flush();
184 os.close();
185 }
186
187 public String displayFileContent() {
188
189 StringWriter str = new StringWriter();
190 if (StringUtils.isNotEmpty(this.fileName) && isValidPath()) {
191 FileReader logFile = null;
192 LineNumberReader input = null;
193 try {
194
195 File file = getFile();
196
197 logFile = new FileReader(file);
198 this.fileSizeInLines = countLines(file);
199 PrintWriter writer = new PrintWriter(str);
200
201 input = new LineNumberReader(logFile);
202
203 String line;
204 int numLines = 0;
205 while ((line = input.readLine()) != null) {
206
207 if (input.getLineNumber() >= this.currentPosition) {
208 writer.write(StringEscapeUtils.escapeHtml(line));
209 writer.write("<br/>");
210 numLines++;
211 }
212 if (numLines >= this.maxNumLinesPerPage) {
213 break;
214 }
215 }
216 writer.flush();
217 this.text = str.toString();
218 writer.close();
219
220 setFieldValues();
221
222 } catch (Exception e) {
223 this.text = e.getMessage();
224 log.error("Error can't read file:", e);
225 return VIEW_SHOW;
226 } finally {
227
228 closeFile(logFile, input);
229 }
230 }
231
232 return VIEW_SHOW;
233 }
234
235
236
237
238 private boolean isValidPath() {
239 String canonicalPath = null;
240 try {
241 File file = getFile();
242 if (file != null) {
243 canonicalPath = file.getCanonicalPath();
244 } else {
245 this.text = "Invalid file path.";
246 return false;
247 }
248 } catch (IOException e) {
249 this.text = e.getMessage();
250 log.error("Can't read file: ", e);
251 return false;
252 }
253 if (StringUtils.startsWith(canonicalPath, this.logsFolder)) {
254 return true;
255 }
256 this.text = "Invalid file path.";
257 return false;
258 }
259
260 private File getFile() {
261 if (this.fileName.length() > 0) {
262 File file = new File(this.logsFolder + "/" + this.fileName);
263 return file;
264 }
265 return null;
266 }
267
268 private void setFieldValues() {
269 this.pageNumber = (this.currentPosition / this.maxNumLinesPerPage) + 1;
270 this.totalPages = (this.fileSizeInLines / this.maxNumLinesPerPage) + 1;
271 long mod = this.currentPosition % this.maxNumLinesPerPage;
272 if (mod > 0) {
273
274 this.pageNumber++;
275 this.totalPages++;
276 }
277 }
278
279
280 private long countLines(File file) {
281 int count = 0;
282 FileReader fileReader = null;
283 LineNumberReader lineReader = null;
284 try {
285 fileReader = new FileReader(file);
286 lineReader = new LineNumberReader(fileReader);
287
288 lineReader.skip(file.length() );
289 count = lineReader.getLineNumber() + 1;
290
291 } catch (Exception e) {
292 count = 0;
293 } finally {
294
295 closeFile(fileReader, lineReader);
296 }
297
298 return count;
299 }
300
301 private void closeFile(FileReader fileReader, LineNumberReader lineReader) {
302 try {
303 if (fileReader != null) {
304 fileReader.close();
305
306 }
307 if (lineReader != null) {
308 lineReader.close();
309 }
310 } catch (Exception e) {
311
312 }
313 }
314
315 public String getFileName() {
316 return this.fileName;
317 }
318
319 public void setFileName(String fileName) {
320 this.fileName = fileName;
321 }
322
323 public Collection getNamesList() {
324 if (this.namesList == null) {
325 this.namesList = getLogFiles();
326 }
327 return this.namesList;
328 }
329
330 public String getText() {
331 return this.text;
332 }
333
334 public long getCurrentPosition() {
335 return this.currentPosition;
336 }
337
338 public void setCurrentPosition(long currentPosition) {
339
340 this.currentPosition = Math.max(0, Math.min(currentPosition, this.fileSizeInLines - (this.fileSizeInLines % this.maxNumLinesPerPage)));
341 }
342
343 public long getFileSizeInLines() {
344 return this.fileSizeInLines;
345 }
346
347 public void setFileSizeInLines(long fileSizeInLines) {
348 this.fileSizeInLines = fileSizeInLines;
349 }
350
351 public long getPageNumber() {
352 return this.pageNumber;
353 }
354
355 public long getTotalPages() {
356 return this.totalPages;
357 }
358
359 public long getMaxNumLinesPerPage() {
360 return this.maxNumLinesPerPage;
361 }
362
363
364
365
366
367 public void setMaxNumLinesPerPage(long maxNumLinesPerPage) {
368 if (maxNumLinesPerPage < 1) {
369 return;
370 }
371 this.maxNumLinesPerPage = maxNumLinesPerPage;
372 }
373
374 }