@@ -36,46 +36,24 @@ func init() {
36
36
})
37
37
}
38
38
39
- func ParseNginxCombined (line []byte ) (LogItem , error ) {
40
- baseIdx := 0
41
- // get the first -
42
- delimIndex := bytes .IndexByte (line , '-' )
43
- if delimIndex == - 1 {
44
- return LogItem {}, errors .New ("unexpected format: no - (empty identity)" )
45
- }
46
-
47
- clientIP := line [:delimIndex - 1 ]
48
- baseIdx = delimIndex + 1
49
- // get time within [$time_local]
50
- leftBracketIndex := bytes .IndexByte (line [baseIdx :], '[' )
51
- if leftBracketIndex == - 1 {
52
- return LogItem {}, errors .New ("unexpected format: no [ (datetime)" )
39
+ func ParseNginxCombined (line []byte ) (logItem LogItem , err error ) {
40
+ fields , err := splitFields (line )
41
+ if err != nil {
42
+ return logItem , err
53
43
}
54
- rightBracketIndex := bytes .IndexByte (line [baseIdx + leftBracketIndex + 1 :], ']' )
55
- if rightBracketIndex == - 1 {
56
- return LogItem {}, errors .New ("unexpected format: no ] (datetime)" )
44
+ if len (fields ) != 9 {
45
+ return logItem , fmt .Errorf ("invalid format: expected 9 fields, got %d" , len (fields ))
57
46
}
58
47
59
- localTimeByte := line [baseIdx + leftBracketIndex + 1 : baseIdx + leftBracketIndex + rightBracketIndex + 1 ]
60
- // localTime, err := time.Parse("02/Jan/2006:15:04:05 -0700", string(localTimeByte))
61
- // if err != nil {
62
- // return LogItem{}, err
63
- // }
64
- localTime := clfDateParse (localTimeByte )
65
- baseIdx += leftBracketIndex + rightBracketIndex + 2
66
-
67
- // get URL within first "$request"
68
- leftQuoteIndex := bytes .IndexByte (line [baseIdx :], '"' )
69
- if leftQuoteIndex == - 1 {
70
- return LogItem {}, errors .New ("unexpected format: no \" (request)" )
71
- }
72
- rightQuoteIndex := findEndingDoubleQuote (line [baseIdx + leftQuoteIndex + 1 :])
73
- if rightQuoteIndex == - 1 {
74
- return LogItem {}, errors .New ("unexpected format: no \" after first \" (request)" )
48
+ if string (fields [1 ]) != "-" {
49
+ return logItem , errors .New ("unexpected format: no - (empty identity)" )
75
50
}
76
51
77
- url := line [baseIdx + leftQuoteIndex + 1 : baseIdx + leftQuoteIndex + rightQuoteIndex + 1 ]
78
- baseIdx += leftQuoteIndex + rightQuoteIndex + 2
52
+ logItem .Client = string (fields [0 ])
53
+ logItem .Time = clfDateParse (fields [3 ])
54
+
55
+ requestLine := fields [4 ]
56
+ url := requestLine
79
57
// strip HTTP method in url
80
58
spaceIndex := bytes .IndexByte (url , ' ' )
81
59
if spaceIndex == - 1 {
@@ -91,51 +69,16 @@ func ParseNginxCombined(line []byte) (LogItem, error) {
91
69
} else {
92
70
url = url [:spaceIndex ]
93
71
}
72
+ logItem .URL = string (url )
94
73
95
- // get size ($body_bytes_sent)
96
- baseIdx += 1
97
- leftSpaceIndex := bytes .IndexByte (line [baseIdx :], ' ' )
98
- if leftSpaceIndex == - 1 {
99
- return LogItem {}, errors .New ("unexpected format: no space after $request (code)" )
100
- }
101
- rightSpaceIndex := bytes .IndexByte (line [baseIdx + leftSpaceIndex + 1 :], ' ' )
102
- if rightSpaceIndex == - 1 {
103
- return LogItem {}, errors .New ("unexpected format: no space after $body_bytes_sent (size)" )
104
- }
105
- sizeBytes := line [baseIdx + leftSpaceIndex + 1 : baseIdx + leftSpaceIndex + rightSpaceIndex + 1 ]
106
- size , err := strconv .ParseUint (string (sizeBytes ), 10 , 64 )
74
+ sizeBytes := fields [6 ]
75
+ logItem .Size , err = strconv .ParseUint (string (sizeBytes ), 10 , 64 )
107
76
if err != nil {
108
- return LogItem {} , err
77
+ return logItem , err
109
78
}
110
- baseIdx += leftSpaceIndex + rightSpaceIndex + 2
111
79
112
- // skip referer
113
- leftQuoteIndex = bytes .IndexByte (line [baseIdx :], '"' )
114
- if leftQuoteIndex == - 1 {
115
- return LogItem {}, errors .New ("unexpected format: no \" (referer)" )
116
- }
117
- rightQuoteIndex = findEndingDoubleQuote (line [baseIdx + leftQuoteIndex + 1 :])
118
- if rightQuoteIndex == - 1 {
119
- return LogItem {}, errors .New ("unexpected format: no \" after first \" (referer)" )
120
- }
121
- baseIdx += 1 + leftQuoteIndex + rightQuoteIndex + 2
122
- // get UA
123
- leftQuoteIndex = bytes .IndexByte (line [baseIdx :], '"' )
124
- if leftQuoteIndex == - 1 {
125
- return LogItem {}, errors .New ("unexpected format: no \" (user-agent)" )
126
- }
127
- rightQuoteIndex = findEndingDoubleQuote (line [baseIdx + leftQuoteIndex + 1 :])
128
- if rightQuoteIndex == - 1 {
129
- return LogItem {}, errors .New ("unexpected format: no \" after first \" (user-agent)" )
130
- }
131
- userAgent := line [baseIdx + leftQuoteIndex + 1 : baseIdx + leftQuoteIndex + rightQuoteIndex + 1 ]
132
- return LogItem {
133
- Size : size ,
134
- Client : string (clientIP ),
135
- Time : localTime ,
136
- URL : string (url ),
137
- Useragent : string (userAgent ),
138
- }, nil
80
+ logItem .Useragent = string (fields [8 ])
81
+ return
139
82
}
140
83
141
84
var nginxCombinedRe = regexp .MustCompile (
0 commit comments