rb.rotate 0.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.
@@ -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