60 lines
1.1 KiB
Go
60 lines
1.1 KiB
Go
|
package logfmt_test
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"github.com/kr/logfmt"
|
||
|
"log"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
type Measurement struct {
|
||
|
Key string
|
||
|
Val float64
|
||
|
Unit string // (e.g. ms, MB, etc)
|
||
|
}
|
||
|
|
||
|
type Measurements []*Measurement
|
||
|
|
||
|
var measurePrefix = []byte("measure.")
|
||
|
|
||
|
func (mm *Measurements) HandleLogfmt(key, val []byte) error {
|
||
|
if !bytes.HasPrefix(key, measurePrefix) {
|
||
|
return nil
|
||
|
}
|
||
|
i := bytes.LastIndexFunc(val, isDigit)
|
||
|
v, err := strconv.ParseFloat(string(val[:i+1]), 10)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
m := &Measurement{
|
||
|
Key: string(key[len(measurePrefix):]),
|
||
|
Val: v,
|
||
|
Unit: string(val[i+1:]),
|
||
|
}
|
||
|
*mm = append(*mm, m)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// return true if r is an ASCII digit only, as opposed to unicode.IsDigit.
|
||
|
func isDigit(r rune) bool {
|
||
|
return '0' <= r && r <= '9'
|
||
|
}
|
||
|
|
||
|
func Example_customHandler() {
|
||
|
var data = []byte("measure.a=1ms measure.b=10 measure.c=100MB measure.d=1s garbage")
|
||
|
|
||
|
mm := make(Measurements, 0)
|
||
|
if err := logfmt.Unmarshal(data, &mm); err != nil {
|
||
|
log.Fatalf("err=%q", err)
|
||
|
}
|
||
|
for _, m := range mm {
|
||
|
fmt.Printf("%v\n", *m)
|
||
|
}
|
||
|
// Output:
|
||
|
// {a 1 ms}
|
||
|
// {b 10 }
|
||
|
// {c 100 MB}
|
||
|
// {d 1 s}
|
||
|
}
|