logfmt package - github.com/kr/logfmt - Go Packages (original) (raw)
Package implements the decoding of logfmt key-value pairs.
Example logfmt message:
foo=bar a=14 baz="hello kitty" cool%story=bro f %^asdf
Example result in JSON:
{ "foo": "bar", "a": 14, "baz": "hello kitty", "cool%story": "bro", "f": true, "%^asdf": true }
EBNFish:
ident_byte = any byte greater than ' ', excluding '=' and '"' string_byte = any byte excluding '"' and '' garbage = !ident_byte ident = ident_byte, { ident byte } key = ident value = ident | '"', { string_byte | '', '"' }, '"' pair = key, '=', value | key, '=' | key message = { garbage, pair }, garbage
package main
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 main() { 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}
This section is empty.
func Unmarshal(data []byte, v interface{}) (err error)
Unmarshal parses the logfmt encoding data and stores the result in the value pointed to by v. If v is an Handler, HandleLogfmt will be called for each key-value pair.
If v is not a Handler, it will pass v to NewStructHandler and use the returned StructHandler for decoding.
type Handler ¶
type Handler interface { HandleLogfmt(key, val []byte) error }
Handler is the interface implemented by objects that accept logfmt key-value pairs. HandleLogfmt must copy the logfmt data if it wishes to retain the data after returning.
type HandlerFunc ¶
The HandlerFunc type is an adapter to allow the use of ordinary functions as logfmt handlers. If f is a function with the appropriate signature, HandlerFunc(f) is a Handler object that calls f.
type InvalidUnmarshalError struct { Type reflect.Type }
An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. (The argument to Unmarshal must be a non-nil pointer.)
type StructHandler ¶
type StructHandler struct {
}
StructHandler unmarshals logfmt into a struct. It matches incoming keys to the the struct's fields (either the struct field name or its tag, preferring an exact match but also accepting a case-insensitive match.
Field types supported by StructHandler are:
all numeric types (e.g. float32, int, etc.) []byte string bool - true if key is present, false otherwise (the value is ignored). time.Duration - uses time.ParseDuration
If a field is a pointer to an above type, and a matching key is not present in the logfmt data, the pointer will be untouched.
If v is not a pointer to an Handler or struct, Unmarshal will return an error.
An UnmarshalTypeError describes a logfmt value that was not appropriate for a value of a specific Go type.