5 Memcached - A Plugin to monitor Memcached Servers (Multigraph)
 
   7 =head1 MUNIN CONFIGURATION
 
  10  env.host 127.0.0.1     *default*
 
  11  env.port 11211         *default*
 
  12  env.timescale 3        *default*
 
  14 =head2 MUNIN ENVIRONMENT CONFIGURATION EXPLANATION
 
  16  host = host we are going to monitor
 
  17  port = port we are connecting to, in order to gather stats
 
  18  timescale = what time frame do we want to format our graphs too
 
  20 =head1 NODE CONFIGURATION
 
  22 Please make sure you can telnet to your memcache servers and issue the
 
  23  following commands: stats, stats settings, stats items and stats slabs.
 
  25 Available Graphs contained in this Plugin
 
  27 bytes => This graphs the current network traffic in and out
 
  29 commands => I<MULTIGRAPH> This graphs the current commands being issued to the memcache machine. B<Multigraph breaks this down to per slab.>
 
  31 conns => This graphs the current, max connections as well as avg conns per sec avg conns per sec is derived from total_conns / uptime.
 
  33 evictions => I<MULTIGRAPH> This graphs the current evictions on the node. B<Multigraph breaks this down to per slab.>
 
  35 items => I<MULTIGRAPH> This graphs the current items and total items in the memcached node. B<Multigraph breaks this down to per slab.>
 
  37 memory => I<MULTIGRAPH> This graphs the current and max memory allocation B<Multigraph breaks this down to per slab.>
 
  39 The following example holds true for all graphing options in this plugin.
 
  40  Example: ln -s /usr/share/munin/plugins/memcached_multi_ /etc/munin/plugins/memcached_multi_bytes
 
  42 =head1 ADDITIONAL INFORMATION
 
  44 You will find that some of the graphs have LEI on them. This was done in order to save room
 
  45 on space for text and stands for B<Last Evicted Item>.
 
  47 The B<Timescale> variable formats certain graphs based on the following guidelines.
 
  50  3 => Hours  B<*Default*>
 
  53 =head1 ACKNOWLEDGEMENTS
 
  55 The core of this plugin is based on the mysql_ plugin maintained by Kjell-Magne Ãierud
 
  57 Thanks to dormando as well for putting up with me ;)
 
  61 Matt West < https://code.google.com/p/memcached-munin-plugin/ >
 
  70     #%# capabilities=autoconf suggest
 
  80 my $host = $ENV{host} || "127.0.0.1";
 
  81 my $port = $ENV{port} || 11211;
 
  84 # This hash contains the information contained in two memcache commands
 
  85 # stats and stats settings.
 
  88 # This gives us eviction rates and other hit stats per slab
 
  89 # We track this so we can see if something was evicted earlier than necessary
 
  92 # This gives us the memory size and usage per slab
 
  93 # We track this so we can see what slab is being used the most and has no free chunks 
 
  94 # so we can re-tune memcached to allocate more pages for the specified chunk size
 
  96 my $timescale = $ENV{timescale} || 3;
 
  97 # This gives us the ability to control the timescale our graphs are displaying.
 
  98 # The default it set to divide by hours, if you want to get seconds set it to 1.
 
  99 # Options: 1 = seconds, 2 = minutes, 3 = hours, 4 = days
 
 101 # So I was trying to figure out how to build this up, and looking at some good examples
 
 102 # I decided to use the format, or for the most part, the format from the mysql_ munin plugin
 
 103 # for Innodb by Kjell-Magne Ãierud, it just spoke ease of flexibility especially with multigraphs
 
 106 # %graphs   is a container for all of the graph definition information. In here is where you'll
 
 107 #           find the configuration information for munin's graphing procedure.
 
 110 #   $graph{graph_name} => {
 
 112 #           # You'll find keys and values stored here for graph manipulation
 
 115 #           # Name: name given to data value
 
 116 #           # Attr: Attribute for given value
 
 117 #           { name => 'Name', (Attr) },
 
 125         args => '--base 1000 --lower-limit 0',
 
 126         vlabel => 'Items in Memcached',
 
 127         category => 'memcached',
 
 129         info => 'This graph shows the number of items in use by memcached',
 
 132         { name => 'curr_items', label => 'Current Items', min => '0' },
 
 133         { name => 'total_items', label => 'New Items', min => '0', type => 'DERIVE' },
 
 139         args => '--base 1024 --lower-limit 0',
 
 140         vlabel => 'Bytes Used',
 
 141         category => 'memcached',
 
 142         title => 'Memory Usage',
 
 143         info => 'This graph shows the memory consumption of memcached',
 
 146         { name => 'limit_maxbytes', draw => 'AREA', label => 'Maximum Bytes Allocated', min => '0' },
 
 147         { name => 'bytes', draw => 'AREA', label => 'Current Bytes Used', min => '0' },
 
 153         args => '--base 1000',
 
 154         vlabel => 'bits in (-) / out (+)',
 
 155         title => 'Network Traffic',
 
 156         category => 'memcached',
 
 157         info => 'This graph shows the network traffic in (-) / out (+) of the machine',
 
 158         order => 'bytes_read bytes_written',
 
 161         { name => 'bytes_read', type => 'DERIVE', label => 'Network Traffic coming in (-)', graph => 'no', cdef => 'bytes_read,8,*', min => '0' },
 
 162         { name => 'bytes_written', type => 'DERIVE', label => 'Traffic in (-) / out (+)', negative => 'bytes_read', cdef => 'bytes_written,8,*', min => '0' },
 
 168         args => '--base 1000 --lower-limit 0',
 
 169         vlabel => 'Connections per ${graph_period}',
 
 170         category => 'memcached',
 
 171         title => 'Connections',
 
 172         info => 'This graph shows the number of connections being handled by memcached',
 
 173         order => 'max_conns curr_conns avg_conns',
 
 176         { name => 'curr_conns', label => 'Current Connections', min => '0' },
 
 177         { name => 'max_conns', label => 'Max Connections', min => '0' },
 
 178         { name => 'avg_conns' , label => 'Avg Connections', min => '0' },
 
 182 $graphs{commands} = {
 
 184         args => '--base 1000 --lower-limit 0',
 
 185         vlabel => 'Commands per ${graph_period}',
 
 186         category => 'memcached',
 
 188         info => 'This graph shows the number of commands being handled by memcached',
 
 191         { name => 'cmd_get', type => 'DERIVE', label => 'Gets', info => 'Cumulative number of retrieval reqs', min => '0' },
 
 192         { name => 'cmd_set', type => 'DERIVE', label => 'Sets', info => 'Cumulative number of storage reqs', min => '0' },
 
 193         { name => 'get_hits', type => 'DERIVE', label => 'Get Hits', info => 'Number of keys that were requested and found', min => '0' },
 
 194         { name => 'get_misses', type => 'DERIVE', label => 'Get Misses', info => 'Number of keys there were requested and not found', min => '0' },
 
 195         { name => 'delete_hits', type => 'DERIVE', label => 'Delete Hits', info => 'Number of delete requests that resulted in a deletion of a key', min => '0' },
 
 196         { name => 'delete_misses', type => 'DERIVE', label => 'Delete Misses', info => 'Number of delete requests for missing key', min => '0' },
 
 197         { name => 'incr_hits', type => 'DERIVE', label => 'Increment Hits', info => 'Number of successful increment requests', min => '0' },
 
 198         { name => 'incr_misses', type => 'DERIVE', label => 'Increment Misses', info => 'Number of unsuccessful increment requests', min => '0' },
 
 199         { name => 'decr_hits', type => 'DERIVE', label => 'Decrement Hits', info => 'Number of successful decrement requests', min => '0' },
 
 200         { name => 'decr_misses', type => 'DERIVE', label => 'Decrement Misses', info => 'Number of unsuccessful decrement requests', min => '0' },
 
 204 $graphs{evictions} = {
 
 206         args => '--base 1000 --lower-limit 0',
 
 207         vlabel => 'Evictions per ${graph_period}',
 
 208         category => 'memcached',
 
 209         title => 'Evictions',
 
 210         info => 'This graph shows the number of evictions per second',
 
 213         { name => 'evictions', label => 'Evictions', info => 'Cumulative Evictions Across All Slabs', type => 'DERIVE', min => '0' },
 
 214         { name => 'evicted_nonzero', label => 'Evictions prior to Expire', info => 'Cumulative Evictions forced to expire prior to expiration', type => 'DERIVE', min => '0' },
 
 215         { name => 'reclaimed', label => 'Reclaimed Items', info => 'Cumulative Reclaimed Item Entries Across All Slabs', type => 'DERIVE', min => '0' },
 
 219 $graphs{slabchnks} = {
 
 221         args => '--base 1000 --lower-limit 0',
 
 222         vlabel => 'Available Chunks for this Slab',
 
 223         category => 'memcached',
 
 224         title => 'Chunk Usage for Slab: ',
 
 225         info => 'This graph shows you the chunk usage for this memory slab.',
 
 228         { name => 'total_chunks', label => 'Total Chunks Available', min => '0' },
 
 229         { name => 'used_chunks', label => 'Total Chunks in Use', min => '0' },
 
 230         { name => 'free_chunks', label => 'Total Chunks Not in Use (Free)', min => '0' },
 
 234 $graphs{slabhits} = {
 
 236         args => '--base 1000 --lower-limit 0',
 
 237         vlabel => 'Hits per Slab per ${graph_period}',
 
 238         category => 'memcached',
 
 239         title => 'Hits for Slab: ',
 
 240         info => 'This graph shows you the successful hit rate for this memory slab.',
 
 243         { name => 'get_hits', label => 'Get Requests', type => 'DERIVE', min => '0' },
 
 244         { name => 'cmd_set', label => 'Set Requests', type => 'DERIVE', min => '0' },
 
 245         { name => 'delete_hits', label => 'Delete Requests', type => 'DERIVE', min => '0' },
 
 246         { name => 'incr_hits', label => 'Increment Requests', type => 'DERIVE', min => '0' },
 
 247         { name => 'decr_hits', label => 'Decrement Requests', type => 'DERIVE', min => '0' },
 
 251 $graphs{slabevics} = {
 
 253         args => '--base 1000 --lower-limit 0',
 
 254         vlabel => 'Evictions per Slab per ${graph_period}',
 
 255         category => 'memcached',
 
 256         title => 'Evictions for Slab: ',
 
 257         info => 'This graph shows you the eviction rate for this memory slab.',
 
 260         { name => 'evicted', label => 'Total Evictions', type => 'DERIVE', min => '0' },
 
 261         { name => 'evicted_nonzero', label => 'Evictions from LRU Prior to Expire', type => 'DERIVE', min => '0' },
 
 262         { name => 'reclaimed', label => 'Reclaimed Expired Items', info => 'This is number of times items were stored in expired entry memory space', type => 'DERIVE', min => '0' },
 
 266 $graphs{slabevictime} = {
 
 268         args => '--base 1000 --lower-limit 0',
 
 269         vlabel => ' since Request for LEI',
 
 270         category => 'memcached',
 
 271         title => 'Eviction Request Time for Slab: ',
 
 272         info => 'This graph shows you the time since we requested the last evicted item',
 
 275         { name => 'evicted_time', label => 'Eviction Time (LEI)', info => 'Time Since Request for Last Evicted Item', min => '0' },
 
 279 $graphs{slabitems} = {
 
 281         args => '--base 1000 --lower-limit 0',
 
 282         vlabel => 'Items per Slab',
 
 283         category => 'memcached',
 
 284         title => 'Items in Slab: ',
 
 285         info => 'This graph shows you the number of items and reclaimed items per slab.',
 
 288         { name => 'number', label => 'Items', info => 'This is the amount of items stored in this slab', min => '0' },
 
 292 $graphs{slabitemtime} = {
 
 294         args => '--base 1000 --lower-limit 0',
 
 295         vlabel => ' since item was stored',
 
 296         category => 'memcached',
 
 297         title => 'Age of Eldest Item in Slab: ',
 
 298         info => 'This graph shows you the time of the eldest item in this slab',
 
 301         { name => 'age', label => 'Eldest Item\'s Age', min => '0' },
 
 306 #### Config Check ####
 
 309 if (defined $ARGV[0] && $ARGV[0] eq 'config') {
 
 311     $0 =~ /memcached_multi_(.+)*/;
 
 314     die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
 
 316     # We need to fetch the stats before we do any config, cause its needed for multigraph
 
 319     # Now lets go ahead and print out our config.
 
 325 #### Autoconf Check ####
 
 328 if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
 
 330     my $s = IO::Socket::INET->new(
 
 340         print "no (unable to connect to $host\[:$port\])\n";
 
 346 #### Suggest Check ####
 
 349 if (defined $ARGV[0] && $ARGV[0] eq 'suggest') {
 
 351     my $s = IO::Socket::INET->new(
 
 358         my @rootplugins = ('bytes','conns','commands','evictions','items','memory');
 
 359         foreach my $plugin (@rootplugins) {
 
 364         print "no (unable to connect to $host\[:$port\])\n";
 
 370 #### Well We aren't running (auto)config/suggest so lets print some stats ####
 
 376 #### Subroutines for printing info gathered from memcached ####
 
 380 #### This subroutine performs the bulk processing for printing statistics.
 
 385     $0 =~ /memcached_multi_(.+)*/;
 
 388     die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
 
 390     # Well we need to actually fetch the stats before we do anything to them.
 
 393     # Now lets go ahead and print out our output.
 
 395     if ($plugin eq 'memory') {
 
 396         @subgraphs = ('slabchnks');
 
 397         foreach my $slabid(sort{$a <=> $b} keys %chnks) {
 
 398             print_submulti_output($slabid,$plugin,@subgraphs);
 
 400         print_rootmulti_output($plugin);
 
 401     } elsif ($plugin eq 'commands') {
 
 402         @subgraphs = ('slabhits');
 
 403         foreach my $slabid(sort{$a <=> $b} keys %chnks) {
 
 404             print_submulti_output($slabid,$plugin,@subgraphs);
 
 406         print_rootmulti_output($plugin);
 
 407     } elsif ($plugin eq 'evictions') {
 
 408         @subgraphs = ('slabevics','slabevictime');
 
 409         foreach my $slabid (sort{$a <=> $b} keys %items) {
 
 410             print_submulti_output($slabid,$plugin,@subgraphs);
 
 412         print_rootmulti_output($plugin);
 
 413     } elsif ($plugin eq 'items') {
 
 414         @subgraphs = ('slabitems','slabitemtime');
 
 415         foreach my $slabid (sort{$a <=> $b} keys %items) {
 
 416             print_submulti_output($slabid,$plugin,@subgraphs);
 
 418         print_rootmulti_output($plugin);
 
 420         print_root_output($plugin);
 
 427 #### This subroutine is for the root non-multigraph graphs which render on the main node page ####
 
 430 sub print_root_output {
 
 433     my $graph = $graphs{$plugin};
 
 435     print "graph memcached_$plugin\n";
 
 437     if ($plugin ne 'conns') {
 
 438         foreach my $dsrc (@{$graph->{datasrc}}) {
 
 439             my %datasrc = %$dsrc;
 
 440             while ( my ($key, $value) = each(%datasrc)) {
 
 441                 next if ($key ne 'name');
 
 442                 my $output = $stats{$value};
 
 443                 print "$dsrc->{name}.value $output\n";
 
 448         foreach my $dsrc (@{$graph->{datasrc}}) {
 
 449             my %datasrc = %$dsrc;
 
 450             while ( my ($key, $value) = each(%datasrc)) {
 
 451                 if ($value eq 'max_conns') {
 
 452                     $output = $stats{maxconns};
 
 453                 } elsif ($value eq 'curr_conns') {
 
 454                     $output = $stats{curr_connections};
 
 455                 } elsif ($value eq 'avg_conns') {
 
 456                     $output = sprintf("%02d", $stats{total_connections} / $stats{uptime});
 
 460                 print "$dsrc->{name}.value $output\n";
 
 469 #### This subroutine is for the root multigraph graphs which render on the main node page ####
 
 472 sub print_rootmulti_output {
 
 475     my $graph = $graphs{$plugin};
 
 477     print "multigraph memcached_$plugin\n";
 
 479     foreach my $dsrc (@{$graph->{datasrc}}) {
 
 481         my %datasrc = %$dsrc;
 
 482         while ( my ($key, $value) = each(%datasrc)) {
 
 483             next if ($key ne 'name');
 
 484             if (($plugin eq 'evictions') && ($value eq 'evicted_nonzero')) {
 
 485                 foreach my $slabid (sort{$a <=> $b} keys %items) {
 
 486                     $output += $items{$slabid}->{evicted_nonzero};
 
 489                 $output = $stats{$value};
 
 491             print "$dsrc->{name}.value $output\n";
 
 499 #### This subroutine is for the sub multigraph graphs created via the multigraph plugin ####
 
 502 sub print_submulti_output {
 
 503     my ($slabid,$plugin,@subgraphs) = (@_);
 
 504     my $currslab = undef;
 
 506     foreach my $sgraph (@subgraphs) {
 
 508         my $graph = $graphs{$sgraph};
 
 510         print "multigraph memcached_$plugin.$sgraph\_$slabid\n";
 
 512         if ($plugin eq 'evictions') {
 
 513             $currslab = $items{$slabid};
 
 514         } elsif ($plugin eq 'memory') {
 
 515             $currslab = $chnks{$slabid};
 
 516         } elsif ($plugin eq 'commands') {
 
 517             $currslab = $chnks{$slabid};
 
 518         } elsif ($plugin eq 'items') {
 
 519             $currslab = $items{$slabid};
 
 524         foreach my $dsrc (@{$graph->{datasrc}}) {
 
 525             my %datasrc = %$dsrc;
 
 526             while ( my ($key, $value) = each(%datasrc)) {
 
 527                 next if ($key ne 'name');
 
 528                 my $output = $currslab->{$value};
 
 529                 if (($sgraph eq 'slabevictime') || ($sgraph eq 'slabitemtime')) {
 
 530                     $output = time_scale('data',$output); ;
 
 532                 print "$dsrc->{name}.value $output\n";
 
 541 #### Subroutines for printing out config information for graphs ####
 
 545 #### This subroutine does the bulk printing the config info per graph ####
 
 551     if ($plugin eq 'memory') {
 
 552         @subgraphs = ('slabchnks');
 
 553         foreach my $slabid (sort{$a <=> $b} keys %chnks) {
 
 554             print_submulti_config($slabid,$plugin,@subgraphs);
 
 556         print_rootmulti_config($plugin);
 
 557     } elsif ($plugin eq 'commands') {
 
 558         @subgraphs = ('slabhits');
 
 559         foreach my $slabid (sort{$a <=> $b} keys %chnks) {
 
 560             print_submulti_config($slabid,$plugin,@subgraphs);
 
 562         print_rootmulti_config($plugin);
 
 563     } elsif ($plugin eq 'evictions') {
 
 564         @subgraphs = ('slabevics','slabevictime');
 
 565         foreach my $slabid (sort{$a <=> $b}  keys %items) {
 
 566             print_submulti_config($slabid,$plugin,@subgraphs);
 
 568         print_rootmulti_config($plugin);
 
 569     } elsif ($plugin eq 'items') {
 
 570         @subgraphs = ('slabitems','slabitemtime');
 
 571         foreach my $slabid (sort{$a <=> $b} keys %items) {
 
 572             print_submulti_config($slabid,$plugin,@subgraphs);
 
 574         print_rootmulti_config($plugin);
 
 576         print_root_config($plugin);
 
 583 #### This subroutine is for the config info for sub multigraph graphs created via the multigraph plugin ####
 
 586 sub print_submulti_config {
 
 587     my ($slabid,$plugin,@subgraphs) = (@_);
 
 588     my ($slabitems,$slabchnks) = undef;
 
 590     foreach my $sgraph (@subgraphs) {
 
 592         my $graph = $graphs{$sgraph};
 
 594         my %graphconf = %{$graph->{config}};
 
 596         print "multigraph memcached_$plugin.$sgraph\_$slabid\n";
 
 598         while ( my ($key, $value) = each(%graphconf)) {
 
 599                 if ($key eq 'title') {
 
 600                     print "graph_$key $value" . "$slabid" . " ($chnks{$slabid}->{chunk_size} Bytes)\n";
 
 601                 } elsif (($key eq 'vlabel') && (($sgraph eq 'slabevictime') || ($sgraph eq 'slabitemtime'))) {
 
 602                 $value = time_scale('config',$value);
 
 603                 print "graph_$key $value\n";
 
 605                 print "graph_$key $value\n";
 
 609         foreach my $dsrc (@{$graph->{datasrc}}) {
 
 610             my %datasrc = %$dsrc;
 
 611             while ( my ($key, $value) = each(%datasrc)) {
 
 612                 next if ($key eq 'name');
 
 613                 print "$dsrc->{name}.$key $value\n";
 
 622 #### This subroutine is for the config info for root multigraph graphs which render on the main node page ####
 
 625 sub print_rootmulti_config {
 
 628     die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
 
 630     my $graph = $graphs{$plugin};
 
 632     my %graphconf = %{$graph->{config}};
 
 634     print "multigraph memcached_$plugin\n";
 
 636     while ( my ($key, $value) = each(%graphconf)) {
 
 637         print "graph_$key $value\n";
 
 640     foreach my $dsrc (@{$graph->{datasrc}}) {
 
 641         my %datasrc = %$dsrc;
 
 642         while ( my ($key, $value) = each(%datasrc)) {
 
 643             next if ($key eq 'name');
 
 644             print "$dsrc->{name}.$key $value\n";
 
 652 #### This subroutine is for the config info for non multigraph graphs which render on the main node page ####
 
 655 sub print_root_config {
 
 658     die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
 
 660     my $graph = $graphs{$plugin};
 
 662     my %graphconf = %{$graph->{config}};
 
 664     print "graph memcached_$plugin\n";
 
 666     while ( my ($key, $value) = each(%graphconf)) {
 
 667         print "graph_$key $value\n";
 
 670     foreach my $dsrc (@{$graph->{datasrc}}) {
 
 671         my %datasrc = %$dsrc;
 
 672         while ( my ($key, $value) = each(%datasrc)) {
 
 673             next if ($key eq 'name');
 
 674             print "$dsrc->{name}.$key $value\n";
 
 682 #### This subroutine actually performs the data fetch for us ####
 
 683 #### These commands do not lock up Memcache at all ####
 
 687     my $s = IO::Socket::INET->new(
 
 693     die "Error: Unable to Connect to $host\[:$port\]\n" unless $s;
 
 695     print $s "stats\r\n";
 
 697     while (my $line = <$s>) {
 
 698         if ($line =~ /STAT\s(.+?)\s(\d+)/) {
 
 699             my ($skey,$svalue) = ($1,$2);
 
 700             $stats{$skey} = $svalue;
 
 702         last if $line =~ /^END/;
 
 705     print $s "stats settings\r\n";
 
 707     while (my $line = <$s>) {
 
 708         if ($line =~ /STAT\s(.+?)\s(\d+)/) {
 
 709             my ($skey,$svalue) = ($1,$2);
 
 710             $stats{$skey} = $svalue;
 
 712         last if $line =~ /^END/;
 
 715     print $s "stats slabs\r\n";
 
 717     while (my $line = <$s>) {
 
 718         if ($line =~ /STAT\s(\d+):(.+)\s(\d+)/) {
 
 719             my ($slabid,$slabkey,$slabvalue) = ($1,$2,$3);
 
 720             $chnks{$slabid}->{$slabkey} = $slabvalue;
 
 722         last if $line =~ /^END/;
 
 725     print $s "stats items\r\n";
 
 727     while (my $line = <$s>) {
 
 728         if ($line =~ /STAT\sitems:(\d+):(.+?)\s(\d+)/) {
 
 729             my ($itemid,$itemkey,$itemvalue) = ($1,$2,$3);
 
 730             $items{$itemid}->{$itemkey} = $itemvalue;
 
 732         last if $line =~ /^END/;
 
 737 #### This subroutine is to help manage the time_scale settings for the graph
 
 741     my ($configopt,$origvalue) = (@_);
 
 744     if ($configopt eq 'config') {
 
 745         if ($timescale == 1) {
 
 746             $value = "Seconds" . $origvalue;
 
 747         } elsif ($timescale == 2) {
 
 748             $value = "Minutes" . $origvalue;
 
 749         } elsif (($timescale == 3) || ($timescale > 4) || (!defined($timescale))) {
 
 750             $value = "Hours" . $origvalue;
 
 751         } elsif ($timescale == 4) {
 
 752             $value = "Days" . $origvalue;
 
 754     } elsif ($configopt eq 'data') {
 
 755         if ($timescale == 1) {
 
 756             $value = sprintf("%02.2f", $origvalue / 1);
 
 757         } elsif ($timescale == 2) {
 
 758             $value = sprintf("%02.2f", $origvalue / 60);
 
 759         } elsif (($timescale == 3) || ($timescale > 4) || (!defined($timescale))) {
 
 760             $value = sprintf("%02.2f", $origvalue / 3600);
 
 761         } elsif ($timescale == 4) {
 
 762             $value = sprintf("%02.2f", $origvalue / 86400);
 
 765         die "Unknown time_scale option given: either [config/data]\n";