Switch to using an aggregated logs query and infinite scrolling
This should allow users to work with large logs set. Fixes #294
This commit is contained in:
parent
572d6ba53c
commit
3d6c92901c
15 changed files with 270 additions and 99 deletions
|
@ -14,6 +14,7 @@ from data import model
|
|||
from auth import scopes
|
||||
from app import avatar
|
||||
|
||||
LOGS_PER_PAGE = 500
|
||||
|
||||
def log_view(log):
|
||||
view = {
|
||||
|
@ -33,8 +34,16 @@ def log_view(log):
|
|||
|
||||
return view
|
||||
|
||||
def aggregated_log_view(log):
|
||||
view = {
|
||||
'kind': log.kind.name,
|
||||
'count': log.count,
|
||||
'datetime': format_date(log.datetime)
|
||||
}
|
||||
|
||||
def get_logs(start_time, end_time, performer_name=None, repository=None, namespace=None):
|
||||
return view
|
||||
|
||||
def _validate_logs_arguments(start_time, end_time, performer_name):
|
||||
performer = None
|
||||
if performer_name:
|
||||
performer = model.user.get_user(performer_name)
|
||||
|
@ -58,12 +67,31 @@ def get_logs(start_time, end_time, performer_name=None, repository=None, namespa
|
|||
if not end_time:
|
||||
end_time = datetime.today()
|
||||
|
||||
return (start_time, end_time, performer)
|
||||
|
||||
|
||||
def get_logs(start_time, end_time, performer_name=None, repository=None, namespace=None, page=None):
|
||||
(start_time, end_time, performer) = _validate_logs_arguments(start_time, end_time, performer_name)
|
||||
page = page if page else 1
|
||||
logs = model.log.list_logs(start_time, end_time, performer=performer, repository=repository,
|
||||
namespace=namespace)
|
||||
namespace=namespace, page=page, count=LOGS_PER_PAGE + 1)
|
||||
|
||||
return {
|
||||
'start_time': format_date(start_time),
|
||||
'end_time': format_date(end_time),
|
||||
'logs': [log_view(log) for log in logs]
|
||||
'logs': [log_view(log) for log in logs[0:LOGS_PER_PAGE]],
|
||||
'page': page,
|
||||
'has_additional': len(logs) > LOGS_PER_PAGE,
|
||||
}
|
||||
|
||||
def get_aggregate_logs(start_time, end_time, performer_name=None, repository=None, namespace=None):
|
||||
(start_time, end_time, performer) = _validate_logs_arguments(start_time, end_time, performer_name)
|
||||
|
||||
aggregated_logs = model.log.get_aggregated_logs(start_time, end_time, performer=performer,
|
||||
repository=repository, namespace=namespace)
|
||||
|
||||
return {
|
||||
'aggregated': [aggregated_log_view(log) for log in aggregated_logs]
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,6 +104,7 @@ class RepositoryLogs(RepositoryParamResource):
|
|||
@parse_args
|
||||
@query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('page', 'The page number for the logs', type=int, default=1)
|
||||
def get(self, args, namespace, repository):
|
||||
""" List the logs for the specified repository. """
|
||||
repo = model.repository.get_repository(namespace, repository)
|
||||
|
@ -84,7 +113,7 @@ class RepositoryLogs(RepositoryParamResource):
|
|||
|
||||
start_time = args['starttime']
|
||||
end_time = args['endtime']
|
||||
return get_logs(start_time, end_time, repository=repo, namespace=namespace)
|
||||
return get_logs(start_time, end_time, repository=repo, page=args['page'])
|
||||
|
||||
|
||||
@resource('/v1/user/logs')
|
||||
|
@ -97,6 +126,7 @@ class UserLogs(ApiResource):
|
|||
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('performer', 'Username for which to filter logs.', type=str)
|
||||
@query_param('page', 'The page number for the logs', type=int, default=1)
|
||||
def get(self, args):
|
||||
""" List the logs for the current user. """
|
||||
performer_name = args['performer']
|
||||
|
@ -104,7 +134,8 @@ class UserLogs(ApiResource):
|
|||
end_time = args['endtime']
|
||||
|
||||
user = get_authenticated_user()
|
||||
return get_logs(start_time, end_time, performer_name=performer_name, namespace=user.username)
|
||||
return get_logs(start_time, end_time, performer_name=performer_name, namespace=user.username,
|
||||
page=args['page'])
|
||||
|
||||
|
||||
@resource('/v1/organization/<orgname>/logs')
|
||||
|
@ -117,6 +148,7 @@ class OrgLogs(ApiResource):
|
|||
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('performer', 'Username for which to filter logs.', type=str)
|
||||
@query_param('page', 'The page number for the logs', type=int, default=1)
|
||||
@require_scope(scopes.ORG_ADMIN)
|
||||
def get(self, args, orgname):
|
||||
""" List the logs for the specified organization. """
|
||||
|
@ -126,6 +158,73 @@ class OrgLogs(ApiResource):
|
|||
start_time = args['starttime']
|
||||
end_time = args['endtime']
|
||||
|
||||
return get_logs(start_time, end_time, namespace=orgname, performer_name=performer_name)
|
||||
return get_logs(start_time, end_time, namespace=orgname, performer_name=performer_name,
|
||||
page=args['page'])
|
||||
|
||||
raise Unauthorized()
|
||||
|
||||
|
||||
@resource('/v1/repository/<repopath:repository>/aggregatelogs')
|
||||
@path_param('repository', 'The full path of the repository. e.g. namespace/name')
|
||||
class RepositoryAggregateLogs(RepositoryParamResource):
|
||||
""" Resource for fetching aggregated logs for the specific repository. """
|
||||
@require_repo_admin
|
||||
@nickname('getAggregateRepoLogs')
|
||||
@parse_args
|
||||
@query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str)
|
||||
def get(self, args, namespace, repository):
|
||||
""" Returns the aggregated logs for the specified repository. """
|
||||
repo = model.repository.get_repository(namespace, repository)
|
||||
if not repo:
|
||||
raise NotFound()
|
||||
|
||||
start_time = args['starttime']
|
||||
end_time = args['endtime']
|
||||
return get_aggregate_logs(start_time, end_time, repository=repo)
|
||||
|
||||
|
||||
@resource('/v1/user/aggregatelogs')
|
||||
@internal_only
|
||||
class UserAggregateLogs(ApiResource):
|
||||
""" Resource for fetching aggregated logs for the current user. """
|
||||
@require_user_admin
|
||||
@nickname('getAggregateUserLogs')
|
||||
@parse_args
|
||||
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('performer', 'Username for which to filter logs.', type=str)
|
||||
def get(self, args):
|
||||
""" Returns the aggregated logs for the current user. """
|
||||
performer_name = args['performer']
|
||||
start_time = args['starttime']
|
||||
end_time = args['endtime']
|
||||
|
||||
user = get_authenticated_user()
|
||||
return get_aggregate_logs(start_time, end_time, performer_name=performer_name,
|
||||
namespace=user.username)
|
||||
|
||||
|
||||
@resource('/v1/organization/<orgname>/aggregatelogs')
|
||||
@path_param('orgname', 'The name of the organization')
|
||||
@related_user_resource(UserLogs)
|
||||
class OrgAggregateLogs(ApiResource):
|
||||
""" Resource for fetching aggregate logs for the entire organization. """
|
||||
@nickname('getAggregateOrgLogs')
|
||||
@parse_args
|
||||
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
|
||||
@query_param('performer', 'Username for which to filter logs.', type=str)
|
||||
@require_scope(scopes.ORG_ADMIN)
|
||||
def get(self, args, orgname):
|
||||
""" Gets the aggregated logs for the specified organization. """
|
||||
permission = AdministerOrganizationPermission(orgname)
|
||||
if permission.can():
|
||||
performer_name = args['performer']
|
||||
start_time = args['starttime']
|
||||
end_time = args['endtime']
|
||||
|
||||
return get_aggregate_logs(start_time, end_time, namespace=orgname,
|
||||
performer_name=performer_name)
|
||||
|
||||
raise Unauthorized()
|
||||
|
|
Reference in a new issue