The readlinks are IMO irrelevant, it is just checking if paths are symlinks or regular files/dirs. In some scenarios, if it’s expecting the latter, but finds the former, it can be suspicious.
Those logs for failing system dont include the unlink call on /usr/local/mydir/myapp/logs/myapp/.attach_pid290, did you not include it or is it not there.
The logic is a bit confusing - it creates this empty .attach_pid*file but seems to just do a stat on it (in a separate thread) and then unlink it. On a working system. It used to do this elsewhere on the filesystem, but in 8.19.5 (likely all 8.19+) it does so in path.logs directory which it has chdir-ed to so is the CWD.
In a normal shell, as the elasticsearch process running user, can you chdir to the “failing path.logs directory, and while there create then stat then remove an empty file?
–
EDIT: I read a bit, and it seems this “create .attach_pid, stat that file in another thread, then unlink it” sequence is normal. To quote:
Every HotSpot JVM periodically checks for a file named .attach_pid in /tmp or under its /proc//root/tmp. If it finds one, it knows someone wants to attach.
It’s still not clear why thats happening in the directory from path.logs and not one of the temporary directories above. And maybe, in some cases, this mechanism is failing to actually wake up the “Attach Listener”, so your actual attach fails, via the .java_pid* file, fails. Can maybe workaround with “-Dcom.sun.management.jmxremote” to the JVM options as this forces the “Attach Listener” to start without the need for .attach_pid “prompt”.