def write_to_ssm(extract, config): """forwards usage records to SSM""" # ensure outgoing directory existence ssm_input_path = os.path.expanduser(config['ssm_input_path']) if not os.access(ssm_input_path, os.F_OK): os.makedirs(ssm_input_path, 0755) # only write non void URs file if len(extract) > 0: output = config['ssm_input_header'] + "\n" # itterate over VMs for vmname in extract.keys(): logging.debug("generating ssm input file for VM %s" % vmname) for item in orderedFields: logging.debug("generating record %s: %s" % (item, extract[vmname][item])) output += "%s: %s\n" % (item, extract[vmname][item]) output += config['ssm_input_sep'] + "\n" # write file try: dirq = QueueSimple(ssm_input_path) dirq.add(output) except: logging.error('unable to push message in apel-ssm queue <%s>' % ssm_input_path) else: logging.debug('no usage records, skip forwarding to SSM')
def test11_purge_multDirMultElement(self): 'QueueSimple.purge() multiple directories & elements' qs = QueueSimple(self.qdir, granularity=1) qs.add('foo') assert qs.count() == 1 time.sleep(2) qs.add('bar') assert qs.count() == 2 assert len(os.listdir(self.qdir)) == 2 qs.purge() assert qs.count() == 2 elem = qs.first() qs.lock(elem) qs.remove(elem) assert qs.count() == 1 qs.purge() assert len(os.listdir(self.qdir)) == 1 time.sleep(2) qs.add('baz') assert len(os.listdir(self.qdir)) == 2 for elem in qs: qs.lock(elem) elem1 = qs.first() lock_path1 = self.qdir + '/' + elem1 + LOCKED_SUFFIX assert os.path.exists(lock_path1) is True os.utime(lock_path1, (time.time() - 25, time.time() - 25)) qs.purge(maxlock=10) assert os.path.exists(lock_path1) is False elem2 = qs.next() lock_path2 = self.qdir + '/' + elem2 + LOCKED_SUFFIX assert os.path.exists(lock_path2) is True
def test01_init(self): 'QueueSimple.__init__()' path = self.tempdir + '/aaa/bbb/ccc' granularity = 30 qs = QueueSimple(path, granularity=granularity) assert qs.path == path assert qs.granularity == granularity
def test07_get(self): 'QueueSimple.get()' data = 'foo'.encode() qs = QueueSimple(self.qdir) elem = qs.add(data) qs.lock(elem) self.assertEqual(qs.get(elem), data)
def check_dir(root): ''' Check the directory for incoming, outgoing, reject or accept directories. If they exist, check them for messages. ''' print '\nStarting message status script.' print 'Root directory: %s\n' % root queues = [] incoming = os.path.join(root, 'incoming') if os.path.isdir(incoming): queues.append(Queue(incoming, schema=QSCHEMA)) outgoing = os.path.join(root, 'outgoing') # outgoing uses QueueSimple, not Queue if os.path.isdir(outgoing): queues.append(QueueSimple(outgoing)) reject = os.path.join(root, 'reject') if os.path.isdir(reject): queues.append(Queue(reject, schema=QSCHEMA)) accept = os.path.join(root, 'accept') if os.path.isdir(accept): queues.append(Queue(accept, schema=QSCHEMA)) for q in queues: msgs, locked = check_queue(q) #check_empty_dirs(q) print ' Messages: %s' % msgs print ' Locked: %s\n' % locked if locked > 0: question = 'Unlock %s messages?' % locked if ask_user(question): clear_locks(q)
def __init__(self, dest, qpath, cert, key, api_version): """Initialize a Sender.""" self._cert = cert self._key = key self._outq = QueueSimple(qpath) self._dest = dest self._api_version = api_version
def __init__(self, db, qpath, inc_vos=None, exc_vos=None, local=False, withhold_dns=False): self._db = db outpath = os.path.join(qpath, "outgoing") self._msgq = QueueSimple(outpath) self._inc_vos = inc_vos self._exc_vos = exc_vos self._local = local self._withhold_dns = withhold_dns
def test08_count(self): 'QueueSimple.count()' qs = QueueSimple(self.qdir) # add "normal" element qs.add('foo') # simply add a file (fake element) into the elements directory fake_elem = os.listdir(self.qdir)[0] + '/' + 'foo.bar' open(self.qdir + '/' + fake_elem, 'w').write('') self.assertEqual(qs.count(), 1)
def test05_add_path(self): 'QueueSimple.add_path()' qs = QueueSimple(self.qdir) data = 'foo0oo' path = self.tempdir + '/foo.bar' open(path, 'w').write(data) elem = qs.add_path(path) assert open(self.qdir + '/' + elem).read() == data self.failIf(os.path.exists(path))
def test06_lock_unlock(self): 'QueueSimple.lock()' qs = QueueSimple(self.qdir) data = 'foo' elem_name = 'foo.bar' elem_full_path = self.qdir + '/' + elem_name open(elem_full_path, 'w').write(data) self.assertEqual(qs.lock(elem_name), 1) self.failUnless(os.path.exists(elem_full_path + LOCKED_SUFFIX)) qs.unlock(elem_name)
def test09_remove(self): 'QueueSimple.remove()' qs = QueueSimple(self.qdir, granularity=1) for _ in range(5): qs.add('foo') assert qs.count() == 5 for elem in qs: qs.lock(elem) qs.remove(elem) self.assertEqual(qs.count(), 0)
def test02_add_data(self): 'QueueSimple._add_data()' data = 'f0o' qs = QueueSimple(self.qdir) _subdirName, _fullFnOrig = qs._add_data(data) subdirs = os.listdir(self.qdir) assert len(subdirs) == 1 assert _subdirName == subdirs[0] subdir = self.qdir + '/' + subdirs[0] files = os.listdir(subdir) assert len(files) == 1 fn = subdir + '/' + files[0] assert _fullFnOrig == fn assert open(fn, 'r').read() == data
def test03_add_path(self): 'QueueSimple._add_path()' data = 'abc' qs = QueueSimple(self.qdir) _dir = 'elems' elems_dir = self.qdir + '/' + _dir os.mkdir(elems_dir) _tmpName = self.tempdir + '/elem.tmp' open(_tmpName, 'w').write(data) assert len(os.listdir(self.tempdir)) == 2 newName = qs._add_path(_tmpName, _dir) assert len(os.listdir(elems_dir)) == 1 assert len(os.listdir(self.tempdir)) == 1 assert open(self.qdir + '/' + newName).read() == data
def test10_purge_oneDirOneElement(self): 'QueueSimple.purge() one directory & element' qs = QueueSimple(self.qdir) qs.add('foo') self.assertEqual(qs.count(), 1) elem = qs.first() qs.lock(elem) elem_path_lock = self.qdir + '/' + elem + LOCKED_SUFFIX self.assert_(os.path.exists(elem_path_lock) is True) time.sleep(2) qs.purge(maxlock=1) self.assert_(os.path.exists(elem_path_lock) is False) self.assertEqual(qs.count(), 1) self.assertEqual(len(os.listdir(self.qdir)), 1)
def new_dirq(path, _schema): """Create a new Directory::Queue object, optionally with schema. """ kwargs = {} if opts.type == "simple": if opts.granularity is not None: kwargs['granularity'] = opts.granularity return QueueSimple(path, **kwargs) else: if _schema: schema = {'body': 'string', 'header': 'table?'} kwargs['schema'] = schema if opts.maxelts: kwargs['maxelts'] = opts.maxelts return queue.Queue(path, **kwargs)
def submit_state_change(job, transfer, transfer_state): """ Writes a state change message to the dirq """ msg_enabled = pylons.config.get('fts3.MonitoringMessaging', False) if not msg_enabled or msg_enabled.lower() == 'false': return publish_dn = pylons.config.get('fts3.MonitoringPublishDN', False) msg_dir = pylons.config.get('fts3.MessagingDirectory', '/var/lib/fts3') mon_dir = os.path.join(msg_dir, 'monitoring') _user_dn = job['user_dn'] if publish_dn else '' msg = dict( endpnt=pylons.config['fts3.Alias'], user_dn=_user_dn, src_url=transfer['source_surl'], dst_url=transfer['dest_surl'], vo_name=job['vo_name'], source_se=transfer['source_se'], dest_se=transfer['dest_se'], job_id=job['job_id'], file_id=transfer['file_id'], job_state=job['job_state'], file_state=transfer_state, retry_counter=0, retry_max=0, timestamp=time.time() * 1000, job_metadata=job['job_metadata'], file_metadata=transfer['file_metadata'], ) tmpfile = tempfile.NamedTemporaryFile(dir=msg_dir, delete=False) tmpfile.write("SS ") json.dump(msg, tmpfile) tmpfile.close() q = QueueSimple(path=mon_dir) q.add_path(tmpfile.name) log.debug("Sent SUBMITTED state for %s %d" % (job['job_id'], transfer['file_id']))
def run_queue_once(): from dirq.QueueSimple import QueueSimple dirq = QueueSimple(QDIR) dirq.purge(30,60) did_work = False for name in dirq: if not dirq.lock(name): continue data = dirq.get(name) log.debug("item: %s", data) item = json.loads(data) signal.alarm(15) queue_ts = item['ts'] start = time.time() try : block(item['ip'], item['comment'], item['duration']) except Exception as e: #Was this a whitelisted host or similarly invalid request #Versus a server error? if hasattr(e, 'response') and e.response is not None and e.response.status_code == 400 and 'non_field_errors' in e.response.json(): log.info("Ignored API Error %s", e.response.json()) else: text = e.response.text if hasattr(e, 'response') else '' log.exception("API Error. HTTP Response: %r", text) raise end = time.time() signal.alarm(0) dirq.remove(name) log.info("block ip=%s queue_latency=%0.2f api_latency=%0.2f", item['ip'], start-queue_ts, end-start) did_work = True return did_work
import codecs import time import datetime import csv from dirq.QueueSimple import QueueSimple from toolbox.cswaHelpers import * from common import cspace from common.utils import deURN from cspace_django_site.main import cspace_django_site MAINCONFIG = cspace_django_site.getConfig() DIRQ = QueueSimple('/tmp/cswa') MAXLOCATIONS = 1000 import xml.etree.ElementTree as etree def getWhen2Post(config): try: when2post = config.get('info', 'when2post') except: # default is update immediately when2post = 'update' return when2post
def __init__(self, hosts_and_ports, qpath, cert, key, dest=None, listen=None, capath=None, check_crls=False, use_ssl=False, username=None, password=None, enc_cert=None, verify_enc_cert=True, pidfile=None): ''' Creates an SSM2 object. If a listen value is supplied, this SSM2 will be a receiver. ''' self._conn = None self._last_msg = None self._brokers = hosts_and_ports self._cert = cert self._key = key self._enc_cert = enc_cert self._capath = capath self._check_crls = check_crls self._user = username self._pwd = password self._use_ssl = use_ssl # use pwd auth if we're supplied both user and pwd self._use_pwd = username is not None and password is not None self.connected = False self._listen = listen self._dest = dest self._valid_dns = [] self._pidfile = pidfile # create the filesystem queues for accepted and rejected messages if dest is not None and listen is None: self._outq = QueueSimple(qpath) elif listen is not None: inqpath = os.path.join(qpath, 'incoming') rejectqpath = os.path.join(qpath, 'reject') self._inq = Queue(inqpath, schema=Ssm2.QSCHEMA) self._rejectq = Queue(rejectqpath, schema=Ssm2.REJECT_SCHEMA) else: raise Ssm2Exception('SSM must be either producer or consumer.') # check that the cert and key match if not crypto.check_cert_key(self._cert, self._key): raise Ssm2Exception('Cert and key don\'t match.') # check the server certificate provided if enc_cert is not None: log.info('Messages will be encrypted using %s' % enc_cert) if not os.path.isfile(self._enc_cert): raise Ssm2Exception( 'Specified certificate file does not exist: %s.' % self._enc_cert) if verify_enc_cert: if not crypto.verify_cert_path(self._enc_cert, self._capath, self._check_crls): raise Ssm2Exception( 'Failed to verify server certificate %s against CA path %s.' % (self._enc_cert, self._capath))
def __init__(self, hosts_and_ports, qpath, cert, key, dest=None, listen=None, capath=None, check_crls=False, use_ssl=False, username=None, password=None, enc_cert=None, verify_enc_cert=True, pidfile=None, path_type='dirq', protocol=STOMP_MESSAGING, project=None, token=''): ''' Creates an SSM2 object. If a listen value is supplied, this SSM2 will be a receiver. ''' self._conn = None self._last_msg = None self._brokers = hosts_and_ports self._cert = cert self._key = key self._enc_cert = enc_cert self._capath = capath self._check_crls = check_crls self._user = username self._pwd = password self._use_ssl = use_ssl # use pwd auth if we're supplied both user and pwd self._use_pwd = username is not None and password is not None self.connected = False self._listen = listen self._dest = dest self._valid_dns = [] self._pidfile = pidfile # Used to differentiate between STOMP and AMS methods self._protocol = protocol # Used when interacting with an Argo Messaging Service self._project = project self._token = token if self._protocol == Ssm2.AMS_MESSAGING: self._ams = ArgoMessagingService(endpoint=self._brokers[0], token=self._token, cert=self._cert, key=self._key, project=self._project) # create the filesystem queues for accepted and rejected messages if dest is not None and listen is None: # Determine what sort of outgoing structure to make if path_type == 'dirq': if QueueSimple is None: raise ImportError("dirq path_type requested but the dirq " "module wasn't found.") self._outq = QueueSimple(qpath) elif path_type == 'directory': self._outq = MessageDirectory(qpath) else: raise Ssm2Exception('Unsupported path_type variable.') elif listen is not None: inqpath = os.path.join(qpath, 'incoming') rejectqpath = os.path.join(qpath, 'reject') # Receivers must use the dirq module, so make a quick sanity check # that dirq is installed. if Queue is None: raise ImportError("Receiving SSMs must use dirq, but the dirq " "module wasn't found.") self._inq = Queue(inqpath, schema=Ssm2.QSCHEMA) self._rejectq = Queue(rejectqpath, schema=Ssm2.REJECT_SCHEMA) else: raise Ssm2Exception('SSM must be either producer or consumer.') # check that the cert and key match if not crypto.check_cert_key(self._cert, self._key): raise Ssm2Exception('Cert and key don\'t match.') # Check that the certificate has not expired. if not crypto.verify_cert_date(self._cert): raise Ssm2Exception('Certificate %s has expired or will expire ' 'within a day.' % self._cert) # check the server certificate provided if enc_cert is not None: log.info('Messages will be encrypted using %s', enc_cert) if not os.path.isfile(self._enc_cert): raise Ssm2Exception( 'Specified certificate file does not exist: %s.' % self._enc_cert) # Check that the encyption certificate has not expired. if not crypto.verify_cert_date(enc_cert): raise Ssm2Exception( 'Encryption certificate %s has expired or will expire ' 'within a day. Please obtain the new one from the final ' 'server receiving your messages.' % enc_cert) if verify_enc_cert: if not crypto.verify_cert_path(self._enc_cert, self._capath, self._check_crls): raise Ssm2Exception( 'Failed to verify server certificate %s against CA path %s.' % (self._enc_cert, self._capath)) # If the overall SSM log level is info, we want to only # see entries from stomp.py and connectionpool at WARNING and above. if logging.getLogger("ssm.ssm2").getEffectiveLevel() == logging.INFO: logging.getLogger("stomp.py").setLevel(logging.WARNING) logging.getLogger( "requests.packages.urllib3.connectionpool").setLevel( logging.WARNING) # If the overall SSM log level is debug, we want to only # see entries from stomp.py and connectionpool at INFO above. elif logging.getLogger( "ssm.ssm2").getEffectiveLevel() == logging.DEBUG: logging.getLogger("stomp.py").setLevel(logging.INFO) logging.getLogger( "requests.packages.urllib3.connectionpool").setLevel( logging.INFO)
def process_period(config, period): period_start = period['instant'] + dateutil.relativedelta.relativedelta( seconds=-period['range_sec']) print( f"Processing year {period['year']}, month {period['month']}, " f"querying from {period['instant'].isoformat()} and going back {period['range_sec']} s to {period_start.isoformat()}." ) queries = QueryLogic(queryRange=(str(period['range_sec']) + 's')) # SSL generally not used for Prometheus access within a cluster # Docs on instant query API: https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries prom = PrometheusConnect(url=config.prometheus_server, disable_ssl=True) prom_connect_params = { 'time': period['instant'].isoformat(), 'timeout': config.query_timeout } raw_results, results, result_lengths = {}, {}, [] # iterate over each query (cputime, starttime, endtime, cores) producing raw_results['cputime'] etc. for query_name, query_string in vars(queries).items(): # Each of these raw_results is a list of dicts. Each dict in the list represents an individual data point, and contains: # 'metric': a dict of one or more key-value pairs of labels, one of which is the pod name ('exported_pod'). # 'value': a list in which the 0th element is the timestamp of the value, and 1th element is the actual value we're interested in. print(f'Executing {query_name} query: {query_string}') t1 = timer() raw_results[query_name] = prom.custom_query(query=query_string, params=prom_connect_params) t2 = timer() results[query_name] = dict(rearrange(raw_results[query_name])) result_lengths.append(len(results[query_name])) t3 = timer() print( f'Query finished in {t2 - t1} s, processed in {t3 - t2} s. Got {len(results[query_name])} items from {len(raw_results[query_name])} results. Peak RAM usage: {resource.getrusage(resource.RUSAGE_SELF).ru_maxrss}K.' ) del raw_results[query_name] cputime = results['cputime'] endtime = results['endtime'] starttime = results['starttime'] cores = results['cores'] # Confirm the assumption that cputime should have the fewest entries, while starttime and cores may have additional ones # corresponding to jobs that have started but not finished yet, and endtime may have additional ones if there are pods without CPU resource requests. # We only want the jobs for which all values are available: start time, end time, CPU request. # Note that jobs which started last month and finished this month will be properly included and accounted in this month. assert len(cputime) == min( result_lengths), "cputime should be the shortest list" # However, jobs that finished last month may show up in this month's data if they are still present on the cluster this month (in Completed state). # Exclude them by filtering with a lambda (since you can't pass an argument to a function object AFAIK). endtime = dict( filter(lambda x: x[1] >= datetime.datetime.timestamp(period_start), endtime.items())) # Prepare to iterate over jobs which meet all criteria. valid_jobs = cputime.keys() & endtime.keys() # avoid sending empty records if len(valid_jobs) == 0: print('No records to process.') return sum_cputime = 0 t4 = timer() for key in valid_jobs: assert endtime[key] > starttime[ key], "job end time is before start time" # double check cputime calc of this job delta = abs(cputime[key] - (endtime[key] - starttime[key]) * cores[key]) assert delta < 0.001, "cputime calculation is inaccurate" sum_cputime += cputime[key] # CPU time as calculated here means (# cores * job duration), which apparently corresponds to # the concept of wall time in APEL accounting. It is not clear what CPU time means in APEL; # could be the actual CPU usage % integrated over the job (# cores * job duration * usage) # but this does not seem to be documented clearly. Some batch systems do not actually measure # this so it is not reported consistently or accurately. Some sites have CPU efficiency # (presumably defined as CPU time / wall time) time that is up to ~ 500% of the walltime, or # always fixed at 100%. In Kubernetes, the actual CPU usage % is tracked by metrics server # (not KSM), which is not meant to be used for monitoring or accounting purposes and is not # scraped by Prometheus. So just use walltime = cputime sum_cputime = round(sum_cputime) sum_walltime = sum_cputime print(f'total cputime: {sum_cputime}, total walltime: {sum_walltime}') # Write output to the message queue on local filesystem # https://dirq.readthedocs.io/en/latest/queuesimple.html#directory-structure dirq = QueueSimple(str(config.output_path)) summary_output = summary_message( config, year=period['year'], month=period['month'], wall_time=sum_walltime, cpu_time=sum_cputime, n_jobs=len(endtime), # this appears faster than getting min/max during the dict iteration above first_end=round(min(endtime.values())), last_end=round(max(endtime.values()))) sync_output = sync_message(config, year=period['year'], month=period['month'], n_jobs=len(endtime)) t5 = timer() summary_file = dirq.add(summary_output) sync_file = dirq.add(sync_output) print(f'Analyzed {len(endtime)} records in {t5 - t4} s.') print(f'Writing summary record to {config.output_path}/{summary_file}:') print('--------------------------------\n' + summary_output + '--------------------------------') print(f'Writing sync record to {config.output_path}/{sync_file}:') print('--------------------------------\n' + sync_output + '--------------------------------')
def test04_add(self): 'QueueSimple.add()' data = 'foo bar' qs = QueueSimple(self.qdir) elem = qs.add(data) assert open(self.qdir + '/' + elem).read() == data
"""Tool to convert unloaded messages to loadable ones.""" from dirq.QueueSimple import QueueSimple from dirq.queue import Queue inpath = '/root/iris/messages' outpath = '/root/iris/messages/incoming' OUTQSCHEMA = {"body": "string", "signer": "string", "empaid": "string?", "error": "string?"} inq = QueueSimple(inpath) outq = Queue(outpath, schema=OUTQSCHEMA) for name in inq: if not inq.lock(name): continue data = inq.get(name) outq.add({'body': data, 'signer': 'iris', 'empaid': 'local'}) inq.remove(name)
from dirq.QueueSimple import QueueSimple from random import randint import time path = '/tmp/test' print("start consuming...") dirq = QueueSimple(path) done = 0 while True: for name in dirq: # print("element: %s %s" % (path, name)) if not dirq.lock(name): #print("couldn't lock: %s" % name) # name = dirq.next() continue element = dirq.get(name) #print(element.keys()) print("Body: \"%s\"" % element) if randint(1, 2) % 2: done += 1 dirq.remove(name) #print('Removed') else: dirq.unlock(name) #name = dirq.next() print("consumed %i elements" % done) total_left = dirq.count() print("elements left in the queue: %d" % total_left) time.sleep(0.5)
def queue(ip, comment, duration): from dirq.QueueSimple import QueueSimple dirq = QueueSimple(QDIR) rec = dict(ip=ip, comment=comment, duration=duration, ts=time.time()) dirq.add(json.dumps(rec)) return True
from time import sleep, time import datetime #from cswaUpdateCSpace import processqueueelement queue_dir = sys.argv[1] # sample producer # dirq = QueueSimple(queue_dir) # for count in range(1,101): # name = dirq.add("element %i\n" % count) # print("# added element %i as %s" % (count, name)) # sample consumer dirq = QueueSimple(queue_dir) passes = 0 items = 0 elapsedtime = time() logmessageinterval = 60 #seconds WHEN2POST = 'queue' while True: for name in dirq: if not dirq.lock(name): continue print("# reading element %s" % name) data = dirq.get(name) print data # one could use dirq.unlock(name) to only browse the queue... dirq.unlock(name)
def __init__(self, hosts_and_ports, qpath, cert, key, dest=None, listen=None, capath=None, check_crls=False, use_ssl=False, username=None, password=None, enc_cert=None, verify_enc_cert=True, pidfile=None): ''' Creates an SSM2 object. If a listen value is supplied, this SSM2 will be a receiver. ''' self._conn = None self._last_msg = None self._brokers = hosts_and_ports self._cert = cert self._key = key self._enc_cert = enc_cert self._capath = capath self._check_crls = check_crls self._user = username self._pwd = password self._use_ssl = use_ssl # use pwd auth if we're supplied both user and pwd self._use_pwd = username is not None and password is not None self.connected = False self._listen = listen self._dest = dest self._valid_dns = [] self._pidfile = pidfile # create the filesystem queues for accepted and rejected messages if dest is not None and listen is None: self._outq = QueueSimple(qpath) elif listen is not None: inqpath = os.path.join(qpath, 'incoming') rejectqpath = os.path.join(qpath, 'reject') self._inq = Queue(inqpath, schema=Ssm2.QSCHEMA) self._rejectq = Queue(rejectqpath, schema=Ssm2.REJECT_SCHEMA) else: raise Ssm2Exception('SSM must be either producer or consumer.') # check that the cert and key match if not crypto.check_cert_key(self._cert, self._key): raise Ssm2Exception('Cert and key don\'t match.') # Check that the certificate has not expired. if not crypto.verify_cert_date(self._cert): raise Ssm2Exception('Certificate %s has expired.' % self._cert) # check the server certificate provided if enc_cert is not None: log.info('Messages will be encrypted using %s', enc_cert) if not os.path.isfile(self._enc_cert): raise Ssm2Exception( 'Specified certificate file does not exist: %s.' % self._enc_cert) # Check that the encyption certificate has not expired. if not crypto.verify_cert_date(enc_cert): raise Ssm2Exception( 'Encryption certificate %s has expired. Please obtain the ' 'new one from the final server receiving your messages.' % enc_cert) if verify_enc_cert: if not crypto.verify_cert_path(self._enc_cert, self._capath, self._check_crls): raise Ssm2Exception( 'Failed to verify server certificate %s against CA path %s.' % (self._enc_cert, self._capath)) # If the overall SSM log level is info, we want to only # see log entries from stomp.py at the warning level and above. if logging.getLogger("ssm.ssm2").getEffectiveLevel() == logging.INFO: logging.getLogger("stomp.py").setLevel(logging.WARNING) # If the overall SSM log level is debug, we want to only # see log entries from stomp.py at the info level and above. elif logging.getLogger( "ssm.ssm2").getEffectiveLevel() == logging.DEBUG: logging.getLogger("stomp.py").setLevel(logging.INFO)