ADCT Python
Python client API implementation for publishing ADCT data
Loading...
Searching...
No Matches
Classes | Functions
ldms_blob_file_to_http_post Namespace Reference

Classes

class  Blob
 
class  BlobReader
 
class  BlobScanner
 
class  PostFilter
 
class  Readline0
 

Functions

 readline0 (typing.Union[typing.BinaryIO, int] file_=sys.stdin.buffer, bytes separator=b'\0', int blocksize=2 **16)
 
 process_file (fn, url, completed_dir, retry_dir, error_dir, log_dir, retry, validate)
 
 handle_request_status (returned_data)
 
 main ()
 

Function Documentation

◆ handle_request_status()

ldms_blob_file_to_http_post.handle_request_status (   returned_data)
385def handle_request_status(returned_data):
386 status_code = returned_data.status_code
387 if status_code < 200 or status_code > 300:
388 logger.error(f"Status Code: {status_code}, Message: {returned_data.raw}")
389 raise HttpStatusCodeError(status_code)
390 logger.info(f"Posting successful with status Code: {status_code}")
391
392

◆ main()

ldms_blob_file_to_http_post.main ( )
519def main():
520 parser = argparse.ArgumentParser(description="Generate ADC web posts from ldms json stream files.")
521 parser.add_argument("--url", default=None, help="where to post messages (or full path for debug output)")
522 try:
523 parser.add_argument("--validate", default=False, help="verify input is well-formed json before posting", action=argparse.BooleanOptionalAction)
524 parser.add_argument("--retry", default=False, help="whether to publish the retry indices found in retry-dir files instead of all indices", action=argparse.BooleanOptionalAction)
525 except:
526 print("Need python with argparse.BooleanOptionalAction; usually py >= 3.9")
527 return 1
528 parser.add_argument("--completed-dir", default=None, help="where to put index numbers of messages that the server accepted that were not json.")
529 parser.add_argument("--retry-dir", default=None, help="where to put index numbers and files of json messages the server was unavailable for or unhappy with.")
530 parser.add_argument("--error-dir", default=None, help="where to log index numbers of json messages that provoked errors")
531 parser.add_argument("--log-dir", default=None, help="log file directory")
532 parser.add_argument('files', nargs='+')
533 args = parser.parse_args()
534 if args.retry:
535 print("ERROR: retry not implemented yet")
536 sys.exit(1)
537 if args.completed_dir and not os.path.isdir(args.completed_dir):
538 print("ERROR: completed-dir %s missing" % args.completed_dir)
539 sys.exit(1)
540 if args.retry_dir and not os.path.isdir(args.retry_dir):
541 print("ERROR: retry-dir %s is missing" % args.retry_dir)
542 sys.exit(1)
543 if args.error_dir and not os.path.isdir(args.error_dir):
544 print("ERROR: error-dir %s is missing" % args.error_dir)
545 sys.exit(1)
546 if args.log_dir and not os.path.isdir(args.log_dir):
547 print("ERROR: log-dir %s is missing" % args.log_dir)
548 sys.exit(1)
549 for f in args.files:
550 if args.validate:
551 print("with validation");
552 print("Processing " + f)
553 if not args.completed_dir:
554 compdir = os.path.join(os.path.dirname(f),"COMPLETED")
555 else:
556 compdir = args.completed_dir
557 if not args.retry_dir:
558 retdir = os.path.join(os.path.dirname(f),"RETRY")
559 else:
560 retdir = args.retry_dir
561 # Given the output naming conventions, retdir, compdir can be the same, though this might
562 # make future glob processing really slow.
563 # files cannot be processed in place unless it is a retry run (which is not yet implemented)
564 maxerr = process_file(f, args.url, compdir, retdir, args.error_dir, args.log_dir, args.retry, args.validate)
565 if maxerr < 2:
566 print("Processed {}".format(f))
567 else:
568 print("Retry maybe needed for {} in {}: maxerr {}".format(os.path.basename(f), retdir, maxerr))
569
570 return 0
571

◆ process_file()

