예제 #1
0
func lastUpdate(ctx *cli.Context) {
	filename, err := getFilenameArg(ctx)
	if err != nil {
		showError(ctx, err)
		return
	}

	rrd, err := cdata.OpenRrdRawFile(filename, true)
	if err != nil {
		fmt.Fprintln(ctx.App.Writer, err)
		return
	}
	defer rrd.Close()

	for _, datasource := range rrd.Datasources {
		fmt.Fprintf(ctx.App.Writer, " %s", datasource.GetName())
	}
	fmt.Fprint(ctx.App.Writer, "\n\n")

	fmt.Fprintf(ctx.App.Writer, "%10d:", rrd.LastUpdate.Unix())
	for _, datasource := range rrd.Datasources {
		fmt.Fprintf(ctx.App.Writer, " %s", datasource.GetLastValue())
	}
	fmt.Fprint(ctx.App.Writer, "\n")
}
예제 #2
0
파일: update.go 프로젝트: untoldwind/gorrd
func updateCommand(ctx *cli.Context) {
	filename, err := getFilenameArg(ctx)
	if err != nil {
		showError(ctx, err)
		return
	}

	rrd, err := cdata.OpenRrdRawFile(filename, false)
	if err != nil {
		showError(ctx, err)
		return
	}
	defer rrd.Close()

	timestamp, values, err := parseUpdateArg(ctx, rrd)
	if err != nil {
		showError(ctx, err)
		return
	}

	if err := rrd.Update(timestamp, values); err != nil {
		showError(ctx, err)
		return
	}
}
예제 #3
0
파일: last.go 프로젝트: untoldwind/gorrd
func last(ctx *cli.Context) {
	filename, err := getFilenameArg(ctx)
	if err != nil {
		showError(ctx, err)
		return
	}

	rrd, err := cdata.OpenRrdRawFile(filename, true)
	if err != nil {
		fmt.Fprintln(ctx.App.Writer, err)
		return
	}
	defer rrd.Close()

	fmt.Fprintf(ctx.App.Writer, "%d\n", rrd.LastUpdate.Unix())
}
예제 #4
0
func runDumpCommand(rrdFileName string) (string, error) {
	rrd, err := cdata.OpenRrdRawFile(rrdFileName, true)
	if err != nil {
		return "", err
	}
	defer rrd.Close()

	buffer := bytes.NewBufferString("")
	xmlDumper, err := dump.NewXmlOutput(buffer, true)
	if err != nil {
		return "", err
	}

	if err := rrd.DumpTo(xmlDumper); err != nil {
		return "", err
	}

	return buffer.String(), nil
}
예제 #5
0
파일: dump.go 프로젝트: untoldwind/gorrd
func dumpCommand(ctx *cli.Context) {
	filename, err := getFilenameArg(ctx)
	if err != nil {
		showError(ctx, err)
		return
	}

	rrd, err := cdata.OpenRrdRawFile(filename, true)
	if err != nil {
		fmt.Fprintln(ctx.App.Writer, err)
		return
	}
	defer rrd.Close()

	xmlDumper, err := dump.NewXmlOutput(ctx.App.Writer, true)
	if err != nil {
		fmt.Fprintln(ctx.App.Writer, err)
		return
	}
	if err := rrd.DumpTo(xmlDumper); err != nil {
		fmt.Fprintln(ctx.App.Writer, err)
		return
	}
}
예제 #6
0
func TestUpdateCompatibility(t *testing.T) {
	rrdtool, err := findRrdTool()

	if err != nil {
		t.Skipf("rrdtool not found: %s", err.Error())
		return
	}

	runUpdateCommand := func(filename string, timestamp time.Time, values ...string) error {
		rrd, err := cdata.OpenRrdRawFile(filename, false)
		if err != nil {
			return err
		}
		defer rrd.Close()

		return rrd.Update(timestamp, values)
	}

	Convey("Given minimal rrdfile with 5m step and 1 pdp per cdp", t, func() {
		tempDir := os.TempDir()
		rrdFileName := filepath.Join(tempDir, fmt.Sprintf("comp_update1-%d.rrd", time.Now().UnixNano()))
		defer os.Remove(rrdFileName)

		start := 1455218381
		So(rrdtool.create(
			rrdFileName,
			strconv.Itoa(start),
			"300",
			"DS:watts:GAUGE:300:0:100000",
			"DS:counter:COUNTER:300:0:10000",
			"RRA:AVERAGE:0.5:1:24",
			"RRA:MIN:0.5:1:24",
			"RRA:MAX:0.5:1:24",
			"RRA:LAST:0.5:1:24",
		), ShouldBeNil)

		Convey("When values are added in stepsize", func() {
			rrdFileNameCopy := filepath.Join(tempDir, fmt.Sprintf("comp_update1-copy-%d.rrd", time.Now().UnixNano()))
			defer os.Remove(rrdFileNameCopy)

			for i := 1; i < 10; i++ {
				copyFile(rrdFileName, rrdFileNameCopy)
				So(rrdtool.update(
					rrdFileName,
					fmt.Sprintf("%d:%d:%d", 300*i+start, i*100+5, i*200+10),
				), ShouldBeNil)

				err := runUpdateCommand(rrdFileNameCopy, time.Unix(int64(300*i+start), 0), strconv.Itoa(i*100+5), strconv.Itoa(i*200+10))

				So(err, ShouldBeNil)
				So(rrdFileNameCopy, shouldHaveSameContentAs, rrdFileName)
			}
		})

		Convey("When values are added with gaps", func() {
			rrdFileNameCopy := filepath.Join(tempDir, fmt.Sprintf("comp_update1-copy-%d.rrd", time.Now().UnixNano()))
			defer os.Remove(rrdFileNameCopy)

			timestamp := int64(start + 400)
			for i := 0; i < 20; i++ {
				copyFile(rrdFileName, rrdFileNameCopy)
				So(rrdtool.update(
					rrdFileName,
					fmt.Sprintf("%d:%d:%d", timestamp, i*100+5, i*200+10),
				), ShouldBeNil)

				err := runUpdateCommand(rrdFileNameCopy, time.Unix(timestamp, 0), strconv.Itoa(i*100+5), strconv.Itoa(i*200+10))

				So(err, ShouldBeNil)
				So(rrdFileNameCopy, shouldHaveSameContentAs, rrdFileName)

				if i%4 < 3 {
					timestamp += 200
				} else {
					timestamp += 400
				}
			}
		})
	})

	Convey("Given minimal rrdfile with 5m step", t, func() {
		tempDir := os.TempDir()
		rrdFileName := filepath.Join(tempDir, fmt.Sprintf("comp_update2-%d.rrd", time.Now().UnixNano()))
		defer os.Remove(rrdFileName)

		start := 1455218381
		So(rrdtool.create(
			rrdFileName,
			strconv.Itoa(start),
			"300",
			"DS:watts:GAUGE:300:0:100000",
			"RRA:AVERAGE:0.5:12:24",
			"RRA:MIN:0.5:12:24",
			"RRA:MAX:0.5:12:24",
			"RRA:LAST:0.5:12:24",
		), ShouldBeNil)

		Convey("When values are added within stepsize", func() {
			rrdFileNameCopy := filepath.Join(tempDir, fmt.Sprintf("comp_update2-copy-%d.rrd", time.Now().UnixNano()))
			defer os.Remove(rrdFileNameCopy)

			for i := 1; i < 5; i++ {
				copyFile(rrdFileName, rrdFileNameCopy)
				So(rrdtool.update(
					rrdFileName,
					fmt.Sprintf("%d:%d", i+start, i*100+5),
				), ShouldBeNil)

				err := runUpdateCommand(rrdFileNameCopy, time.Unix(int64(i+start), 0), strconv.Itoa(i*100+5))

				So(err, ShouldBeNil)
				So(rrdFileNameCopy, shouldHaveSameContentAs, rrdFileName)
			}
		})
	})

	Convey("Given minimal rrdfile with 5m step and 2 pdp per cdp", t, func() {
		tempDir := os.TempDir()
		rrdFileName := filepath.Join(tempDir, fmt.Sprintf("comp_update3-%d.rrd", time.Now().UnixNano()))
		defer os.Remove(rrdFileName)

		start := 1455218381
		So(rrdtool.create(
			rrdFileName,
			strconv.Itoa(start),
			"300",
			"DS:watts:GAUGE:300:0:100000",
			"RRA:AVERAGE:0.5:2:24",
			"RRA:MIN:0.5:2:24",
			"RRA:MAX:0.5:2:24",
			"RRA:LAST:0.5:2:24",
		), ShouldBeNil)

		Convey("When values are added in stepsize", func() {
			rrdFileNameCopy := filepath.Join(tempDir, fmt.Sprintf("comp_update3-copy-%d.rrd", time.Now().UnixNano()))
			defer os.Remove(rrdFileNameCopy)

			for i := 1; i < 10; i++ {
				copyFile(rrdFileName, rrdFileNameCopy)
				So(rrdtool.update(
					rrdFileName,
					fmt.Sprintf("%d:%d", 300*i+start, i*100+5),
				), ShouldBeNil)

				err := runUpdateCommand(rrdFileNameCopy, time.Unix(int64(300*i+start), 0), strconv.Itoa(i*100+5))

				So(err, ShouldBeNil)
				So(rrdFileNameCopy, shouldHaveSameContentAs, rrdFileName)
			}
		})

		Convey("When values are added with gaps", func() {
			rrdFileNameCopy := filepath.Join(tempDir, fmt.Sprintf("comp_update3-copy-%d.rrd", time.Now().UnixNano()))
			defer os.Remove(rrdFileNameCopy)

			timestamp := int64(start + 400)
			for i := 0; i < 20; i++ {
				copyFile(rrdFileName, rrdFileNameCopy)
				So(rrdtool.update(
					rrdFileName,
					fmt.Sprintf("%d:%d", timestamp, i*100+5),
				), ShouldBeNil)

				err := runUpdateCommand(rrdFileNameCopy, time.Unix(timestamp, 0), strconv.Itoa(i*100+5))

				So(err, ShouldBeNil)
				So(rrdFileNameCopy, shouldHaveSameContentAs, rrdFileName)

				if i%4 < 3 {
					timestamp += 200
				} else {
					timestamp += 400
				}
			}
		})
	})
}