aix-errlog 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a6e98415b5db1bba3a83301429dbc6fb7d8e5f860a35c75225596c3f3493f9df
4
- data.tar.gz: 77e593f0c156f3dd12209eed4806d7d87e0cf15710ef42dbb3eb96f0804dc043
3
+ metadata.gz: e5294c01b19b7bd0a1977c511df790d5d002c34fa968c4c1ccc432d927f7406a
4
+ data.tar.gz: a7e9fe17605da84b4f4c0cc694c99886a3690859cbf52a37854a045e151a6e0f
5
5
  SHA512:
6
- metadata.gz: 7f20031f90faa552c4f99795b9fd2395b9658cd3b2aa3a02590b10bc68d3615ffab59fc21aeb84fb9ae46512f4644539a899ea97a79067325a065082845ecdc3
7
- data.tar.gz: 6d8753b599485fdc819c80e646d5b318794ed49ce89ad5112af38efa804fcb8982344f7b8891a84f6df8befc34a511c66e00e98799596c094a2732729fb2094a
6
+ metadata.gz: ee963b63a3877ca69c5e180e7f20613ac41c0a9ba424cdda648e1ba9aefb089b4280d8b7212081ea9e74dfe3f792a7edd7bbd82dd2d7cfc80f69d46e5953c286
7
+ data.tar.gz: 6d34ac53693e129524de2ddeac04559e1ed8a33d0cc0c12b80090977e95316bf8d54b04e9e229fbdcb5c2541be7404c2f83dca0bf671ed141124042efba29eab
@@ -4,14 +4,21 @@ require 'aix/errlog/constants'
4
4
 
5
5
  module AIX
6
6
  module Errlog
7
+ PARSE_REGEX = /(?:^Detail Data$\n(.*?))?(?:^Symptom Data$\n(.*))?\z/m.freeze
8
+
7
9
  ##
8
10
  # An errlog entry class. Used to parse the raw errlog_entry_t struct into a
9
11
  # more useful Ruby object.
10
12
  #
11
13
  # You shouldn't need to invoke this class directly; it is generated by the
12
14
  # Errlog#forward_each and Errlog#reverse_each.
15
+ #
16
+ # Unfortunately, the retreived detail and symptom fields aren't horribly
17
+ # useful, and IBM has presented no API for parsing these correctly, so the
18
+ # only canonical path to getting the correct detail and symptom data is
19
+ # through a call to the errpt command.
13
20
  class Entry
14
- attr_reader :magic, :sequence, :label, :timestamp, :crcid, :errdiag, :machineid, :nodeid, :class, :type, :resource, :rclass, :rtype, :vpd_ibm, :vpd_user, :in, :connwhere, :flags, :detail, :symptom, :dup_count, :dup_time1, :dup_time2, :wparid
21
+ attr_reader :magic, :sequence, :label, :timestamp, :crcid, :errdiag, :machineid, :nodeid, :class, :type, :resource, :rclass, :rtype, :vpd_ibm, :vpd_user, :in, :connwhere, :flags, :raw_detail, :raw_symptom, :dup_count, :dup_time1, :dup_time2, :wparid
15
22
 
16
23
  def initialize(raw)
17
24
  @magic = raw[:el_magic]
@@ -33,14 +40,37 @@ module AIX
33
40
  @connwhere = raw[:el_connwhere].to_s.freeze
34
41
  @flags = raw[:el_flags]
35
42
  length = raw[:el_detail_length]
36
- @detail = raw[:el_detail_data].to_ptr.get_bytes(0, length).freeze
43
+ @raw_detail = raw[:el_detail_data].to_ptr.get_bytes(0, length).freeze
37
44
  length = raw[:el_symptom_length]
38
- @symptom = raw[:el_symptom_data].to_ptr.get_bytes(0, length).freeze
45
+ @raw_symptom = raw[:el_symptom_data].to_ptr.get_bytes(0, length).freeze
39
46
  @dup_count = raw[:el_errdup][:ed_dupcount]
40
47
  @dup_time1 = Time.at(raw[:el_errdup][:ed_time1]).freeze
41
48
  @dup_time2 = Time.at(raw[:el_errdup][:ed_time2]).freeze
42
49
  @wparid = raw[:el_wparid].to_s.freeze
43
50
  end