ldms_blob_file_to_http_post.process_file (   fn,
  url,
  completed_dir,
  retry_dir,
  error_dir,
  log_dir,
  retry,
  validate 
)
 @return maximum error code seen in add function calls. if > 1,
file retry later may be useful.
318def process_file(fn, url, completed_dir, retry_dir, error_dir, log_dir, retry, validate):
319 """ @return maximum error code seen in add function calls. if > 1,
320 file retry later may be useful."""
321 br = BlobReader(fn)
322 pf = PostFilter(br, url, completed_dir, retry_dir, error_dir, log_dir, validate)
323 if br.timing:
324 print("total timing: %d " % (len(br.timing)//2))
325 # print("%g %s" % (0, br.timing[0]+1e-6*br.timing[1]))
326 # print("%g %s" % (-1, br.timing[-4]+1e-6*br.timing[-3]))
327 if br.offset:
328 print("total offsets: %d " % len(br.offset))
329 # print("%d %s" % (0, br.offset[0]))
330 # print("%d %s" % (-1, br.offset[-1]))
331 if br.stype:
332 print("total types: %d " % len(br.stype))
333 # print("%d %c" % (0, br.stype[0]))
334 # print("%d %c" % (-1, br.stype[-1]))
335 if len(br.blobs):
336 print("total blobs: %d " % (len(br.blobs)))
337 # print("%d %s" % (0, br.blobs[0]))
338 # print("%d %s" % (-1, br.blobs[-1]))
339 nb = len(br.blobs)
340 if br.timing and len(br.timing)//2 != nb:
341 print("timing data %d not same size as blobs %d" % (len(br.timing)//2, nb))
342 if br.offset and len(br.offset) != nb:
343 print("offset data %d not same size as blobs %d" % (len(br.offset), nb))
344 if br.stype and len(br.stype) != nb:
345 print("type data %d not same size as blobs %d" % (len(br.stype), nb))
346 #
347 maxerr = 0
348 result = 0
349 lineno = 0
350 for i in range(0, len(br.blobs)):
351 lineno = 0
352 try:
353 bl = br.blobs[i]
354 if br.stype and i < len(br.stype):
355 t = br.stype[i]
356 else:
357 # halfassed check for json string
358 if bl[0] == '{' and bl[-1] == '}':
359 t = 'j'
360 else:
361 t = 's'
362 if br.timing:
363 try:
364 ts = (br.timing[2*i], br.timing[2*i +1])
365 except:
366 ts = (int(br.filetime), 0)
367 else:
368 ts = (int(br.filetime), 0)
369 b = Blob(i, bl, ts, t)
370 result = pf.add(b)
371 if result > maxerr:
372 maxerr = result
373 except Exception as error:
374 print("Unable to process blob ", str(i), " ", type(error).__name__, "-", error)
375 traceback.print_exception(error)
376 print("Blob: ",bl)
377 # relocate file
378 if maxerr < 2:
379 pf.move_files(fn, completed_dir, "DONE") ; # either completed or unpostable
380 else:
381 pf.move_files(fn, retry_dir, "RETRY")
382 pf.finish()
383 return maxerr
384

◆ readline0()

ldms_blob_file_to_http_post.readline0 ( typing.Union[typing.BinaryIO, int]   file_ = sys.stdin.buffer,
bytes   separator = b'\0',
int   blocksize = 2 ** 16 
)
Instantiate Readline0 class and yield what we get back.

file_ defaults to sys.stdin, separator defaults to a null, and blocksize defaults to 64K.
71def readline0(file_: typing.Union[typing.BinaryIO, int] = sys.stdin.buffer, separator: bytes = b'\0', blocksize: int = 2 ** 16):
72 # pylint: disable=W1401
73 # W1401: We really do want a null byte
74 """
75 Instantiate Readline0 class and yield what we get back.
76
77 file_ defaults to sys.stdin, separator defaults to a null, and blocksize defaults to 64K.
78 """
79 readline0_obj = Readline0(file_, separator, blocksize)
80 # FIXME: This should become a yield from eventually.
81 for line in readline0_obj.sequence():
82 yield line
83
84