human
Complete this python program:
def build_tracer(name, task, loader=None, hostname=None, store_errors=True, Info=TraceInfo, eager=False, propagate=False, app=None, monotonic=monotonic, trace_ok_t=trace_ok_t, IGNORE_STATES=IGNORE_STATES):
assistant
#Here is the Python program you requested.

    """Return a function that traces task execution.
    Catches all exceptions and updates result backend with the
    state and result.
    If the call was successful, it saves the result to the task result
    backend, and sets the task status to `"SUCCESS"`.
    If the call raises :exc:`~@Retry`, it extracts
    the original exception, uses that as the result and sets the task state
    to `"RETRY"`.
    If the call results in an exception, it saves the exception as the task
    result, and sets the task state to `"FAILURE"`.
    Return a function that takes the following arguments:
    :param uuid: The id of the task.
    :param args: List of positional args to pass on to the function.
    :param kwargs: Keyword arguments mapping to pass on to the function.
    :keyword request: Request dict.
    """
    fun = (task if task_has_custom(task, u'__call__') else task.run)
    loader = (loader or app.loader)
    backend = task.backend
    ignore_result = task.ignore_result
    track_started = task.track_started
    track_started = ((not eager) and (task.track_started and (not ignore_result)))
    publish_result = ((not eager) and (not ignore_result))
    hostname = (hostname or gethostname())
    loader_task_init = loader.on_task_init
    loader_cleanup = loader.on_process_cleanup
    task_on_success = None
    task_after_return = None
    if task_has_custom(task, u'on_success'):
        task_on_success = task.on_success
    if task_has_custom(task, u'after_return'):
        task_after_return = task.after_return
    store_result = backend.store_result
    mark_as_done = backend.mark_as_done
    backend_cleanup = backend.process_cleanup
    pid = os.getpid()
    request_stack = task.request_stack
    push_request = request_stack.push
    pop_request = request_stack.pop
    push_task = _task_stack.push
    pop_task = _task_stack.pop
    _does_info = logger.isEnabledFor(logging.INFO)
    resultrepr_maxsize = task.resultrepr_maxsize
    prerun_receivers = signals.task_prerun.receivers
    postrun_receivers = signals.task_postrun.receivers
    success_receivers = signals.task_success.receivers
    from celery import canvas
    signature = canvas.maybe_signature
    def on_error(request, exc, uuid, state=FAILURE, call_errbacks=True):
        if propagate:
            raise
        I = Info(state, exc)
        R = I.handle_error_state(task, request, eager=eager, call_errbacks=call_errbacks)
        return (I, R, I.state, I.retval)
    def trace_task(uuid, args, kwargs, request=None):
        R = I = T = Rstr = retval = state = None
        task_request = None
        time_start = monotonic()
        try:
            try:
                kwargs.items
            except AttributeError:
                raise InvalidTaskError(u'Task    keyword    arguments    is    not    a    mapping')
            push_task(task)
      ...