func findNums(prefix string, kvs map[string]interface{}, out io.Writer) {
	for k, v := range kvs {
		vf, ok := v.(float64)
		if !ok {
			continue
		}
		_, err := fmt.Fprintf(out, "rsyslog.%v.%v:%d|g\n", prefix, sanitizeKey(k), int(vf))
		if err != nil {
			el.Println("Error while writing", err)
		}
	}
}
Take the entire json blob and find any key/value pairs whose value is number and formulate a stat entry
package main
import (
	"bufio"
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"net"
	"os"
)
const (
	VERSION         = "1.0.0"
	CHAR_UNDERSCORE = byte(95)
	CHAR_UPPER_A    = byte(65)
	CHAR_UPPER_Z    = byte(90)
	CHAR_LOWER_A    = byte(97)
	CHAR_LOWER_Z    = byte(122)
	CHAR_0          = byte(48)
	CHAR_9          = byte(57)
	CASE_DELTA      = 32  
)
var el = log.New(os.Stderr, "", 0)
var b = make([]byte, 255)  
func printVersion() {
	fmt.Fprintf(os.Stderr, "go-rsyslog-pstats %s\n", VERSION)
}
func printHelp() {
	fmt.Fprintln(os.Stderr, "go-rsyslog-pstats --port number\n")
	fmt.Fprintf(os.Stderr, "Parses and forwards rsyslog process stats to a local statsite or statsd process\n\n")
	flag.PrintDefaults()
}
func parseConfig() (port string) {
	flag.Usage = printHelp
	outPort := flag.String("port", "", "Statsite udp port to connect to")
	printV := flag.Bool("version", false, "Prints the version string")
	flag.Parse()
	if *printV {
		printVersion()
		os.Exit(0)
	}
	return *outPort
}
func main() {
	outPort := parseConfig()
	in := bufio.NewReader(os.Stdin)
	if outPort == "" {
		el.Println("No port was provided\n")
		printHelp()
		os.Exit(1)
	}
	udpAddr, err := net.ResolveUDPAddr("udp", "localhost:"+outPort)
	if err != nil {
		el.Fatal("Could not resolve address", err)
	}
	out, err := net.DialUDP("udp", nil, udpAddr)
	if err != nil {
		el.Fatal("Could not dial address", err)
	}
	lb := make([]byte, 0, 1024)
	for {
		lb, err = in.ReadBytes('\n')
		if err != nil {
			el.Fatalln("Failed to read line from input", err)
		}
		parseMsg(lb, out)
	}
}
func sanitizeKey(s string) string {
	pos := 0
	last := CHAR_UNDERSCORE
	for _, r := range s {
		c := byte(r)
		if c < CHAR_0 || (c > CHAR_9 && c < CHAR_UPPER_A) || (c > CHAR_UPPER_Z && c < CHAR_LOWER_A) || c > CHAR_LOWER_Z {
			if last == CHAR_UNDERSCORE {
				continue
			}
			c = CHAR_UNDERSCORE
		}
		if c >= CHAR_UPPER_A && c <= CHAR_UPPER_Z {
			c = byte(c + CASE_DELTA)
		}
		b[pos] = c
		last = b[pos]
		pos++
	}
	if b[pos-1] == CHAR_UNDERSCORE {
		pos--
	}
	return string(b[:pos])
}