def track_command()

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