This commit is contained in:
Alex Yang
2026-03-30 01:04:46 +08:00
parent 050aa421b1
commit f627244b8f
5978 changed files with 1502187 additions and 2947 deletions
+121 -37
View File
@@ -454,7 +454,12 @@ func (s *Server) initRequestInfo(w dns.ResponseWriter, r *dns.Msg) *requestInfo
domain = domain[:len(domain)-1]
}
// 获取查询类型
queryType = dns.TypeToString[r.Question[0].Qtype]
if t, ok := dns.TypeToString[r.Question[0].Qtype]; ok {
queryType = t
} else {
// 处理未知类型,使用数字表示
queryType = fmt.Sprintf("TYPE%d", r.Question[0].Qtype)
}
qType = r.Question[0].Qtype
// 更新查询类型统计
s.updateStats(func(stats *Stats) {
@@ -2471,7 +2476,7 @@ func (s *Server) GetStats() *Stats {
}
// GetQueryLogs 获取查询日志
func (s *Server) GetQueryLogs(limit, offset int, sortField, sortDirection, resultFilter, searchTerm string) []QueryLog {
func (s *Server) GetQueryLogs(limit, offset int, sortField, sortDirection, resultFilter, searchTerm, queryType string) []QueryLog {
s.queryLogsMutex.RLock()
defer s.queryLogsMutex.RUnlock()
@@ -2482,9 +2487,18 @@ func (s *Server) GetQueryLogs(limit, offset int, sortField, sortDirection, resul
if limit <= 0 {
limit = 100 // 默认返回100条日志
}
// 设置合理的上限,防止请求过多数据
if limit > 1000 {
limit = 1000
}
// 创建日志副本用于过滤和排序
var logsCopy []QueryLog
// 预分配切片容量,减少内存分配
var filteredLogs []QueryLog
capacity := len(s.queryLogs)
if capacity > 10000 {
capacity = 10000 // 限制最大容量,避免内存使用过高
}
filteredLogs = make([]QueryLog, 0, capacity)
// 先过滤日志
for _, log := range s.queryLogs {
@@ -2493,62 +2507,101 @@ func (s *Server) GetQueryLogs(limit, offset int, sortField, sortDirection, resul
continue
}
// 应用解析类型过滤
if queryType != "" && log.QueryType != queryType {
continue
}
// 应用搜索过滤
if searchTerm != "" {
// 搜索域名或客户端IP
// 搜索域名或客户端IP,使用strings.Contains的优化版本
if !strings.Contains(log.Domain, searchTerm) && !strings.Contains(log.ClientIP, searchTerm) {
continue
}
}
logsCopy = append(logsCopy, log)
filteredLogs = append(filteredLogs, log)
}
// 排序日志
if sortField != "" {
sort.Slice(logsCopy, func(i, j int) bool {
var a, b interface{}
switch sortField {
case "time":
a = logsCopy[i].Timestamp
b = logsCopy[j].Timestamp
case "clientIp":
a = logsCopy[i].ClientIP
b = logsCopy[j].ClientIP
case "domain":
a = logsCopy[i].Domain
b = logsCopy[j].Domain
case "responseTime":
a = logsCopy[i].ResponseTime
b = logsCopy[j].ResponseTime
case "blockRule":
a = logsCopy[i].BlockRule
b = logsCopy[j].BlockRule
default:
// 默认按时间排序
a = logsCopy[i].Timestamp
b = logsCopy[j].Timestamp
}
// 根据排序方向比较
// 使用更高效的排序方式,避免反射操作
switch sortField {
case "time":
if sortDirection == "asc" {
return compareValues(a, b) < 0
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].Timestamp.Before(filteredLogs[j].Timestamp)
})
} else {
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].Timestamp.After(filteredLogs[j].Timestamp)
})
}
return compareValues(a, b) > 0
case "clientIp":
if sortDirection == "asc" {
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].ClientIP < filteredLogs[j].ClientIP
})
} else {
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].ClientIP > filteredLogs[j].ClientIP
})
}
case "domain":
if sortDirection == "asc" {
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].Domain < filteredLogs[j].Domain
})
} else {
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].Domain > filteredLogs[j].Domain
})
}
case "responseTime":
if sortDirection == "asc" {
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].ResponseTime < filteredLogs[j].ResponseTime
})
} else {
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].ResponseTime > filteredLogs[j].ResponseTime
})
}
case "blockRule":
if sortDirection == "asc" {
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].BlockRule < filteredLogs[j].BlockRule
})
} else {
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].BlockRule > filteredLogs[j].BlockRule
})
}
default:
// 默认按时间降序排序
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].Timestamp.After(filteredLogs[j].Timestamp)
})
}
} else {
// 默认按时间降序排序
sort.Slice(filteredLogs, func(i, j int) bool {
return filteredLogs[i].Timestamp.After(filteredLogs[j].Timestamp)
})
}
// 计算返回范围
start := offset
end := offset + limit
if end > len(logsCopy) {
end = len(logsCopy)
if end > len(filteredLogs) {
end = len(filteredLogs)
}
if start >= len(logsCopy) {
if start >= len(filteredLogs) {
return []QueryLog{} // 没有数据,返回空切片
}
return logsCopy[start:end]
// 直接返回子切片,避免不必要的内存分配
return filteredLogs[start:end]
}
// compareValues 比较两个值
@@ -2593,6 +2646,37 @@ func (s *Server) GetQueryLogsCount() int {
return len(s.queryLogs)
}
// GetQueryLogsCountWithFilter 获取带过滤条件的查询日志总数
func (s *Server) GetQueryLogsCountWithFilter(resultFilter, searchTerm, queryType string) int {
s.queryLogsMutex.RLock()
defer s.queryLogsMutex.RUnlock()
count := 0
for _, log := range s.queryLogs {
// 应用结果过滤
if resultFilter != "" && log.Result != resultFilter {
continue
}
// 应用解析类型过滤
if queryType != "" && log.QueryType != queryType {
continue
}
// 应用搜索过滤
if searchTerm != "" {
// 搜索域名或客户端IP
if !strings.Contains(log.Domain, searchTerm) && !strings.Contains(log.ClientIP, searchTerm) {
continue
}
}
count++
}
return count
}
// GetQueryStats 获取查询统计信息
func (s *Server) GetQueryStats() map[string]interface{} {
s.statsMutex.Lock()