You can redirect stderr/stdout to a process substitution that adds the prefix of choice. For example, this script:
#! /bin/bash
exec > >(trap "" INT TERM; sed 's/^/foo: /')
exec 2> >(trap "" INT TERM; sed 's/^/foo: (stderr) /' >&2)
echo foo
echo bar >&2
date
Produces this output:
foo: foo
foo: (stderr) bar
foo: Fri Apr 27 20:04:34 IST 2018
The first two lines redirect stdout and stderr respectively to sed commands that add foo:  and foo: (stderr) to the input.
The calls to the shell built-in command trap make sure that the subshell does not exit when terminating the script with Ctrl+C or by sending the SIGTERM signal using kill $pid. This ensures that your shell won't forcefully terminate your script because the stdout file descriptor disappears when sed exits because it received the termination signal as well. Effectively you can still use exit traps in your main script and sed will still be running to process any output generated while running your exit traps. The subshell should still exit after your main script ends so sed process won't be left running forever.
