mirror of
https://github.com/xcat2/confluent.git
synced 2026-08-25 08:06:46 +00:00
Let nodeeventlog show one log rather than all of them
Every entry already says which log it came from, so -s narrows the output to the ones asked for and "-s list" names what a node offers. Some of what a platform keeps is noise: an AMI MegaRAC's event log is a list of redfish sessions being opened and closed, while its useful records are elsewhere. A selection cannot be cleared, since the platforms offer no such thing and clearing more than was asked for is not something to do quietly.
This commit is contained in:
@@ -53,7 +53,13 @@ argparser.add_option('-t', '--timeframe', type='string',
|
||||
'entries from the last hours or days. '
|
||||
'1h would be one hour, 4d would be four days. '
|
||||
'format <num>h or <num>d'
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
argparser.add_option('-s', '--source', type='string',
|
||||
help='only show entries from the named logs, comma '
|
||||
'delimited. "-s list" names the logs this node '
|
||||
'offers instead of showing entries')
|
||||
(options, args) = argparser.parse_args()
|
||||
try:
|
||||
noderange = args[0]
|
||||
@@ -72,6 +78,19 @@ if len(args) == 2:
|
||||
argparser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
listmode = bool(options.source) and options.source.lower() == 'list'
|
||||
wantsources = None
|
||||
if options.source and not listmode:
|
||||
wantsources = set(x.strip().lower() for x in options.source.split(',')
|
||||
if x.strip())
|
||||
if options.source and deletemode:
|
||||
# Clearing a subset is not something the platforms offer, and clearing more
|
||||
# than was asked for is not something to do quietly
|
||||
sys.stderr.write(
|
||||
'Clearing a selection of logs is not supported, so --source cannot be '
|
||||
'combined with clear\n')
|
||||
sys.exit(1)
|
||||
|
||||
session = client.Command()
|
||||
exitcode = 0
|
||||
|
||||
@@ -125,6 +144,7 @@ if options.timeframe:
|
||||
sys.exit(1)
|
||||
timeframe = dt.now() - tdelta
|
||||
|
||||
sources_seen = {}
|
||||
event_dict = {}
|
||||
nodes = []
|
||||
for res in session.read('/noderange/{0}/nodes/'.format(args[0])):
|
||||
@@ -145,6 +165,17 @@ for rsp in func('/noderange/{0}/events/hardware/log'.format(noderange)):
|
||||
exitcode |= 1
|
||||
if 'events' in thisdata:
|
||||
evtdata = thisdata['events']
|
||||
for evt in evtdata:
|
||||
if evt.get('log_id', None):
|
||||
sources_seen.setdefault(node, set()).add(evt['log_id'])
|
||||
if listmode:
|
||||
continue
|
||||
if wantsources is not None:
|
||||
# Filter before any tail is taken, or asking for the last
|
||||
# few entries of one log would answer with fewer
|
||||
evtdata = [x for x in evtdata if (x.get('log_id', '')
|
||||
or '').lower()
|
||||
in wantsources]
|
||||
if options.lines:
|
||||
event_dict[node].extend(evtdata)
|
||||
else:
|
||||
@@ -158,7 +189,24 @@ for rsp in func('/noderange/{0}/events/hardware/log'.format(noderange)):
|
||||
else:
|
||||
print('{0}: {1}'.format(node, format_event(evt)))
|
||||
|
||||
if options.lines:
|
||||
if listmode:
|
||||
for node in nodes:
|
||||
found = sorted(sources_seen.get(node, ()))
|
||||
if found:
|
||||
print('{0}: {1}'.format(node, ','.join(found)))
|
||||
else:
|
||||
sys.stderr.write(
|
||||
'No event log sources reported for "{0}"\n'.format(node))
|
||||
elif wantsources is not None:
|
||||
for node in nodes:
|
||||
found = set(x.lower() for x in sources_seen.get(node, ()))
|
||||
missing = wantsources - found
|
||||
if missing and found:
|
||||
sys.stderr.write('{0}: no such log source: {1}, this node has {2}\n'
|
||||
.format(node, ','.join(sorted(missing)),
|
||||
','.join(sorted(sources_seen[node]))))
|
||||
|
||||
if options.lines and not listmode:
|
||||
for node in nodes:
|
||||
evtdata_list = event_dict[node]
|
||||
if len(evtdata_list) != 0:
|
||||
|
||||
@@ -3,13 +3,23 @@ nodeeventlog(8) -- Pull eventlog from confluent nodes
|
||||
|
||||
## SYNOPSIS
|
||||
|
||||
`nodeeventlog [options] <noderange> [clear]`
|
||||
`nodeeventlog [options] [-s <sources>] <noderange> [clear]`
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
`nodeeventlog` pulls and optionally clears the event log from the requested
|
||||
noderange.
|
||||
|
||||
A platform may keep its events in more than one log, and some of those are
|
||||
noisier than others. Reading gathers every log the platform describes as an
|
||||
event log, wherever it keeps them, and `-s` narrows the output to the ones
|
||||
asked for. `-s list` names the logs a node offers rather than showing entries.
|
||||
|
||||
Clearing is deliberately narrower than reading: it only touches the logs the
|
||||
platform's own manager publishes, so a log that only a read reaches is never
|
||||
destroyed by one. A selection cannot be cleared, so `-s` and `clear` are
|
||||
refused together.
|
||||
|
||||
## OPTIONS
|
||||
|
||||
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
|
||||
@@ -25,10 +35,24 @@ noderange.
|
||||
entries from within the last one hour.
|
||||
|
||||
|
||||
* `-s SOURCES`, `--source=SOURCES`:
|
||||
only show entries from the named logs, comma delimited and matched without
|
||||
regard to case. `-s list` names the logs the node offers instead of showing
|
||||
entries. A platform that named a log "list" would be shadowed by that.
|
||||
|
||||
* `-h`, `--help`:
|
||||
Show help message and exit
|
||||
|
||||
## EXAMPLES
|
||||
* Ask which logs a node keeps:
|
||||
`# nodeeventlog n2 -s list`
|
||||
`n2: AuditLog,EventLog,Logs,SEL`
|
||||
|
||||
* Pull only the sel and the chassis log, leaving the audit noise out:
|
||||
`# nodeeventlog n2 -s SEL,Logs`
|
||||
`n2: 07/23/2026 13:03:12 SEL: Processor - Thermal Trip`
|
||||
`n2: 08/05/2026 04:30:26 Logs: PowerUnit - Power Off`
|
||||
|
||||
* Pull the event log from n2 and n3:
|
||||
`# nodeeventlog n2,n3`
|
||||
`n2: 05/03/2017 11:44:25 Event Log Disabled - SEL Fullness - Log clear`
|
||||
|
||||
Reference in New Issue
Block a user