diff --git a/logparser/v5/main.go b/logparser/v5/main.go index aebd436..c848dd2 100644 --- a/logparser/v5/main.go +++ b/logparser/v5/main.go @@ -23,10 +23,14 @@ func main() { p := pipe.New( pipe.NewTextLog(os.Stdin), + // pipe.NewJSONLog(os.Stdin), + pipe.NewTextReport(os.Stdout), // pipe.NewJSONReport(os.Stdout), - pipe.FilterBy(pipe.DomainExtFilter("com", "io")), - pipe.GroupBy(pipe.DomainGrouper), + + // pipe.FilterBy(pipe.DomainExtFilter("com", "io")), + // pipe.GroupBy(pipe.DomainGrouper), + // new(passThrough), ) diff --git a/logparser/v5/pipe/group.go b/logparser/v5/pipe/group.go index 2eda161..e50beca 100644 --- a/logparser/v5/pipe/group.go +++ b/logparser/v5/pipe/group.go @@ -17,7 +17,7 @@ type GroupFunc = func(Record) (key string) // Group records by a key. type Group struct { - sum map[string]Record // metrics per group key + sum map[string]record // metrics per group key keys []string // unique group keys key GroupFunc } @@ -27,7 +27,7 @@ type Group struct { // The returned group will group the record using the key. func GroupBy(key GroupFunc) *Group { return &Group{ - sum: make(map[string]Record), + sum: make(map[string]record), key: key, } } @@ -41,7 +41,7 @@ func (g *Group) Consume(records Iterator) error { g.keys = append(g.keys, k) } - g.sum[k] = r.Sum(g.sum[k]) + g.sum[k] = r.sum(g.sum[k]) return nil }) @@ -52,7 +52,7 @@ func (g *Group) Each(yield func(Record) error) error { sort.Strings(g.keys) for _, k := range g.keys { - if err := yield(g.sum[k]); err != nil { + if err := yield(Record{g.sum[k]}); err != nil { return err } } diff --git a/logparser/v5/pipe/jsonreport.go b/logparser/v5/pipe/jsonreport.go index f2ada20..26945d5 100644 --- a/logparser/v5/pipe/jsonreport.go +++ b/logparser/v5/pipe/jsonreport.go @@ -27,6 +27,6 @@ func (t *JSONReport) Consume(records Iterator) error { enc := json.NewEncoder(t.w) return records.Each(func(r Record) error { - return enc.Encode(r) + return enc.Encode(&r) }) } diff --git a/logparser/v5/pipe/record.go b/logparser/v5/pipe/record.go index 1cd1a6a..33a1119 100644 --- a/logparser/v5/pipe/record.go +++ b/logparser/v5/pipe/record.go @@ -18,15 +18,23 @@ type record struct { uniques int } -// Sum the numeric fields with another record. -func (r Record) Sum(other Record) Record { +// recordJSON is used for marshaling and unmarshaling JSON. +type recordJSON struct { + Domain string + Page string + Visits int + Uniques int +} + +// sum the numeric fields with another record. +func (r record) sum(other record) record { r.visits += other.visits r.uniques += other.uniques return r } -// UnmarshalText to a *Record. -func (r *Record) UnmarshalText(p []byte) (err error) { +// UnmarshalText to a *record. +func (r *record) UnmarshalText(p []byte) (err error) { fields := strings.Fields(string(p)) if len(fields) != fieldsLength { return fmt.Errorf("wrong number of fields %q", fields) @@ -43,23 +51,23 @@ func (r *Record) UnmarshalText(p []byte) (err error) { return validate(*r) } -// UnmarshalJSON to a *Record. -func (r *Record) UnmarshalJSON(data []byte) error { - // `methodless` doesn't have any methods including UnmarshalJSON. - // This trick prevents the stack-overflow (infinite loop). - type methodless Record +// UnmarshalJSON to a *record. +func (r *record) UnmarshalJSON(data []byte) error { + var rj recordJSON - var m methodless - if err := json.Unmarshal(data, &m); err != nil { + if err := json.Unmarshal(data, &rj); err != nil { return err } - // Cast back to the Record and save. - *r = Record(m) - + *r = record{rj.Domain, rj.Page, rj.Visits, rj.Uniques} return validate(*r) } +// MarshalJSON of a *record. +func (r *record) MarshalJSON() ([]byte, error) { + return json.Marshal(recordJSON{r.domain, r.page, r.visits, r.uniques}) +} + // parseStr helps UnmarshalText for string to positive int parsing. func parseStr(name, v string) (int, error) { n, err := strconv.Atoi(v) @@ -70,7 +78,7 @@ func parseStr(name, v string) (int, error) { } // validate whether a parsed record is valid or not. -func validate(r Record) (err error) { +func validate(r record) (err error) { switch { case r.domain == "": err = errors.New("record.domain cannot be empty") diff --git a/logparser/v5/pipe/textreport.go b/logparser/v5/pipe/textreport.go index 0c8c0f0..00ca37e 100644 --- a/logparser/v5/pipe/textreport.go +++ b/logparser/v5/pipe/textreport.go @@ -39,10 +39,10 @@ func (t *TextReport) Consume(records Iterator) error { write(w, "DOMAINS\tPAGES\tVISITS\tUNIQUES\n") write(w, "-------\t-----\t------\t-------\n") - var total Record + var total record err := records.Each(func(r Record) error { - total = r.Sum(total) + total = r.sum(total) write(w, "%s\t%s\t%d\t%d\n", r.domain, r.page,