Commit 6b52f2a5 authored by Daniele Venzano's avatar Daniele Venzano

Remove service logs API

parent 8ba4ccd3
...@@ -23,7 +23,6 @@ import zoe_api.master_api ...@@ -23,7 +23,6 @@ import zoe_api.master_api
import zoe_lib.applications import zoe_lib.applications
import zoe_lib.exceptions import zoe_lib.exceptions
import zoe_lib.state import zoe_lib.state
from zoe_lib.swarm_client import SwarmClient
from zoe_lib.config import get_conf from zoe_lib.config import get_conf
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -124,18 +123,6 @@ class APIEndpoint: ...@@ -124,18 +123,6 @@ class APIEndpoint:
ret = [s for s in services if s.user_id == uid or role == 'admin'] ret = [s for s in services if s.user_id == uid or role == 'admin']
return ret return ret
def service_logs(self, uid, role, service_id):
"""Retrieve the logs for the given service."""
service = self.sql.service_list(id=service_id, only_one=True)
if service is None:
raise zoe_api.exceptions.ZoeNotFoundException('No such service')
if service.user_id != uid and role != 'admin':
raise zoe_api.exceptions.ZoeAuthException()
if service.backend_id is None:
raise zoe_api.exceptions.ZoeNotFoundException('Container is not running')
swarm = SwarmClient(get_conf())
return swarm.logs(service.docker_id, stream)
def statistics_scheduler(self, uid_, role_): def statistics_scheduler(self, uid_, role_):
"""Retrieve statistics about the scheduler.""" """Retrieve statistics about the scheduler."""
success, message = self.master.scheduler_statistics() success, message = self.master.scheduler_statistics()
......
...@@ -22,7 +22,7 @@ import tornado.web ...@@ -22,7 +22,7 @@ import tornado.web
from zoe_api.rest_api.execution import ExecutionAPI, ExecutionCollectionAPI, ExecutionDeleteAPI from zoe_api.rest_api.execution import ExecutionAPI, ExecutionCollectionAPI, ExecutionDeleteAPI
from zoe_api.rest_api.info import InfoAPI from zoe_api.rest_api.info import InfoAPI
from zoe_api.rest_api.userinfo import UserInfoAPI from zoe_api.rest_api.userinfo import UserInfoAPI
from zoe_api.rest_api.service import ServiceAPI, ServiceLogsAPI from zoe_api.rest_api.service import ServiceAPI
from zoe_api.rest_api.discovery import DiscoveryAPI from zoe_api.rest_api.discovery import DiscoveryAPI
from zoe_api.rest_api.statistics import SchedulerStatsAPI from zoe_api.rest_api.statistics import SchedulerStatsAPI
from zoe_api.rest_api.login import LoginAPI from zoe_api.rest_api.login import LoginAPI
...@@ -48,7 +48,6 @@ def api_init(api_endpoint) -> List[tornado.web.URLSpec]: ...@@ -48,7 +48,6 @@ def api_init(api_endpoint) -> List[tornado.web.URLSpec]:
tornado.web.url(API_PATH + r'/execution', ExecutionCollectionAPI, route_args), tornado.web.url(API_PATH + r'/execution', ExecutionCollectionAPI, route_args),
tornado.web.url(API_PATH + r'/service/([0-9]+)', ServiceAPI, route_args), tornado.web.url(API_PATH + r'/service/([0-9]+)', ServiceAPI, route_args),
tornado.web.url(API_PATH + r'/service/logs/([0-9]+)', ServiceLogsAPI, route_args),
tornado.web.url(API_PATH + r'/discovery/by_group/([0-9]+)/([a-z0-9A-Z\-]+)', DiscoveryAPI, route_args), tornado.web.url(API_PATH + r'/discovery/by_group/([0-9]+)/([a-z0-9A-Z\-]+)', DiscoveryAPI, route_args),
......
...@@ -15,20 +15,15 @@ ...@@ -15,20 +15,15 @@
"""The Service API endpoint.""" """The Service API endpoint."""
from concurrent.futures import ThreadPoolExecutor
import logging import logging
from tornado.web import RequestHandler from tornado.web import RequestHandler
import tornado.gen
import tornado.iostream
from zoe_api.rest_api.utils import catch_exceptions, get_auth, manage_cors_headers from zoe_api.rest_api.utils import catch_exceptions, get_auth, manage_cors_headers
from zoe_api.api_endpoint import APIEndpoint # pylint: disable=unused-import from zoe_api.api_endpoint import APIEndpoint # pylint: disable=unused-import
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
THREAD_POOL = ThreadPoolExecutor(20)
class ServiceAPI(RequestHandler): class ServiceAPI(RequestHandler):
"""The Service API endpoint.""" """The Service API endpoint."""
...@@ -59,48 +54,3 @@ class ServiceAPI(RequestHandler): ...@@ -59,48 +54,3 @@ class ServiceAPI(RequestHandler):
def data_received(self, chunk): def data_received(self, chunk):
"""Not implemented as we do not use stream uploads""" """Not implemented as we do not use stream uploads"""
pass pass
class ServiceLogsAPI(RequestHandler):
"""The Service logs API endpoint."""
def initialize(self, **kwargs):
"""Initializes the request handler."""
self.api_endpoint = kwargs['api_endpoint'] # type: APIEndpoint
self.connection_closed = False
def on_connection_close(self):
"""Tornado callback for clients closing the connection."""
self.connection_closed = True
@catch_exceptions
@tornado.gen.coroutine
def get(self, service_id):
"""HTTP GET method."""
uid, role = get_auth(self)
log_gen = self.api_endpoint.service_logs(uid, role, service_id, stream=True)
while True:
try:
log_line = yield THREAD_POOL.submit(next, log_gen)
except StopIteration:
break
self.write(log_line)
try:
yield self.flush()
except tornado.iostream.StreamClosedError:
break
if self.connection_closed:
break
log.debug('Finished log stream for service {}'.format(service_id))
self.finish()
def data_received(self, chunk):
"""Not implemented as we do not use stream uploads"""
pass
...@@ -35,20 +35,6 @@ from zoe_lib.executions import ZoeExecutionsAPI ...@@ -35,20 +35,6 @@ from zoe_lib.executions import ZoeExecutionsAPI
from zoe_lib.applications import app_validate from zoe_lib.applications import app_validate
def _log_stream_stdout(service_id, timestamps):
service_api = ZoeServiceAPI(utils.zoe_url(), utils.zoe_user(), utils.zoe_pass())
try:
for line in service_api.get_logs(service_id):
if timestamps:
print(line[0], line[1])
else:
print(line[1])
except KeyboardInterrupt:
print('CTRL-C detected, exiting...')
return 'interrupt'
return 'stream_end'
def info_cmd(args_): def info_cmd(args_):
"""Queries the info endpoint.""" """Queries the info endpoint."""
info_api = ZoeInfoAPI(utils.zoe_url(), utils.zoe_user(), utils.zoe_pass()) info_api = ZoeInfoAPI(utils.zoe_url(), utils.zoe_user(), utils.zoe_pass())
...@@ -105,26 +91,9 @@ def exec_start_cmd(args): ...@@ -105,26 +91,9 @@ def exec_start_cmd(args):
if old_status != current_status: if old_status != current_status:
print('Execution is now {}'.format(current_status)) print('Execution is now {}'.format(current_status))
old_status = current_status old_status = current_status
if current_status == 'running': if current_status == 'terminated':
break break
time.sleep(1) time.sleep(1)
monitor_service_id = None
service_api = ZoeServiceAPI(utils.zoe_url(), utils.zoe_user(), utils.zoe_pass())
for service_id in execution['services']:
service = service_api.get(service_id)
if service['description']['monitor']:
monitor_service_id = service['id']
break
print('\n>------ start of log streaming -------<\n')
why_stop = _log_stream_stdout(monitor_service_id, False)
print('\n>------ end of log streaming -------<\n')
if why_stop == 'stream_end':
print('Execution finished')
exit(0)
elif why_stop == 'interrupt':
print('Do not worry, your execution ({}) is still running.'.format(exec_id))
exit(1)
def exec_get_cmd(args): def exec_get_cmd(args):
...@@ -178,11 +147,6 @@ def exec_rm_cmd(args): ...@@ -178,11 +147,6 @@ def exec_rm_cmd(args):
exec_api.delete(args.id) exec_api.delete(args.id)
def logs_cmd(args):
"""Retrieves and streams the logs of a service."""
_log_stream_stdout(args.service_id, args.timestamps)
def stats_cmd(args_): def stats_cmd(args_):
"""Prints statistics on Zoe internals.""" """Prints statistics on Zoe internals."""
stats_api = ZoeStatisticsAPI(utils.zoe_url(), utils.zoe_user(), utils.zoe_pass()) stats_api = ZoeStatisticsAPI(utils.zoe_url(), utils.zoe_user(), utils.zoe_pass())
...@@ -211,7 +175,7 @@ def process_arguments() -> Tuple[ArgumentParser, Namespace]: ...@@ -211,7 +175,7 @@ def process_arguments() -> Tuple[ArgumentParser, Namespace]:
argparser_app_validate.set_defaults(func=app_validate_cmd) argparser_app_validate.set_defaults(func=app_validate_cmd)
argparser_exec_start = subparser.add_parser('start', help="Start an application") argparser_exec_start = subparser.add_parser('start', help="Start an application")
argparser_exec_start.add_argument('-s', '--synchronous', action='store_true', help="Do not detach, wait for execution to finish, print main service log") argparser_exec_start.add_argument('-s', '--synchronous', action='store_true', help="Do not detach, wait for execution to finish")
argparser_exec_start.add_argument('name', help="Name of the execution") argparser_exec_start.add_argument('name', help="Name of the execution")
argparser_exec_start.add_argument('jsonfile', type=FileType("r"), help='Application description') argparser_exec_start.add_argument('jsonfile', type=FileType("r"), help='Application description')
argparser_exec_start.set_defaults(func=exec_start_cmd) argparser_exec_start.set_defaults(func=exec_start_cmd)
...@@ -235,11 +199,6 @@ def process_arguments() -> Tuple[ArgumentParser, Namespace]: ...@@ -235,11 +199,6 @@ def process_arguments() -> Tuple[ArgumentParser, Namespace]:
argparser_execution_kill.add_argument('id', type=int, help="Execution id") argparser_execution_kill.add_argument('id', type=int, help="Execution id")
argparser_execution_kill.set_defaults(func=exec_rm_cmd) argparser_execution_kill.set_defaults(func=exec_rm_cmd)
argparser_logs = subparser.add_parser('logs', help="Streams the service logs")
argparser_logs.add_argument('service_id', type=int, help="Service id")
argparser_logs.add_argument('-t', '--timestamps', action='store_true', help="Prefix timestamps for each line")
argparser_logs.set_defaults(func=logs_cmd)
argparser_stats = subparser.add_parser('stats', help="Prints all available statistics") argparser_stats = subparser.add_parser('stats', help="Prints all available statistics")
argparser_stats.set_defaults(func=stats_cmd) argparser_stats.set_defaults(func=stats_cmd)
......
...@@ -45,20 +45,3 @@ class ZoeServiceAPI(ZoeAPIBase): ...@@ -45,20 +45,3 @@ class ZoeServiceAPI(ZoeAPIBase):
raise ZoeAPIException('service "{}" not found'.format(container_id)) raise ZoeAPIException('service "{}" not found'.format(container_id))
else: else:
raise ZoeAPIException('error retrieving service {}'.format(container_id)) raise ZoeAPIException('error retrieving service {}'.format(container_id))
def get_logs(self, container_id):
"""
Retrieve service logs.
:param container_id:
:return:
"""
response, status_code = self._rest_get_stream('/service/logs/' + str(container_id))
if status_code == 200:
for line in response.iter_lines():
line = line.decode('utf-8').split(' ', 1)
yield line
elif status_code == 404:
raise ZoeAPIException('service "{}" not found'.format(container_id))
else:
raise ZoeAPIException('error retrieving service {}'.format(container_id))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment