Most active commenters
  • frollogaston(4)
  • idontwantthis(4)
  • phito(4)
  • monkeyelite(3)

←back to thread

1087 points smartmic | 31 comments | | HN request time: 1.99s | source | bottom
Show context
titanomachy ◴[] No.44305194[source]
“Good debugger worth weight in shiny rocks, in fact also more”

I’ve spent time at small startups and on “elite” big tech teams, and I’m usually the only one on my team using a debugger. Almost everyone in the real world (at least in web tech) seems to do print statement debugging. I have tried and failed to get others interested in using my workflow.

I generally agree that it’s the best way to start understanding a system. Breaking on an interesting line of code during a test run and studying the call stack that got me there is infinitely easier than trying to run the code forwards in my head.

Young grugs: learning this skill is a minor superpower. Take the time to get it working on your codebase, if you can.

replies(48): >>44305342 #>>44305375 #>>44305388 #>>44305397 #>>44305400 #>>44305414 #>>44305437 #>>44305534 #>>44305552 #>>44305628 #>>44305806 #>>44306019 #>>44306034 #>>44306065 #>>44306133 #>>44306145 #>>44306181 #>>44306196 #>>44306403 #>>44306413 #>>44306490 #>>44306654 #>>44306671 #>>44306799 #>>44307053 #>>44307204 #>>44307278 #>>44307864 #>>44307933 #>>44308158 #>>44308299 #>>44308373 #>>44308540 #>>44308675 #>>44309088 #>>44309822 #>>44309825 #>>44309836 #>>44310156 #>>44310430 #>>44310742 #>>44311403 #>>44311432 #>>44311683 #>>44312050 #>>44312132 #>>44313580 #>>44315651 #
1. roncesvalles ◴[] No.44305375[source]
I'd love to use a real debugger but as someone who has only ever worked at large companies, this was just never an option. In a microservices mesh architecture, you can't really run anything locally at all, and the test environment is often not configured to allow hooking up a stepping debugger. Print debugging is all you have. If there's a problem with the logging system itself or something that crashes the program before the logs can flush, then not even that.
replies(5): >>44305439 #>>44305754 #>>44306109 #>>44310661 #>>44312810 #
2. frollogaston ◴[] No.44305439[source]
Same, this isn't my choice, debuggers don't work here. And we don't even have microservices.
replies(1): >>44310416 #
3. idontwantthis ◴[] No.44305754[source]
At my company our system is composed of 2 dozen different services and all of them can run locally in minikube and easily be debugged in jetbrains.
replies(3): >>44307287 #>>44307354 #>>44309201 #
4. alisonatwork ◴[] No.44306109[source]
This is basically it. When I started programming in C, I used a debugger all the time. Even a bit later doing Java monoliths I could spin up the whole app on my local and debug in the IDE. But nowadays running a dozen processes and containers and whatnot, it's just hopeless. The individual developer experience has gone very much backwards in the microservice era so the best thing to do is embrace observability, feature toggles etc and test in prod or a staging environment somewhere outside of your local machine.
5. phito ◴[] No.44307287[source]
Yes, it's perfectly doable even if you're doing microservices. Not being able to debug your application is an engineering failure.
replies(2): >>44308706 #>>44310501 #
6. roncesvalles ◴[] No.44307354[source]
Where do configs and secrets come from? Also, big company = hundreds of microservices.
replies(1): >>44309276 #
7. thunspa ◴[] No.44308706{3}[source]
can you say more? how do you do it?
replies(2): >>44310324 #>>44310610 #
8. ninkendo ◴[] No.44309201[source]
I certainly know how to debug each of the services in my environment, but how do you step-through debug a single request across services? Like, if service A make a gRPC call to service B, are you saying you can “step into” the call from A and your debugger is able to break on the corresponding call in B? And frames from the call in A are there in a logical “stack” from the breakpoint in B?

(Honest question… if such a workflow is possible I’d love to hear about it. Debugging just a single service at a time in isolation is boring and obvious, but if there’s something I’m missing I’d be really curious.)

replies(1): >>44310600 #
9. ninkendo ◴[] No.44309276{3}[source]
In my experience you just slap minikube or k3s on your dev machine, and treat it as any other environment. Argo, helm, kustomize, whatever can all work against a local single-node cluster just fine. It takes some effort to make sure your configs are overridable per-environment, but it’s worth doing. (And something you’re hopefully doing anyway if you’re doing any kind of integration/test environment.)

It also requires that each of your services can scale down as well as they can scale up… none of them should be so huge that your whole cluster can’t fit on a single machine, if you’re just simulating one “request” at a time. (Single instances of everything, don’t reserve memory, etc.) There’s use cases where this isn’t practical, but in most cases it’s very doable.

replies(1): >>44310604 #
10. phito ◴[] No.44310324{4}[source]
We mostly have dotnet services in k8s, using Rider (IDE) and Telepresence for remote debugging. Having observability (OpenTelemetry) is also really useful.
11. monkeyelite ◴[] No.44310416[source]
> debuggers don't work here

It’s impossible? Or would take engineering work to enable

