发布于 

java,通过接口读取配置文件

对应环境下的配置文件

1
2
3
server-log:
enabled: true # 设置为true开启日志读取功能
filePath: /Users/edy/Documents/console.log # 日志文件路径

LogReaderProperties

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Data;

@Data
@Component
@ConfigurationProperties(prefix = "server-log")
public class LogReaderProperties {
private String filePath;
private boolean enabled = false;
}

SystemLogController

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

import com.touchsmail.util.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;
import java.time.*;
import java.time.format.*;
import javax.annotation.Resource;

@RestController
@RequestMapping("/service/logs")
public class SystemLogController {

// private static final String LOG_FILE_PATH = "/Users/edy/Documents/console.log";
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

@Resource
private LogReaderProperties properties;

// 增加响应头,处理中文乱码
private HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
headers.set(HttpHeaders.CONTENT_ENCODING, "UTF-8");
headers.set(HttpHeaders.CONTENT_TYPE, "text/plain;charset=UTF-8");
return headers;
}


private void checkEnabled() {
if (!properties.isEnabled()) {
throw new IllegalStateException("log not open!");
}
}

private void checkFileExists() {
if (StringUtils.isBlank(properties.getFilePath()) || !Files.exists(Paths.get(properties.getFilePath()))) {
throw new IllegalStateException("log file does not exist!");
}
}

@GetMapping("/")
public ResponseEntity<String> explain() {
checkEnabled();
checkFileExists();
final String content = "// 读取全部日志\n" +
"GET http://localhost:6001/service/logs/all\n" +
"\n" +
"// 读取最新10条日志\n" +
"GET http://localhost:6001/service/logs/latest?lines=10\n" +
"\n" +
"// 读取指定时间范围的日志\n" +
"GET http://localhost:6001/service/logs/time?startTime=2024-12-01 00:00:00&endTime=2024-12-31 00:00:00\n" +
"\n" +
"// 流式读取日志\n" +
"GET http://localhost:6001/service/logs/stream?bufferSize=100";
return new ResponseEntity<>(content, getHeaders(), HttpStatus.OK);
}

@GetMapping("/all")
public ResponseEntity<String> readAllLogs() {
checkEnabled();
checkFileExists();
try {
String content = new String(Files.readAllBytes(Paths.get(properties.getFilePath())), StandardCharsets.UTF_8);
return new ResponseEntity<>(content, getHeaders(), HttpStatus.OK);
} catch (IOException e) {
return new ResponseEntity<>("读取日志文件失败: " + e.getMessage(), getHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@GetMapping("/latest")
public ResponseEntity<String> readLatestLogs(@RequestParam(defaultValue = "10") int lines) {
try {
List<String> allLines = Files.readAllLines(Paths.get(properties.getFilePath()), StandardCharsets.UTF_8);
int startIndex = Math.max(0, allLines.size() - lines);
List<String> latestLines = allLines.subList(startIndex, allLines.size());

StringBuilder result = new StringBuilder();
for (String line : latestLines) {
result.append(line).append("\n");
}

return new ResponseEntity<>(result.toString(), getHeaders(), HttpStatus.OK);
} catch (IOException e) {
return new ResponseEntity<>("读取日志文件失败: " + e.getMessage(), getHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@GetMapping("/time")
public ResponseEntity<String> readLogsByTimeRange(
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
try {
List<String> allLines = Files.readAllLines(Paths.get(properties.getFilePath()), StandardCharsets.UTF_8);
StringBuilder result = new StringBuilder();

for (String line : allLines) {
try {
String timeStr = line.substring(0, 19);
LocalDateTime logTime = LocalDateTime.parse(timeStr, DATE_FORMAT);

if ((logTime.isEqual(startTime) || logTime.isAfter(startTime)) &&
(logTime.isEqual(endTime) || logTime.isBefore(endTime))) {
result.append(line).append("\n");
}
} catch (Exception e) {
// Skip malformed log entries
continue;
}
}

return new ResponseEntity<>(result.toString(), getHeaders(), HttpStatus.OK);
} catch (IOException e) {
return new ResponseEntity<>("读取日志文件失败: " + e.getMessage(), getHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@GetMapping("/stream")
public ResponseEntity<String> streamLog(@RequestParam(defaultValue = "100") int maxLines) {
try {
List<String> lines = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(properties.getFilePath()), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
if (lines.size() > maxLines) {
lines.remove(0);
}
}
}

StringBuilder result = new StringBuilder();
for (String line : lines) {
result.append(line).append("\n");
}

return new ResponseEntity<>(result.toString(), getHeaders(), HttpStatus.OK);
} catch (IOException e) {
return new ResponseEntity<>("读取日志文件失败: " + e.getMessage(), getHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

结构关系:

tools
LogReaderProperties
SystemLogController

调用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

//调用说明
GET http://localhost:8080/service/logs/

// 读取全部日志
GET http://localhost:8080/service/logs/all

// 读取最新10条日志
GET http://localhost:8080/service/logs/latest?lines=10

// 读取指定时间范围的日志
GET http://localhost:8080/service/logs/time?startTime=2024-12-01 00:00:00&endTime=2024-12-30 00:00:00

// 流式读取日志
GET http://localhost:8080/service/logs/stream?bufferSize=100