mirror of https://github.com/halo-dev/halo
feat: create get logfile content api.
parent
514dfcf5dc
commit
e6497f97ad
|
@ -119,4 +119,9 @@ public class AdminController {
|
||||||
Application.restart();
|
Application.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "halo/logfile")
|
||||||
|
@ApiOperation("Get halo log file content.")
|
||||||
|
public BaseResponse<String> getLogFiles(@RequestParam("lines") Long lines) {
|
||||||
|
return BaseResponse.ok(HttpStatus.OK.getReasonPhrase(), adminService.getLogFiles(lines));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ public interface AdminService {
|
||||||
|
|
||||||
String APPLICATION_CONFIG_NAME = "application.yaml";
|
String APPLICATION_CONFIG_NAME = "application.yaml";
|
||||||
|
|
||||||
|
String LOG_PATH = "logs/spring.log";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticates.
|
* Authenticates.
|
||||||
*
|
*
|
||||||
|
@ -97,4 +99,12 @@ public interface AdminService {
|
||||||
* @param content new content
|
* @param content new content
|
||||||
*/
|
*/
|
||||||
void updateApplicationConfig(String content);
|
void updateApplicationConfig(String content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get halo logs content.
|
||||||
|
*
|
||||||
|
* @param lines lines
|
||||||
|
* @return logs content.
|
||||||
|
*/
|
||||||
|
String getLogFiles(Long lines);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import run.halo.app.utils.HaloUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -463,4 +464,57 @@ public class AdminServiceImpl implements AdminService {
|
||||||
throw new ServiceException("保存配置文件失败", e);
|
throw new ServiceException("保存配置文件失败", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLogFiles(Long lines) {
|
||||||
|
|
||||||
|
File file = new File(haloProperties.getWorkDir(), LOG_PATH);
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
long count = 0;
|
||||||
|
|
||||||
|
RandomAccessFile randomAccessFile = null;
|
||||||
|
try {
|
||||||
|
randomAccessFile = new RandomAccessFile(file, "r");
|
||||||
|
long length = randomAccessFile.length();
|
||||||
|
if (length == 0L) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
} else {
|
||||||
|
long pos = length - 1;
|
||||||
|
while (pos > 0) {
|
||||||
|
pos--;
|
||||||
|
randomAccessFile.seek(pos);
|
||||||
|
if (randomAccessFile.readByte() == '\n') {
|
||||||
|
String line = randomAccessFile.readLine();
|
||||||
|
result.append(new String(line.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
|
||||||
|
result.append(StringUtils.LF);
|
||||||
|
count++;
|
||||||
|
if (count == lines) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pos == 0) {
|
||||||
|
randomAccessFile.seek(0);
|
||||||
|
result.append(new String(randomAccessFile.readLine().getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
|
||||||
|
result.append(StringUtils.LF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ServiceException("读取日志失败", e);
|
||||||
|
} finally {
|
||||||
|
if (randomAccessFile != null) {
|
||||||
|
try {
|
||||||
|
randomAccessFile.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<!DOCTYPE html><html lang=zh-cmn-Hans><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><meta name=robots content=noindex,nofllow><meta name=generator content="Halo 1.2.0-beta.1"><link rel=icon href=/logo.png><title>Halo Dashboard</title><style>#loader{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;border:solid 3px #e5e5e5;border-top-color:#333;border-radius:50%;width:30px;height:30px;animation:spin .6s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}</style><link href=/css/chunk-0b44f908.c76aeee1.css rel=prefetch><link href=/css/chunk-0e87dfa3.0e33e21a.css rel=prefetch><link href=/css/chunk-7b4a6534.0e33e21a.css rel=prefetch><link href=/css/chunk-7e9c61cd.e32891ce.css rel=prefetch><link href=/css/chunk-8adae550.ae3f2f3c.css rel=prefetch><link href=/css/chunk-966610cc.be194fd2.css rel=prefetch><link href=/css/chunk-db4f48dc.e76ee991.css rel=prefetch><link href=/js/chunk-0b44f908.4f129c2e.js rel=prefetch><link href=/js/chunk-0ba750a2.a3aae303.js rel=prefetch><link href=/js/chunk-0e87dfa3.613e35ea.js rel=prefetch><link href=/js/chunk-17f8cd22.212b0305.js rel=prefetch><link href=/js/chunk-27659703.4ea75fab.js rel=prefetch><link href=/js/chunk-2d0b383e.adb53737.js rel=prefetch><link href=/js/chunk-2d0b64bf.ee7f7ab3.js rel=prefetch><link href=/js/chunk-2d0b8b03.d1890be1.js rel=prefetch><link href=/js/chunk-2d0cf13d.d40d4f27.js rel=prefetch><link href=/js/chunk-2d21a35c.33d6a9d2.js rel=prefetch><link href=/js/chunk-2d221c57.5d8dcffe.js rel=prefetch><link href=/js/chunk-2d228c74.56913b27.js rel=prefetch><link href=/js/chunk-2d228d13.8662d997.js rel=prefetch><link href=/js/chunk-37a26d88.728cb7c7.js rel=prefetch><link href=/js/chunk-5889a1fc.219bec60.js rel=prefetch><link href=/js/chunk-5b9394ac.474c8c42.js rel=prefetch><link href=/js/chunk-664d53d7.377af06e.js rel=prefetch><link href=/js/chunk-6709ac89.7a98f194.js rel=prefetch><link href=/js/chunk-76ee4b7f.677347b0.js rel=prefetch><link href=/js/chunk-7b4a6534.f1d63242.js rel=prefetch><link href=/js/chunk-7e9c61cd.15eaa9c8.js rel=prefetch><link href=/js/chunk-8adae550.cf26d4e7.js rel=prefetch><link href=/js/chunk-966610cc.22160297.js rel=prefetch><link href=/js/chunk-98555926.05f61e9d.js rel=prefetch><link href=/js/chunk-db4f48dc.00fbfdd6.js rel=prefetch><link href=/js/chunk-ddaf34b4.7faf5a6d.js rel=prefetch><link href=/js/chunk-ec5bbb3c.9b0a75e4.js rel=prefetch><link href=/js/chunk-f04cc1dc.2447c1e9.js rel=prefetch><link href=/css/app.01b9c5fe.css rel=preload as=style><link href=/css/chunk-vendors.473c34a0.css rel=preload as=style><link href=/js/app.e6e8ea5b.js rel=preload as=script><link href=/js/chunk-vendors.a941ddfb.js rel=preload as=script><link href=/css/chunk-vendors.473c34a0.css rel=stylesheet><link href=/css/app.01b9c5fe.css rel=stylesheet></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app><div id=loader></div></div><script src=/js/chunk-vendors.a941ddfb.js></script><script src=/js/app.e6e8ea5b.js></script></body></html>
|
<!DOCTYPE html><html lang=zh-cmn-Hans><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><meta name=robots content=noindex,nofllow><meta name=generator content="Halo 1.2.0-beta.1"><link rel=icon href=/logo.png><title>Halo Dashboard</title><style>#loader{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;border:solid 3px #e5e5e5;border-top-color:#333;border-radius:50%;width:30px;height:30px;animation:spin .6s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}</style><link href=/css/chunk-0b44f908.c76aeee1.css rel=prefetch><link href=/css/chunk-0e87dfa3.0e33e21a.css rel=prefetch><link href=/css/chunk-7b4a6534.0e33e21a.css rel=prefetch><link href=/css/chunk-7e9c61cd.e32891ce.css rel=prefetch><link href=/css/chunk-8adae550.ae3f2f3c.css rel=prefetch><link href=/css/chunk-966610cc.be194fd2.css rel=prefetch><link href=/css/chunk-db4f48dc.e76ee991.css rel=prefetch><link href=/js/chunk-0b44f908.4f129c2e.js rel=prefetch><link href=/js/chunk-0ba750a2.a3aae303.js rel=prefetch><link href=/js/chunk-0e87dfa3.613e35ea.js rel=prefetch><link href=/js/chunk-17f8cd22.212b0305.js rel=prefetch><link href=/js/chunk-27659703.4ea75fab.js rel=prefetch><link href=/js/chunk-2d0b383e.adb53737.js rel=prefetch><link href=/js/chunk-2d0b64bf.ee7f7ab3.js rel=prefetch><link href=/js/chunk-2d0b8b03.d1890be1.js rel=prefetch><link href=/js/chunk-2d0cf13d.d40d4f27.js rel=prefetch><link href=/js/chunk-2d21a35c.33d6a9d2.js rel=prefetch><link href=/js/chunk-2d221c57.5d8dcffe.js rel=prefetch><link href=/js/chunk-2d228c74.56913b27.js rel=prefetch><link href=/js/chunk-2d228d13.8662d997.js rel=prefetch><link href=/js/chunk-37a26d88.728cb7c7.js rel=prefetch><link href=/js/chunk-5889a1fc.7b49eaf0.js rel=prefetch><link href=/js/chunk-5b9394ac.474c8c42.js rel=prefetch><link href=/js/chunk-664d53d7.377af06e.js rel=prefetch><link href=/js/chunk-6709ac89.7a98f194.js rel=prefetch><link href=/js/chunk-76ee4b7f.677347b0.js rel=prefetch><link href=/js/chunk-7b4a6534.f1d63242.js rel=prefetch><link href=/js/chunk-7e9c61cd.15eaa9c8.js rel=prefetch><link href=/js/chunk-8adae550.cf26d4e7.js rel=prefetch><link href=/js/chunk-966610cc.22160297.js rel=prefetch><link href=/js/chunk-98555926.05f61e9d.js rel=prefetch><link href=/js/chunk-db4f48dc.00fbfdd6.js rel=prefetch><link href=/js/chunk-ddaf34b4.7faf5a6d.js rel=prefetch><link href=/js/chunk-ec5bbb3c.9b0a75e4.js rel=prefetch><link href=/js/chunk-f04cc1dc.2447c1e9.js rel=prefetch><link href=/css/app.01b9c5fe.css rel=preload as=style><link href=/css/chunk-vendors.473c34a0.css rel=preload as=style><link href=/js/app.3874b09d.js rel=preload as=script><link href=/js/chunk-vendors.a941ddfb.js rel=preload as=script><link href=/css/chunk-vendors.473c34a0.css rel=stylesheet><link href=/css/app.01b9c5fe.css rel=stylesheet></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app><div id=loader></div></div><script src=/js/chunk-vendors.a941ddfb.js></script><script src=/js/app.3874b09d.js></script></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue