<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Computer Support &#187; rotate</title>
	<atom:link href="http://www.xiitec.com/blog/tag/rotate/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.xiitec.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 30 Dec 2009 08:40:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Rotating Log Files</title>
		<link>http://www.xiitec.com/blog/2008/02/04/rotating-log-files/</link>
		<comments>http://www.xiitec.com/blog/2008/02/04/rotating-log-files/#comments</comments>
		<pubDate>Mon, 04 Feb 2008 19:28:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shell scripts]]></category>
		<category><![CDATA[logs]]></category>
		<category><![CDATA[rotate]]></category>

		<guid isPermaLink="false">http://www.xiitec.com/blog/?p=96</guid>
		<description><![CDATA[Users who don&#8217;t have much experience with Unix can be quite surprised by how many commands, utilities, and daemons log events to system log files. Even on a computer with lots of disk space, it&#8217;s important to keep an eye on the size of these files and, of course, on their contents too.

As a result, [...]]]></description>
			<content:encoded><![CDATA[<p>Users who don&#8217;t have much experience with Unix can be quite surprised by how many commands, utilities, and daemons log events to system log files. Even on a computer with lots of disk space, it&#8217;s important to keep an eye on the size of these files and, of course, on their contents too.</p>
<p><span id="more-96"></span></p>
<p>As a result, most sysadmins have a set of instructions that they place at the top of their log file analysis utilities, similar to the following:</p>
<blockquote><p>mv $log.2 $log.3<br />
mv $log.1 $log.2<br />
mv $log $log.1<br />
touch $log</p></blockquote>
<p>If run weekly, this would produce a rolling one-month archive of log file information divided into week-size portions of data. However, it&#8217;s just as easy to create a script that accomplishes this for all log files in the /var/log directory at once, thereby relieving any log file analysis scripts of the burden.</p>
<p>The script steps through each file in the /var/log directory that matches a particular set of criteria, checking each matching file&#8217;s rotation schedule and last-modified date to see if it&#8217;s time for it to be rotated.</p>
<blockquote><p>#!/bin/sh<br />
# rotatelogs &#8211; Rolls logfiles in /var/log for archival purposes.<br />
#    Uses a config file to allow customization of how frequently<br />
#    each log should be rolled. The config file is in<br />
#       logfilename=duration<br />
#    format, where duration is in days. If, in the config<br />
#    file, an entry is missing for a particular logfilename,<br />
#    rotatelogs won&#8217;t rotate the file more frequently than every seven days.</p>
<p>logdir=&#8221;/var/log&#8221;<br />
config=&#8221;/var/log/rotatelogs.conf&#8221;<br />
mv=&#8221;/bin/mv&#8221;<br />
default_duration=7     count=0</p>
<p>duration=$default_duration</p>
<p>if [ ! -f $config ] ; then<br />
echo &#8220;$0: no config file found. Can&#8217;t proceed.&#8221; &gt;&amp;2; exit 1<br />
fi</p>
<p>if [ ! -w $logdir -o ! -x $logdir ] ; then<br />
echo &#8220;$0: you don&#8217;t have the appropriate permissions in $logdir&#8221; &gt;&amp;2<br />
exit 1<br />
fi</p>
<p>cd $logdir</p>
<p># While we&#8217;d like to use &#8216;:digit:&#8217; with the find, many versions of<br />
# find don&#8217;t support POSIX character class identifiers, hence [0-9]</p>
<p>for name in $(find . -type f -size +0c ! -name &#8216;*[0-9]*&#8217; \<br />
! -name &#8216;\.*&#8217; ! -name &#8216;*conf&#8217; -maxdepth 1 -print | sed &#8217;s/^\.\///&#8217;)<br />
do</p>
<p>count=$(( $count + 1 ))</p>
<p># Grab this entry from the config file</p>
<p>duration=&#8221;$(grep &#8220;^${name}=&#8221; $config|cut -d= -f2)&#8221;<br />
if [ -z $duration ] ; then<br />
duration=$default_duration<br />
elif [ "$duration" = "0" ] ; then<br />
echo &#8220;Duration set to zero: skipping $name&#8221;<br />
continue<br />
fi</p>
<p>back1=&#8221;${name}.1&#8243;; back2=&#8221;${name}.2&#8243;;<br />
back3=&#8221;${name}.3&#8243;; back4=&#8221;${name}.4&#8243;;</p>
<p># If the most recently rolled log file (back1) has been modified within<br />
# the specific quantum, then it&#8217;s not time to rotate it.</p>
<p>if [ -f "$back1" ] ; then<br />
if [ -z $(find \"$back1\" -mtime +$duration -print 2&gt;/dev/null) ]<br />
then<br />
echo -n &#8220;$name&#8217;s most recent backup is more recent than $duration &#8221;<br />
echo &#8220;days: skipping&#8221; ;   continue<br />
fi<br />
fi</p>
<p>echo &#8220;Rotating log $name (using a $duration day schedule)&#8221;</p>
<p># Rotate, starting with the oldest log<br />
if [ -f "$back3" ] ; then<br />
echo &#8220;&#8230; $back3 -&gt; $back4&#8243; ; $mv -f &#8220;$back3&#8243; &#8220;$back4&#8243;<br />
fi<br />
if [ -f "$back2" ] ; then<br />
echo &#8220;&#8230; $back2 -&gt; $back3&#8243; ; $mv -f &#8220;$back2&#8243; &#8220;$back3&#8243;<br />
fi<br />
if [ -f "$back1" ] ; then<br />
echo &#8220;&#8230; $back1 -&gt; $back2&#8243; ; $mv -f &#8220;$back1&#8243; &#8220;$back2&#8243;<br />
fi<br />
if [ -f "$name" ] ; then<br />
echo &#8220;&#8230; $name -&gt; $back1&#8243; ; $mv -f &#8220;$name&#8221; &#8220;$back1&#8243;<br />
fi<br />
touch &#8220;$name&#8221;<br />
chmod 0600 &#8220;$name&#8221;<br />
done</p>
<p>if [ $count -eq 0 ] ; then<br />
echo &#8220;Nothing to do: no log files big enough or old enough to rotate&#8221;<br />
fi<br />
exit 0</p></blockquote>
<p>To truly be useful, the script needs to work with a configuration file that lives in /var/log, which allows different log files to be set to different rotation schedules. The contents of a typical configuration file are as follows:</p>
<blockquote><p># Configuration file for the log rotation script.<br />
# Format is    name=duration    where &#8216;name&#8217; can be any<br />
# filename that appears in the /var/log directory. Duration<br />
# is measured in days.</p>
<p>ftp.log=30<br />
lastlog=14<br />
lookupd.log=7<br />
lpr.log=30<br />
mail.log=7<br />
netinfo.log=7<br />
secure.log=7<br />
statistics=7<br />
system.log=14<br />
# Anything with a duration of zero is not rotated<br />
wtmp=0</p></blockquote>
<p>The heart of this script is the find statement:</p>
<blockquote><p> for name in $(find . -type f -size +0c ! -name &#8216;*[0-9]*&#8217; \<br />
! -name &#8216;\.*&#8217; ! -name &#8216;*conf&#8217; -maxdepth 1 -print | sed &#8217;s/^\.\///&#8217;)</p></blockquote>
<p>This creates a loop, returning all files in the /var/log directory that are greater than 0 characters in size, don&#8217;t contain a number in their name, don&#8217;t start with a period (Mac OS X in particular dumps a lot of oddly named log files in this directory; they all need to be skipped), and don&#8217;t end with the word &#8220;conf&#8221; (we don&#8217;t want to rotate out the rotatelogs.conf file, for obvious reasons!). The maxdepth 1 ensures that find doesn&#8217;t step into subdirectories. Finally, the sed invocation removes any leading ./ sequences.</p>
<p>The Results</p>
<blockquote><p>$ sudo rotatelogs<br />
ftp.log&#8217;s most recent backup is more recent than 30 days: skipping<br />
Rotating log lastlog (using a 14 day schedule)<br />
&#8230; lastlog -&gt; lastlog.1<br />
lpr.log&#8217;s most recent backup is more recent than 30 days: skipping</p></blockquote>
<p>Notice that of all the log files in /var/log, only three matched the specified find criteria, and of those only one, lastlog, hadn&#8217;t been backed up sufficiently recently, according to the duration values in the configuration file shown earlier.</p>
<p>One example of how this script could be even more useful is to have the oldest archive file, the old $back4 file, emailed to a central storage site before it&#8217;s over-written by the mv command in the following statement:</p>
<blockquote><p>echo &#8220;&#8230; $back3 -&gt; $back4&#8243; ; $mv -f &#8220;$back3&#8243; &#8220;$back4&#8243;</p></blockquote>
<p>Another useful enhancement to rotatelogs would be to compress all rotated logs to further save on disk space, which would also require that the script recognize and work properly with compressed files as it proceeded.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xiitec.com/blog/2008/02/04/rotating-log-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

