Revision 087f5520 lib/client/gnt_job.py
b/lib/client/gnt_job.py | ||
---|---|---|
286 | 286 |
@return: the desired exit code |
287 | 287 |
|
288 | 288 |
""" |
289 |
def format_msg(level, text): |
|
290 |
"""Display the text indented.""" |
|
291 |
ToStdout("%s%s", " " * level, text) |
|
292 |
|
|
293 |
def result_helper(value): |
|
294 |
"""Format a result field in a nice way.""" |
|
295 |
if isinstance(value, (tuple, list)): |
|
296 |
return "[%s]" % utils.CommaJoin(value) |
|
297 |
else: |
|
298 |
return str(value) |
|
299 |
|
|
300 | 289 |
selected_fields = [ |
301 | 290 |
"id", "status", "ops", "opresult", "opstatus", "oplog", |
302 | 291 |
"opstart", "opexec", "opend", "received_ts", "start_ts", "end_ts", |
... | ... | |
306 | 295 |
cl = GetClient() |
307 | 296 |
result = cl.Query(constants.QR_JOB, selected_fields, qfilter).data |
308 | 297 |
|
309 |
first = True
|
|
298 |
job_info_container = []
|
|
310 | 299 |
|
311 | 300 |
for entry in result: |
312 |
if not first: |
|
313 |
format_msg(0, "") |
|
314 |
else: |
|
315 |
first = False |
|
316 |
|
|
317 | 301 |
((_, job_id), (rs_status, status), (_, ops), (_, opresult), (_, opstatus), |
318 | 302 |
(_, oplog), (_, opstart), (_, opexec), (_, opend), (_, recv_ts), |
319 | 303 |
(_, start_ts), (_, end_ts)) = entry |
320 | 304 |
|
321 | 305 |
# Detect non-normal results |
322 | 306 |
if rs_status != constants.RS_NORMAL: |
323 |
format_msg(0, "Job ID %s not found" % job_id)
|
|
307 |
job_info_container.append("Job ID %s not found" % job_id)
|
|
324 | 308 |
continue |
325 | 309 |
|
326 |
format_msg(0, "Job ID: %s" % job_id) |
|
310 |
# Container for produced data |
|
311 |
job_info = [("Job ID", job_id)] |
|
312 |
|
|
327 | 313 |
if status in _USER_JOB_STATUS: |
328 | 314 |
status = _USER_JOB_STATUS[status] |
329 | 315 |
else: |
330 | 316 |
raise errors.ProgrammerError("Unknown job status code '%s'" % status) |
331 | 317 |
|
332 |
format_msg(1, "Status: %s" % status)
|
|
318 |
job_info.append(("Status", status))
|
|
333 | 319 |
|
334 | 320 |
if recv_ts is not None: |
335 |
format_msg(1, "Received: %s" % FormatTimestamp(recv_ts))
|
|
321 |
job_info.append(("Received", FormatTimestamp(recv_ts)))
|
|
336 | 322 |
else: |
337 |
format_msg(1, "Missing received timestamp (%s)" % str(recv_ts))
|
|
323 |
job_info.append(("Received", "unknown (%s)" % str(recv_ts)))
|
|
338 | 324 |
|
339 | 325 |
if start_ts is not None: |
340 | 326 |
if recv_ts is not None: |
... | ... | |
342 | 328 |
delta = " (delta %.6fs)" % d1 |
343 | 329 |
else: |
344 | 330 |
delta = "" |
345 |
format_msg(1, "Processing start: %s%s" %
|
|
346 |
(FormatTimestamp(start_ts), delta))
|
|
331 |
job_info.append(("Processing start", "%s%s" %
|
|
332 |
(FormatTimestamp(start_ts), delta)))
|
|
347 | 333 |
else: |
348 |
format_msg(1, "Processing start: unknown (%s)" % str(start_ts))
|
|
334 |
job_info.append(("Processing start", "unknown (%s)" % str(start_ts)))
|
|
349 | 335 |
|
350 | 336 |
if end_ts is not None: |
351 | 337 |
if start_ts is not None: |
... | ... | |
353 | 339 |
delta = " (delta %.6fs)" % d2 |
354 | 340 |
else: |
355 | 341 |
delta = "" |
356 |
format_msg(1, "Processing end: %s%s" %
|
|
357 |
(FormatTimestamp(end_ts), delta))
|
|
342 |
job_info.append(("Processing end", "%s%s" %
|
|
343 |
(FormatTimestamp(end_ts), delta)))
|
|
358 | 344 |
else: |
359 |
format_msg(1, "Processing end: unknown (%s)" % str(end_ts))
|
|
345 |
job_info.append(("Processing end", "unknown (%s)" % str(end_ts)))
|
|
360 | 346 |
|
361 | 347 |
if end_ts is not None and recv_ts is not None: |
362 | 348 |
d3 = end_ts[0] - recv_ts[0] + (end_ts[1] - recv_ts[1]) / 1000000.0 |
363 |
format_msg(1, "Total processing time: %.6f seconds" % d3)
|
|
349 |
job_info.append(("Total processing time", "%.6f seconds" % d3))
|
|
364 | 350 |
else: |
365 |
format_msg(1, "Total processing time: N/A") |
|
366 |
format_msg(1, "Opcodes:") |
|
351 |
job_info.append(("Total processing time", "N/A")) |
|
352 |
|
|
353 |
opcode_container = [] |
|
367 | 354 |
for (opcode, result, status, log, s_ts, x_ts, e_ts) in \ |
368 | 355 |
zip(ops, opresult, opstatus, oplog, opstart, opexec, opend): |
369 |
format_msg(2, "%s" % opcode["OP_ID"]) |
|
370 |
format_msg(3, "Status: %s" % status) |
|
356 |
opcode_info = [] |
|
357 |
opcode_info.append(("Opcode", opcode["OP_ID"])) |
|
358 |
opcode_info.append(("Status", status)) |
|
359 |
|
|
371 | 360 |
if isinstance(s_ts, (tuple, list)): |
372 |
format_msg(3, "Processing start: %s" % FormatTimestamp(s_ts))
|
|
361 |
opcode_info.append(("Processing start", FormatTimestamp(s_ts)))
|
|
373 | 362 |
else: |
374 |
format_msg(3, "No processing start time") |
|
363 |
opcode_info.append(("Processing start", "N/A")) |
|
364 |
|
|
375 | 365 |
if isinstance(x_ts, (tuple, list)): |
376 |
format_msg(3, "Execution start: %s" % FormatTimestamp(x_ts))
|
|
366 |
opcode_info.append(("Execution start", FormatTimestamp(x_ts)))
|
|
377 | 367 |
else: |
378 |
format_msg(3, "No execution start time") |
|
368 |
opcode_info.append(("Execution start", "N/A")) |
|
369 |
|
|
379 | 370 |
if isinstance(e_ts, (tuple, list)): |
380 |
format_msg(3, "Processing end: %s" % FormatTimestamp(e_ts))
|
|
371 |
opcode_info.append(("Processing end", FormatTimestamp(e_ts)))
|
|
381 | 372 |
else: |
382 |
format_msg(3, "No processing end time") |
|
383 |
format_msg(3, "Input fields:") |
|
384 |
for key in utils.NiceSort(opcode.keys()): |
|
385 |
if key == "OP_ID": |
|
386 |
continue |
|
387 |
val = opcode[key] |
|
388 |
if isinstance(val, (tuple, list)): |
|
389 |
val = ",".join([str(item) for item in val]) |
|
390 |
format_msg(4, "%s: %s" % (key, val)) |
|
391 |
if result is None: |
|
392 |
format_msg(3, "No output data") |
|
393 |
elif isinstance(result, (tuple, list)): |
|
394 |
if not result: |
|
395 |
format_msg(3, "Result: empty sequence") |
|
396 |
else: |
|
397 |
format_msg(3, "Result:") |
|
398 |
for elem in result: |
|
399 |
format_msg(4, result_helper(elem)) |
|
400 |
elif isinstance(result, dict): |
|
401 |
if not result: |
|
402 |
format_msg(3, "Result: empty dictionary") |
|
403 |
else: |
|
404 |
format_msg(3, "Result:") |
|
405 |
for key, val in result.iteritems(): |
|
406 |
format_msg(4, "%s: %s" % (key, result_helper(val))) |
|
407 |
else: |
|
408 |
format_msg(3, "Result: %s" % result) |
|
409 |
format_msg(3, "Execution log:") |
|
373 |
opcode_info.append(("Processing end", "N/A")) |
|
374 |
|
|
375 |
opcode_info.append(("Input fields", opcode)) |
|
376 |
opcode_info.append(("Result", result)) |
|
377 |
|
|
378 |
exec_log_container = [] |
|
410 | 379 |
for serial, log_ts, log_type, log_msg in log: |
411 | 380 |
time_txt = FormatTimestamp(log_ts) |
412 | 381 |
encoded = FormatLogMessage(log_type, log_msg) |
413 |
format_msg(4, "%s:%s:%s %s" % (serial, time_txt, log_type, encoded)) |
|
382 |
|
|
383 |
# Arranged in this curious way to preserve the brevity for multiple |
|
384 |
# logs. This content cannot be exposed as a 4-tuple, as time contains |
|
385 |
# the colon, causing some YAML parsers to fail. |
|
386 |
exec_log_info = [("Time", time_txt), |
|
387 |
("Content", (serial, log_type, encoded,)), |
|
388 |
] |
|
389 |
exec_log_container.append(exec_log_info) |
|
390 |
opcode_info.append(("Execution log", exec_log_container)) |
|
391 |
|
|
392 |
opcode_container.append(opcode_info) |
|
393 |
|
|
394 |
job_info.append(("Opcodes", opcode_container)) |
|
395 |
job_info_container.append(job_info) |
|
396 |
|
|
397 |
PrintGenericInfo(job_info_container) |
|
398 |
|
|
414 | 399 |
return 0 |
415 | 400 |
|
416 | 401 |
|
Also available in: Unified diff