123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- package indexer
- import (
- "strconv"
- "strings"
- "time"
- "github.com/0xJacky/Nginx-UI/internal/geolite"
- "github.com/0xJacky/Nginx-UI/internal/nginx_log/parser"
- "github.com/uozi-tech/cosy/logger"
- )
- // Global parser instance
- var (
- logParser *parser.OptimizedParser // Use the concrete type
- )
- func init() {
- // Initialize the parser with all its dependencies during package initialization.
- uaParser := parser.NewSimpleUserAgentParser()
- var geoIPService parser.GeoIPService
- geoService, err := geolite.GetService()
- if err != nil {
- logger.Warnf("Failed to initialize GeoIP service, geo-enrichment will be disabled: %v", err)
- } else {
- geoIPService = parser.NewGeoLiteAdapter(geoService)
- }
- // Create the optimized parser with real dependencies.
- logParser = parser.NewOptimizedParser(nil, uaParser, geoIPService)
- }
- // ParseLogLine parses a raw log line into a structured LogDocument
- func ParseLogLine(line string) (*LogDocument, error) {
- entry, err := logParser.ParseLine(line)
- if err != nil {
- return nil, err
- }
- // Convert parser.AccessLogEntry to indexer.LogDocument
- // This mapping is necessary because the indexer and parser might have different data structures.
- logDoc := &LogDocument{
- Timestamp: entry.Timestamp,
- IP: entry.IP,
- RegionCode: entry.RegionCode,
- Province: entry.Province,
- City: entry.City,
- Method: entry.Method,
- Path: entry.Path,
- PathExact: entry.Path, // Use the same for now
- Protocol: entry.Protocol,
- Status: entry.Status,
- BytesSent: entry.BytesSent,
- Referer: entry.Referer,
- UserAgent: entry.UserAgent,
- Browser: entry.Browser,
- BrowserVer: entry.BrowserVer,
- OS: entry.OS,
- OSVersion: entry.OSVersion,
- DeviceType: entry.DeviceType,
- RequestTime: entry.RequestTime,
- Raw: entry.Raw,
- }
- if entry.UpstreamTime != nil {
- logDoc.UpstreamTime = entry.UpstreamTime
- }
- return logDoc, nil
- }
- // Quick parse for request field "GET /path HTTP/1.1"
- func parseRequestField(request string) (method, path, protocol string) {
- parts := strings.Split(request, " ")
- if len(parts) == 3 {
- return parts[0], parts[1], parts[2]
- }
- return "UNKNOWN", request, "UNKNOWN"
- }
- // Quick parse for timestamp, e.g., "02/Jan/2006:15:04:05 -0700"
- func parseTimestamp(ts string) int64 {
- t, err := time.Parse("02/Jan/2006:15:04:05 -0700", ts)
- if err != nil {
- return 0
- }
- return t.Unix()
- }
- // Quick string to int64 conversion
- func toInt64(s string) int64 {
- val, _ := strconv.ParseInt(s, 10, 64)
- return val
- }
- // Quick string to int conversion
- func toInt(s string) int {
- val, _ := strconv.Atoi(s)
- return val
- }
|