It does not "write the o/p to std output". It writes it to stderr. Also it won't write stdout to your file either. When you use command substitution you are telling it to write stdout to the variable TOTALFILES.
If you want your output to go to both the variable and the file you will need to use tee:
totalfiles=$(ls "${sourcedir}/${sourcesubdir}/"*.txt | wc -l | tee "${workdir}/${logfname}")
However this also wont send stderr to your log file, to do that you could do:
totalfiles=$(ls "${sourcedir}/${sourcesubdir}/"*.txt 2>"${workdir}/${logfname}" | wc -l | tee "${workdir}/${logfname}")
stdin is fd0
stdout is fd1
stderr is fd2
To redirect stdout:
foo > /path/file
Which is equivalent to:
foo 1> /path/file
To redirect stderr:
foo 2> /path/file
To redirect both:
foo > /path/file 2>&1
Note that the order of redirections is significant
Reading: 3.6 Redirections
With bash you can also shorten this using &> for example:
foo &> /path/file
(You should avoid uppercase variable names, you should also quote all your variables and use $( ... ) instead of backticks.