I quickly set up an example that should make it pretty clear what's going on:
[{"id":"1ae4d5e11a65ec7b","type":"subflow","name":"Logging (global instead of flow context)","info":"### Inputs\n - **log_type_prefix**:\n - `msg.log_type_prefix` or `env.log_type_prefix`\n - [**Prefix** (uID) Log message]\n - **uID**:\n - `msg.uID`\n - [Prefix (**uID**) Log message]\n - **log_msg**:\n - `msg.log_message`\n - [Prefix (uID) **Log message**]\n - **print_log**: boolean","category":"","in":[{"x":80,"y":60,"wires":[{"id":"9a60922deec717f8"}]}],"out":[],"env":[{"name":"log_type_prefix","type":"str","value":"globalPrefix"}],"meta":{},"color":"#DDAA99"},{"id":"9a60922deec717f8","type":"function","z":"1ae4d5e11a65ec7b","name":"Create log function","func":"node.warn(msg)\nif (!msg.log_type_prefix) {\n msg.log_type_prefix = env.get(\"log_type_prefix\");\n}\n\nlet buffer = \"\";\nif (global.keys().includes(msg.uID)) {\n buffer = global.get(msg.uID);\n} else {\n buffer = \"--------------------------------------------------\\n\"\n}\nbuffer += `[${msg.log_type_prefix} (${msg.uID})] ${msg.log_msg}\\n`\nbuffer += `${JSON.stringify(msg)}\\n`\n\nglobal.set(msg.uID, buffer)\nif (msg.print_log) {\n global.set(msg.uID, undefined)\n return { log_msg: `${buffer}\\n` }\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":210,"y":60,"wires":[["0acf4665bec5abf7"]]},{"id":"0acf4665bec5abf7","type":"flogger","z":"1ae4d5e11a65ec7b","name":"Log","logfile":"bedroom_lights_automation.log","inputchoice":"object","inputobject":"log_msg","inputobjectType":"msg","inputmoustache":"[{{log_type_prefix}} ({{uID}})] {{log_msg}}","loglevel":"INFO","logconfig":"2d86649a1f8356dd","sendpane":true,"x":370,"y":60,"wires":[[]]},{"id":"23e49dfd85a84a57","type":"subflow","name":"Logging","info":"### Inputs\n - **log_type_prefix**:\n - `msg.log_type_prefix` or `env.log_type_prefix`\n - [**Prefix** (uID) Log message]\n - **uID**:\n - `msg.uID`\n - [Prefix (**uID**) Log message]\n - **log_msg**:\n - `msg.log_message`\n - [Prefix (uID) **Log message**]\n - **print_log**: boolean","category":"","in":[{"x":80,"y":60,"wires":[{"id":"5c75ed62173fca58"}]}],"out":[],"env":[{"name":"log_type_prefix","type":"str","value":""}],"meta":{},"color":"#DDAA99"},{"id":"5c75ed62173fca58","type":"function","z":"23e49dfd85a84a57","name":"Create log function","func":"node.warn(msg)\nif (!msg.log_type_prefix) {\n msg.log_type_prefix = env.get(\"log_type_prefix\");\n}\n\nlet buffer = \"\";\nif (flow.keys().includes(msg.uID)) {\n buffer = flow.get(msg.uID);\n} else {\n buffer = \"--------------------------------------------------\\n\"\n}\nbuffer += `[${msg.log_type_prefix} (${msg.uID})] ${msg.log_msg}\\n`\nbuffer += `${JSON.stringify(msg)}\\n`\n\nflow.set(msg.uID, buffer)\nif (msg.print_log) {\n flow.set(msg.uID, undefined)\n return { log_msg: `${buffer}\\n` }\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":210,"y":60,"wires":[["c3a82a246d514d57"]]},{"id":"c3a82a246d514d57","type":"flogger","z":"23e49dfd85a84a57","name":"Log","logfile":"bedroom_lights_automation.log","inputchoice":"object","inputobject":"log_msg","inputobjectType":"msg","inputmoustache":"[{{log_type_prefix}} ({{uID}})] {{log_msg}}","loglevel":"INFO","logconfig":"2d86649a1f8356dd","sendpane":true,"x":370,"y":60,"wires":[[]]},{"id":"2d86649a1f8356dd","type":"config-log","logname":"Basic logging","logdir":"/data/logs","stamp":"local","logstyle":"plain","logrotate":false,"logcompress":false,"logrotatecount":"5","logsize":"1000","logtopic":false,"logsource":false},{"id":"92a034d42eaf462c","type":"subflow","name":"test logging flow","info":"","category":"","in":[{"x":80,"y":100,"wires":[{"id":"3b95e60fce02e0f3"},{"id":"663e8730cc2d106e"},{"id":"a8041a8e88a39498"}]}],"out":[],"env":[],"meta":{},"color":"#DDAA99"},{"id":"3b95e60fce02e0f3","type":"subflow:23e49dfd85a84a57","z":"92a034d42eaf462c","name":"","env":[{"name":"log_type_prefix","value":"flowPrefix","type":"str"}],"x":200,"y":80,"wires":[]},{"id":"663e8730cc2d106e","type":"delay","z":"92a034d42eaf462c","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":200,"y":120,"wires":[["7afdc468e9843e49","621ea2cbdfcc4ca6","338f0eb90fcb2182"]]},{"id":"7afdc468e9843e49","type":"subflow:23e49dfd85a84a57","z":"92a034d42eaf462c","name":"","env":[{"name":"log_type_prefix","value":"flowPrefix","type":"str"}],"x":380,"y":80,"wires":[]},{"id":"621ea2cbdfcc4ca6","type":"delay","z":"92a034d42eaf462c","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":380,"y":120,"wires":[["0cc41f6eed291603"]]},{"id":"66a0cc845ce779f3","type":"subflow:23e49dfd85a84a57","z":"92a034d42eaf462c","name":"","env":[{"name":"log_type_prefix","value":"flowPrefix","type":"str"}],"x":760,"y":80,"wires":[]},{"id":"0cc41f6eed291603","type":"change","z":"92a034d42eaf462c","name":"","rules":[{"t":"set","p":"print_log","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":120,"wires":[["66a0cc845ce779f3","3d81df2cf71b9eb7"]]},{"id":"a8041a8e88a39498","type":"subflow:1ae4d5e11a65ec7b","z":"92a034d42eaf462c","name":"","x":290,"y":200,"wires":[]},{"id":"338f0eb90fcb2182","type":"subflow:1ae4d5e11a65ec7b","z":"92a034d42eaf462c","name":"","x":470,"y":160,"wires":[]},{"id":"3d81df2cf71b9eb7","type":"subflow:1ae4d5e11a65ec7b","z":"92a034d42eaf462c","name":"","x":850,"y":120,"wires":[]},{"id":"2585ba6af801602c","type":"inject","z":"f6f2187d.f17ca8","name":"","props":[{"p":"uID","v":"testUID","vt":"str"},{"p":"log_msg","v":"bla","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":320,"y":1980,"wires":[["84e27cdcdb6cd09f"]]},{"id":"84e27cdcdb6cd09f","type":"subflow:92a034d42eaf462c","z":"f6f2187d.f17ca8","name":"","x":480,"y":1980,"wires":[]}]
Be aware that this uses node-red-contrib-flogger-now. Replacing the flogger nodes with debug nodes should also work, but the log file shows it a bit more clearly than the debug output. If you'd prefer a version with simple debug nodes, let me know.
If I hit the inject button, after the set delays, this is what I see in my log:
2022/01/27 11:13:13 INFO --------------------------------------------------
[flowPrefix (testUID)] bla
{"_msgid":"8a09643d6feb263d","uID":"testUID","log_msg":"bla","print_log":true,"log_type_prefix":"flowPrefix"}
2022/01/27 11:13:13 INFO --------------------------------------------------
[globalPrefix (testUID)] bla
{"_msgid":"8a09643d6feb263d","uID":"testUID","log_msg":"bla","log_type_prefix":"globalPrefix"}
[globalPrefix (testUID)] bla
{"_msgid":"8a09643d6feb263d","uID":"testUID","log_msg":"bla","log_type_prefix":"globalPrefix"}
[globalPrefix (testUID)] bla
{"_msgid":"8a09643d6feb263d","uID":"testUID","log_msg":"bla","print_log":true,"log_type_prefix":"globalPrefix"}
If you look at the logging subflows, the code in the function node is exactly the same, other than one using the flow context, the other using the global context.
The one that uses the flow context uses "flowPrefix", the one with the global context uses "globalPrefix". As you can see, the flow context logging subflow only prints one message, the last one. The logging subflow that uses the global context prints the message 3 times (because it was sent to 3 different logging nodes sequentially, that's what it should do).
I also tried a version where the logging node is triggered by separate messages, instead of one message reaching multiple logging nodes sequentially. This way it does seem to work as expected. I guess this means that the flow context is only set/updated when a message has completed its route, while the global context is set/updated immediately?
Also, when I'm in a subflow, on the context data tab in the sidebar, it says "none selected" when I refresh the flow context. I assume this is to be expected, but I'm not sure why, and what it means with "none selected".