replies(1): >>44311713 #
12. 9rx ◴[] No.44310501{3}[source]
A multi-process application isn't the same as microservices. Microservices is a team organization technique, seeing individual teams operate in isolation, as if they were individual businesses. You can't debug other team's services any more than you can debug what happens when you make a call to OpenAI. That is the level of separation you are up against in a microservices context. If you can, you're on the same team, and thus don't have microservices, just a single service.
replies(1): >>44317198 #
13. idontwantthis ◴[] No.44310600{3}[source]
No I can’t debug multiple services at once, unfortunately. But I will switch between them as I track the request over multiple runs. Also extensive logging in available in grafana helps me know which service is having the issue before I start debugging.
replies(1): >>44311641 #
14. idontwantthis ◴[] No.44310604{4}[source]
Yes all of this.
15. idontwantthis ◴[] No.44310610{4}[source]
See ninkendo’s comment. They are doing it with the same tools we are.
16. mananaysiempre ◴[] No.44310661[source]
> In a microservices mesh architecture, you can't really run anything locally at all, and the test environment is often not configured to allow hooking up a stepping debugger.

I don't often use a debugger, and I still feel the need to point out Visual Studio could step into DCOM RPCs across machines in the first release of DCOM, ca. 1995. (The COM specification has a description of how that is accomplished.)

17. steve_adams_86 ◴[] No.44311641{4}[source]
This is usually enough for me, too. Use tracing, figure out where things fell apart in the traces, isolate those service(s), and debug from there. It's definitely more work. When we start new projects, I encourage people not to use services until proven necessary because this added layer of friction is a real drag. For a lot of us that isn't a choice, though.
18. frollogaston ◴[] No.44311713{3}[source]
It's not a realtime system kind of thing where the debugger would change the behavior too much... It's possible with enough engineering work, but nobody has put that work in, in fact they had a debugger for some staging envs that they deleted. Lately they keep adding more red tape making it hard to even run something locally, let alone attach a debugger.

I guess you can attach a debugger for unit tests, but that's not very useful.

replies(1): >>44314103 #
19. soseng ◴[] No.44312810[source]
Curious to learn more about why it is difficult to debug. I'm not familiar with service mesh. I also work at a large corp, but we use gateways and most things are event driven with kafka across domain boundaries. I spend most of my time debugging each service locally by injecting mock messages or objects. I do this one at a time if the problem is upstream. Usually, our logging helps us pinpoint the exact service at to target for debugging. It's really easy. Our devops infrastructure has built out patterns and libraries when teams need to mint a new service. Everything is standardized with terraform. Everything has the same standard swagger pages, everything is using okta, etc.. Seems a bit boring (which is good)
replies(1): >>44313032 #
20. theshrike79 ◴[] No.44313032[source]
It's easy if Someone(tm) has already set up a system where you can whip up the relevant bits with something like localstack.

But if there is no support from anyone and you'll be starting from scratch, you've print-debugged and fixed the issue before you get the debugger attached to anything relevant.

replies(1): >>44313112 #
21. soseng ◴[] No.44313112{3}[source]
I suppose in the description of "large corp" and service mesh, Someone would already exist and this would already have been worked out. It would be a nightmare dealing with hundreds of microservices without this kind of game plan.
22. Kwantuum ◴[] No.44314103{4}[source]
> I guess you can attach a debugger for unit tests, but that's not very useful.

That is in fact incredibly useful

replies(1): >>44314389 #
23. frollogaston ◴[] No.44314389{5}[source]
Eh, it's there for those who want it, but nobody uses it
replies(1): >>44314732 #
24. monkeyelite ◴[] No.44314732{6}[source]
See this just sounds like you do not have an engineering culture or learning, enabling, and using debuggers.
replies(2): >>44314984 #>>44315120 #
25. ◴[] No.44314984{7}[source]
26. frollogaston ◴[] No.44315120{7}[source]
Not sure what an engineering culture is, but I don't want it. I just want to attach a debugger to our stuff (not the unit tests).
replies(1): >>44319608 #
27. phito ◴[] No.44317198{4}[source]
What? We have dozens of microservices owned by multiple teams, but nothing stops you from cloning the git repository of another team's microservice and debug it the same way you would debug your own.
replies(2): >>44317970 #>>44318032 #
28. ◴[] No.44317970{5}[source]
29. 9rx ◴[] No.44318032{5}[source]
Service is provided by people. You, for example, discover a problem with OpenAI's system that you integrate with and the only way you can address it is to employ the services of the people who work for OpenAI. While that is an example of a macroservice (or what we usually just call a service), it playing out in the macro economy, microservice is the same concept except applied in the micro scale.

But you checking out the code and debugging it means that you are providing the service. Where, exactly, do you find the service (micro or otherwise) boundary in this case?

Or are you just struggling to say that your service utilizes multiple applications?

replies(1): >>44335005 #
30. monkeyelite ◴[] No.44319608{8}[source]
*engineering culture of

It’s a similar muscle to exercise as using a profiler.

31. phito ◴[] No.44335005{6}[source]
Sorry but I fail to see how your comments are relevant in this discussion.