Differences
This shows you the differences between two versions of the page.
— |
manual:100:4_help.3_maintenance [2019/10/29 15:16] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ===== Maintenance ===== | ||
+ | ==== Logrotate cacti.log ==== | ||
+ | |||
+ | === Requirements === | ||
+ | By default, cacti uses the file <cacti_dir>/log/cacti.log for logging purpose. There's no automatic cleanup of this file. So, without further intervention, there's a good chance, that this file reaches a file size limit of your filesystem. This will stop any further polling process. | ||
+ | For *NIX type systems, **logrotate** is a widely known utility that solves exactly this problem. The following descriptions assumes you've set up a standard logrotate environment. | ||
+ | The examples are based on a Fedora 6 environment. I assume, that Red Hat type installations will work the same way. I hope, but am not sure, that this howto is easily portable for Debian/Ubuntu and stuff and hopefully even for *BSD. | ||
+ | |||
+ | === The logrotate Configuration File === | ||
+ | The logrotate function is well described in the man pages. My setup is as follows: | ||
+ | |||
+ | <code bash># logrotate cacti.log | ||
+ | /var/www/html/cacti/log/cacti.log { | ||
+ | # keep 7 versions online | ||
+ | rotate 7 | ||
+ | # rotate each day | ||
+ | daily | ||
+ | # don't compress, but | ||
+ | # if disk space is an issue, change to | ||
+ | # compress | ||
+ | nocompress | ||
+ | # create new file with <mode> <user> <group> attributes | ||
+ | create 644 cactiuser cactiuser | ||
+ | # add a YYYYMMDD extension instead of a number | ||
+ | dateext | ||
+ | }</code> | ||
+ | |||
+ | Descriptions are given inline. Copy those statements from above into **/etc/logrotate.d/cacti**. This is the recommended file for application-specific logrotate files. | ||
+ | |||
+ | === Test === | ||
+ | logrotate configuration files are tested by running | ||
+ | |||
+ | <code bash>logrotate -fd /etc/logrotate.d/cacti | ||
+ | reading config file /etc/logrotate.d/cacti | ||
+ | reading config info for /var/www/html/cacti/log/cacti.log | ||
+ | |||
+ | Handling 1 logs | ||
+ | |||
+ | rotating pattern: /var/www/html/cacti/log/cacti.log forced from command line (7 rotations) | ||
+ | empty log files are rotated, old logs are removed | ||
+ | considering log /var/www/html/cacti/log/cacti.log | ||
+ | log needs rotating | ||
+ | rotating log /var/www/html/cacti/log/cacti.log, log->rotateCount is 7 | ||
+ | glob finding old rotated logs failed | ||
+ | renaming /var/www/html/cacti/log/cacti.log to /var/www/html/cacti/log/cacti.log-20071004 | ||
+ | creating new log mode = 0644 uid = 502 gid = 502</code> | ||
+ | |||
+ | This is a dry run, no rotation is actually performed. Option **-f** forces log rotation even if the rotate criterium is not fulfilled. Option **-d** issues debug output but will suppress any real log rotation. Verify by listing the log directory: nothing has changed at all! | ||
+ | |||
+ | Now we will request log rotation using | ||
+ | |||
+ | <code bash>logrotate -f /etc/logrotate.d/cacti</code> | ||
+ | |||
+ | No output is produced, but you will see the effect | ||
+ | |||
+ | <code>ls -l /var/www/html/cacti/log | ||
+ | -rw-r--r-- 1 cactiuser cactiuser 0 4. Okt 21:35 cacti.log | ||
+ | -rw-r--r-- 1 cactiuser cactiuser 228735 4. Okt 21:35 cacti.log-20071004</code> | ||
+ | |||
+ | Of course, the date extension on the file will change accordingly. Please notice, that a new cacti.log file was created. If you issue the command again, nothing will happen: | ||
+ | |||
+ | <code>logrotate -fv /etc/logrotate.d/cacti | ||
+ | reading config file /etc/logrotate.d/cacti | ||
+ | reading config info for /var/www/html/cacti/log/cacti.log | ||
+ | |||
+ | Handling 1 logs | ||
+ | |||
+ | rotating pattern: /var/www/html/cacti/log/cacti.log forced from command line (7 rotations) | ||
+ | empty log files are rotated, old logs are removed | ||
+ | considering log /var/www/html/cacti/log/cacti.log | ||
+ | log needs rotating | ||
+ | rotating log /var/www/html/cacti/log/cacti.log, log->rotateCount is 7 | ||
+ | destination /var/www/html/cacti/log/cacti.log-20071004 already exists, skipping rotation</code> | ||
+ | |||
+ | If you want to see all those 7 rotations on one single day, remove the **dateext** directive temporarily from the configuration file. | ||
+ | |||
+ | ==== Daily MySQL Dump of the Cacti SQL Database using logrotate ==== | ||
+ | |||
+ | === Requirements === | ||
+ | By default, cacti uses the MySQL database named **cacti**. You may want to consider dumping this database on regular intervals for failsafe reason. For a single dump, you will usually enter this dump command directly into crontab. | ||
+ | It is possible, to mis-use logrotate to create daily dumps, append dateext-like timestamps to each dump and keep a distinct number of generations online. For a basic setup, see [[#logrotate_cacti.log|Logrotate cacti.log]], | ||
+ | The following descriptions assumes you've set up a standard logrotate environment. | ||
+ | The examples are based on a Fedora 6 environment. I assume, that Red Hat type installations will work the same way. I hope, but am not sure, that this howto is easily portable for Debian/Ubuntu and stuff and hopefully even for *BSD. | ||
+ | |||
+ | === The logrotate Configuration File for MySQL Dumping the Cacti Database === | ||
+ | It is absolutely necessary for this example, that a single dump file already exists. Else, logrotate will skip any execution due to a missing "log" file. My setup is as follows: | ||
+ | |||
+ | <code bash># logrotate sql dump file | ||
+ | /var/www/html/cacti/log/cacti_dump.sql { | ||
+ | # keep 31 generations online | ||
+ | rotate 31 | ||
+ | # create a daily dump | ||
+ | daily | ||
+ | # don't compress the dump | ||
+ | nocompress | ||
+ | # create using this <mode> <user> <group> | ||
+ | create 644 cactiuser cactiuser | ||
+ | # append a nice date to the file | ||
+ | dateext | ||
+ | # delete all generations older than 31 days | ||
+ | maxage 31 | ||
+ | # run this script AFTER rotating the previous cacti_dump.sql file | ||
+ | # make sure to use the correct database, user and password, see ./include/config.php | ||
+ | prerotate | ||
+ | /usr/bin/mysqldump --user=cactiuser --password=cactiuser --lock-tables --add-drop-database --add-drop-table cacti > /var/www/html/cacti/log/cacti_dump.sql | ||
+ | endscript | ||
+ | }</code> | ||
+ | |||
+ | You may add this configuration to /etc/logrotate.d/cacti, even if the logrotate of cacti.log is already given there. Prior to testing this configuration, don't forget to | ||
+ | |||
+ | <code>touch /var/www/html/cacti/log/cacti_dump.sql</code> | ||
+ | |||
+ | Now run the test as follows | ||
+ | |||
+ | <code bash>logrotate -fv /etc/logrotate.d/cacti | ||
+ | reading config file /etc/logrotate.d/cacti | ||
+ | reading config info for /var/www/html/cacti/log/cacti_dump.sql | ||
+ | |||
+ | Handling 1 log | ||
+ | |||
+ | rotating pattern: /var/www/html/cacti/log/cacti_dump.sql forced from command line (31 rotations) | ||
+ | empty log files are rotated, old logs are removed | ||
+ | considering log /var/www/html/cacti/log/cacti_dump.sql | ||
+ | log needs rotating | ||
+ | rotating log /var/www/html/cacti/log/cacti_dump.sql, log->rotateCount is 31 | ||
+ | glob finding old rotated logs failed | ||
+ | running prerotate script | ||
+ | renaming /var/www/html/cacti/log/cacti_dump.sql to /var/www/html/cacti/log/cacti_dump.sql-20071004 | ||
+ | creating new log mode = 0644 uid = 502 gid = 502</code> | ||
+ | |||
+ | Now list the results | ||
+ | |||
+ | <code bash>ls -l /var/www/html/log/cacti_dump* | ||
+ | -rw-r--r-- 1 cactiuser cactiuser 0 4. Okt 22:10 cacti_dump.sql | ||
+ | -rw-r--r-- 1 cactiuser cactiuser 318441 4. Okt 22:10 cacti_dump.sql-20071004</code> | ||
+ | |||
+ | ==== Migrating RRD Files between Architectures ==== | ||
+ | |||
+ | - Run this Script on source-host.<code bash>#/bin/csh | ||
+ | # This scripts dumps all rrd in the working dir | ||
+ | # into xml files. | ||
+ | set files=`echo *.rrd` | ||
+ | foreach file ( $files ) | ||
+ | set base = `basename $file .rrd` | ||
+ | /bin/rrdtool dump $file > /tmp/new1/$base.xml | ||
+ | end</code> | ||
+ | - `tar-gzip` the xmls and transfer them to the target system. | ||
+ | - uncompress and untar the file to an empty directory. | ||
+ | - Run this script on target-host in the choosen directory<code>#/bin/csh | ||
+ | # restores rrds from xml-dumps. | ||
+ | set files=`echo *.xml` | ||
+ | foreach file ($files) | ||
+ | set base = `basename $file .xml` | ||
+ | /opt/local/bin/rrdtool restore $file /opt/local/htdocs/cacti/rra/$base.rrd | ||
+ | end </code> | ||
+ | |||
+ | |||
+ | ==== Migrating RRD Files between Architectures and Hosts ==== | ||
+ | |||
+ | The goal of this part is quite the same as the previous one. The script was created with some more restrictions in mind: | ||
+ | - neither the source nor the target host have enough space for both rrd and xml files | ||
+ | - communication between both hosts is restricted to encrypted communication only (aka ssh, scp) | ||
+ | |||
+ | The script (rrdmigrate.pl) has to be run on the host, were rrd files already exists. It uses some commands that both must be present and available in the $PATH of the user in question. Else you will have to provide **/full/path/to/command**, but this requires customization of the script, so it was omitted. It accepts some required and some optional parameters: | ||
+ | - **-t** specifies the target host, where the data has to be copied to | ||
+ | - **-i** specifies the ssh key file (e.g. ~/.ssh/id_rsa) to avoid multitudes of password entries | ||
+ | - **-u** specifies the user on the traget system, which must have write access to the target directory (usually: cactiuser) | ||
+ | - **-f** filemask of the rrd files that shall be treated. **Enclose in quotes!** e.g. /var/www/html/cacti/rra/*.rrd | ||
+ | optionally | ||
+ | - **-d** debug level: [0|1|2] | ||
+ | |||
+ | **Example**\\ perl rrdmigrate.pl -t target -u cactiuser -i /home/cactiuser/.ssh/id_rsa -f "/var/www/html/cacti/rra/*.rrd" | ||
+ | |||
+ | This will dump, move and restore all rrd files, one by one, to the target host **target** using **cactiuser** and a given ssh key. It will use a minimal space overhead, only for the current rrd file. Do not expect that this is as fast as scp-ing rrd files between servers. So, please test in advance, of there's a real need for rrdtool dump and restore! | ||
+ | |||
+ | <code perl>#!/usr/bin/perl | ||
+ | # ----------------------------------------------------------------------------- | ||
+ | |||
+ | $NAME_ = basename($0); | ||
+ | $PURPOSE_ = "resize an existing rrd"; | ||
+ | $SYNOPSIS_ = "$NAME_ | ||
+ | -f <filemask> | ||
+ | -t <target host> | ||
+ | -u <cactiuser> | ||
+ | -i <ssh key> | ||
+ | [-d <debug>]"; | ||
+ | $REQUIRES_ = "Getopt::Std, File::Basename, File::stat, File::KGlob"; | ||
+ | $VERSION_ = "Version 0.1"; | ||
+ | $DATE_ = "2010-12-23"; | ||
+ | $AUTHOR_ = "Reinhard Scheck"; | ||
+ | |||
+ | # ----------------------------------------------------------------------------- | ||
+ | # This program is distributed under the terms of the GNU General Public License | ||
+ | |||
+ | # --- required Modules -------------------------------------------------------- | ||
+ | use Getopt::Std; | ||
+ | use File::Basename; | ||
+ | |||
+ | # --- initialization ---------------------------------------------------------- | ||
+ | my $debug = 0; # minimal output | ||
+ | |||
+ | # --- usage ------------------------------------------------------------------- | ||
+ | sub usage { | ||
+ | |||
+ | print STDOUT "$NAME_ $VERSION_ - $PURPOSE_ | ||
+ | Usage: $SYNOPSIS_ | ||
+ | Requires: $REQUIRES_ | ||
+ | Author: $AUTHOR_ | ||
+ | Date: $DATE_ | ||
+ | Options: | ||
+ | -f, filemask of the source rrds, enclose in tics! | ||
+ | -t, target host | ||
+ | -u, cactiuser | ||
+ | -i, ssh key filename used for scp, ssh operations | ||
+ | -d, debug level (0=standard, 1=function trace, 2=verbose) | ||
+ | -h, usage and options (this help) | ||
+ | |||
+ | No parameter validation done. Hope you know what you're going to do!\n\n"; | ||
+ | exit 1; | ||
+ | } | ||
+ | |||
+ | # --- write_log --------------------------------------------------------------- | ||
+ | sub write_log { | ||
+ | |||
+ | my $_level = $_[0]; | ||
+ | my $_text = $_[1]; | ||
+ | |||
+ | if ( $debug >= $_level ) { | ||
+ | print $_text; | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | # --- run_cmd --------------------------------------------------------------- | ||
+ | sub run_cmd { | ||
+ | |||
+ | my $_cmd = $_[0]; | ||
+ | my $_lvl = $_[1]; | ||
+ | defined($i_[2]) ? (my $_pre = $_[2] . " ") : (my $_pre = '' ); | ||
+ | &write_log($_lvl, $_pre . $_cmd . "\n"); | ||
+ | |||
+ | system($_cmd); | ||
+ | } | ||
+ | |||
+ | # --- main -------------------------------------------------------------------- | ||
+ | # --- assign input parameters ------------------------------------------------- | ||
+ | getopts('ht:d:f:i:u:'); | ||
+ | &usage() if $opt_h; | ||
+ | defined($opt_d) ? ($debug = $opt_d ) : ($debug = 0 ); | ||
+ | defined($opt_i) ? ($key = "-i $opt_i") : ($key = '' ); | ||
+ | |||
+ | # --- check for dependent parms ----------------------------------------------- | ||
+ | if ( !defined($opt_f) ) { &write_log(0, "Option -f missing\n\n"); &usage; } else { $filemask = $opt_f; }; | ||
+ | if ( !defined($opt_t) ) { &write_log(0, "Option -t missing\n\n"); &usage; } else { $host = $opt_t; }; | ||
+ | if ( !defined($opt_u) ) { &write_log(0, "Option -u missing\n\n"); &usage; } else { $user = $opt_u; }; | ||
+ | |||
+ | # --- suffixes ---------------------------------------------------------------- | ||
+ | my $_gzip_ext = ".gz"; | ||
+ | my $_xml_ext = ".xml"; | ||
+ | |||
+ | # --- loop for all files of given filemask ------------------------------------ | ||
+ | my @files = glob($filemask); | ||
+ | for my $file ( @files ) { | ||
+ | my ($fname, $path, $ext) = fileparse($file, '\..*'); | ||
+ | my $_xml_file = $path . $fname . $_xml_ext; | ||
+ | my $_gzip_file = $_xml_file . $_gzip_ext; | ||
+ | |||
+ | &run_cmd("rrdtool dump $file > $_xml_file", 0); | ||
+ | &run_cmd("gzip -fq " . $_xml_file, 1); | ||
+ | &run_cmd("scp -q $key $_gzip_file $user\@$host:$_gzip_file", 1); | ||
+ | &run_cmd("ssh -q $key $host \"gunzip $_gzip_file;rm -f $file;rrdtool restore $_xml_file $file;rm -f $_xml_file\"", 1); | ||
+ | &run_cmd("rm -f $_xml_file", 1); | ||
+ | &write_log(0, " ... done.\n"); | ||
+ | }</code> |