Logging is the key, in this matter.
Take a look at our TSynLog
class available in our Open Source SynCommons library.
It does have the JCL Debug / MadExcept features, with some additional (like customer-side profiling, and logging):
- logging with a set of levels;
- fast, low execution overhead;
- can load .map file symbols to be used in logging;
- compression of .map into binary .mab (900 KB -> 70 KB);
- inclusion of the .map/.mab into the .exe;
- reading of an external .map to add unit names and line numbers to a log file without .map available information at execution;
- exception logging (Delphi or low-level exceptions) with unit names and line numbers;
- optional stack trace with units and line numbers;
- methods or procedure recursive tracing, with Enter and auto-Leave using interfaces;
- high resolution time stamps, for customer-side profiling of the application execution;
- set / enumerates / TList / TPersistent / TObjectList / TContainer / dynamic array JSON serialization;
- per-thread or global logging;
- multiple log files on the same process;
- integrated log archival (in zip or any other format);
- Open Source, works from Delphi 5 up to XE.