Logrotate.d for every httpd instance for loop?

/etc/logrotate.d

-rwxr-xr-x 1 root root 263 Aug 28 23:17 httpd-stooffsprod
-rwxr-x--- 1 root root 273 Jul 10  2015 httpd-mwsi2hprodhist2
-rwxr-x--- 1 root root 261 Aug 11 17:28 httpd-mwsihist2
-rwxr-x--- 1 root root 269 Jul 20  2015 httpd-mwsiprodhist2

I need to figure out how to build a for loop script that will create a file with this content in each of the files but replace the httpd- (fill in the blank) with every instance of httpd in the /apps/apache/ directory?

/apps/apache/httpd-capefsprod/logs/*log {
    rotate 7
    compress
    missingok
    notifempty
    sharedscripts
    daily
    delaycompress
    nomail
    postrotate
        /sbin/service httpd-stoofsprod reload > /dev/null 2>/dev/null || true
    endscript
}

I apologize for not doing the formatting properly. Still no answers?

---------- Post updated at 08:48 AM ---------- Previous update was at 08:46 AM ----------

I created this forloop, to create the file from a template file but I don't know how to do the awk inside the file to change the name to match up, to all the instances in the /apps/apache/ directory? Any help?

#!/bin/bash
#set -xv
#####################################################
#                                                   #
#   Script                   #
#  
#                                                   #
#####################################################
# End Summary                                        

list=`cat /usr/local/scripts/aplist.txt`
clear
for i in $list;
do
cp /etc/logrotate.d/httpd-test /etc/logrotate.d/$i

echo " "

done;

If you would show us sample input files and the corresponding output you are trying to produce based on those input files, you would have a much better chance of getting a response.

I still don't get it.
The /apps/apache/httpd-capefsprod/logs/*log is a key and may only exist once.
It cannot be copied to other files in logrotate.d/
For the same reason a template file may not be located there.

Maybe from this you can tell what I'm attempting at. I'm trying to get a list of all the jvm's running on webservers and then create a logrotated file for each one. However if the file already exist in /etc/logrotated/ I don't want to over write it, want to skip the existing. Then inside the file I'm trying to replace for each one the hostname inside the file.

ls -d /apps/apahce/*httpd* >/usr/local/scripts/jvmlist.txt 
jvmlist=`/usr/local/scripts/jvmlist.txt`
clear
for name in $jvmlist
  do
     
	if [ ! -f /etc/logrotated/$name cp /usr/local/scripts/examplescript.txt ]; then cp /usr/local/scripts/examplescript.txt /usr/local/scripts/stage/$name
	 
	cd /usr/local/scripts/stage/
	
	sed -i 's/examplehost/$name/g' /usr/local/scripts/stage/$name
         
	 
	 

There are several problems here:

  1. A for loop requires a do and a done . You have no done .
  2. An if statement requires a then and a fi . You have no fi .
  3. Shell variables are not expanded inside single quotes. And, since $name will expand to a string containing slash characters ( / ), you can't use slash as the separator in the sed substitute command. Use double quotes instead of single quotes around your sed program and use vertical bar (AKA pipe symbol) or some other character that won't appear in any expansion of $name instead of slash.
  4. Your for loop will execute once (with $name expanding to the name of the file that contains the names you want to process); not once for each file you want to process (with $name expanding to the name of a file you want to process). And, there is no need for a temporary file here. And, if you're going to define a variable specifying the name of your temporary file, define that variable before you have the name hardcoded into other commands and use the variable name consistently.
  5. Do you really have a directory named /apps/apahce ? Or should it be /apps/apache ?
  6. The three arguments /etc/logrotated/$name cp /usr/local/scripts/examplescript.txt cannot match the name of a regular file because the test -f (AKA [ -f ... ] command in your if statement expects one operand; not three.

Making lots and lots of wild assumptions, maybe something more like:

ls -d /apps/apache/*httpd* | while read -r name
do	if [ ! -f "/usr/local/scripts/stage$name" ]
	then	sed 's|examplehost|$name|g' /usr/local/scripts/examplescript.txt > "/usr/local/scripts/stage$name"
	fi
done

Thanks for your patience in advance.

[root@/usr/local/scripts]# ls -ltr
-rwxrwxrwx 1 root root  253 Mar  8 09:41 examplelogconfig
drwxr-xr-x 2 root root 4096 Mar  8 09:51 stage
-rwxrwxrwx 1 root root  276 Mar  8 10:13 logrot.sh

[root@/apps/apache]# ls -ltr
drwxr-x--- 9 awdmw awdmw 4096 Jul 19  2013 httpd-fibcbeta
drwxr-x--- 9 awdmw awdmw 4096 Jul 19  2013 httpd-fibctrain
drwxr-x--- 9 awdmw awdmw 4096 Oct 17  2013 httpd-gundsdev
drwxr-x--- 9 awdmw awdmw 4096 Oct 31  2013 httpd-gundstrain
drwxr-x--- 9 awdmw awdmw 4096 Feb 21  2014 httpd-dliqat
drwxr-xr-x 9 awdmw awdmw 4096 Mar 11  2014 httpd-dlidev
drwxr-x--- 9 awdmw awdmw 4096 Apr  1  2014 httpd-dliuat
drwxr-x--- 9 awdmw awdmw 4096 Apr  2  2014 httpd-dlitrain

[root@uxtwsadcmrk01 logrotate.d]# ls �ltr

-rw-r--r--. 1 root root 329 Jul 10  2012 psacct
-rw-r--r--. 1 root root 540 Aug 30  2012 syslog
-rw-r--r--  1 root root  32 Nov  6  2012 up2date
-rwxr-x---  1 root root 259 Jul 19  2013 httpd-fibcbeta
-rwxr-x---  1 root root 261 Jul 19  2013 httpd-fibctrain
-rwxr-x---  1 root root 259 Oct 17  2013 httpd-gundsdev

The examplelogconfig in the usr/local/scripts dir and the httpd-fibcbeta in the logrotate.d are the same file, I was just trying to use teh exampleconfig, and look through the /apps/apache/ directory see which names are there, and then create a file for each one in the /etc/logrotate.d directory except change the host name. The caviat is I can't just put them in production so I have to put them in /usr/local/scripts/stage/ directory for later putting them in production. I have a ton of boxes to do this on, with normally a bunch of instances of jvms etc in /apps/apache/ and not much in /etc/logrotate.d ---- if this were just a few not a big deal but there are a ton of webs for me to do etc.

Cat httpd-fibctrain

/apps/apache/httpd-fibctrain/logs/*log {
    rotate 7
    compress
    missingok
    notifempty
    sharedscripts
    daily
    delaycompress
    nomail
    postrotate
        /sbin/service httpd-fibctrain reload > /dev/null 2>/dev/null || true
    endscript
}

[root@/usr/local/scripts]# cat examplelogconfig
/apps/apache/examplehost/logs/*log {
    rotate 7
    compress
    missingok
    notifempty
    sharedscripts
    daily
    delaycompress
    nomail
    postrotate
        /sbin/service examplehost reload > /dev/null 2>/dev/null || true
    endscript
}

So I was trying to say

if the directory exist in /apps/apache/*httpd* then create a file from the exampleconfig for each instance that (doesn't already exist) in /etc/logrotate.d/ directory and then change out the example host in the file with the hostname of the /apps/apache/*httpd* name and place a copy of that new example config named httpd- into /usr/local/scripts/stage/

The following makes sense (to me)

for instance in /apps/apache/*httpd*
do
  if [ -d "$instance" ] && [ ! -f /etc/logrotate.d/"$instance" ] && service "$instance" status >/dev/null 2>&1
  then
    sed "s|examplehost|$instance|g" </usr/local/scripts/examplelogconfig >/etc/logrotate.d/"$instance"
  fi
done

I don't know what the /usr/local/scripts/stage/ is for; you can add a cp command in the loop block if needed.

ls -d /apps/apache/*httpd* | while read -r name
do	if [ ! -f "/apps/apache/$name" ]
	then	cp /usr/local/scripts/examplescript.txt /usr/local/scripts/stage/ \
        sed 's|examplehost|$name|g' /usr/local/scripts/stage/$name > "/usr/local/scripts/stage/$name"
	fi
done

I tried to change what you started not quite working for me.

---------- Post updated at 01:06 PM ---------- Previous update was at 01:04 PM ----------

Ok one min I didn't see this last post....

---------- Post updated at 01:09 PM ---------- Previous update was at 01:06 PM ----------

I think this should work

for instance in /apps/apache/*httpd*
do
  if [ -d "$instance" ] && [ ! -f /etc/logrotate.d/"$instance" ] && service "$instance" status >/dev/null 2>&1
  then
    sed "s|examplehost|$instance|g" </usr/local/scripts/examplelogconfig >/usr/local/scripts/stage/"$instance"
  fi
done

I have to copy them into /usr/local/scripts/stage/ before I can later move them to /etc/logrotate.d/ during non production hours etc.

---------- Post updated at 01:19 PM ---------- Previous update was at 01:09 PM ----------

My output is this from running that....

>I removed /dev/null 2>&1

/apps/apache/httpd-cibcbeta: unrecognized service
/apps/apache/httpd-cibctrain: unrecognized service
/apps/apache/httpd-fundsdev: unrecognized service
/apps/apache/httpd-fundstrain: unrecognized service
/apps/apache/httpd-mlidev: unrecognized service
/apps/apache/httpd-mliqat: unrecognized service
/apps/apache/httpd-mlitrain: unrecognized service
/apps/apache/httpd-mliuat: unrecognized service

---------- Post updated at 01:30 PM ---------- Previous update was at 01:19 PM ----------

and if I remove

&& service "$instance" status >/dev/null 2>&1

Then I get...

./logrot.sh: line 8: /usr/local/scripts/stage//apps/apache/httpd-cibcbeta: No such file or directory
./logrot.sh: line 8: /usr/local/scripts/stage//apps/apache/httpd-cibctrain: No such file or directory
./logrot.sh: line 8: /usr/local/scripts/stage//apps/apache/httpd-fakedir: No such file or directory
./logrot.sh: line 8: /usr/local/scripts/stage//apps/apache/httpd-fundsdev: No such file or directory
./logrot.sh: line 8: /usr/local/scripts/stage//apps/apache/httpd-fundstrain: No such file or directory
./logrot.sh: line 8: /usr/local/scripts/stage//apps/apache/httpd-mlidev: No such file or directory
./logrot.sh: line 8: /usr/local/scripts/stage//apps/apache/httpd-mliqat: No such file or directory
./logrot.sh: line 8: /usr/local/scripts/stage//apps/apache/httpd-mlitrain: No such file or directory
./logrot.sh: line 8: /usr/local/scripts/stage//apps/apache/httpd-mliuat: No such file or directory

My bad, $instance needs to be the short file name.

if cd /apps/apache
then
  for instance in *httpd*
  do
    if [ -d "$instance" ] && [ ! -f /etc/logrotate.d/"$instance" ] && service "$instance" status >/dev/null 2>&1
    then
      sed "s|examplehost|$instance|g" </usr/local/scripts/examplelogconfig >/usr/local/scripts/stage/"$instance"
    fi
  done
fi

BTW the staging only makes sense for testing, i.e. if there is no test system.
I would rather let the script directly copy to /etc/logrotate.d/, and run the script at the desired maintenance slot.

I'm still getting

when I removed /dev/null 2>&1

I get several of these errors

/apps/apache/httpd-fakedir: unrecognized service

In my last script there is

  for instance in *httpd*

So $instance becomes the short name httpd-fakedir not the pathname /apps/apache/httpd-fakedir

1 Like

I understand that but it's not copying the file over to the directory and then doing the sed statement it just gives me the unrecognized

Can you just have 1 log rotate that does them all?

/apps/apache/*/logs/*log {
    rotate 7
    compress
    missingok
    notifempty
    sharedscripts
    daily
    delaycompress
    nomail
    postrotate
          SERV=${1#*apache/}
          SERV=${SERV%%/*}
          /sbin/service $SERV reload > /dev/null 2>/dev/null || true
    endscript
}

Edit: I can see sharedscripts would cause an issue here (would only reload the last SERVER rotated)
if you don't mind restarting everything after it's done you could just use /usr/bin/killall -HUP httpd in the postrotate:

/apps/apache/*/logs/*log {
    rotate 7
    compress
    missingok
    notifempty
    sharedscripts
    daily
    delaycompress
    nomail
    postrotate
        /usr/bin/killall -HUP httpd
    endscript
}

No because there may need to be tweaks of them depending on the client. And I you could set that up also but this is how they want it done.

---------- Post updated at 09:37 AM ---------- Previous update was at 09:04 AM ----------

#!/bin/bash

if cd /apps/apache
then
  for instance in *httpd*
  do
    if [ -d "$instance" ] && [ ! -f /etc/logrotate.d/"$instance" ] 
    then
      sed "s|examplehost|$instance|g" </usr/local/scripts/examplelogconfig >/usr/local/scripts/stage/"$instance"
    fi
  done
fi

This worked thank you all