in samcli/lib/telemetry/metric.py [0:0]
def track_command(func):
"""
Decorator to track execution of a command. This method executes the function, gathers all relevant metrics,
reports the metrics and returns.
If you have a Click command, you can track as follows:
.. code:: python
@click.command(...)
@click.options(...)
@track_command
def hello_command():
print('hello')
"""
def wrapped(*args, **kwargs):
telemetry = Telemetry()
exception = None
return_value = None
exit_reason = "success"
exit_code = 0
duration_fn = _timer()
try:
# Execute the function and capture return value. This is returned back by the wrapper
# First argument of all commands should be the Context
return_value = func(*args, **kwargs)
except UserException as ex:
# Capture exception information and re-raise it later so we can first send metrics.
exception = ex
exit_code = ex.exit_code
if ex.wrapped_from is None:
exit_reason = type(ex).__name__
else:
exit_reason = ex.wrapped_from
except Exception as ex:
exception = ex
# Standard Unix practice to return exit code 255 on fatal/unhandled exit.
exit_code = 255
exit_reason = type(ex).__name__
try:
ctx = Context.get_current_context()
metric_specific_attributes = get_all_experimental_statues() if ctx.experimental else {}
try:
template_dict = ctx.template_dict
project_type = ProjectTypes.CDK.value if is_cdk_project(template_dict) else ProjectTypes.CFN.value
metric_specific_attributes["projectType"] = project_type
except AttributeError:
LOG.debug("Template is not provided in context, skip adding project type metric")
metric_name = "commandRunExperimental" if ctx.experimental else "commandRun"
metric = Metric(metric_name)
metric.add_data("awsProfileProvided", bool(ctx.profile))
metric.add_data("debugFlagProvided", bool(ctx.debug))
metric.add_data("region", ctx.region or "")
metric.add_data("commandName", ctx.command_path) # Full command path. ex: sam local start-api
if metric_specific_attributes:
metric.add_data("metricSpecificAttributes", metric_specific_attributes)
# Metric about command's execution characteristics
metric.add_data("duration", duration_fn())
metric.add_data("exitReason", exit_reason)
metric.add_data("exitCode", exit_code)
telemetry.emit(metric)
except RuntimeError:
LOG.debug("Unable to find Click Context for getting session_id.")
if exception:
raise exception # pylint: disable=raising-bad-type
return return_value
return wrapped