mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-10-27 02:24:40 +00:00
Compare commits
2 commits
2f82d6ab20
...
fc53d8f9e5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc53d8f9e5 | ||
|
|
0510c6d7b2 |
2 changed files with 101 additions and 44 deletions
|
|
@ -598,40 +598,56 @@
|
||||||
this.formattedLogs = this.logs?.length > 0 ? this.formatLogs(this.logs) : "No Record...";
|
this.formattedLogs = this.logs?.length > 0 ? this.formatLogs(this.logs) : "No Record...";
|
||||||
},
|
},
|
||||||
formatLogs(logs) {
|
formatLogs(logs) {
|
||||||
let formattedLogs = '';
|
let formattedLogs = `
|
||||||
|
<style>
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
logs.forEach((log, index) => {
|
table td, table th {
|
||||||
if(index > 0) formattedLogs += '<br>';
|
padding: 2px 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
const parts = log.split(' ');
|
<table>
|
||||||
|
<tr>
|
||||||
if(parts.length === 10) {
|
<th>Date</th>
|
||||||
const dateTime = `<b>${parts[0]} ${parts[1]}</b>`;
|
<th>From</th>
|
||||||
const from = `<b>${parts[3]}</b>`;
|
<th>To</th>
|
||||||
const to = `<b>${parts[5].replace(/^\/+/, "")}</b>`;
|
<th>Inbound</th>
|
||||||
|
<th>Outbound</th>
|
||||||
|
<th>Email</th>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
|
logs.reverse().forEach((log, index) => {
|
||||||
let outboundColor = '';
|
let outboundColor = '';
|
||||||
if (parts[9] === "b") {
|
if (log.Event === 1) {
|
||||||
outboundColor = ' style="color: #e04141;"'; //red for blocked
|
outboundColor = ' style="color: #e04141;"'; //red for blocked
|
||||||
}
|
}
|
||||||
else if (parts[9] === "p") {
|
else if (log.Event === 2) {
|
||||||
outboundColor = ' style="color: #3c89e8;"'; //blue for proxies
|
outboundColor = ' style="color: #3c89e8;"'; //blue for proxies
|
||||||
}
|
}
|
||||||
|
|
||||||
formattedLogs += `<span${outboundColor}>
|
let text = ``;
|
||||||
${dateTime}
|
if (log.Email !== "") {
|
||||||
${parts[2]}
|
text = `<td>${log.Email}</td>`;
|
||||||
${from}
|
|
||||||
${parts[4]}
|
|
||||||
${to}
|
|
||||||
${parts.slice(6, 9).join(' ')}
|
|
||||||
</span>`;
|
|
||||||
} else {
|
|
||||||
formattedLogs += `<span>${log}</span>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formattedLogs += `
|
||||||
|
<tr ${outboundColor}>
|
||||||
|
<td><b>${new Date(log.DateTime).toLocaleString()}</b></td>
|
||||||
|
<td>${log.FromAddress}</td>
|
||||||
|
<td>${log.ToAddress}</td>
|
||||||
|
<td>${log.Inbound}</td>
|
||||||
|
<td>${log.Outbound}</td>
|
||||||
|
${text}
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
});
|
});
|
||||||
|
|
||||||
return formattedLogs;
|
return formattedLogs += "</table>";
|
||||||
},
|
},
|
||||||
hide() {
|
hide() {
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,16 @@ type ServerService struct {
|
||||||
noIPv6 bool
|
noIPv6 bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LogEntry struct {
|
||||||
|
DateTime time.Time
|
||||||
|
FromAddress string
|
||||||
|
ToAddress string
|
||||||
|
Inbound string
|
||||||
|
Outbound string
|
||||||
|
Email string
|
||||||
|
Event int
|
||||||
|
}
|
||||||
|
|
||||||
func getPublicIP(url string) string {
|
func getPublicIP(url string) string {
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Timeout: 3 * time.Second,
|
Timeout: 3 * time.Second,
|
||||||
|
|
@ -516,19 +526,25 @@ func (s *ServerService) GetXrayLogs(
|
||||||
showBlocked string,
|
showBlocked string,
|
||||||
showProxy string,
|
showProxy string,
|
||||||
freedoms []string,
|
freedoms []string,
|
||||||
blackholes []string) []string {
|
blackholes []string) []LogEntry {
|
||||||
|
|
||||||
|
const (
|
||||||
|
Direct = iota
|
||||||
|
Blocked
|
||||||
|
Proxied
|
||||||
|
)
|
||||||
|
|
||||||
countInt, _ := strconv.Atoi(count)
|
countInt, _ := strconv.Atoi(count)
|
||||||
var lines []string
|
var entries []LogEntry
|
||||||
|
|
||||||
pathToAccessLog, err := xray.GetAccessLogPath()
|
pathToAccessLog, err := xray.GetAccessLogPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lines
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open(pathToAccessLog)
|
file, err := os.Open(pathToAccessLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lines
|
return nil
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
|
|
@ -547,37 +563,62 @@ func (s *ServerService) GetXrayLogs(
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
//adding suffixes to further distinguish entries by outbound
|
var entry LogEntry
|
||||||
if hasSuffix(line, freedoms) {
|
parts := strings.Fields(line)
|
||||||
|
|
||||||
|
for i, part := range parts {
|
||||||
|
|
||||||
|
if i == 0 {
|
||||||
|
dateTime, err := time.Parse("2006/01/02 15:04:05.999999", parts[0]+" "+parts[1])
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
entry.DateTime = dateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
if part == "from" {
|
||||||
|
entry.FromAddress = parts[i+1]
|
||||||
|
} else if part == "accepted" {
|
||||||
|
entry.ToAddress = parts[i+1]
|
||||||
|
} else if strings.HasPrefix(part, "[") {
|
||||||
|
entry.Inbound = part[1:]
|
||||||
|
} else if strings.HasSuffix(part, "]") {
|
||||||
|
entry.Outbound = part[:len(part)-1]
|
||||||
|
} else if part == "email:" {
|
||||||
|
entry.Email = parts[i+1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if logEntryContains(line, freedoms) {
|
||||||
if showDirect == "false" {
|
if showDirect == "false" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
line = line + " f"
|
entry.Event = Direct
|
||||||
} else if hasSuffix(line, blackholes) {
|
} else if logEntryContains(line, blackholes) {
|
||||||
if showBlocked == "false" {
|
if showBlocked == "false" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
line = line + " b"
|
entry.Event = Blocked
|
||||||
} else {
|
} else {
|
||||||
if showProxy == "false" {
|
if showProxy == "false" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
line = line + " p"
|
entry.Event = Proxied
|
||||||
}
|
}
|
||||||
|
|
||||||
lines = append(lines, line)
|
entries = append(entries, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(lines) > countInt {
|
if len(entries) > countInt {
|
||||||
lines = lines[len(lines)-countInt:]
|
entries = entries[len(entries)-countInt:]
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines
|
return entries
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasSuffix(line string, suffixes []string) bool {
|
func logEntryContains(line string, suffixes []string) bool {
|
||||||
for _, sfx := range suffixes {
|
for _, sfx := range suffixes {
|
||||||
if strings.HasSuffix(line, sfx+"]") {
|
if strings.Contains(line, sfx+"]") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue