You can use exec -a (as found in bash, ksh93, zsh, mksh, yash but not POSIX yet) that is used to specify an argv[0] to a command being executed:
#! /bin/bash -
printf '%s\n' "$0 $*" >> /some/log
exec -a "$0" /usr/bin/do_stuff_real "$@"
 Note that that $0 is not the argv[0] that the command receives. It is the path of the script as passed to execve() (and which is passed as argument to bash), but that's likely to be enough for your purpose.
 As an example, if make_tea was invoked as:
execv("/usr/bin/make_tea", ["make_tea", "--sugar=2"])
 As a shell would typically do when invoking the command by name (looking up the executable in $PATH), the wrapper would to:
execv("/usr/bin/do_stuff_real", ["/usr/bin/make_tea", "--sugar=2"])
That's not:
execv("/usr/bin/do_stuff_real", ["make_tea", "--sugar=2"])
 but that's good enough as do_stuff_real knows it's meant to make tea.
 Where that would be a problem is if do_stuff was invoked as:
execv("/usr/bin/do_stuff", ["/usr/bin/make_tea", "--sugar=2"])
as that would be translated to:
execv("/usr/bin/do_stuff_real", ["/usr/bin/do_stuff", "--sugar=2"])
That would not happen during normal operations, but note that our wrapper does something like that.
 On most systems, the argv[0] as passed to the script is lost once the interpreter (here /bin/bash) is executed (the argv[0] of the interpreter on most systems is the path given on the she-bang line) so there's nothing a shell script can do about it.
 If you wanted to pass the argv[0] along, you'd need to compile an executable. Something like:
#include <stdio.h>
int main(int argc, char *argv[], char *envp[])
{
   /* add logging */
   execve("/usr/bin/do_stuff_real", argv, envp);
   perror("execve");
   return 127;
}
 
                