logrotate 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +9 -0
- data/Manifest.txt +3 -0
- data/README.txt +148 -26
- data/Rakefile +1 -1
- data/lib/logrotate.rb +2 -245
- data/lib/logrotate/impl.rb +416 -0
- data/lib/logrotate/logrotate.rb +86 -0
- data/lib/logrotate/rotateinfo.rb +166 -0
- data/test/test_logrotate.rb +78 -37
- metadata +6 -3
data/History.txt
CHANGED
@@ -1,2 +1,11 @@
|
|
1
|
+
=== 1.1.0 / 2008-08-20
|
2
|
+
* Enhanced the rotate file methods to return status information
|
3
|
+
regarding the rotation: the newly rotated file, the list of rotated
|
4
|
+
files, the list of deleted files, etc.
|
5
|
+
* Refactored the implementation of the file rotation methods into a
|
6
|
+
separate class (LogRotate::Impl) and exposed a few of these
|
7
|
+
implementation methods for public use.
|
8
|
+
|
1
9
|
=== 1.0.0 / 2008-06-19
|
2
10
|
Initial release of LogRotate. This package is unit tested fully.
|
11
|
+
|
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
* Project Page: http://rubyforge.org/projects/logrotate/
|
3
|
-
* Documentation: http://logrotate.rubyforge.org/
|
1
|
+
Object
|
4
2
|
|
5
3
|
== DESCRIPTION:
|
6
4
|
|
@@ -24,27 +22,158 @@ None (known).
|
|
24
22
|
== SYNOPSIS:
|
25
23
|
Here are some sample invocations of the library.
|
26
24
|
|
27
|
-
Rotate a log file with simple extensions: .1, .2, etc, keep
|
28
|
-
files around (.1 .. .
|
29
|
-
|
25
|
+
Rotate a log file with simple extensions: .1, .2, etc, keep 3 rotated
|
26
|
+
files around (.1 .. .3), and gzip the rotated files (.1.gz, .. .3.gz):
|
27
|
+
======<tt>examples/rotate_count.rb</tt>:
|
30
28
|
#!/usr/bin/env ruby
|
31
29
|
|
30
|
+
require 'fileutils'
|
32
31
|
require 'rubygems'
|
33
32
|
require 'logrotate'
|
34
33
|
|
35
34
|
options = {
|
36
|
-
:count =>
|
35
|
+
:count => 2,
|
37
36
|
:gzip => true
|
38
37
|
}
|
39
38
|
|
40
|
-
|
39
|
+
1.upto(3) do |iteration|
|
40
|
+
|
41
|
+
FileUtils.touch("/tmp/erwin.dat")
|
42
|
+
result = LogRotate.rotate_file("/tmp/erwin.dat", options)
|
43
|
+
|
44
|
+
print "=================================================\n"
|
45
|
+
print "Iteration \##{iteration}\n"
|
46
|
+
print "=================================================\n"
|
47
|
+
print result, "\n"
|
48
|
+
end
|
49
|
+
|
50
|
+
# clean up all files created by this example
|
51
|
+
FileUtils.rm_f(Dir.glob('/tmp/erwin.dat.*'))
|
52
|
+
|
53
|
+
======<tt>Output</tt>:
|
54
|
+
=================================================
|
55
|
+
Iteration #1
|
56
|
+
=================================================
|
57
|
+
Rotated Files And Counts:
|
58
|
+
file -> /tmp/erwin.dat.1.gz, index -> 1
|
59
|
+
Rotated Files:
|
60
|
+
/tmp/erwin.dat.1.gz
|
61
|
+
Deleted Files:
|
62
|
+
New Rotated File:
|
63
|
+
/tmp/erwin.dat.1.gz
|
64
|
+
|
65
|
+
=================================================
|
66
|
+
Iteration #2
|
67
|
+
=================================================
|
68
|
+
Rotated Files And Counts:
|
69
|
+
file -> /tmp/erwin.dat.1.gz, index -> 1
|
70
|
+
file -> /tmp/erwin.dat.2.gz, index -> 2
|
71
|
+
Rotated Files:
|
72
|
+
/tmp/erwin.dat.1.gz
|
73
|
+
/tmp/erwin.dat.2.gz
|
74
|
+
Deleted Files:
|
75
|
+
New Rotated File:
|
76
|
+
/tmp/erwin.dat.1.gz
|
77
|
+
|
78
|
+
=================================================
|
79
|
+
Iteration #3
|
80
|
+
=================================================
|
81
|
+
Rotated Files And Counts:
|
82
|
+
file -> /tmp/erwin.dat.1.gz, index -> 1
|
83
|
+
file -> /tmp/erwin.dat.2.gz, index -> 2
|
84
|
+
Rotated Files:
|
85
|
+
/tmp/erwin.dat.1.gz
|
86
|
+
/tmp/erwin.dat.2.gz
|
87
|
+
Deleted Files:
|
88
|
+
/tmp/erwin.dat.2.gz
|
89
|
+
New Rotated File:
|
90
|
+
/tmp/erwin.dat.1.gz
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
Rotate a log file with date/time extensions.
|
95
|
+
======<tt>examples/rotate_date_time.rb</tt>:
|
96
|
+
#!/usr/bin/env/ruby
|
97
|
+
|
98
|
+
require 'fileutils'
|
99
|
+
require 'rubygems'
|
100
|
+
require 'logrotate'
|
101
|
+
|
102
|
+
options = {
|
103
|
+
:date_time_ext => true,
|
104
|
+
:date_time_format => '%F_%T',
|
105
|
+
:count => 2
|
106
|
+
}
|
107
|
+
|
108
|
+
1.upto(3) do |iteration|
|
109
|
+
|
110
|
+
FileUtils.touch("/tmp/erwin.dat")
|
111
|
+
result = LogRotate.rotate_file("/tmp/erwin.dat", options)
|
112
|
+
|
113
|
+
print "=================================================\n"
|
114
|
+
print "Iteration \##{iteration}\n"
|
115
|
+
print "=================================================\n"
|
116
|
+
print result, "\n"
|
117
|
+
|
118
|
+
# Sleep for a short period so that next time rotate_file is called,
|
119
|
+
# the current second will be different (and thus the rotated file
|
120
|
+
# name will be different than the last).
|
121
|
+
sleep(1.5)
|
122
|
+
end
|
123
|
+
|
124
|
+
# clean up all files created by this example
|
125
|
+
FileUtils.rm_f(Dir.glob('/tmp/erwin.dat.*'))
|
126
|
+
|
127
|
+
======<tt>Output</tt>:
|
128
|
+
=================================================
|
129
|
+
Iteration #1
|
130
|
+
=================================================
|
131
|
+
Rotated Files And Dates:
|
132
|
+
file -> /tmp/erwin.dat.2008-08-21_12:37:39, date_time -> 2008-08-21T12:37:39+00:00
|
133
|
+
file -> /tmp/erwin.dat.2008-08-21_12:37:37, date_time -> 2008-08-21T12:37:37+00:00
|
134
|
+
Rotated Files:
|
135
|
+
/tmp/erwin.dat.2008-08-21_12:37:39
|
136
|
+
/tmp/erwin.dat.2008-08-21_12:37:37
|
137
|
+
Deleted Files:
|
138
|
+
New Rotated File:
|
139
|
+
/tmp/erwin.dat.2008-08-21_12:37:39
|
140
|
+
|
141
|
+
=================================================
|
142
|
+
Iteration #2
|
143
|
+
=================================================
|
144
|
+
Rotated Files And Dates:
|
145
|
+
file -> /tmp/erwin.dat.2008-08-21_12:37:41, date_time -> 2008-08-21T12:37:41+00:00
|
146
|
+
file -> /tmp/erwin.dat.2008-08-21_12:37:39, date_time -> 2008-08-21T12:37:39+00:00
|
147
|
+
Rotated Files:
|
148
|
+
/tmp/erwin.dat.2008-08-21_12:37:41
|
149
|
+
/tmp/erwin.dat.2008-08-21_12:37:39
|
150
|
+
Deleted Files:
|
151
|
+
/tmp/erwin.dat.2008-08-21_12:37:37
|
152
|
+
New Rotated File:
|
153
|
+
/tmp/erwin.dat.2008-08-21_12:37:41
|
154
|
+
|
155
|
+
=================================================
|
156
|
+
Iteration #3
|
157
|
+
=================================================
|
158
|
+
Rotated Files And Dates:
|
159
|
+
file -> /tmp/erwin.dat.2008-08-21_12:37:42, date_time -> 2008-08-21T12:37:42+00:00
|
160
|
+
file -> /tmp/erwin.dat.2008-08-21_12:37:41, date_time -> 2008-08-21T12:37:41+00:00
|
161
|
+
Rotated Files:
|
162
|
+
/tmp/erwin.dat.2008-08-21_12:37:42
|
163
|
+
/tmp/erwin.dat.2008-08-21_12:37:41
|
164
|
+
Deleted Files:
|
165
|
+
/tmp/erwin.dat.2008-08-21_12:37:39
|
166
|
+
New Rotated File:
|
167
|
+
/tmp/erwin.dat.2008-08-21_12:37:42
|
168
|
+
|
41
169
|
|
42
170
|
|
43
171
|
Rotate a set of log files with date extensions, and move the rotated
|
44
172
|
files to a specified directory:
|
45
|
-
|
173
|
+
======<tt>examples/rotate_date.rb</tt>:
|
46
174
|
#!/usr/bin/env ruby
|
47
175
|
|
176
|
+
require 'fileutils'
|
48
177
|
require 'rubygems'
|
49
178
|
require 'logrotate'
|
50
179
|
|
@@ -64,29 +193,19 @@ files to a specified directory:
|
|
64
193
|
}
|
65
194
|
|
66
195
|
LogRotate.rotate_files(files, options)
|
67
|
-
|
68
|
-
|
69
|
-
Rotate a log file with date/time extensions.
|
70
|
-
======+examples/rotate_date_time.rb+:
|
71
|
-
#!/usr/bin/env/ruby
|
72
196
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
options = {
|
77
|
-
:date_time_ext => true,
|
78
|
-
:date_time_format => '%F_%T'
|
79
|
-
}
|
80
|
-
|
81
|
-
LogRotate.rotate_file("/tmp/erwin.dat", options)
|
197
|
+
# clean up all files and directories created by this example
|
198
|
+
FileUtils.rm_f(Dir.glob"/tmp/erwin*.dat")
|
199
|
+
FileUtils.rm_rf("/tmp/archives")
|
82
200
|
|
83
201
|
|
84
202
|
Rotate a log file that is currently being written to by a live
|
85
203
|
process. After the file is rotated, notify the live process to reopen
|
86
204
|
its log file.
|
87
|
-
|
205
|
+
======<tt>examples/rotate_live.rb</tt>:
|
88
206
|
#!/usr/bin/env ruby
|
89
207
|
|
208
|
+
require 'fileutils'
|
90
209
|
require 'rubygems'
|
91
210
|
require 'logrotate'
|
92
211
|
|
@@ -104,6 +223,9 @@ its log file.
|
|
104
223
|
}
|
105
224
|
|
106
225
|
LogRotate.rotate_file("/tmp/hupper.dat", options)
|
226
|
+
|
227
|
+
# clean up all files created by this example
|
228
|
+
FileUtils.rm_rf(Dir.glob("/tmp/hupper*"))
|
107
229
|
|
108
230
|
|
109
231
|
== REQUIREMENTS:
|
@@ -119,12 +241,12 @@ Hoe is required but only for running the tests.
|
|
119
241
|
* Homepage: http://www.designingpatterns.com
|
120
242
|
* Blogs: http://blogs.designingpatterns.com
|
121
243
|
|
122
|
-
== SUPPORT
|
244
|
+
== SUPPORT:
|
123
245
|
Please post questions, concerns, or requests for enhancement to the forums on
|
124
246
|
the project page. Alternatively, direct contact information for
|
125
247
|
Designing Patterns can be found on the project page for this gem.
|
126
248
|
|
127
|
-
== ENHANCEMENTS
|
249
|
+
== ENHANCEMENTS:
|
128
250
|
Please feel free to contact us with any ideas; we will try our best to
|
129
251
|
enhance the software and respond to user requests. Of course, we are more
|
130
252
|
likely to work on a particular enhancement if we know that there are users
|
data/Rakefile
CHANGED
data/lib/logrotate.rb
CHANGED
@@ -1,246 +1,3 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'English'
|
4
|
-
require 'zlib'
|
5
|
-
require 'date'
|
6
|
-
|
7
|
-
#
|
8
|
-
# This module provides a few methods for log rotation.
|
9
|
-
#
|
10
|
-
|
11
|
-
module LogRotate
|
12
|
-
|
13
|
-
DEFAULT_COUNT = 5
|
14
|
-
DEFAULT_GZIP = false
|
15
|
-
DEFAULT_DATE_TIME_EXTENSION = false
|
16
|
-
|
17
|
-
DEFAULT_DATE_TIME_FORMAT = '%F'
|
18
|
-
|
19
|
-
#
|
20
|
-
# ====Description: This method rotates the given files.
|
21
|
-
#
|
22
|
-
# ====Parameters:
|
23
|
-
# [file(s)]
|
24
|
-
# The files to be rotated.
|
25
|
-
# [options = {}]
|
26
|
-
# A list of optional arguments.
|
27
|
-
#
|
28
|
-
# See rotate_file for details.
|
29
|
-
#
|
30
|
-
def self.rotate_files(files, options)
|
31
|
-
files.each do |file|
|
32
|
-
rotate_single_file(file, options)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
#
|
37
|
-
# ====Description: This method rotates the given file(s).
|
38
|
-
# There are 2 types of extensions that can be used: the default
|
39
|
-
# extension which is an integer value (".1", ".2", ..), and a
|
40
|
-
# date/time extension (".2008-08-01", ..). If a date/time extension
|
41
|
-
# is chosen, the caller can specify a date/time format for this
|
42
|
-
# extension.
|
43
|
-
#
|
44
|
-
# ====Parameters:
|
45
|
-
# [file]
|
46
|
-
# The file to be rotated.
|
47
|
-
# [options = {}]
|
48
|
-
# A list of optional arguments.
|
49
|
-
#
|
50
|
-
# The optional arguments are listed below:
|
51
|
-
# +count+:: The number of rotated files to be kept.
|
52
|
-
# +directory+:: The directory to store the newly rotated file. If this
|
53
|
-
# option is unspecified, the original file's directory
|
54
|
-
# will be used.
|
55
|
-
# +date_time_ext+:: Whether the extension on the rotated files should be
|
56
|
-
# a date. Possible values are: +true+, +false+.
|
57
|
-
# +date_time_format+:: For use with +date_time_ext+. This specifies the
|
58
|
-
# format of the date / time extension.
|
59
|
-
# +date_time+:: For use with +date_time_ext+. The +DateTime+ that will be
|
60
|
-
# used to construct the extension of the newly rotated file.
|
61
|
-
# If this option is not specified, the current date and time
|
62
|
-
# will be used.
|
63
|
-
# +pre_rotate+:: A +Proc+ to be executed before the rotation is started.
|
64
|
-
# +post_rotate+:: A +Proc+ to be executed after the rotation is finished,
|
65
|
-
# and before the newly rotated file is zipped.
|
66
|
-
# +gzip+:: Whether the newly rotated file should be gzipped. Possible
|
67
|
-
# values are: +true+, +false+.
|
68
|
-
#
|
69
|
-
def self.rotate_file(file, options)
|
70
|
-
rotate_single_file(file, options)
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.rotate_single_file(file, options = {})
|
74
|
-
gzip = options[:gzip] ? options[:gzip] : DEFAULT_GZIP
|
75
|
-
|
76
|
-
# error checking
|
77
|
-
if (!File.exist?(file)) then raise "File does not exist: #{file}." end
|
78
|
-
if (!File.readable?(file)) then raise "File is not readable: #{file}." end
|
79
|
-
|
80
|
-
if (options[:pre_rotate]) then options[:pre_rotate].call() end
|
81
|
-
|
82
|
-
new_backup = ""
|
83
|
-
if (options[:date_time_ext])
|
84
|
-
new_backup = rotate_file_date_extension(file, options)
|
85
|
-
else
|
86
|
-
new_backup = rotate_file_integer_extension(file, options)
|
87
|
-
end
|
88
|
-
|
89
|
-
if (options[:post_rotate]) then options[:post_rotate].call() end
|
90
|
-
|
91
|
-
if (gzip) then gzip_file(new_backup) end
|
92
|
-
end
|
93
|
-
private_class_method(:rotate_single_file)
|
94
|
-
|
95
|
-
def self.rotate_file_date_extension(file, options)
|
96
|
-
count = options[:count] ? options[:count] : DEFAULT_COUNT
|
97
|
-
|
98
|
-
now = options[:date_time] ? options[:date_time] : DateTime.now()
|
99
|
-
|
100
|
-
date_time_format = options[:date_time_format] ? options[:date_time_format] : DEFAULT_DATE_TIME_FORMAT
|
101
|
-
|
102
|
-
# Get a list of the rotated files.
|
103
|
-
(source_directory, base_name) = File.split(file)
|
104
|
-
directory = options[:directory] ? options[:directory] : source_directory
|
105
|
-
|
106
|
-
rotated_files = Dir.entries(directory).map do |entry|
|
107
|
-
rslt = nil
|
108
|
-
|
109
|
-
# Validate the rotated file. Since the caller is allowed to
|
110
|
-
# specify the date/time format, here we do not have a regular
|
111
|
-
# expression to match the date/time portion of the rotated
|
112
|
-
# file's extension. As a result, some foreign files can sneak
|
113
|
-
# into our list of rotated files (eg. base_file.GARBAGE.gz). Thus,
|
114
|
-
# the rotated file is validated below, and if invalid, it is
|
115
|
-
# skipped / left alone / not considered in the rotation.
|
116
|
-
|
117
|
-
if (entry.match("^#{base_name}\..+(\.gz)?$"))
|
118
|
-
|
119
|
-
# Validation #1: convert the date/time portion of the
|
120
|
-
# extension to a DateTime object and skip the file if an
|
121
|
-
# exception is thrown.
|
122
|
-
begin
|
123
|
-
match_data = entry.match("\.([^.]+)(\.gz)?$")
|
124
|
-
date_time = DateTime.strptime(match_data[1], date_time_format)
|
125
|
-
gz = match_data[2] ? match_data[2] : ""
|
126
|
-
|
127
|
-
# Validation #2: convert the date/time portion of the
|
128
|
-
# extension to a DateTime object and back to a string again.
|
129
|
-
# Then reconstruct the rotated file name with this string,
|
130
|
-
# and ensure the reconstructed rotated file matches the
|
131
|
-
# original. This will take into account cases where
|
132
|
-
# strptime succeeded but had additional garbage characters
|
133
|
-
# present.
|
134
|
-
# eg: date_time_format = '%F', file = 'mysql_backup.2008-08-04.BACK.gz'
|
135
|
-
reconstructed_file = "#{base_name}.#{date_time.strftime(date_time_format)}#{gz}"
|
136
|
-
if (entry == reconstructed_file)
|
137
|
-
rslt = { :date_time => date_time, :file => entry }
|
138
|
-
end
|
139
|
-
rescue => e
|
140
|
-
end
|
141
|
-
|
142
|
-
rslt
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
rotated_files = rotated_files.select { |rotated_file| rotated_file }
|
147
|
-
|
148
|
-
# Sort files by date (newer to older).
|
149
|
-
rotated_files.sort! { |left, right| right[:date_time] <=> left[:date_time] }
|
150
|
-
|
151
|
-
# Remove the oldest files so that there are count rotated files remaining.
|
152
|
-
|
153
|
-
# Determine how many old files to be removed.
|
154
|
-
new_backup_base_name = base_name + "." + now.strftime(date_time_format)
|
155
|
-
|
156
|
-
# Add 1 to account for the additional rotated file that will be
|
157
|
-
# created after the original file passed in is rotated.
|
158
|
-
num_old_files = rotated_files.length() - count + 1
|
159
|
-
|
160
|
-
# There is a chance that the newly rotated file will have the same
|
161
|
-
# name as one of the already existing rotated files (eg. if the
|
162
|
-
# extension is simply the date, and the job is ran a second time
|
163
|
-
# in the same day). In this case, there will be 1 less rotated
|
164
|
-
# file (and thus 1 less to delete).
|
165
|
-
if (rotated_files.find {|rotated_file| rotated_file[:file] == new_backup_base_name})
|
166
|
-
num_old_files -= 1
|
167
|
-
end
|
168
|
-
|
169
|
-
if (num_old_files > 0)
|
170
|
-
old_files = rotated_files.slice!(-num_old_files, num_old_files)
|
171
|
-
File.unlink(*old_files.map {|old_file| File.join(directory, old_file[:file]) })
|
172
|
-
end
|
173
|
-
|
174
|
-
# Rename the original file.
|
175
|
-
new_backup = File.join(directory, new_backup_base_name)
|
176
|
-
File.rename(file, new_backup)
|
177
|
-
|
178
|
-
return new_backup
|
179
|
-
end
|
180
|
-
private_class_method(:rotate_file_date_extension)
|
181
|
-
|
182
|
-
def self.rotate_file_integer_extension(file, options)
|
183
|
-
count = options[:count] ? options[:count] : DEFAULT_COUNT
|
184
|
-
|
185
|
-
# Get a list of the backed up files.
|
186
|
-
(source_directory, base_name) = File.split(file)
|
187
|
-
directory = options[:directory] ? options[:directory] : source_directory
|
188
|
-
|
189
|
-
rotated_files = Dir.entries(directory).select do |entry|
|
190
|
-
entry.match("#{base_name}\.[0-9]+(\.gz)?$")
|
191
|
-
end
|
192
|
-
|
193
|
-
rotated_files.map! do |rotated_file|
|
194
|
-
index = rotated_file.match("\.([0-9]+)(\.gz)?$")[1].to_i()
|
195
|
-
{ :index => index, :file => rotated_file }
|
196
|
-
end
|
197
|
-
|
198
|
-
# Delete old files.
|
199
|
-
old_files = rotated_files.select { |rotated_file| rotated_file[:index] >= count }
|
200
|
-
File.unlink(*old_files.map {|old_file| File.join(directory, old_file[:file]) })
|
201
|
-
|
202
|
-
rotated_files = rotated_files - old_files
|
203
|
-
|
204
|
-
# Sort files such that the back up count is descending (eg. [hello.txt.5, hello.txt.4, ..]).
|
205
|
-
rotated_files.sort! { |left, right| right[:index] <=> left[:index] }
|
206
|
-
|
207
|
-
# Rotate - Increment the back up index on each file.
|
208
|
-
rotated_files.each do |rotated_file|
|
209
|
-
|
210
|
-
new_index = rotated_file[:index] + 1
|
211
|
-
new_file = rotated_file[:file].sub(/(^.*\.)(#{rotated_file[:index]})(.gz)?$/,
|
212
|
-
"\\1#{new_index}\\3")
|
213
|
-
File.rename(File.join(directory, rotated_file[:file]),
|
214
|
-
File.join(directory, new_file))
|
215
|
-
end
|
216
|
-
|
217
|
-
# Rename the original file.
|
218
|
-
new_backup = File.join(directory, base_name + ".1")
|
219
|
-
File.rename(file, new_backup)
|
220
|
-
|
221
|
-
return new_backup
|
222
|
-
end
|
223
|
-
private_class_method(:rotate_file_integer_extension)
|
224
|
-
|
225
|
-
def self.gzip_file(file)
|
226
|
-
# Zip the original file if necessary.
|
227
|
-
gzip_file = file + ".gz"
|
228
|
-
|
229
|
-
begin
|
230
|
-
File.open(file) do |file_stream|
|
231
|
-
Zlib::GzipWriter.open(gzip_file) do |gz|
|
232
|
-
while (buffer = file_stream.read(1024))
|
233
|
-
gz.write(buffer)
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
rescue => error
|
238
|
-
raise "Unable to zip file: #{file}. Error: #{error}\n"
|
239
|
-
end
|
240
|
-
|
241
|
-
File.unlink(file)
|
242
|
-
end
|
243
|
-
private_class_method(:gzip_file)
|
244
|
-
|
245
|
-
end
|
1
|
+
#!/usr/bin/env ruby
|
246
2
|
|
3
|
+
require 'logrotate/logrotate'
|