In production, server side Swift appears to the OS just like any other native binary. Therefore, the same debugging strategies apply. For performance tracing,
perf is the main tool for the job, which you can use to generate flame graphs and other useful diagnostics. It can therefore also be used as a replacement for the macOS
sample command for getting call stacks.
For capturing crash logs, this is often a consideration for your runtime environment. Some process is responsible for starting and monitoring your service, whether that’s the Docker daemon or your init process (like
systemd). That process should also be responsible for storing and delivering logs to some logging aggregation system. Exactly what your solution should look like here is hard to say because there are so many different choices, but this is a fairly standard log aggregation process.
Your last point, logging a stack trace on Swift
Error, is the most important one. This is not something you can do in general in Swift.
Error does not capture a stack trace: it’s an extremely cheap error propagation mechanism, not much more complex at runtime than Go’s
(result, error) return pattern. This is great in terms of performance but limiting in terms of metadata. For now there is no general solution to the problem of capturing stack traces on
Error. If this is an
Error your code emits, you can always emit an appropriate error log that contains a stack, but if it is not you are limited in your ability to do much more at this time.