How do you typically deal with cross cutting concepts like logging, where there is no interface in the standard library, in larger code bases or when using external dependencies? E.g. Python has a standard logging concept where any logging facility can plug into. And it’s clear that is comes with a cost (every logging call is dispatching). But how do you typically solve auch things in Ada?
First there cannot be any standard logging. There are too many cases handled completely differently.
As for measurement data in our middleware (100% Ada) each channel could be marked on/off for logging any time. If you run a mileage test you log only certain channels when certain conditions are met. E.g. say, when a vibration channel leaves the tolerance band one starts logging of some very fast channels to catch up how the drill breaks, when it gets back the logging is halted etc. Of course the cost of dispatching calls is zero in comparison with other overhead, e.g. sampling, pushing data, networking, pre-processing, hard drive I/O etc. If you need to care about dispatching calls you have a serious problem and probably need a different hardware and different ways. E.g. our middleware supports oversampling of the channels when you sample a hundred of measurements and then push them trough the middleware.
Then you must ensure that by a system crash the log will not be lost. Then you must support chunking log files. A complete log could become many gigabytes long. Of course, everything is binary and time stamped. No relational databases, because the overhead of indexing is massive.
I mostly use Ada on Linux systems, so I use an Ada binding to syslog. That pushes most of the work onto syslogd, which is almost infinitely configurable for what it does with log messages. Sadly, systemd, which I am not fond of, is attempting to squeeze out syslog.