From dc5f5f12e61a92b6eca78d0d9f1bd404f32c2580 Mon Sep 17 00:00:00 2001 From: Andrew Melton Date: Fri, 7 Jun 2013 13:34:26 -0400 Subject: [PATCH 1/3] Adding verifier detail to audit report --- reports/nova_usage_audit.py | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/reports/nova_usage_audit.py b/reports/nova_usage_audit.py index a87587e..61f749e 100644 --- a/reports/nova_usage_audit.py +++ b/reports/nova_usage_audit.py @@ -76,10 +76,10 @@ def _audit_launches_to_exists(launches, exists): if not found: msg = "Couldn't find exists for launch (%s, %s)" msg = msg % (instance, launch1['launched_at']) - fails.append([launch1['id'], msg]) + fails.append(['Launch', launch1['id'], msg]) else: msg = "No exists for instance (%s)" % instance - fails.append(['-', msg]) + fails.append(['Launch', '-', msg]) return fails @@ -130,7 +130,7 @@ def _audit_for_exists(exists_query): def _verifier_audit_for_period(beginning, ending): - report = {} + summary = {} filters = { 'audit_period_beginning': beginning, @@ -138,7 +138,7 @@ def _verifier_audit_for_period(beginning, ending): } periodic_exists = models.InstanceExists.objects.filter(**filters) - report['periodic'] = _audit_for_exists(periodic_exists) + summary['periodic'] = _audit_for_exists(periodic_exists) filters = { 'audit_period_beginning': beginning, @@ -146,9 +146,18 @@ def _verifier_audit_for_period(beginning, ending): } instant_exists = models.InstanceExists.objects.filter(**filters) - report['instantaneous'] = _audit_for_exists(instant_exists) + summary['instantaneous'] = _audit_for_exists(instant_exists) - return report + filters = { + 'audit_period_beginning': beginning, + 'audit_period_ending__lte': ending, + 'status': models.InstanceExists.FAILED + } + failed = models.InstanceExists.objects.filter(**filters) + detail = [] + for exist in failed: + detail.append(['Exist', exist.id, exist.fail_reason]) + return summary, detail def _launch_audit_for_period(beginning, ending): @@ -201,13 +210,14 @@ def audit_for_period(beginning, ending): beginning_decimal = dt.dt_to_decimal(beginning) ending_decimal = dt.dt_to_decimal(ending) - verifier_report = _verifier_audit_for_period(beginning_decimal, + (verify_summary, + verify_detail) = _verifier_audit_for_period(beginning_decimal, ending_decimal) detail, new_count, old_count = _launch_audit_for_period(beginning_decimal, ending_decimal) summary = { - 'verifier': verifier_report, + 'verifier': verify_summary, 'launch_fails': { 'total_failures': len(detail), 'new_launches': new_count, @@ -216,7 +226,8 @@ def audit_for_period(beginning, ending): } details = { - 'launch_fails': detail + 'exist_fails': verify_detail, + 'launch_fails': detail, } return summary, details @@ -251,7 +262,7 @@ def store_results(start, end, summary, details): 'created': dt.dt_to_decimal(datetime.datetime.utcnow()), 'period_start': start, 'period_end': end, - 'version': 1, + 'version': 2, 'name': 'nova usage audit' } @@ -261,7 +272,8 @@ def store_results(start, end, summary, details): def make_json_report(summary, details): report = [{'summary': summary}, - ['Launch ID', 'Error Description']] + ['Object', 'ID', 'Error Description']] + report.extend(details['exist_fails']) report.extend(details['launch_fails']) return json.dumps(report) From e244c02ea41616655816bc5172265ab25579987d Mon Sep 17 00:00:00 2001 From: Andrew Melton Date: Fri, 7 Jun 2013 15:10:48 -0400 Subject: [PATCH 2/3] Include disabled computes in usage seed --- util/usage_seed.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/util/usage_seed.py b/util/usage_seed.py index a33f8d9..d189701 100644 --- a/util/usage_seed.py +++ b/util/usage_seed.py @@ -20,7 +20,7 @@ """ Usage: python usage_seed.py [period_length] [sql_connection] - python usage_seed hour mysql://user:password@nova-db.example.com/nova?charset=utf8 + python usage_seed.py hour mysql://user:password@nova-db.example.com/nova?charset=utf8 The idea behind usage seeding is to take the current state of all active instances on active compute hosts and insert that data into @@ -49,7 +49,7 @@ if __name__ == '__main__': from nova.compute import task_states from nova.context import RequestContext from nova.db import api as novadb -from nova.db.sqlalchemy import api +from nova.db.sqlalchemy import api as sqlapi from nova.db.sqlalchemy import models as novamodels POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), @@ -115,20 +115,25 @@ def _delete_for_instance(instance): return delete -def get_active_instances(period_length): +def get_computes(): context = RequestContext('1', '1', is_admin=True) + return sqlapi.model_query(context, novamodels.Service, + read_deleted='no')\ + .filter_by(topic='compute').all() + + +def get_active_instances(period_length): start, end = get_previous_period(datetime.datetime.utcnow(), period_length) - session = api.get_session() - computes = novadb.service_get_all_by_topic(context, 'compute') + session = sqlapi.get_session() + computes = get_computes() active_instances = [] yesterday = datetime.datetime.utcnow() - datetime.timedelta(days=1) for compute in computes: if compute.updated_at > yesterday: query = session.query(novamodels.Instance) - - active_filter = api.or_(novamodels.Instance.terminated_at == None, - novamodels.Instance.terminated_at > start) - query = query.filter(active_filter) + active_filter = (novamodels.Instance.terminated_at == None, + novamodels.Instance.terminated_at > start) + query = query.filter(sqlapi.or_(*active_filter)) query = query.filter_by(host=compute.host) for instance in query.all(): From 918ba0aa2bfcf152b609dc78afb9f511b32d5a34 Mon Sep 17 00:00:00 2001 From: Andrew Melton Date: Tue, 11 Jun 2013 16:03:41 -0400 Subject: [PATCH 3/3] Rotating logs at midnight --- stacktach/stacklog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stacktach/stacklog.py b/stacktach/stacklog.py index b700c8c..9955751 100644 --- a/stacktach/stacklog.py +++ b/stacktach/stacklog.py @@ -33,7 +33,7 @@ def _make_logger(name): log = logging.getLogger(__name__) log.setLevel(logging.DEBUG) handler = logging.handlers.TimedRotatingFileHandler('%s.log' % name, - when='h', interval=6, backupCount=4) + when='midnight', interval=1, backupCount=3) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) log.addHandler(handler)