With zsh (and zsh only) and its multios feature:
your-cmd 2> stdout+stderr.log >&2 2> stderr.log
As fd 2 is redirected twice, zsh implements an internal tee to have it sent to both files.
With bash (or any Bourne-like shell (other than zsh where you'd need to disable multios for it to work here)), you can do the teeing by hand with:
{ your-cmd 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
(though you lose the exit status of your-cmd. zsh has it in $pipestatus[1], bash in "${PIPESTATUS[0]}" though (provided the redirection into stderr+stdout.log didn't fail)).
To record the pid of your-cmd, you could do:
{ sh -ec 'echo "$$" > /var/run/pidfile; exec your-cmd' 2>&1 >&3 3>&- |
tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
With yash and it's process redirection feature:
your-cmd > stdout+stderr.log 2>(tee stderr.log)
(but note that yash will not wait for the termination of that tee command, so the log files may not be complete by the time you run the next command after that).
Something similar (and with the same caveat) can be done with process substitution in bash, zsh and ksh93:
{ your-cmd 2> >(tee stderr.log); } > stderr+stdout.log
To run in background and get the pid:
(exec your-cmd 2> >(tee stderr.log)) > stderr+stdout.log & pid=$!
With rc:
{your-cmd |[2=0] tee stderr.log} > stdout+stderr.log
rc's pipes allow specifying which file descriptors are connected to the pipe. With other shells, it's always fd 1 of the left command and fd 0 of the right one (hence the little dance with fd 3 above to shift file descriptors around). rc will report failure if either your-cmd or tee fails, though the exact number may be lost.