func setupUDPListener(listen string, errorChannel chan error) {
	addr, err := net.ResolveUDPAddr("udp", listen)

	if err != nil {
		errorChannel <- err
		return
	}

	conn, err := net.ListenUDP("udp", addr)

	if err != nil {
		errorChannel <- err
		return
	}

	errorChannel <- gotelemetry.NewLogError("Graphite => Listening for UDP plaintext messages on %s", conn.LocalAddr())

	buf := make([]byte, 2048)

	for {
		if n, addr, err := conn.ReadFromUDP(buf); err == nil {
			remoteAddress := addr.String() + ", UDP"

			if err := parseRequest(remoteAddress, string(buf[0:n]), errorChannel); err != nil {
				errorChannel <- gotelemetry.NewErrorWithFormat(400, "Graphite => [%s, UDP] Error %s while receving data", nil, addr, err)
			}
		} else {
			errorChannel <- gotelemetry.NewErrorWithFormat(400, "Graphite => [%s, UDP] Error %s while receving data", nil, addr, err)
		}
	}
}
func parseRequest(remoteAddress, request string, errorChannel chan error) error {
	request = strings.TrimSpace(request)

	if request == "" {
		return nil
	}

	line := splitter.Split(request, -1)

	switch len(line) {
	case 2:
		return parseCounterRequest(remoteAddress, line, errorChannel)

	case 3:
		return parseTraditionalRequest(remoteAddress, line, errorChannel)

	default:
		return gotelemetry.NewErrorWithFormat(
			400, "Graphite => [%s] Unable to parse request %s",
			nil,
			remoteAddress,
			request,
		)
	}
}
func parseCounterRequest(remoteAddress string, line []string, errorChannel chan error) error {
	counterName := line[0]
	valueString := line[1]

	isSetOperation := valueString[0] == '='

	if isSetOperation {
		valueString = strings.TrimPrefix(valueString, "=")
	}

	value, err := strconv.ParseInt(valueString, 10, 64)

	if err != nil {
		return gotelemetry.NewErrorWithFormat(
			400, "Graphite => [%s] Invalid value %s: %s",
			nil,
			remoteAddress,
			line[1],
			err.Error(),
		)
	}

	counter, isCreated, err := aggregations.GetCounter(counterName)

	if isCreated {
		errorChannel <- gotelemetry.NewLogError("Graphite => Started receiving graphite data for '%s'", counterName)
	}

	if err != nil {
		return gotelemetry.NewErrorWithFormat(
			500, "Graphite => [%s] Unable to get counter %s: %s",
			nil,
			remoteAddress,
			counterName,
			err.Error(),
		)
	}

	if isSetOperation {
		counter.SetValue(value)
	} else {
		counter.Increment(value)
	}

	return nil
}
Beispiel #4
0
func (p *ProcessPlugin) performHTTPTask(j *job.Job) (string, error) {
	j.Debugf("Retrieving expression from URL `%s`", p.url)

	r, err := http.Get(p.url)

	if err != nil {
		return "", err
	}

	defer r.Body.Close()

	out, err := ioutil.ReadAll(r.Body)

	if r.StatusCode > 399 {
		return string(out), gotelemetry.NewErrorWithFormat(r.StatusCode, "HTTP request failed with status %d", nil, r.StatusCode)
	}

	return string(out), nil
}
func parseTraditionalRequest(remoteAddress string, line []string, errorChannel chan error) error {
	seriesName := line[0]

	value, err := strconv.ParseFloat(line[1], 64)

	if err != nil {
		return gotelemetry.NewErrorWithFormat(
			400, "Graphite => [%s] Invalid value %s: %s",
			nil,
			remoteAddress,
			line[1],
			err.Error(),
		)
	}

	timestamp, err := strconv.ParseInt(line[2], 10, 64)

	if err != nil {
		return gotelemetry.NewErrorWithFormat(
			400, "Graphite => [%s] Invalid timestamp %s: %s",
			nil,
			remoteAddress,
			line[2],
			err.Error(),
		)
	}

	series, isCreated, err := aggregations.GetSeries(seriesName)

	if err != nil {
		return gotelemetry.NewErrorWithFormat(
			500, "Graphite => [%s] Unable to get series %s: %s",
			nil,
			remoteAddress,
			seriesName,
			err.Error(),
		)
	}

	if isCreated {
		errorChannel <- gotelemetry.NewLogError("Graphite => Started receiving graphite data for '%s'", seriesName)
	}

	ts := time.Unix(timestamp, 0)

	if err := series.Push(&ts, value); err != nil {
		return gotelemetry.NewErrorWithFormat(
			500, "Graphite => [%s] Unable to push value %f with timestamp %s to series %s: %s",
			nil,
			remoteAddress,
			value,
			ts,
			seriesName,
			err.Error(),
		)
	}

	errorChannel <- gotelemetry.NewDebugError(
		"Graphite => [%s] Pushed value %f to series %s at time %s",
		remoteAddress,
		value,
		seriesName,
		ts,
	)

	return nil
}