51
+
52
+ def errpt
53
+ @errpt ||= %x(errpt -al#{@sequence}).freeze
54
+ end
55
+
56
+ def parse_errpt
57
+ unless @parsed
58
+ @detail, @symptom = errpt.match(PARSE_REGEX).captures
59
+ @detail ||= ''.freeze
60
+ @symptom ||= ''.freeze
61
+ @detail.freeze
62
+ @symptom.freeze
63
+ @parsed = true
64
+ end
65
+ end
66
+ def detail
67
+ parse_errpt unless @parsed
68
+ @detail
69
+ end
70
+ def symptom
71
+ parse_errpt unless @parsed
72
+ @symptom
73
+ end
44
74
  end
45
75
  end
46
76
  end
@@ -30,11 +30,10 @@ module AIX
30
30
  # operates as a cursor, so if you try to re-invoke one before it is
31
31
  # finished, the cursor will get reset, and you'll get jumbled results).
32
32
  # While one of these enumerators as active, trying to re-invoke one will
33
- # raise an EnumeratorError.
33
+ # raise an Errors::EnumeratorError.
34
34
  #
35
- # If you need to do complex matching, use the #match_* methods in here to
36
- # create Match objects to work with. You can see Match for more details as
37
- # to how to create those.
35
+ # If you need to do complex matching, use #match or ::match to build a match
36
+ # expression using a DSL.
38
37
  #
39
38
  # A simple example, showing how to get a list of all labels of all log
40
39
  # entries in forward order which contain the string 'KILL' in their label
@@ -47,19 +46,19 @@ module AIX
47
46
  # require 'aix/errlog'
48
47
  #
49
48
  # AIX::Errlog.open do |log|
50
- # log.forward_each(match: (
51
- # log.match_label.include?('KILL') & (
49
+ # log.forward_each(match: log.match {
50
+ # label.include?('KILL') & (
52
51
  # (
53
- # (log.match_sequence > 1000) &
54
- # (log.match_timestamp >= DateTime.new(2017, 1, 1)) &
55
- # (log.match_timestamp < DateTime.new(2017, 2, 1))
52
+ # (sequence > 1000) &
53
+ # (timestamp >= DateTime.new(2017, 1, 1)) &
54
+ # (timestamp < DateTime.new(2017, 2, 1))
56
55
  # ) | (
57
- # (log.match_sequence < 500) &
58
- # (log.match_timestamp >= DateTime.new(2016, 12, 1)) &
59
- # (log.match_timestamp < DateTime.new(2017, 1, 1))
56
+ # (sequence < 500) &
57
+ # (timestamp >= DateTime.new(2016, 12, 1)) &
58
+ # (timestamp < DateTime.new(2017, 1, 1))
60
59
  # )
61
60
  # )
62
- # )).map(&:label)
61
+ # }).map(&:label)
63
62
  # end
64
63
  #
65
64
  # Certainly, that looks a little complex, but it is a bit more efficient
@@ -156,7 +155,7 @@ module AIX
156
155
  # An active enumerator can not be nested within another active enumerator,
157
156
  # including the block form of this. If you invoke any of the #each_
158
157
  # methods while another has not finished and exited, you'll raise an
159
- # EnumeratorError. You can create an enumerator of one within the other,
158
+ # Errors::EnumeratorError. You can create an enumerator of one within the other,
160
159
  # as long as you don't activate it until the first one has exited.
161
160
  #
162
161
  # Warning: if the sequence does not exist (which is common when error logs
@@ -190,7 +189,7 @@ module AIX
190
189
  # An active enumerator can not be nested within another active enumerator,
191
190
  # including the block form of this. If you invoke any of the #each_
192
191
  # methods while another has not finished and exited, you'll raise an
193
- # EnumeratorError. You can create an enumerator of one within the other,
192
+ # Errors::EnumeratorError. You can create an enumerator of one within the other,
194
193
  # as long as you don't activate it until the first one has exited.
195
194
  #
196
195
  # Warning: if the sequence does not exist (which is common when error logs
@@ -208,129 +207,33 @@ module AIX
208
207
  end
209
208
 
210
209
  ##
211
- # Match convenience function. Gets a Leaf match for comparing against
212
- # sequence.
213
- def match_sequence
214
- Match.new(left: :sequence)
215
- end
216
- ##
217
- # Match convenience function. Gets a Leaf match for comparing against
218
- # label.
219
- def match_label
220
- Match.new(left: :label)
221
- end
222
- ##
223
- # Match convenience function. Gets a Leaf match for comparing against
224
- # timestamp.
225
- def match_timestamp
226
- Match.new(left: :timestamp)
227
- end
228
- ##
229
- # Match convenience function. Gets a Leaf match for comparing against
230
- # crcid.
231
- def match_crcid
232
- Match.new(left: :crcid)
233
- end
234
- ##
235
- # Match convenience function. Gets a Leaf match for comparing against
236
- # machineid.
237
- def match_machineid
238
- Match.new(left: :machineid)
239
- end
240
- ##
241
- # Match convenience function. Gets a Leaf match for comparing against
242
- # nodeid.
243
- def match_nodeid
244
- Match.new(left: :nodeid)
245
- end
246
- ##
247
- # Match convenience function. Gets a Leaf match for comparing against
248
- # class.
249
- def match_class
250
- Match.new(left: :class)
251
- end
252
- ##
253
- # Match convenience function. Gets a Leaf match for comparing against
254
- # type.
255
- def match_type
256
- Match.new(left: :type)
257
- end
258
- ##
259
- # Match convenience function. Gets a Leaf match for comparing against
260
- # resource.
261
- def match_resource
262
- Match.new(left: :resource)
263
- end
264
- ##
265
- # Match convenience function. Gets a Leaf match for comparing against
266
- # rclass.
267
- def match_rclass
268
- Match.new(left: :rclass)
269
- end
270
- ##
271
- # Match convenience function. Gets a Leaf match for comparing against
272
- # rtype.
273
- def match_rtype
274
- Match.new(left: :rtype)
275
- end
276
- ##
277
- # Match convenience function. Gets a Leaf match for comparing against
278
- # vpd_ibm.
279
- def match_vpd_ibm
280
- Match.new(left: :vpd_ibm)
281
- end
282
- ##
283
- # Match convenience function. Gets a Leaf match for comparing against
284
- # vpd_user.
285
- def match_vpd_user
286
- Match.new(left: :vpd_user)
287
- end
288
- ##
289
- # Match convenience function. Gets a Leaf match for comparing against in.
290
- def match_in
291
- Match.new(left: :in)
292
- end
293
- ##
294
- # Match convenience function. Gets a Leaf match for comparing against
295
- # connwhere.
296
- def match_connwhere
297
- Match.new(left: :connwhere)
298
- end
299
- ##
300
- # Match convenience function. Gets a Leaf match for comparing against
301
- # flag_err64.
302
- def match_flag_err64
303
- Match.new(left: :flag_err64)
304
- end
305
- ##
306
- # Match convenience function. Gets a Leaf match for comparing against
307
- # flag_errdup.
308
- def match_flag_errdup
309
- Match.new(left: :flag_errdup)
310
- end
311
- ##
312
- # Match convenience function. Gets a Leaf match for comparing against
313
- # detail_data.
314
- def match_detail_data
315
- Match.new(left: :detail_data)
316
- end
317
- ##
318
- # Match convenience function. Gets a Leaf match for comparing against
319
- # symptom_data.
320
- def match_symptom_data
321
- Match.new(left: :symptom_data)
322
- end
323
- ##
324
- # Match convenience function. Gets a Leaf match for comparing against
325
- # errdiag.
326
- def match_errdiag
327
- Match.new(left: :errdiag)
210
+ # Calls ::match
211
+ def match(&block)
212
+ Errlog.match(&block)
328
213
  end
214
+
329
215
  ##
330
- # Match convenience function. Gets a Leaf match for comparing against
331
- # wparid.
332
- def match_wparid
333
- Match.new(left: :wparid)
216
+ # Used to build a match expression using a DSL. This simply calls
217
+ # instance_eval on Match, so remember the semantics of block scope. If
218
+ # you have a local +sequence+ variable, for instance, you'll need to use
219
+ # an explicit self to escape that:
220
+ #
221
+ # [2] pry(main)> AIX::Errlog::Errlog.match { sequence }
222
+ # => #<AIX::Errlog::Match:0xeb32a4df @left=:sequence, @operator=nil, @right=nil>
223
+ # [3] pry(main)> sequence = 5
224
+ # => 5
225
+ # [4] pry(main)> AIX::Errlog::Errlog.match { sequence }
226
+ # => 5
227
+ # [5] pry(main)> AIX::Errlog::Errlog.match { self.sequence }
228
+ # => #<AIX::Errlog::Match:0xcb7d8c03 @left=:sequence, @operator=nil, @right=nil>
229
+ # [6] pry(main)> AIX::Errlog::Errlog.match { self.sequence > sequence }
230
+ # => #<AIX::Errlog::Match:0x7be0bbf5 @left=:sequence, @operator=:gt, @right=5>
231
+ #
232
+ # In any case, this function lets you use a block as a shortcut to call a
233
+ # bunch of public class methods on the Match class, in order to build
234
+ # complex match expressions, as shown in the summary of this class.
235
+ def self.match(&block)
236
+ Match.instance_eval(&block)
334
237
  end
335
238
 
336
239
  private
@@ -344,7 +247,7 @@ module AIX
344
247
  return if status == :done
345
248
  Errors.throw(status, "handle: #{@handle}, sequence: #{id}") unless status == :ok
346
249
 
347
- Entry.new(entry).freeze
250
+ Entry.new(entry)
348
251
  end
349
252
 
350
253
  ##
@@ -356,7 +259,7 @@ module AIX
356
259
  return if status == :done
357
260
  Errors.throw(status, "handle: #{@handle}, match: #{match}") unless status == :ok
358
261
 
359
- Entry.new(entry).freeze
262
+ Entry.new(entry)
360
263
  end
361
264
 
362
265
  ##
@@ -366,7 +269,7 @@ module AIX
366
269
  status = Lib.errlog_find_next(@handle, entry)
367
270
  return if status == :done
368
271
  Errors.throw(status, "handle: #{@handle}") unless status == :ok
369
- Entry.new(entry).freeze
272
+ Entry.new(entry)
370
273
  end
371
274
 
372
275
  ##
@@ -393,7 +296,7 @@ module AIX
393
296
  # An active enumerator can not be nested within another active enumerator,
394
297
  # including the block form of this. If you invoke any of the #each_
395
298
  # methods while another has not finished and exited, you'll raise an
396
- # EnumeratorError. You can create an enumerator of one within the other,
299
+ # Errors::EnumeratorError. You can create an enumerator of one within the other,
397
300
  # as long as you don't activate it until the first one has exited.
398
301
  #
399
302
  # Warning: if the sequence does not exist (which is common when error logs
@@ -9,8 +9,7 @@ module AIX
9
9
  # A class that is useful for building errlog matchers.
10
10
  #
11
11
  # You usually won't need to access this class directly; you'll be able to
12
- # create instances of it indirectly through the field accessors that are
13
- # available in Errlog.
12
+ # create instances of it indirectly through the use of Errlog::match
14
13
  #
15
14
  # You can build field matchers using the methods on the errlog and standard
16
15
  # logical operators, and there are standard conversions for certain things
@@ -18,18 +17,18 @@ module AIX
18
17
  # entries only in January 2018 with +FOO+ in the label somewhere, you cold
19
18
  # use a match like this with an Errlog instance.
20
19
  #
21
- # (
22
- # (errlog.match_timestamp >= DateTime.new(2018, 1, 1)) &
23
- # (errlog.match_timestamp < DateTime.new(2018, 2, 1)) &
24
- # errlog.match_label.include?('FOO')
25
- # )
20
+ # errlog.match {
21
+ # (timestamp >= DateTime.new(2018, 1, 1)) &
22
+ # (timestamp < DateTime.new(2018, 2, 1)) &
23
+ # label.include?('FOO')
24
+ # }
26
25
  #
27
26
  # It really is that easy. The rest of the magic is done for you behind the
28
27
  # scenes, as long as you follow the rules and know how to make these matches
29
28
  # in the C equivalent. Note that there must always be a Match on the left
30
29
  # side of all comparisons, so something like
31
30
  #
32
- # DateTime.new(2018, 1, 1) <= errlog.match_timestamp
31
+ # DateTime.new(2018, 1, 1) <= errlog.match{timestamp}
33
32
  #
34
33
  # is not possible.
35
34
  #
@@ -151,6 +150,132 @@ module AIX
151
150
  operator: :not,
152
151
  )
