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)