1 # ================================================================================
2 # Copyright (c) 2019 Wipro Limited Intellectual Property. All rights reserved.
3 # ================================================================================
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 # ============LICENSE_END=========================================================
18 """:@CtxLogger.log_ctx: decorator for logging the cloudify ctx before and after operation"""
22 from functools import wraps
24 from cloudify import ctx
25 from cloudify.context import NODE_INSTANCE, RELATIONSHIP_INSTANCE
28 class CtxLogger(object):
29 """static class for logging cloudify context ctx"""
31 def _get_ctx_node_info(ctx_node):
34 return {'id': ctx_node.id, 'name': ctx_node.name, 'type': ctx_node.type,
35 'type_hierarchy': ctx_node.type_hierarchy, 'properties': ctx_node.properties}
38 def _get_ctx_instance_info(ctx_instance):
41 return {'id' : ctx_instance.id, 'runtime_properties' : ctx_instance.runtime_properties,
42 'relationships' : CtxLogger._get_ctx_instance_relationships_info(ctx_instance)}
45 def _get_ctx_instance_relationships_info(ctx_instance):
46 if not ctx_instance or not ctx_instance.relationships:
48 return [{'target': CtxLogger._get_ctx_source_target_info(r.target), \
49 'type':r.type, 'type_hierarchy':r.type_hierarchy} \
50 for r in ctx_instance.relationships]
53 def _get_ctx_source_target_info(ctx_source_target):
54 if not ctx_source_target:
56 return {'node': CtxLogger._get_ctx_node_info(ctx_source_target.node),
57 'instance' : CtxLogger._get_ctx_instance_info(ctx_source_target.instance)}
61 """collect the context data from ctx"""
64 'blueprint.id': ctx.blueprint.id,
65 'deployment.id': ctx.deployment.id,
66 'execution_id': ctx.execution_id,
67 'workflow_id': ctx.workflow_id,
68 'task_id': ctx.task_id,
69 'task_name': ctx.task_name,
70 'task_queue': ctx.task_queue,
71 'task_target': ctx.task_target,
73 'name': ctx.operation.name,
74 'retry_number': ctx.operation.retry_number,
75 'max_retries': ctx.operation.max_retries
78 'name': ctx.plugin.name,
79 'package_name': ctx.plugin.package_name,
80 'package_version': ctx.plugin.package_version,
81 'prefix': ctx.plugin.prefix,
82 'workdir': ctx.plugin.workdir
85 if ctx.type == NODE_INSTANCE:
86 context['node'] = CtxLogger._get_ctx_node_info(ctx.node)
87 context['instance'] = CtxLogger._get_ctx_instance_info(ctx.instance)
88 elif ctx.type == RELATIONSHIP_INSTANCE:
89 context['source'] = CtxLogger._get_ctx_source_target_info(ctx.source)
90 context['target'] = CtxLogger._get_ctx_source_target_info(ctx.target)
95 def log_ctx_info(func_name):
96 ctx.logger.info("NODE_INSTANCE: {}",NODE_INSTANCE)
97 """shortcut for logging of the ctx of the function"""
99 ctx.logger.info("NODE_INSTANCE: {}",NODE_INSTANCE)
100 if ctx.type == NODE_INSTANCE:
101 ctx.logger.info("{0} {1} context: {2}".format(\
102 func_name, ctx.instance.id, json.dumps(CtxLogger.get_ctx_info())))
103 elif ctx.type == RELATIONSHIP_INSTANCE:
104 ctx.logger.info("{0} context: {1}".format(\
105 func_name, json.dumps(CtxLogger.get_ctx_info())))
106 except Exception as ex:
107 ctx.logger.error("Failed to log the node context: {0}: {1}" \
108 .format(str(ex), traceback.format_exc()))
111 def log_ctx(pre_log=True, after_log=False, exe_task=None):
112 """Decorate each operation on the node to log the context - before and after.
113 Optionally save the current function name into runtime_properties[exe_task]
115 def log_ctx_info_decorator(func, **arguments):
116 """Decorate each operation on the node to log the context"""
119 def wrapper(*args, **kwargs):
120 """the actual logger before and after"""
122 if ctx.type == NODE_INSTANCE and exe_task:
123 ctx.instance.runtime_properties[exe_task] = func.__name__
124 except Exception as ex:
125 ctx.logger.error("Failed to set exe_task {0}: {1}: {2}" \
126 .format(exe_task, str(ex), traceback.format_exc()))
128 CtxLogger.log_ctx_info('before ' + func.__name__)
130 result = func(*args, **kwargs)
133 CtxLogger.log_ctx_info('after ' + func.__name__)
137 return log_ctx_info_decorator