diff --git a/internal/nodes/http_request.go b/internal/nodes/http_request.go index 5cf9092..bc4b203 100644 --- a/internal/nodes/http_request.go +++ b/internal/nodes/http_request.go @@ -928,11 +928,26 @@ func (this *HTTPRequest) Format(source string) string { return "" } - // os - // TODO - // browser - // TODO + if prefix == "browser" { + var result = stats.SharedUserAgentParser.Parse(this.RawReq.UserAgent()) + switch suffix { + case "os.name": + return result.OS.Name + case "os.version": + return result.OS.Version + case "name": + return result.BrowserName + case "version": + return result.BrowserVersion + case "isMobile": + if result.IsMobile { + return "1" + } else { + return "0" + } + } + } return "${" + varName + "}" }) diff --git a/internal/stats/http_request_stat_manager.go b/internal/stats/http_request_stat_manager.go index 3bab2eb..3a29d27 100644 --- a/internal/stats/http_request_stat_manager.go +++ b/internal/stats/http_request_stat_manager.go @@ -29,7 +29,6 @@ type StatItem struct { } var SharedHTTPRequestStatManager = NewHTTPRequestStatManager() -var sharedUserAgentParser = NewUserAgentParser() // HTTPRequestStatManager HTTP请求相关的统计 // 这里的统计是一个辅助统计,注意不要因为统计而影响服务工作性能 @@ -223,8 +222,8 @@ Loop: serverId := userAgentString[:atIndex] userAgent := userAgentString[atIndex+1:] - var result = sharedUserAgentParser.Parse(userAgent) - var osInfo = result.os + var result = SharedUserAgentParser.Parse(userAgent) + var osInfo = result.OS if len(osInfo.Name) > 0 { dotIndex := strings.Index(osInfo.Version, ".") if dotIndex > -1 { @@ -233,7 +232,7 @@ Loop: this.systemMap[serverId+"@"+osInfo.Name+"@"+osInfo.Version]++ } - var browser, browserVersion = result.browserName, result.browserVersion + var browser, browserVersion = result.BrowserName, result.BrowserVersion if len(browser) > 0 { dotIndex := strings.Index(browserVersion, ".") if dotIndex > -1 { diff --git a/internal/stats/user_agent_parser.go b/internal/stats/user_agent_parser.go index 3190d75..a815e0b 100644 --- a/internal/stats/user_agent_parser.go +++ b/internal/stats/user_agent_parser.go @@ -5,10 +5,12 @@ package stats import ( "github.com/TeaOSLab/EdgeNode/internal/utils" "github.com/mssola/user_agent" + "sync" ) +var SharedUserAgentParser = NewUserAgentParser() + // UserAgentParser UserAgent解析器 -// 只支持单线程 type UserAgentParser struct { parser *user_agent.UserAgent @@ -17,6 +19,7 @@ type UserAgentParser struct { maxCacheItems int cacheCursor int + locker sync.RWMutex } func NewUserAgentParser() *UserAgentParser { @@ -50,19 +53,25 @@ func (this *UserAgentParser) Parse(userAgent string) (result UserAgentParserResu return } + this.locker.RLock() cacheResult, ok := this.cacheMap1[userAgent] if ok { + this.locker.RUnlock() return cacheResult } cacheResult, ok = this.cacheMap2[userAgent] if ok { + this.locker.RUnlock() return cacheResult } + this.locker.RUnlock() + this.locker.Lock() this.parser.Parse(userAgent) - result.os = this.parser.OSInfo() - result.browserName, result.browserVersion = this.parser.Browser() + result.OS = this.parser.OSInfo() + result.BrowserName, result.BrowserVersion = this.parser.Browser() + result.IsMobile = this.parser.Mobile() if this.cacheCursor == 0 { this.cacheMap1[userAgent] = result @@ -77,6 +86,7 @@ func (this *UserAgentParser) Parse(userAgent string) (result UserAgentParserResu this.cacheMap1 = map[string]UserAgentParserResult{} } } + this.locker.Unlock() return } diff --git a/internal/stats/user_agent_parser_result.go b/internal/stats/user_agent_parser_result.go index b9d6fb5..f48bdcb 100644 --- a/internal/stats/user_agent_parser_result.go +++ b/internal/stats/user_agent_parser_result.go @@ -5,7 +5,8 @@ package stats import "github.com/mssola/user_agent" type UserAgentParserResult struct { - os user_agent.OSInfo - browserName string - browserVersion string + OS user_agent.OSInfo + BrowserName string + BrowserVersion string + IsMobile bool }