我是Perl和RRD的新手。
我试图实现一个简单的例子,虽然它看起来运行正常但是没有显示输出。图片是正常生成的,但图表中没有数据。
我一直在关注CPAN文档的实现RRD::Simple
,理论上我做错了。我试图调试代码,看起来很好,但是当打印图表时,没有数据。
#!/usr/bin/perl
use strict;
use warnings;
use RRD::Simple ();
use Data::Dumper;
$| = 1; # Flush the output
my ($rrd, $unixtime, $file);
$file = "perl.txt";
my $path = '/home/os/Desktop/Test_Perl/';
my $period = '3years';
my $rrdfile = 'myfile.rrd';
while (sleep 15) {
open(FH, ">>", $file) || die "Unable to open $file: $!\n";
my $range = 50;
my $minimum = 100;
my $random_number_in = int(rand($range)) + $minimum;
my $random_number_out = int(rand($range)) + $minimum;
my $random_number_sec = int(rand($range)) + $minimum;
# Create an interface object
$rrd = RRD::Simple->new(
file => $rrdfile,
cf => [qw( AVERAGE MIN MAX LAST )],
#default_dstype => "DERIVE",
);
unless (-e $rrdfile) {
# Create a new RRD file with 3 data sources called
# bytesIn, bytesOut and faultsPerSec.
$rrd->create(
$period,
step => 5, # 5 sec interval
bytesIn => "GAUGE",
bytesOut => "GAUGE",
faultsPerSec => "GAUGE"
);
}
# Put some arbitary data values in the RRD file for the same
# 3 data sources called bytesIn, bytesOut and faultsPerSec.
$rrd->update(
bytesIn => $random_number_in,
bytesOut => $random_number_out,
faultsPerSec => $random_number_sec
);
print FH "This is the bytes_in: $random_number_in\n";
print FH "This is the bytes_out: $random_number_out\n";
print FH "This is the bytes_sec: $random_number_sec\n";
# Generate graphs:
# /home/os/Desktop/Test_Perl/myfile-hourly.png, /home/os/Desktop/Test_Perl/myfile-daily.png
# /home/os/Desktop/Test_Perl/myfile-weekly.png, /home/os/Desktop/Test_Perl/myfile-monthly.png
my %rtn = $rrd->graph(
$rrdfile,
destination => $path,
basename => "my_graph",
timestamp => "both", # graph, rrd, both or none
periods => [qw(hour day week month)], # omit to generate all graphs
sources => [qw(bytesIn bytesOut faultsPerSec)],
source_colors => [qw(ff0000 aa3333 000000)],
source_labels => [("Bytes In", "Bytes Out", "Faults Per Second")],
source_drawtypes => [qw(LINE1 AREA LINE)],
line_thickness => 2,
extended_legend => 1,
title => "Network Interface eth0",
vertical_label => "Bytes/Faults",
width => 800,
height => 500,
interlaced => "", # If images are interlaced they become visible to browsers more quickly
);
printf("Created %s\n", join(", ", map { $rtn{$_}->[0] } keys %rtn));
# Return information about an RRD file
my $info = $rrd->info($rrdfile); # This method will return a complex data structure containing details about the RRD file, including RRA and data source information.
print Data::Dumper::Dumper($info);
my @sources = $rrd->sources($rrdfile);
my $seconds = $rrd->retention_period($rrdfile); # This method will return the maximum period of time (in seconds) that the RRD file will store data for.
# Get unixtime of when RRD file was last updated
$unixtime = $rrd->last($rrdfile);
print FH "myfile.rrd was last updated at " . scalar(localtime($unixtime)) . "\n";
# Get list of data source names from an RRD file
my @dsnames = $rrd->sources;
print "Available data sources: " . join(", ", @dsnames) . "\n";
my $heartbeat_In = $rrd->heartbeat($rrdfile, "bytesIn");
my $heartbeat_Out = $rrd->heartbeat($rrdfile, "bytesOut");
my $heartbeat_sec = $rrd->heartbeat($rrdfile, "faultsPerSec"); # This method will return the current heartbeat of a data source.
printf "This is the heartbeat_in: %s\n", $heartbeat_In;
my @rtn_In = $rrd->heartbeat($rrdfile, "bytesIn", 10);
my @rtn_Out = $rrd->heartbeat($rrdfile, "bytesOut", 10);
my @rtn_sec = $rrd->heartbeat($rrdfile, "faultsPerSec", 10); # This method will set a new heartbeat of a data source.
close(FH);
}
部分输出:
'myfilerrd' => {
'last_ds' => 'U',
'value' => undef,
'min' => '0',
'max' => undef,
'minimal_heartbeat' => 120,
'index' => 3,
'type' => 'DERIVE',
'unknown_sec' => 15
}
我不明白为什么值未定义?
答案 0 :(得分:0)
经过3-4天的测试和在互联网上搜索更多信息后,我找到了问题的答案。 RRD是一个非常简单易用的工具,但非常强大。我建议任何人通过Perl使用它,特别是使用RRD :: Simple模块非常简单。
答案:
我将RRD的心跳调整为10秒,而我的步骤(数据采集时间)默认为300。如果用户默认情况下未指定步骤“采样频率”,则系统将使用300.结果,图形采用0值,因此没有输出。更多信息和非常好的分析可以在HeartBeat
找到根据我的实验,我发现因为我在create函数中使用了while循环,所以我必须首先给出命令:
my $rrd = RRD::Simple->new( file => "myfile.rrd" );
作为第二步,我必须通过输入命令来终止进程并设置步骤:
my $rrd = RRD::Simple->new(
file => "myfile.rrd",
step => 50 );
根据我的实验,我发现我必须删除下面这段代码必须作为第二步添加到文件中。首先必须进行创建,然后将其添加到循环中。这是因为在用户开始修改它们之前,最初必须使用所有设置创建“myfile.rrd”。
unless (-f "myfile.rrd") {
$rrd->create(
step => 50,
bytesIn => "GAUGE",
bytesOut => "GAUGE",
faultsPerSec => "COUNTER"
);
}
另一点值得一提的是,默认情况下,RRD数据源(DS)设置为GAUGE。更多信息可以在RRDtool
找到可以轻松找到Perl模块CPAN RRD :: Simple,它提供了可以添加到代码中的分析和额外“功能”。
总之 RRD :: Simple 非常简单,可以通过复制粘贴到您的程序中来执行。任何进一步的修改(例如采样率,平均值/最大值/最小值等)都需要一点阅读,但绝对值得付出努力。不幸的是,网上没有太多的例子,所以有些测试需要它来完成,以便了解我需要在我的代码中修改什么才能使它工作。通过撰写这篇简短的分析并提供一些阅读的链接,我希望能够让其他人花费几天时间来解决他的问题。
我再次鼓励任何人尝试实施RRD是一个非常强大的工具,以图形方式查看您的结果并将数据存储长达3年。
答案 1 :(得分:0)
我认为另一个更新可能对某些人有用。而不是通过添加和删除代码来跟踪所有这些过程,以使rrd文件正常工作。
经过修改和实验后,我找到了另一种解决方案。
use strict;
use RRD::Simple;
use RRDs;
my $rrd = RRD::Simple->new(
file => "myfile.rrd",
rrdtool => "/usr/local/rrdtool-1.2.11/bin/rrdtool", #optional
tmpdir => "/var/tmp", #optional
cf => [ qw(AVERAGE MAX) ], #optional
default_dstype => "COUNTER", #optional
on_missing_ds => "add", #optional
RRDs::tune("myfile.rrd", "-i", "Source_Name:0") #optional -i or --minimum
RRDs::tune("myfile.rrd", "-a", "Source_Name:200") #optional -a or --maximum
);
有人可以使用多个可选值,但我建议使用所有这些值,以便您可以完全控制该程序。
我正在使用:
default_dstype => "COUNTER", #optional
因为默认情况下,RRD会将 GAUGE 设置为数据源(DS)。通过将 DS 设置为 COUNTER ,用户可以设置最小值和最大值。这里也可以找到简短的例子RRD::Simple::Examples。