1

I am using the following recipe to perform log rotation:

bash 'adding_logrotate_for_consul' do
  code <<-EOH
    echo "" >> /etc/logrotate.conf
    echo "/tmp/output.log {" >> /etc/logrotate.conf
    echo -e "\tsize 20M" >> /etc/logrotate.conf
    echo -e "\tcreate 700 root root" >> /etc/logrotate.conf
    echo -e "\trotate 3" >> /etc/logrotate.conf
    echo "}" >> /etc/logrotate.conf
  EOH
end

The above code runs completely fine and it adds the following entry in /etc/logrotate.conf

/tmp/output.log {
        size 20M
        create 700 root root
        rotate 3
}

However, after the above entry is added using chef, I have to manually run the following command on the node everytime:

logrotate -s /var/log/logstatus /etc/logrotate.conf

How can I include the above command in chef recipe so that log rotation can be performed using chef recipe after the file size reached 20M??

meallhour
  • 13,921
  • 21
  • 60
  • 117
  • Include this for bookshelf['log_rotation'] { 'file_maxbytes' => 104857600, 'num_to_keep' => 10 } ... your problem should solve. – Lokesh S Jun 11 '20 at 05:49

1 Answers1

4

I think there are a few things here you are doing less than ideally. Let me go one by one:

I am using the following recipe to perform log rotation:

bash 'adding_logrotate_for_consul' do code ...

This is not a good way of creating a logrotate entry. Chef (and other orchestration tools) have a very nice feature called idempotency. Its basic meaning is that you can run the same recipe many times, and it will only converge itself, or "apply" itself, if it is needed. A problem you will have with the way you are doing this is that your block of code will run EVERY time you run you cookbook - so after 5 runs, you will have 5 identical entries in /etc/logrotate.conf. That wouldn't be very good...

Thankfully there are much better ways of doing what you want to do. Are you familiar with the Chef Supermarket? This is a site where you can find many pre-made cookbooks to extend the functionality of your cookbook. So, for your current problem, you could for example use the cookbook called logrotate. How can you use it in your own cookbook? You need to include it by adding the following to these files:

BERKSFILE

source 'https://supermarket.chef.io'
metadata

METADATA.RB

depends 'logrotate'

Now your cookbook is aware of the 'logrotate' cookbook, and you can use the Chef resources it provides. So you could create the following recipe:

logrotate_app 'app_with_logs' do
  path      '/tmp/output.log'
  options   ['size 20M']
  rotate    3
  create    '700 root adm'
end

Now, when you run your recipe, this will create the logrotate entry, only if it doesn't already exist. Handy! (note, this might create the entry in /etc/logrotate.d/ instead of /etc/logratate.conf. This is the preferred way of adding a logrotate entry).

On to the next part.

How can I include the above command in chef recipe so that log rotation can be performed using chef recipe after the file size reached 20M??

Logrotate as a program runs automatically, once a day. When it runs, it will check all entries in /etc/logrotate.conf and /etc/logrotate.d/*, and run them if they fulfil the requirements (in this case, size of 20M). However, since it only runs once a day, depending how fast your log grows, it could be much bigger than 20M by the time it gets evaluated and rotated!

So now, you have two options. Either, one, let logrotate work as it is expected to, and rotate your log once a day if, when it looks at it, its over 20M in size. Or two, you could do what you want to do and run that command in a Chef recipe, although this would not be a good way of doing it. But, for completeness, I will tell you how you can run a command with Chef. But remember! This will, again, NOT be idempotent. Thus why it is not a good way of doing this!

To run a command from a Chef recipe, use the execute resource. For example:

execute 'rotate_my_log_because_I_cant_wait_24h' do
  command 'logrotate -s /var/log/logstatus /etc/logrotate.conf'
end

That will run that command on your node. But again, this is not the recommended way of doing this.

EugeneRomero
  • 514
  • 7
  • 13
  • 1
    Maybe worth adding `cron_d` from the `cron` cookbook to set up a periodic run of logrotate. – Tensibai Sep 26 '16 at 07:50
  • @Tensibai good point! If rotation is needed more than once a day. – EugeneRomero Sep 26 '16 at 12:55
  • @GeneR thanks a lot for your response. I want to ask if the 'logrotate' cookbook depends on another cookbooks. If yes, then how should I refer those cookbooks within Berksfile? – meallhour Sep 26 '16 at 14:53
  • @meallhour berks will do the recursive resolving for you (berks install and berks upload with a chef server should do with a correct knife.rb) – Tensibai Sep 26 '16 at 17:28
  • @meallhour Like Tensibai said, you only need to declare the cookbook you want. Berks will handle any dependencies from the cookbooks you include. If my answer helped you, feel free to "accept" it, it would help me out :) – EugeneRomero Sep 27 '16 at 19:16
  • @GeneR I see we can frequency in the logrotate cookbook. Do you think we can add `frequency 'hourly'` to perform the log rotation every hour? – meallhour Sep 28 '16 at 16:01
  • @meallhour No, because again, logrotate only runs once a day by default, so the minimum frequency you can set is 'daily'. However, if you wish to rotate your log more than once a day, hourly for example, you can use cron. If you include the [cron](https://supermarket.chef.io/cookbooks/cron) cookbook from the Supermarket, Chef can do this for you. Just create a 'cron_d' recipe as explained in that page, give it a 'predefined_value' of '@hourly', and tell it to run the command that rotates your log. That way, the log will get evaluated for rotation once an hour :) – EugeneRomero Sep 29 '16 at 16:39
  • @meallhour also, keep in mind that 'size' in logrotate overrides 'frequency'. So if you set both of those parameters in a logrotate command, only 'size' will be evaluated and 'frequency' will be ignored. [Here](https://support.rackspace.com/how-to/understanding-logrotate-utility/) is a very clear logrotate tutorial explaining these little quirks. – EugeneRomero Sep 29 '16 at 16:42