func pixelAggHandler(r *http.Request, w http.ResponseWriter, rcvr *receiver.Receiver, cmd aggregator.AggCmd) { defer func() { if rc := recover(); rc != nil { log.Printf("pixelAggHandler: Recovered (this request is dropped): %v", rc) } }() sendPixel(w) err := r.ParseForm() if err != nil { log.Printf("pixelAggHandler: error from ParseForm(): %v", err) return } for name, vals := range r.Form { // foo.bar.baz=12.345 for _, valStr := range vals { var val float64 n, _ := fmt.Sscanf(valStr, "%f", &val) if n < 1 { log.Printf("PixelAddHandler: error parsing %q", valStr) return } rcvr.QueueAggregatorCommand(aggregator.NewCommand(cmd, misc.SanitizeName(name), val)) } } }
func (r *Receiver) SetCluster(c clusterer) { r.cluster = c r.dsc.clstr = c name := strings.Replace(c.LocalNode().Name(), ".", "_", -1) name = misc.SanitizeName(name) if ok, _ := regexp.MatchString("[0-9]", name[0:1]); ok { // starts with a digit name = "_" + name // prepend an underscore } if r.ReportStatsPrefix != "" { r.ReportStatsPrefix += ("." + name) } else { r.ReportStatsPrefix = name } }
func parseGraphitePacket(packetStr string) (string, time.Time, float64, error) { var ( name string tstamp int64 value float64 ) if n, err := fmt.Sscanf(packetStr, "%s %f %d", &name, &value, &tstamp); n != 3 || err != nil { return "", time.Time{}, 0, fmt.Errorf("error %v scanning input: %q", err, packetStr) } return misc.SanitizeName(name), time.Unix(tstamp, 0), value, nil }
// ParseStatsdPacket parses a statsd packet e.g: gorets:1|c|@0.1. See // https://github.com/etsy/statsd/blob/master/docs/metric_types.md // There is no need to support multi-metric packets here, since it // uses newline as separator, the text handler in daemon/services.go // would take care of it. func ParseStatsdPacket(packet string) (*Stat, error) { var ( result = &Stat{Sample: 1} parts []string ) parts = strings.Split(packet, ":") if len(parts) < 1 { return nil, fmt.Errorf("invalid packet: %q", packet) } result.Name = misc.SanitizeName(parts[0]) if len(parts) == 1 { result.Value, result.Metric = 1, "c" return result, nil } // NB: This cannot be done with a single Sscanf for "%f|%s|@%f" // because the %s is hungry and will eat the rest of the string. parts = strings.Split(parts[1], "|") if len(parts) < 2 { return nil, fmt.Errorf("invalid packet: %q", packet) } if n, err := fmt.Sscanf(parts[0], "%f", &result.Value); n != 1 || err != nil { return nil, fmt.Errorf("error %v scanning input (cannot parse value|metric): %q", err, packet) } if parts[0][0] == '+' || parts[1][0] == '-' { // safe because "" would cause an error above result.Delta = true } if parts[1] != "c" && parts[1] != "g" && parts[1] != "ms" { return nil, fmt.Errorf("invalid metric type: %q", parts[1]) } result.Metric = parts[1] if len(parts) > 2 { if n, err := fmt.Sscanf(parts[2], "@%f", &result.Sample); n != 1 || err != nil { return nil, fmt.Errorf("error %v scanning input (bad @sample?): %q", err, packet) } if result.Sample < 0 || result.Sample > 1 { return nil, fmt.Errorf("invalid sample: %q (must be between 0 and 1.0)", parts[2]) } } return result, nil }
func PixelHandler(rcvr *receiver.Receiver) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { defer func() { if rc := recover(); rc != nil { log.Printf("PixelHandler: Recovered (this request is dropped): %v", rc) } }() sendPixel(w) err := r.ParseForm() if err != nil { log.Printf("PixelHandler: error from ParseForm(): %v", err) return } for name, vals := range r.Form { // foo.bar.baz=12.345@1425959940 for _, valStr := range vals { var val, ut float64 n, _ := fmt.Sscanf(valStr, "%f@%f", &val, &ut) if n < 1 { log.Printf("PixelHandler: error parsing %q", valStr) return } var ts time.Time if ut == 0 { ts = time.Now() } else { nsec := int64(ut*1000000000) % 1000000000 ts = time.Unix(int64(ut), nsec) } rcvr.QueueDataPoint(misc.SanitizeName(name), ts, val) } } } }