-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
114 lines (101 loc) · 3.22 KB
/
index.js
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
const express = require("express");
const fs = require("fs");
const path = require("path");
const config = require("./config");
const logsReader = require("./logs-reader");
const cloudLogs = require("./cloud-logs");
const app = express();
// Configure Static Content
app.use(express.static("public"));
app.use(express.json());
// Returns the list of log files in the log directory
app.get("/logs", (req, res) => {
fs.readdir(config.LOG_DIR, { recursive: true }, (err, files) => {
if (err) {
console.error("Error reading log directory: " + err);
return res.status(500).send("Unable to read log directory: " + err);
} else {
const logFiles = files.filter((file) =>
fs.statSync(path.join(config.LOG_DIR, file)).isFile()
);
res.json({ files: logFiles });
}
});
});
// Returns the content of the log file
app.get("/logs/:filename(*)", (req, res) => {
const { filename } = req.params;
const { regex, lines } = req.query;
console.log("Filename: " + filename);
// Validate filename
const normalizedFilename = path.normalize(filename);
console.log("Normalized filename: " + normalizedFilename);
const filePath = path.join(config.LOG_DIR, normalizedFilename);
console.log("File path: " + filePath);
if (!filePath.startsWith(config.LOG_DIR)) {
return res.status(403).send("Invalid filename. Path traversal detected.");
}
if (!fs.existsSync(filePath)) {
return res.status(404).send("File not found");
}
const lineCount = lines ? parseInt(lines) : 25;
if (isNaN(lineCount) || lineCount <= 0) {
return res
.status(400)
.send(
"Invalid lines count. Check lines parameter, must be positive integer"
);
}
const regexPattern = regex ? new RegExp(regex) : null;
try {
const filteredLines = logsReader.readLogFile(
filePath,
lineCount,
regexPattern
);
res.json({ lines: filteredLines });
} catch (err) {
console.error("Error reading log file: " + err);
res
.status(500)
.send("Unable to read log file " + filename + " with error: " + err);
}
});
// Returns the list of known servers
app.get("/cloud/servers", (req, res) => {
res.json(cloudLogs.getKnownServers());
});
// Adds a new server to the list of known servers
app.post("/cloud/servers", (req, res) => {
if (!req.body?.name || !req.body?.host || !req.body?.port) {
return res.status(400).send("Invalid request body");
}
cloudLogs.addServer({
name: req.body.name,
host: req.body.host,
port: req.body.port,
});
res.status(201).send("Server added successfully");
});
// Returns the list of log files from all known servers
app.get("/cloud/logs", (req, res) => {
cloudLogs.getAllLogFiles((logs) => {
res.json(logs);
});
});
// Returns the content of the log file from all known servers
app.get("/cloud/logs/:filename(*)", (req, res) => {
const { filename } = req.params;
const { regex, lines } = req.query;
cloudLogs.getAllLogs(filename, lines, regex, (logs) => {
res.json(logs);
});
});
app.listen(config.PORT, (error) => {
if (!error)
console.log(
"Server is Successfully Running, and App is listening on port " +
config.PORT
);
else console.log("Error occurred, server can't start", error);
});