Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorfgsfds <4870330+fgsfds@users.noreply.github.com>2025-08-05 13:10:14 +0300
committerGitHub <noreply@github.com>2025-08-05 13:10:14 +0300
commit419ea63dd0f7f2a693dbf674e411782301e06dc6 (patch)
tree062e7194ba32d04729f0da3df0aa11557c5c34c4 /web
parent6a17285935cad302286d1aed0bb2357b56cf173f (diff)
Added filters to the xray logs viewer (#3314)
* added filters to xray logs viewer * better freedom/blackhole tags handling * better freedom/blackhole tags handling 2 * fix comments * fix comments 2
Diffstat (limited to 'web')
-rw-r--r--web/controller/server.go43
-rw-r--r--web/html/index.html27
-rw-r--r--web/service/server.go56
3 files changed, 110 insertions, 16 deletions
diff --git a/web/controller/server.go b/web/controller/server.go
index dd001f5e..17b25cdc 100644
--- a/web/controller/server.go
+++ b/web/controller/server.go
@@ -17,7 +17,8 @@ var filenameRegex = regexp.MustCompile(`^[a-zA-Z0-9_\-.]+$`)
type ServerController struct {
BaseController
- serverService service.ServerService
+ serverService service.ServerService
+ settingService service.SettingService
lastStatus *service.Status
lastGetStatusTime time.Time
@@ -137,7 +138,45 @@ func (a *ServerController) getLogs(c *gin.Context) {
func (a *ServerController) getXrayLogs(c *gin.Context) {
count := c.Param("count")
- logs := a.serverService.GetXrayLogs(count)
+ filter := c.PostForm("filter")
+ showDirect := c.PostForm("showDirect")
+ showBlocked := c.PostForm("showBlocked")
+ showProxy := c.PostForm("showProxy")
+
+ var freedoms []string
+ var blackholes []string
+
+ //getting tags for freedom and blackhole outbounds
+ config, err := a.settingService.GetDefaultXrayConfig()
+ if err == nil && config != nil {
+ if cfgMap, ok := config.(map[string]interface{}); ok {
+ if outbounds, ok := cfgMap["outbounds"].([]interface{}); ok {
+ for _, outbound := range outbounds {
+ if obMap, ok := outbound.(map[string]interface{}); ok {
+ switch obMap["protocol"] {
+ case "freedom":
+ if tag, ok := obMap["tag"].(string); ok {
+ freedoms = append(freedoms, tag)
+ }
+ case "blackhole":
+ if tag, ok := obMap["tag"].(string); ok {
+ blackholes = append(blackholes, tag)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if len(freedoms) == 0 {
+ freedoms = []string{"direct"}
+ }
+ if len(blackholes) == 0 {
+ blackholes = []string{"blocked"}
+ }
+
+ logs := a.serverService.GetXrayLogs(count, filter, showDirect, showBlocked, showProxy, freedoms, blackholes)
jsonObj(c, logs, nil)
}
diff --git a/web/html/index.html b/web/html/index.html
index 4089e6a6..bc5483b0 100644
--- a/web/html/index.html
+++ b/web/html/index.html
@@ -457,6 +457,14 @@
</a-select>
</a-input-group>
</a-form-item>
+ <a-form-item label="Filter:">
+ <a-input size="small" v-model="xraylogModal.filter" @keyup.enter="openXrayLogs()"></a-input>
+ </a-form-item>
+ <a-form-item>
+ <a-checkbox v-model="xraylogModal.showDirect" @change="openXrayLogs()">Direct</a-checkbox>
+ <a-checkbox v-model="xraylogModal.showBlocked" @change="openXrayLogs()">Blocked</a-checkbox>
+ <a-checkbox v-model="xraylogModal.showProxy" @change="openXrayLogs()">Proxy</a-checkbox>
+ </a-form-item>
<a-form-item :style="{ float: 'right' }">
<a-button type="primary" icon="download" @click="FileManager.downloadTextFile(xraylogModal.logs?.join('\n'), 'x-ui.log')"></a-button>
</a-form-item>
@@ -651,6 +659,9 @@
visible: false,
logs: [],
rows: 20,
+ showDirect: true,
+ showBlocked: true,
+ showProxy: true,
loading: false,
show(logs) {
this.visible = true;
@@ -665,17 +676,17 @@
const parts = log.split(' ');
- if(parts.length === 9) {
+ if(parts.length === 10) {
const dateTime = `<b>${parts[0]} ${parts[1]}</b>`;
const from = `<b>${parts[3]}</b>`;
const to = `<b>${parts[5].replace(/^\/+/, "")}</b>`;
let outboundColor = '';
- if (parts[8].startsWith('blocked')) {
- outboundColor = ' style="color: #e04141;"';
+ if (parts[9] === "b") {
+ outboundColor = ' style="color: #e04141;"'; //red for blocked
}
- else if (!parts[8].startsWith('direct')) {
- outboundColor = ' style="color: #3c89e8;"';
+ else if (parts[9] === "p") {
+ outboundColor = ' style="color: #3c89e8;"'; //blue for proxies
}
formattedLogs += `<span${outboundColor}>
@@ -684,10 +695,10 @@ ${dateTime}
${from}
${parts[4]}
${to}
- ${parts.slice(6).join(' ')}
+ ${parts.slice(6, 9).join(' ')}
</span>`;
} else {
- formattedLogs += `<span>${parts.join(' ')}</span>`;
+ formattedLogs += `<span>${log}</span>`;
}
});
@@ -817,7 +828,7 @@ ${dateTime}
},
async openXrayLogs(){
xraylogModal.loading = true;
- const msg = await HttpUtil.post('server/xraylogs/'+xraylogModal.rows);
+ const msg = await HttpUtil.post('server/xraylogs/'+xraylogModal.rows,{filter: xraylogModal.filter, showDirect: xraylogModal.showDirect, showBlocked: xraylogModal.showBlocked, showProxy: xraylogModal.showProxy});
if (!msg.success) {
return;
}
diff --git a/web/service/server.go b/web/service/server.go
index 2b174e8b..ee13b268 100644
--- a/web/service/server.go
+++ b/web/service/server.go
@@ -482,8 +482,16 @@ func (s *ServerService) GetLogs(count string, level string, syslog string) []str
return lines
}
-func (s *ServerService) GetXrayLogs(count string) []string {
- c, _ := strconv.Atoi(count)
+func (s *ServerService) GetXrayLogs(
+ count string,
+ filter string,
+ showDirect string,
+ showBlocked string,
+ showProxy string,
+ freedoms []string,
+ blackholes []string) []string {
+
+ countInt, _ := strconv.Atoi(count)
var lines []string
pathToAccessLog, err := xray.GetAccessLogPath()
@@ -498,21 +506,57 @@ func (s *ServerService) GetXrayLogs(count string) []string {
defer file.Close()
scanner := bufio.NewScanner(file)
+
for scanner.Scan() {
- line := scanner.Text()
- if strings.TrimSpace(line) == "" || strings.Contains(line, "api -> api") {
+ line := strings.TrimSpace(scanner.Text())
+
+ if line == "" || strings.Contains(line, "api -> api") {
+ //skipping empty lines and api calls
continue
}
+
+ if filter != "" && !strings.Contains(line, filter) {
+ //applying filter if it's not empty
+ continue
+ }
+
+ //adding suffixes to further distinguish entries by outbound
+ if hasSuffix(line, freedoms) {
+ if showDirect == "false" {
+ continue
+ }
+ line = line + " f"
+ } else if hasSuffix(line, blackholes) {
+ if showBlocked == "false" {
+ continue
+ }
+ line = line + " b"
+ } else {
+ if showProxy == "false" {
+ continue
+ }
+ line = line + " p"
+ }
+
lines = append(lines, line)
}
- if len(lines) > c {
- lines = lines[len(lines)-c:]
+ if len(lines) > countInt {
+ lines = lines[len(lines)-countInt:]
}
return lines
}
+func hasSuffix(line string, suffixes []string) bool {
+ for _, sfx := range suffixes {
+ if strings.HasSuffix(line, sfx+"]") {
+ return true
+ }
+ }
+ return false
+}
+
func (s *ServerService) GetConfigJson() (any, error) {
config, err := s.xrayService.GetXrayConfig()
if err != nil {