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.