rb.rotate 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,135 @@
1
+ # encoding: utf-8
2
+ require "yaml"
3
+
4
+ module RbRotate
5
+
6
+ ##
7
+ # Represents hook.
8
+ #
9
+
10
+ class Hook
11
+
12
+ ##
13
+ # Holds name of the hook.
14
+ #
15
+
16
+ @name
17
+
18
+ ##
19
+ # Holds data of the hook.
20
+ #
21
+
22
+ @data
23
+
24
+ ##
25
+ # Holds arguments of the hook.
26
+ #
27
+
28
+ @arguments
29
+
30
+ ##
31
+ # Hold variables for the hook.
32
+ #
33
+
34
+ @variables
35
+
36
+ ##
37
+ # Constructor.
38
+ #
39
+
40
+ def initialize(name, arguments = nil, variables = { })
41
+ @name = name
42
+ @arguments = self.parse_arguments(arguments)
43
+ @variables = variables
44
+ end
45
+
46
+ ##
47
+ # Parses "arguments line".
48
+ #
49
+
50
+ def parse_arguments(string)
51
+ if not string.nil?
52
+ string.split(":")
53
+ else
54
+ []
55
+ end
56
+ end
57
+
58
+ ##
59
+ # Runs hook.
60
+ #
61
+
62
+ def run!
63
+ # Gets commans
64
+ command = self.command.dup
65
+
66
+ # Adds arguments
67
+ self.expand_arguments(command)
68
+
69
+ # Adds variables
70
+ self.expand_variables(command)
71
+
72
+ # Runs it
73
+ pipe = ::File.popen(command)
74
+ pipe.eof? # ask for EOF causes waiting for terminating the pipe process
75
+
76
+ result = pipe.read
77
+ pipe.close()
78
+
79
+ # Parses and returns result
80
+ return self.parse_result(result)
81
+ end
82
+
83
+ ##
84
+ # Expands arguments.
85
+ #
86
+
87
+ def expand_arguments(command)
88
+ @arguments.each_index do |i|
89
+ arg = arguments[i]
90
+ command.gsub! "%" << i.to_s, '"' << arg << '"'
91
+ end
92
+ end
93
+
94
+ ##
95
+ # Expands variables.
96
+ #
97
+
98
+ def expand_variables(command)
99
+ @variables.each_pair do |name, value|
100
+ command.gsub! "%" << name, '"' << value << '"'
101
+ end
102
+ end
103
+
104
+ ##
105
+ # Parses result.
106
+ #
107
+
108
+ def parse_result(result)
109
+ if result.strip.empty?
110
+ return { }
111
+ end
112
+
113
+ result = YAML.load(result)
114
+ if not result.kind_of? Hash
115
+ result = { }
116
+ log "Warning: result of hook '" << @name.to_s << "' wasn't YAML collection. Ignored."
117
+ end
118
+
119
+ return result
120
+ end
121
+
122
+ ##
123
+ # Gets command.
124
+ #
125
+
126
+ def command
127
+ command = Configuration::get.hooks[@name]
128
+ if command.nil?
129
+ raise Exception::new("Invalid hook: " << @name.to_s)
130
+ end
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,25 @@
1
+ # YAML
2
+
3
+ # Contains defaults for the configuration file.
4
+ # You SHOULDN'T need edit it.
5
+
6
+ paths:
7
+ state file: /var/lib/rb.rotate.status
8
+ defaults file: %%configuration/defaults.yaml
9
+ log file: /var/log/rb.rotate.log
10
+
11
+ dirs:
12
+ default:
13
+ directory: /var/log
14
+ recursive: yes
15
+ follow: true
16
+ storage: /var/log/archive
17
+ compress: yes
18
+ decompress: yes
19
+ rotate: 5
20
+ period: weekly
21
+ max size: 20M
22
+ mail: root@localhost
23
+ recycle: remove
24
+ identifier: numeric
25
+ action: move + create
@@ -0,0 +1,349 @@
1
+ # YAML
2
+
3
+ paths:
4
+
5
+ ##
6
+ # Location of the state file (database about log rotation).
7
+ #
8
+ # Default value:
9
+ # /var/lib/rb.rotate.status
10
+ #
11
+
12
+ state file: /var/lib/rb.rotate.status
13
+
14
+ ##
15
+ # Contains location of the file with default values. Content of this
16
+ # file is merged with this file. You sholdn't need edit it.
17
+ #
18
+ # Default value:
19
+ # %%configuration/defaults.yaml
20
+ #
21
+
22
+ defaults file: %%configuration/defaults.yaml
23
+
24
+ ##
25
+ # Contains path to log file.
26
+ #
27
+ # Default value:
28
+ # /var/log/rb.rotate.log
29
+ #
30
+
31
+ log file: /var/log/rb.rotate.log
32
+
33
+ hooks:
34
+ # something: /path/to/some/script %filepath
35
+
36
+ dirs:
37
+
38
+ ##
39
+ # Default directory must be set.
40
+ #
41
+
42
+ default:
43
+
44
+ ##
45
+ # Directory from which will be logs archived. Recursive
46
+ # parameter says if it will be performed in subdirs.
47
+ #
48
+ # Default value:
49
+ # /var/log
50
+ #
51
+
52
+ directory: /var/log
53
+
54
+ ##
55
+ # Defines inheritance. Options missing in the directory settings
56
+ # are then inherited from the parent directory.
57
+ #
58
+ # Default value:
59
+ # nothing
60
+ #
61
+
62
+ #parent:
63
+
64
+ ##
65
+ # Says if archiving will be performed in subdirs of the
66
+ # 'directory' too. It's boolean value, but third value is 'flat'
67
+ # which means, files from subdirs will be archived without
68
+ # respecting the old structure directly to the 'archive'
69
+ # directory. In otherwise, original subdirectory structure will
70
+ # be respected.
71
+ #
72
+ # Possible values:
73
+ # - yes
74
+ # - no
75
+ # - flat
76
+ #
77
+ # Default value:
78
+ # yes
79
+ #
80
+
81
+ recursive: yes
82
+
83
+ ##
84
+ # Says, it should follow symbolic links by transparent way. In
85
+ # storage, they will be handled as normal files and dirs. If
86
+ # false, they will be silently ignored.
87
+ #
88
+ # Default value:
89
+ # yes
90
+ #
91
+
92
+ follow: yes
93
+
94
+ ##
95
+ # Directory to which will be logs archived.
96
+ #
97
+ # Default value:
98
+ # /var/log/archive
99
+ #
100
+
101
+ storage: /var/log/archive
102
+
103
+ ##
104
+ # Says which command use for compressing the log. It must
105
+ # support the same base syntax and '<command> <file>' order
106
+ # as gzip and bzip2. You can specify it both as path with
107
+ # parameters or simply shell command. Uses gzip --best as
108
+ # default if set to 'yes'.
109
+ #
110
+ # It's also necessary specify the extension because without it
111
+ # rotate cannot detect compressed filenames. If you change
112
+ # compression method, all archived logs will be recompressed
113
+ # during next rotation.
114
+ #
115
+ # Default value:
116
+ # no
117
+ #
118
+ # Possible values:
119
+ # [<command>, <extension>]
120
+ # yes
121
+ # no
122
+ #
123
+
124
+ compress: yes
125
+
126
+ ##
127
+ # Says which command use for decompression. It expects the same
128
+ # base syntax as gunzip or bunzip2. Uses gunzip as default if
129
+ # set to 'yes'.
130
+ #
131
+ # Be warn, decompress option must be synchronized with the
132
+ # compress option. Logically, if you set rotate up for
133
+ # compressing the logs, you must temporarily decompress them in
134
+ # archive before appending content to them or mailing them.
135
+ # If you turn off the compressing without decompressing enabled,
136
+ # it will cause damaged archive, of sure.
137
+ #
138
+ # Default value:
139
+ # no
140
+ #
141
+ # Possible values:
142
+ # <command>
143
+ # yes
144
+ # no
145
+ #
146
+
147
+ decompress: yes
148
+
149
+ ##
150
+ # Says logs from which period it will keep accroding to 'type'
151
+ # option. So for example rotate settings '5' of the type
152
+ # 'weekly' means it will keep logs from five weeks.
153
+ #
154
+ # Default value:
155
+ # 5
156
+ #
157
+
158
+ rotate: 5
159
+
160
+ ##
161
+ # Says how old should be log for archiving and in combination
162
+ # with 'rotate' option how old should be logs in archive
163
+ # maximally. (Simply period * rotate.)
164
+ #
165
+ # In contrast to classical logrotate, you can enter wide range
166
+ # of values. Firstly 'yearly', 'monthly' etc. where are their
167
+ # sense probably clear and secondly in format:
168
+ # <number> <period>
169
+ #
170
+ # So for example '2 weeks' or '5 days'. The smallest interval
171
+ # in this format is second, so you can define for example little
172
+ # obscure setting '2 seconds' or so.
173
+ #
174
+ # Be warn, if you will really use seconds with combination of
175
+ # date identifier of the archived files, default identifier
176
+ # format includes minutes only, so without changing it there is
177
+ # danger of rewritting the archived files.
178
+ #
179
+ # Default value:
180
+ # weekly
181
+ #
182
+ # Possible values:
183
+ # - yearly
184
+ # - monthly
185
+ # - weekly
186
+ # - daily
187
+ # - hourly
188
+ # - <number> years
189
+ # - <number> months
190
+ # - <number> weeks
191
+ # - <number> days
192
+ # - <number> hours
193
+ # - <number> minutes
194
+ # - <number> seconds
195
+ #
196
+
197
+ period: weekly
198
+
199
+ ##
200
+ # Guards maximal size of the log. Log is bigger than this value,
201
+ # rotates it. But it keeps other archived logs lifetime, so
202
+ # although log has been rotated prematurely and number of logs
203
+ # in archive is bigger then 'rotate' settings, it will keep all
204
+ # because 'rotate' settings means only number of 'type' units
205
+ # for keeping the log, nothing more.
206
+ #
207
+ # You can use base units here: 'K', 'M' and 'G' which mean
208
+ # appropriate quantity of kilobytes, megabytes and gigabytes.
209
+ #
210
+ # Default value:
211
+ # 20M
212
+ #
213
+
214
+ max size: 20M
215
+
216
+ ##
217
+ # Says to which e-mail address send recycled log or eventually
218
+ # the undefined mail action result.
219
+ #
220
+ # Default value:
221
+ # nothig
222
+ #
223
+
224
+ mail: root@localhost
225
+
226
+ ##
227
+ # Says how to recycle mail removed from archive. It can be
228
+ # removed or removed and mailed to mail specified in 'mail'
229
+ # option. If 'no' or 'keep' option set, old archived logs are
230
+ # kept forever.
231
+ #
232
+ # Default value:
233
+ # remove
234
+ #
235
+ # Possible values:
236
+ # remove
237
+ # mail
238
+ # keep
239
+ # no
240
+ #
241
+
242
+ recycle: remove
243
+
244
+ ##
245
+ # Says which type of archive distinguisher rotate will use.
246
+ # You can state the 'numeric' identifier, then increasing number
247
+ # will be used, or specify the string in date format syntax.
248
+ #
249
+ # Date formatting directives are following:
250
+ #
251
+ # %a - The abbreviated weekday name (``Sun'')
252
+ # %A - The full weekday name (``Sunday'')
253
+ # %b - The abbreviated month name (``Jan'')
254
+ # %B - The full month name (``January'')
255
+ # %c - The preferred local date and time representation
256
+ # %d - Day of the month (01..31)
257
+ # %H - Hour of the day, 24-hour clock (00..23)
258
+ # %I - Hour of the day, 12-hour clock (01..12)
259
+ # %j - Day of the year (001..366)
260
+ # %m - Month of the year (01..12)
261
+ # %M - Minute of the hour (00..59)
262
+ # %p - Meridian indicator (``AM'' or ``PM'')
263
+ # %S - Second of the minute (00..60)
264
+ # %U - Week number of the current year, starting with the
265
+ # first Sunday as the first day of the first week (00..53)
266
+ # %W - Week number of the current year, starting with the
267
+ # first Monday as the first day of the first week (00..53)
268
+ # %w - Day of the week (Sunday is 0, 0..6)
269
+ # %x - Preferred representation for the date alone, no time
270
+ # %X - Preferred representation for the time alone, no date
271
+ # %y - Year without a century (00..99)
272
+ # %Y - Year with century
273
+ # %Z - Time zone name
274
+ # %% - Literal ``%'' character
275
+ #
276
+ # If you type simply 'date', the following format will be used:
277
+ # %Y%m%d.%H%M
278
+ #
279
+ # Generally are supported all directives as listed in:
280
+ # http://ruby-doc.org/core/classes/Time.html#M000298
281
+ #
282
+ # Default value:
283
+ # numeric
284
+ #
285
+ # Possible values:
286
+ # numeric
287
+ # date
288
+ # <some formatting string>
289
+ #
290
+
291
+ identifier: numeric
292
+
293
+ ##
294
+ # Says by which actions archive. Some daemons keep logs open, so
295
+ # there is necessary to copy the old log and truncate the file.
296
+ #
297
+ # One additional option is 'append' which orders appending the
298
+ # log to existing file. It has sense, of sure, only if the
299
+ # 'identifier' option is set by appropriate way, so filename in
300
+ # archive storage is static. Be warn, if you use compression,
301
+ # file will be recompressed in the whole if this action applied.
302
+ #
303
+ # 'Mail' action will mail log to specified address. If its
304
+ # argument is omitted, it will use argument from 'mail' setting.
305
+ #
306
+ # Be warn, this option works by "programmable" way. Tokens are
307
+ # evaluated in the order and without thinking about the right sense.
308
+ # So for example 'copy + move' will cause error because of moving
309
+ # the log to the existing file from previous copying, or
310
+ # 'truncate + copy' will truncate the file and thereafter copy empty
311
+ # file to archive location which probably isn't the required
312
+ # behaviour.
313
+ #
314
+ # It's possible to create chains, it isn't limited by number of two
315
+ # operations. Multiline can be achieved by standard YAML syntax.
316
+ # Chains are very useful for hooks.
317
+ #
318
+ # HOOKS
319
+ #
320
+ # But you can use hooks. Hook will get path to the file
321
+ # generated by preceding built-in operation as parameter
322
+ # %filepath, so it will get for example path to new file in
323
+ # archive in case of 'copy' or 'move' or name of the old file
324
+ # after 'truncate' or 'create'. Hook placed just after
325
+ # another hook will get parameters defined by YAML encoded
326
+ # hash array.
327
+ #
328
+ # Parameters are kept through the chain of actions, they are
329
+ # only overwritten by each action, so if action one will generate
330
+ # some argument and preceding action has generated another two
331
+ # arguments, these two arguments will be available for hooks
332
+ # after the action one too and the third argument will be
333
+ # available with new value set by action one.
334
+ #
335
+ #
336
+ # Possible values:
337
+ # - move
338
+ # - append
339
+ # - create
340
+ # - remove
341
+ # - truncate
342
+ # - mail:<e-mail>
343
+ # - hook:<hook name>
344
+ #
345
+ # Default value:
346
+ # move + create
347
+ #
348
+
349
+ action: move + create