Browse Source

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
fgsfds 2 weeks ago
parent
commit
419ea63dd0
3 changed files with 110 additions and 16 deletions
  1. 41 2
      web/controller/server.go
  2. 19 8
      web/html/index.html
  3. 50 6
      web/service/server.go

+ 41 - 2
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)
 }
 

+ 19 - 8
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;
                 }

+ 50 - 6
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 {