Commit a5c530ee authored by Daniele Venzano's avatar Daniele Venzano

Experimental feature: save service logs into a configurable directory

For now logs cannot be retrieved via any interface
parent 8693304a
......@@ -84,6 +84,8 @@ def load_configuration(test_conf=None):
argparser.add_argument('--ldap-user-gid', type=int, help='LDAP group ID for users', default=5001)
argparser.add_argument('--ldap-guest-gid', type=int, help='LDAP group ID for guests', default=5002)
argparser.add_argument('--service-log-path', help='Save service logs in this directory, EXPERIMENTAL', default='')
opts = argparser.parse_args()
if opts.debug:
argparser.print_values()
......
# Copyright (c) 2016, Daniele Venzano
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Container log storage"""
import logging
import os
import shutil
from zoe_lib.sql_manager import Execution
from zoe_lib.swarm_client import SwarmClient
from zoe_lib.config import get_conf
log = logging.getLogger(__name__)
def _path_from_execution(execution: Execution):
return os.path.join(get_conf().service_log_path, get_conf().deployment_name, str(execution.id))
def _init(execution: Execution):
if get_conf().service_log_path == '':
return None
base_path = _path_from_execution(execution)
try:
os.makedirs(base_path, exist_ok=True)
except (OSError, PermissionError):
log.exception('Error creating the directory at path: {}'.format(base_path))
return None
return base_path
def _shutdown():
pass
def save(execution: Execution):
"""Save the logs of the service specified as argument"""
path = _init(execution)
if path is None:
return
for service in execution.services:
fname = service.name + '.txt'
fpath = os.path.join(path, fname)
swarm = SwarmClient(get_conf())
log_gen = swarm.logs(service.docker_id, stream=True, follow=False)
with open(fpath, 'wb') as fp:
for line in log_gen:
fp.write(line)
_shutdown()
def delete(execution: Execution):
"""Delete the logs for a service"""
path = _init(execution)
if path is None:
return
shutil.rmtree(path)
_shutdown()
......@@ -371,12 +371,13 @@ class SwarmClient:
})
return conts
def logs(self, docker_id: str, stream: bool):
def logs(self, docker_id: str, stream: bool, follow=None):
"""
Retrieves the logs of the selected container.
:param docker_id:
:param stream:
:param follow:
:return:
"""
return self.cli.logs(docker_id, stdout=True, stderr=True, stream=stream, timestamps=True)
return self.cli.logs(docker_id, stdout=True, stderr=True, follow=follow, stream=stream, timestamps=True)
......@@ -18,6 +18,9 @@
import logging
from zoe_lib.sql_manager import Execution, SQLManager
from zoe_lib import exec_logs
from zoe_lib.config import get_conf
from zoe_master.scheduler import ZoeScheduler
log = logging.getLogger(__name__)
......@@ -59,4 +62,5 @@ def restart_resubmit_scheduler(state: SQLManager, scheduler: ZoeScheduler):
def execution_delete(scheduler: ZoeScheduler, execution: Execution):
"""Remove an execution from the scheduler, must only be called if the execution is NOT running."""
exec_logs.delete(execution)
scheduler.remove_execution(execution)
......@@ -25,6 +25,7 @@ from zoe_lib.config import get_conf
from zoe_lib.exceptions import ZoeLibException, ZoeNotEnoughResourcesException
from zoe_lib.sql_manager import Execution, Service
from zoe_lib.swarm_client import DockerContainerOptions, SwarmClient
from zoe_lib import exec_logs
log = logging.getLogger(__name__)
......@@ -146,6 +147,7 @@ def _spawn_service(execution: Execution, service: Service, env_subst_dict: dict)
def terminate_execution(execution: Execution) -> None:
"""Terminate an execution, making sure no containers are left in Swarm."""
execution.set_cleaning_up()
exec_logs.save(execution)
swarm = SwarmClient(get_conf())
for service in execution.services:
assert isinstance(service, Service)
......
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