axslogparser.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package axslogparser
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. )
  7. // Parser is the interface for accesslog
  8. type Parser interface {
  9. Parse(string) (*Log, error)
  10. }
  11. // Log is the struct stored parsed result of single line of accesslog
  12. type Log struct {
  13. VirtualHost string `ltsv:"vhost"`
  14. Host string
  15. RemoteUser string
  16. User string
  17. Time time.Time `ltsv:"-"`
  18. TimeStr string `ltsv:"time"`
  19. Request string `ltsv:"req"`
  20. Status int
  21. Size uint64
  22. Referer string
  23. UserAgent string `ltsv:"ua"`
  24. ReqTime *float64
  25. AppTime *float64
  26. TakenSec *float64 `ltsv:"taken_sec"` // Hatena specific
  27. ForwardedFor string
  28. RequestURI string `ltsv:"uri"`
  29. Protocol string
  30. Method string
  31. }
  32. func (l *Log) breakdownRequest() error {
  33. if l.RequestURI != "" && l.Protocol != "" && l.Method != "" {
  34. return nil
  35. }
  36. stuff := strings.Fields(l.Request)
  37. if len(stuff) != 3 {
  38. return fmt.Errorf("invalid request: %s", l.Request)
  39. }
  40. if len(stuff) > 0 && l.Method == "" {
  41. l.Method = stuff[0]
  42. }
  43. if len(stuff) > 1 && l.RequestURI == "" {
  44. l.RequestURI = stuff[1]
  45. }
  46. if len(stuff) > 2 && l.Protocol == "" {
  47. l.Protocol = stuff[2]
  48. }
  49. return nil
  50. }
  51. const clfTimeLayout = "02/Jan/2006:15:04:05 -0700"
  52. // GuessParser guesses the parser from line
  53. func GuessParser(line string) (Parser, *Log, error) {
  54. var p Parser
  55. if strings.Contains(line, "\thost:") || strings.Contains(line, "\ttime:") {
  56. p = &LTSV{}
  57. l, err := p.Parse(line)
  58. if err == nil {
  59. return p, l, err
  60. }
  61. }
  62. p = &Apache{}
  63. l, err := p.Parse(line)
  64. if err != nil {
  65. return nil, nil, err
  66. }
  67. return p, l, nil
  68. }
  69. // Parse log line
  70. func Parse(line string) (*Log, error) {
  71. _, l, err := GuessParser(line)
  72. return l, err
  73. }