Your comment about debugging is much, much more applicable to monolith services than microservices. Digging into the bowels of a monolith service to trace the path of a service call is brutal, while even for spaghetti code microservices you can rely on the hard boundary between services (even when the boundaries were drawn poorly or correspond to the wrong abstractions) as a definitive type of binary search, as well as a much more natural and composable boundary for automatically mocking calls in tests or during debugging when isolating in which component there is a problem.
With a modular monolith I need one debugger, probably something like trace points as well.
With microservices I need one debugger instance per microservice taking part on the request chain, or the vain hope that the developers actually remembered to log information that actually matters.
If I worked with you, I would give negative feedback regarding your approach to debugging. You don’t appear to be taking steps to isolate the problem, rather just lazily stepping through a debugger expecting it will magically reveal when a problem state has been entered.
In the monolith case, your debugger is likely to step into very low-level procedures defined far away in the source code, with no surrounding context to understand why or to know if sections of code can be categorically removed from the debugging because, as separated sub-components, they could be logically ruled out.
Instead you’ll have to set a watch point or something, run the whole system incredibly verbosely, trip the condition and then set a new watch point accordingly. Essentially doing serially what you could do in log(n) time with a moderately well-decoupled set of microservices.
You’d also have the added benefit that for sub-components you can logically rule out, you can mock them out in your debugging and inject specific test cases, skip slow-running processes, whatever, with the only mock system needed being a simple mock of an http/whatever request library. One simplistic type of mock works for all service boundaries.
To do the same in a monolith, you now have to write custom mocking components and custom logic to apply the mocks at the right places, coming close to doubling the amount of test / debugging tooling you need to write and maintain to achieve the same effect you can literally get for free with microservices (see e.g. requests-mock in Python).
And all this has nothing to do with whether the monolith is well-written or spaghetti code compared to the microservice implementation.