initial commit
This commit is contained in:
commit
885e7d6e02
22 changed files with 3001 additions and 0 deletions
70
internal/parser/access.go
Normal file
70
internal/parser/access.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AccessEntry holds a parsed nginx combined-format access log entry.
|
||||
type AccessEntry struct {
|
||||
RemoteAddr string
|
||||
RemoteUser string
|
||||
Time time.Time
|
||||
Method string
|
||||
Path string
|
||||
Protocol string
|
||||
Status int
|
||||
BytesSent int64
|
||||
Referer string
|
||||
UserAgent string
|
||||
}
|
||||
|
||||
// accessLogRe matches nginx combined log format.
|
||||
// Groups: remoteAddr, remoteUser, time, method, path, protocol, status, bytes, referer, userAgent
|
||||
var accessLogRe = regexp.MustCompile(
|
||||
`^(\S+) - (\S+) \[([^\]]+)\] "(\S+) (\S+) (\S+)" (\d+) (\d+|-) "([^"]*)" "([^"]*)"$`,
|
||||
)
|
||||
|
||||
const accessTimeLayout = "02/Jan/2006:15:04:05 -0700"
|
||||
|
||||
// ParseAccessLine parses a single nginx access log line.
|
||||
// Returns an error for malformed lines.
|
||||
func ParseAccessLine(line string) (AccessEntry, error) {
|
||||
m := accessLogRe.FindStringSubmatch(line)
|
||||
if m == nil {
|
||||
return AccessEntry{}, fmt.Errorf("access: no match: %q", line)
|
||||
}
|
||||
|
||||
t, err := time.Parse(accessTimeLayout, m[3])
|
||||
if err != nil {
|
||||
return AccessEntry{}, fmt.Errorf("access: parse time %q: %w", m[3], err)
|
||||
}
|
||||
|
||||
status, err := strconv.Atoi(m[7])
|
||||
if err != nil {
|
||||
return AccessEntry{}, fmt.Errorf("access: parse status %q: %w", m[7], err)
|
||||
}
|
||||
|
||||
var bytes int64
|
||||
if m[8] != "-" {
|
||||
bytes, err = strconv.ParseInt(m[8], 10, 64)
|
||||
if err != nil {
|
||||
return AccessEntry{}, fmt.Errorf("access: parse bytes %q: %w", m[8], err)
|
||||
}
|
||||
}
|
||||
|
||||
return AccessEntry{
|
||||
RemoteAddr: m[1],
|
||||
RemoteUser: m[2],
|
||||
Time: t,
|
||||
Method: m[4],
|
||||
Path: m[5],
|
||||
Protocol: m[6],
|
||||
Status: status,
|
||||
BytesSent: bytes,
|
||||
Referer: m[9],
|
||||
UserAgent: m[10],
|
||||
}, nil
|
||||
}
|
||||
Loading…
Reference in a new issue