Example #1
0
// Export data from RRD file(s)
func (e *Exporter) xport(start, end time.Time, step time.Duration) (XportResult, error) {
	cStart := C.time_t(start.Unix())
	cEnd := C.time_t(end.Unix())
	cStep := C.ulong(step.Seconds())
	args := e.makeArgs(start, end, step)

	mutex.Lock()
	defer mutex.Unlock()

	var (
		ret      C.int
		cXSize   C.int
		cColCnt  C.ulong
		cLegends **C.char
		cData    *C.double
	)
	err := makeError(C.rrdXport(
		&ret,
		C.int(len(args)),
		&args[0],
		&cXSize, &cStart, &cEnd, &cStep, &cColCnt, &cLegends, &cData,
	))
	if err != nil {
		return XportResult{start, end, step, nil, 0, nil}, err
	}

	start = time.Unix(int64(cStart), 0)
	end = time.Unix(int64(cEnd), 0)
	step = time.Duration(cStep) * time.Second
	colCnt := int(cColCnt)

	legends := make([]string, colCnt)
	for i := 0; i < colCnt; i++ {
		legend := C.arrayGetCString(cLegends, C.int(i))
		legends[i] = C.GoString(legend)
		C.free(unsafe.Pointer(legend))
	}
	C.free(unsafe.Pointer(cLegends))

	rowCnt := (int(cEnd)-int(cStart))/int(cStep) + 1
	valuesLen := colCnt * rowCnt
	values := make([]float64, valuesLen)
	sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&values)))
	sliceHeader.Cap = valuesLen
	sliceHeader.Len = valuesLen
	sliceHeader.Data = uintptr(unsafe.Pointer(cData))
	return XportResult{start, end, step, legends, rowCnt, values}, nil
}
Example #2
0
// Fetch retrieves data from RRD file.
func Fetch(filename, cf string, start, end time.Time, step time.Duration) (FetchResult, error) {
	var null **C.char
	fn := C.CString(filename)
	defer freeCString(fn)
	cCf := C.CString(cf)
	defer freeCString(cCf)
	cStart := C.time_t(start.Unix())
	cEnd := C.time_t(end.Unix())
	cStep := C.ulong(step.Seconds())
	var (
		ret      C.int
		cDsCnt   C.ulong
		cDsNames **C.char
		cData    *C.double
	)
	err := makeError(C.rrdFetch(&ret, fn, cCf, &cStart, &cEnd, &cStep, &cDsCnt, &cDsNames, &cData))
	if err != nil {
		return FetchResult{filename, cf, start, end, step, nil, 0, nil}, err
	}

	if cDsNames == null {
		return FetchResult{filename, cf, start, end, step, nil, 0, nil}, Error("malloc error")
	}

	start = time.Unix(int64(cStart), 0)
	end = time.Unix(int64(cEnd), 0)
	step = time.Duration(cStep) * time.Second
	dsCnt := int(cDsCnt)

	dsNames := make([]string, dsCnt)
	for i := 0; i < dsCnt; i++ {
		dsName := C.arrayGetCString(cDsNames, C.int(i))
		dsNames[i] = C.GoString(dsName)
		C.free(unsafe.Pointer(dsName))
	}
	C.free(unsafe.Pointer(cDsNames))

	rowCnt := (int(cEnd)-int(cStart))/int(cStep) + 1
	valuesLen := dsCnt * rowCnt
	var values []float64
	sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&values)))
	sliceHeader.Cap = valuesLen
	sliceHeader.Len = valuesLen
	sliceHeader.Data = uintptr(unsafe.Pointer(cData))
	return FetchResult{filename, cf, start, end, step, dsNames, rowCnt, values}, nil
}