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