def get_trace_db_by_live_action(liveaction):
    """
    Given a liveaction does the best attempt to return a TraceDB.
    1. From trace_context in liveaction.context
    2. From parent in liveaction.context
    3. From action_execution associated with provided liveaction
    4. Creates a new TraceDB (which calling method is on the hook to persist).

    :param liveaction: liveaction from which to figure out a TraceDB.
    :type liveaction: ``LiveActionDB``

    :returns: (boolean, TraceDB) if the TraceDB was created(but not saved to DB) or
               retrieved from the DB and the TraceDB itself.
    :rtype: ``tuple``
    """
    trace_db = None
    created = False
    # 1. Try to get trace_db from liveaction context.
    #    via trigger_instance + rule or via user specified trace_context
    trace_context = liveaction.context.get(TRACE_CONTEXT, None)
    if trace_context:
        trace_context = _get_valid_trace_context(trace_context)
        trace_db = get_trace(trace_context=trace_context, ignore_trace_tag=True)
        # found a trace_context but no trace_db. This implies a user supplied
        # trace_tag so create a new trace_db
        if not trace_db:
            trace_db = TraceDB(trace_tag=trace_context.trace_tag)
            created = True
        return (created, trace_db)
    # 2. If not found then check if parent context contains an execution_id.
    #    This cover case for child execution of a workflow.
    parent_context = executions.get_parent_context(liveaction_db=liveaction)
    if not trace_context and parent_context:
        parent_execution_id = parent_context.get("execution_id", None)
        if parent_execution_id:
            # go straight to a trace_db. If there is a parent execution then that must
            # be associated with a Trace.
            trace_db = get_trace_db_by_action_execution(
                action_execution_id=parent_execution_id
            )
            if not trace_db:
                raise StackStormDBObjectNotFoundError(
                    "No trace found for execution %s" % parent_execution_id
                )
            return (created, trace_db)
    # 3. Check if the action_execution associated with liveaction leads to a trace_db
    execution = ActionExecution.get(liveaction__id=str(liveaction.id))
    if execution:
        trace_db = get_trace_db_by_action_execution(action_execution=execution)
    # 4. No trace_db found, therefore create one. This typically happens
    #    when execution is run by hand.
    if not trace_db:
        trace_db = TraceDB(trace_tag="execution-%s" % str(liveaction.id))
        created = True
    return (created, trace_db)

    Given a liveaction does the best attempt to return a TraceDB.
    1. From trace_context in liveaction.context
    2. From parent in liveaction.context
    3. From action_execution associated with provided liveaction
    4. Creates a new TraceDB (which calling method is on the hook to persist).

    :param liveaction: liveaction from which to figure out a TraceDB.
    :type liveaction: ``LiveActionDB``

    :returns: (boolean, TraceDB) if the TraceDB was created(but not saved to DB) or
               retrieved from the DB and the TraceDB itself.
    :rtype: ``tuple``
    
st2common/st2common/services/trace.py