You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by mx...@apache.org on 2017/04/06 10:56:24 UTC
incubator-ariatosca git commit: initial support for traceback and
exception in operation logs
Repository: incubator-ariatosca
Updated Branches:
refs/heads/logger_task ad6358082 -> 93444421b
initial support for traceback and exception in operation logs
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/93444421
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/93444421
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/93444421
Branch: refs/heads/logger_task
Commit: 93444421b2a02f9a1dd9c266c310a5c764d4580a
Parents: ad63580
Author: max-orlov <ma...@gigaspaces.com>
Authored: Thu Apr 6 13:56:00 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Thu Apr 6 13:56:05 2017 +0300
----------------------------------------------------------------------
aria/logger.py | 4 ++++
aria/modeling/orchestration.py | 4 ++++
aria/orchestrator/context/common.py | 7 ++++++-
aria/orchestrator/workflows/events_logging.py | 16 ++++++++--------
aria/orchestrator/workflows/executor/base.py | 4 ++--
aria/orchestrator/workflows/executor/process.py | 6 ++++--
aria/orchestrator/workflows/executor/thread.py | 8 ++++++--
examples/hello-world/scripts/stop.sh | 2 ++
.../workflows/executor/test_executor.py | 2 ++
9 files changed, 38 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/93444421/aria/logger.py
----------------------------------------------------------------------
diff --git a/aria/logger.py b/aria/logger.py
index 26ba1e3..f817dca 100644
--- a/aria/logger.py
+++ b/aria/logger.py
@@ -168,6 +168,10 @@ class _SQLAlchemyHandler(logging.Handler):
level=record.levelname,
msg=str(record.msg),
created_at=created_at,
+
+ # Not mandatory.
+ error=getattr(record, 'error', None),
+ traceback=getattr(record, 'traceback', None)
)
self._session.add(log)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/93444421/aria/modeling/orchestration.py
----------------------------------------------------------------------
diff --git a/aria/modeling/orchestration.py b/aria/modeling/orchestration.py
index bf7012f..ef94de8 100644
--- a/aria/modeling/orchestration.py
+++ b/aria/modeling/orchestration.py
@@ -395,6 +395,10 @@ class LogBase(ModelMixin):
msg = Column(String)
created_at = Column(DateTime, index=True)
+ # In case of failed execution
+ error = Column(String)
+ traceback = Column(Text)
+
# region foreign keys
@declared_attr
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/93444421/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index 452f5d0..56e041e 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -44,10 +44,15 @@ class BaseContext(object):
def __getattr__(self, item):
if item.upper() in logging._levelNames:
- return partial(getattr(self._logger, item), extra=dict(task_id=self._task_id))
+ return partial(self._logger_with_task_id, _level=item)
else:
return getattr(self._logger, item)
+ def _logger_with_task_id(self, *args, **kwargs):
+ level = kwargs.pop('_level')
+ kwargs.setdefault('extra', {})['task_id'] = self._task_id
+ return getattr(self._logger, level)(*args, **kwargs)
+
def __init__(
self,
name,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/93444421/aria/orchestrator/workflows/events_logging.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/events_logging.py b/aria/orchestrator/workflows/events_logging.py
index 07981e9..c4bc8c4 100644
--- a/aria/orchestrator/workflows/events_logging.py
+++ b/aria/orchestrator/workflows/events_logging.py
@@ -26,7 +26,7 @@ from .. import events
@events.start_task_signal.connect
def _start_task_handler(task, **kwargs):
- task.context.logger.debug('{actor.name} {task.interface_name}.{task.operation_name} started...'
+ task.context.logger.info('{actor.name} {task.interface_name}.{task.operation_name} started...'
.format(actor=task.actor, task=task))
@@ -37,14 +37,14 @@ def _success_task_handler(task, **kwargs):
@events.on_failure_task_signal.connect
-def _failure_operation_handler(task, exception, **kwargs):
+def _failure_operation_handler(task, exception, traceback, **kwargs):
# todo: add full support for exceptions and errors logging
- task.context.logger.info('{actor.name} {task.interface_name}.{task.operation_name} failed'
- .format(actor=task.actor, task=task))
- error = '{0}: {1}'.format(type(exception).__name__, exception)
- task.context.logger.error('Event: Task failure: {task.name} [{error}]'.format(
- task=task, error=error))
-
+ task.context.logger.error(
+ '{actor.name} {task.interface_name}.{task.operation_name} failed'
+ .format(actor=task.actor, task=task),
+ extra=dict(error='{0}: {1}'.format(type(exception).__name__, exception),
+ traceback=traceback)
+ )
@events.start_workflow_signal.connect
def _start_workflow_handler(context, **kwargs):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/93444421/aria/orchestrator/workflows/executor/base.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/executor/base.py b/aria/orchestrator/workflows/executor/base.py
index 4ae046d..39becef 100644
--- a/aria/orchestrator/workflows/executor/base.py
+++ b/aria/orchestrator/workflows/executor/base.py
@@ -44,8 +44,8 @@ class BaseExecutor(logger.LoggerMixin):
events.start_task_signal.send(task)
@staticmethod
- def _task_failed(task, exception):
- events.on_failure_task_signal.send(task, exception=exception)
+ def _task_failed(task, exception, traceback=None):
+ events.on_failure_task_signal.send(task, exception=exception, traceback=traceback)
@staticmethod
def _task_succeeded(task):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/93444421/aria/orchestrator/workflows/executor/process.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/executor/process.py b/aria/orchestrator/workflows/executor/process.py
index 83d8b55..c75697f 100644
--- a/aria/orchestrator/workflows/executor/process.py
+++ b/aria/orchestrator/workflows/executor/process.py
@@ -236,9 +236,10 @@ class ProcessExecutor(base.BaseExecutor):
except BaseException as e:
e.message += 'Task failed due to {0}.'.format(request['exception']) + \
UPDATE_TRACKED_CHANGES_FAILED_STR
- self._task_failed(task, exception=e)
+ self._task_failed(
+ task, exception=e, traceback=exceptions.get_exception_as_string(*sys.exc_info()))
else:
- self._task_failed(task, exception=request['exception'])
+ self._task_failed(task, exception=request['exception'], traceback=request['traceback'])
def _handle_apply_tracked_changes_request(self, task_id, request, response):
task = self._tasks[task_id]
@@ -322,6 +323,7 @@ class _Messenger(object):
'type': type,
'task_id': self.task_id,
'exception': exceptions.wrap_if_needed(exception),
+ 'traceback': exceptions.get_exception_as_string(*sys.exc_info()),
'tracked_changes': tracked_changes
})
response = _recv_message(sock)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/93444421/aria/orchestrator/workflows/executor/thread.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/executor/thread.py b/aria/orchestrator/workflows/executor/thread.py
index 8b443cc..d69c4a1 100644
--- a/aria/orchestrator/workflows/executor/thread.py
+++ b/aria/orchestrator/workflows/executor/thread.py
@@ -20,7 +20,9 @@ Thread based executor
import Queue
import threading
-from aria.utils import imports
+import sys
+
+from aria.utils import imports, exceptions
from .base import BaseExecutor
from ....modeling.models import Parameter
@@ -64,7 +66,9 @@ class ThreadExecutor(BaseExecutor):
task_func(ctx=task.context, **inputs)
self._task_succeeded(task)
except BaseException as e:
- self._task_failed(task, exception=e)
+ self._task_failed(task,
+ exception=e)
+ # traceback=exceptions.get_exception_as_string(*sys.exc_info()))
# Daemon threads
except BaseException as e:
pass
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/93444421/examples/hello-world/scripts/stop.sh
----------------------------------------------------------------------
diff --git a/examples/hello-world/scripts/stop.sh b/examples/hello-world/scripts/stop.sh
index 5461caf..dea152a 100755
--- a/examples/hello-world/scripts/stop.sh
+++ b/examples/hello-world/scripts/stop.sh
@@ -1,5 +1,7 @@
#!/bin/bash
+exit 1
+
set -e
TEMP_DIR="/tmp"
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/93444421/tests/orchestrator/workflows/executor/test_executor.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/executor/test_executor.py b/tests/orchestrator/workflows/executor/test_executor.py
index d84d1ec..e39a993 100644
--- a/tests/orchestrator/workflows/executor/test_executor.py
+++ b/tests/orchestrator/workflows/executor/test_executor.py
@@ -15,6 +15,7 @@
import logging
import uuid
+from collections import namedtuple
from contextlib import contextmanager
import pytest
@@ -119,6 +120,7 @@ class MockTask(object):
self.ignore_failure = False
self.interface_name = 'interface_name'
self.operation_name = 'operation_name'
+ self.actor = namedtuple('actor', 'name')(name='actor_name')
for state in models.Task.STATES:
setattr(self, state.upper(), state)