diff --git a/README.md b/README.md index 1af9796..5b91567 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,11 @@ The library provides `Reader` type and two constructors for it. Common constructor `NewReader` gets opened file (`io.Reader`) and log format (`string`) as argumets. format is in form os nginx `log_format` string. - + ```go reader := gonx.NewReader(file, format) ``` - + `NewNginxReader` provides mo magic. It gets nginx config file (`io.Reader`) as second argument and `log_format` name (`string`) a third. ```go @@ -37,12 +37,12 @@ See more examples in `example/*.go` sources. As I said above this library is primary for nginx access log parsing, but it can be configured to parse any other format. `NewReader` accepts `format` argument, it will be transformed to regular expression and used for log line by line parsing. Format is nginx-like, here is example `$remote_addr [$time_local] "$request"` - + It should contain variables inn form `$name`. The regular expression will be created using this string format representation `^(?P[^ ]+) \[(?P[^]]+)\] "(?P[^"]+)"$` - -If log line does not match this format, the `Reader.Read` returns an `error`. Otherwise you will get the record of type `map[string][string]` with `remote_addr`, `time_local` and `request` keys filled with parsed values. + +If log line does not match this format, the `Reader.Read` returns an `error`. Otherwise you will get the record of type `Entry` (which is customized `map[string][string]`) with `remote_addr`, `time_local` and `request` keys filled with parsed values. ## Stability @@ -50,7 +50,7 @@ This library API and internal representation can be changed at any moment, but I * `func NewReader(logFile io.Reader, format string) *Reader` * `func NewNginxReader(logFile io.Reader, nginxConf io.Reader, formatName string) (reader *Reader, err error)` -* `func (r *Reader) Read() (record map[string]string, err error)` +* `func (r *Reader) Read() (record Entry, err error)` ## Contributing diff --git a/reader.go b/reader.go index 5dd381a..65ecd27 100644 --- a/reader.go +++ b/reader.go @@ -72,9 +72,11 @@ func (r *Reader) GetFormatRegexp() *regexp.Regexp { return r.re } +type Entry map[string]string + // Read next line from log file, and return parsed record. If all lines read // method return ni, io.EOF -func (r *Reader) Read() (record map[string]string, err error) { +func (r *Reader) Read() (record Entry, err error) { if r.scanner.Scan() { record, err = r.parseRecord(r.scanner.Text()) } else { @@ -86,7 +88,7 @@ func (r *Reader) Read() (record map[string]string, err error) { return } -func (r *Reader) parseRecord(line string) (record map[string]string, err error) { +func (r *Reader) parseRecord(line string) (record Entry, err error) { // Parse line to fill map record. Return error if a line does not match given format re := r.GetFormatRegexp() fields := re.FindStringSubmatch(line) @@ -96,7 +98,7 @@ func (r *Reader) parseRecord(line string) (record map[string]string, err error) } // Iterate over subexp foung and fill the map record - record = make(map[string]string) + record = make(Entry) for i, name := range re.SubexpNames() { if i == 0 { continue diff --git a/reader_test.go b/reader_test.go index ae5519c..e10df92 100644 --- a/reader_test.go +++ b/reader_test.go @@ -20,7 +20,7 @@ func TestGetRecord(t *testing.T) { format := "$remote_addr [$time_local] \"$request\"" file := strings.NewReader(`89.234.89.123 [08/Nov/2013:13:39:18 +0000] "GET /api/foo/bar HTTP/1.1"`) reader := NewReader(file, format) - expected := map[string]string{ + expected := Entry{ "remote_addr": "89.234.89.123", "time_local": "08/Nov/2013:13:39:18 +0000", "request": "GET /api/foo/bar HTTP/1.1",