153
152
  end
153
+
154
+ ##
155
+ # Match convenience function. Gets a Leaf match for comparing against
156
+ # sequence.
157
+ def self.sequence
158
+ new(left: :sequence)
159
+ end
160
+ ##
161
+ # Match convenience function. Gets a Leaf match for comparing against
162
+ # label.
163
+ def self.label
164
+ new(left: :label)
165
+ end
166
+ ##
167
+ # Match convenience function. Gets a Leaf match for comparing against
168
+ # timestamp.
169
+ def self.timestamp
170
+ new(left: :timestamp)
171
+ end
172
+ ##
173
+ # Match convenience function. Gets a Leaf match for comparing against
174
+ # crcid.
175
+ def self.crcid
176
+ new(left: :crcid)
177
+ end
178
+ ##
179
+ # Match convenience function. Gets a Leaf match for comparing against
180
+ # machineid.
181
+ def self.machineid
182
+ new(left: :machineid)
183
+ end
184
+ ##
185
+ # Match convenience function. Gets a Leaf match for comparing against
186
+ # nodeid.
187
+ def self.nodeid
188
+ new(left: :nodeid)
189
+ end
190
+ ##
191
+ # Match convenience function. Gets a Leaf match for comparing against
192
+ # class.
193
+ def self.class
194
+ new(left: :class)
195
+ end
196
+ ##
197
+ # Match convenience function. Gets a Leaf match for comparing against
198
+ # type.
199
+ def self.type
200
+ new(left: :type)
201
+ end
202
+ ##
203
+ # Match convenience function. Gets a Leaf match for comparing against
204
+ # resource.
205
+ def self.resource
206
+ new(left: :resource)
207
+ end
208
+ ##
209
+ # Match convenience function. Gets a Leaf match for comparing against
210
+ # rclass.
211
+ def self.rclass
212
+ new(left: :rclass)
213
+ end
214
+ ##
215
+ # Match convenience function. Gets a Leaf match for comparing against
216
+ # rtype.
217
+ def self.rtype
218
+ new(left: :rtype)
219
+ end
220
+ ##
221
+ # Match convenience function. Gets a Leaf match for comparing against
222
+ # vpd_ibm.
223
+ def self.vpd_ibm
224
+ new(left: :vpd_ibm)
225
+ end
226
+ ##
227
+ # Match convenience function. Gets a Leaf match for comparing against
228
+ # vpd_user.
229
+ def self.vpd_user
230
+ new(left: :vpd_user)
231
+ end
232
+ ##
233
+ # Match convenience function. Gets a Leaf match for comparing against in.
234
+ def self.in
235
+ new(left: :in)
236
+ end
237
+ ##
238
+ # Match convenience function. Gets a Leaf match for comparing against
239
+ # connwhere.
240
+ def self.connwhere
241
+ new(left: :connwhere)
242
+ end
243
+ ##
244
+ # Match convenience function. Gets a Leaf match for comparing against
245
+ # flag_err64.
246
+ def self.flag_err64
247
+ new(left: :flag_err64)
248
+ end
249
+ ##
250
+ # Match convenience function. Gets a Leaf match for comparing against
251
+ # flag_errdup.
252
+ def self.flag_errdup
253
+ new(left: :flag_errdup)
254
+ end
255
+ ##
256
+ # Match convenience function. Gets a Leaf match for comparing against
257
+ # detail_data.
258
+ def self.detail_data
259
+ new(left: :detail_data)
260
+ end
261
+ ##
262
+ # Match convenience function. Gets a Leaf match for comparing against
263
+ # symptom_data.
264
+ def self.symptom_data
265
+ new(left: :symptom_data)
266
+ end
267
+ ##
268
+ # Match convenience function. Gets a Leaf match for comparing against
269
+ # errdiag.
270
+ def self.errdiag
271
+ new(left: :errdiag)
272
+ end
273
+ ##
274
+ # Match convenience function. Gets a Leaf match for comparing against
275
+ # wparid.
276
+ def self.wparid
277
+ new(left: :wparid)
278
+ end
154
279
  end
155
280
  end
156
281
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aix-errlog
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taylor C. Richberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-23 00:00:00.000000000 Z
11
+ date: 2018-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi