2 use strict;
3 use warnings;
5 package RRDCached;
7 =head1 RRDCached
9 This module implements the B<RRDCached> client protocol for bulk updates.
11 =head1 SYNOPSIS
13 my $cache = RRDCached->new('unix:/var/run/rrdcached.sock')
14 or die "Cannot connect to RRDCached";
16 $cache->update('file1.rrd', 'N:10:2:78');
17 $cache->update('file2.rrd', '1222973760:30:0:9', 'N:68:1:55');
18 ...
20 $cache->done();
22 =cut
24 use IO::Socket;
26 #################################################################
28 sub new {
29 my ($class, $daemon) = @_;
30 my $this = {};
32 $daemon ||= $ENV{RRDCACHED_ADDRESS};
33 defined $daemon or return undef;
35 my $sock_family = "INET";
37 if ($daemon =~ m{^unix: | ^/ }x)
38 {
39 $sock_family = "UNIX";
40 $daemon =~ s/^unix://;
41 }
43 my $sock = "IO::Socket::$sock_family"->new($daemon)
44 or die "Cannot connect to daemon";
46 $sock->printflush("BATCH\n");
48 my $go = $sock->getline;
49 warn "We didn't get go-ahead from rrdcached" unless $go =~ /^0/;
51 $sock->autoflush(0);
53 bless { sock => $sock,
54 daemon => $daemon,
55 }, $class;
56 }
58 sub update {
59 my $this = shift;
60 my $file = shift;
61 ## @updates = @_;
63 @_ or warn "No updates for $file!";
65 ## rrdcached doesn't handle N: timestamps
66 my $now = time();
67 s/^N(?=:)/$now/ for (@_);
69 $this->{sock}->print("update $file @_\n");
70 }
72 sub done {
73 my ($this) = @_;
75 my $sock = delete $this->{sock};
77 $sock->printflush(".\n");
78 my $errs = $sock->getline;
80 my ($num_err) = $errs =~ /^(\d+)/;
81 return unless $num_err;
83 $sock->getline for (1..$num_err);
85 $sock->close;
86 }
88 #################################################################
90 1;