clj-async-profiler
clj-async-profiler copied to clipboard
Profiling doesn't work on Alpine docker images out of the box
Hello, The profiler wasn't working for me from inside Alpine docker images (related to #12) and I managed to refine down the steps required to make it work. Some could be additions to the profiler itself, some are just requirements which have to be satisfied:
- The musl compatible .so is missing. Adding it as a resource is the simplest part.
- There's no detection if running in a musl environment or regular linux kernel. Besides resetting the .so path manually there's no comfortable solution.
- Without jdk installed the virtual machine class is missing. Can be remedied by adding
com.sun/tools
as a dependency or specify it should be required externally by the project. There's also an issue with it not being in the regular maven repositories, each version is in another repository entirely, and some of them don't provide https. Has success with[com.sun/tools "1.7.0.13"]
and:repositories [["nuition" "https://nexus.nuiton.org/nexus/content/groups/releases/"]]
- alpine packages requirements:
apk add libstdc++ perl
Then the profiler works from inside a docker image (phew)
Hi, thanks for reporting!
clj-async-profiler is shipped only with those binaries that are built by async-profiler maintainers, so I won't be adding a musl-based binary. But yes, it can be built manually and given to clj-async-profiler, just like you did.
I will add the JDK requirement into the README.
On a tangential note, I honestly wouldn't touch Alpine with a ten-foot pole. I had a fair share of problems with it regarding Unicode in Java, and those same musl-caused issues. Debian-slim image is only 27MB these days, and once you start installing dependencies there's no difference in size between it and Alpine anyway.
Ah, I see. The musl compiled .so was added in v1.6 and you're using 1.5. If you're not interested in moving to the next version, another solution would be:
- the user should have the .so somewhere loadable as a resource.
-
unpack-from-jar
should be made public - finally:
(reset! clj-async-profiler.core/async-profiler-agent-path (unpack-from-jar path))
, which can be triggered externally (api call, etc).
Then the .so could be dynamically initialized by the user (that's what I ended up doing in my use case anyway)
I'll also take your Alpine recommendation to heart. It isn't exactly my decision, but I'll pass it on nonetheless.
The musl compiled .so was added in v1.6 and you're using 1.5.
Oops, I am sorry, I missed that part 😄 In that case, I can surely add it to resources; however, we'll indeed need some sort of identifier that the musl replaces libc in the current environment.
Perhaps this could help?
https://gist.github.com/calebhailey/ed581beb1997892f63637da45263516f
TL;DR - use ldd --version
@bsless Hello Ben, hope you are doing well. Not sure if this still relevant to you, but version 0.5.2 includes the musl-linked binary and the code that chooses to use it when on Alpine.
I'll check that it works in our production environment and report back
Closing this since it should work on Alpine now (at least, the tests are passing on it!).