Earlier quoted context omitted.
That still means each thread will do its own separate log call every second (or whatever the period is) instead of all threads aggregating into a single log call.
No, the timer is still global (that's why you need the compare-and-swap). But the threads only need to do reads most of the time, and reads do not cause contention. Writes do. It looks something like this (pseudocode): static std::atomic deadline{0}; auto now = coarse_clock::now(); auto curDeadline = deadline.load(std::memory_order_relaxed); if (now >= curDeadline && deadline.compare_exchange_strong(curDeadline, now…
Log by time, not by count
61–70 of 109 posts
Re: Log by time, not by count
#62Re: Log by time, not by count
#63Besides the (potential) bug, it is a cool idea, if emitting metrics is not an option.
Re: Log by time, not by count
#64Best advice I ever got on logging: log all major logical branches within code (if/for) if "request" span multiple machine in cloud infrastructure, include request ID in all so logs can be grouped if possible make log level dynamically controlled, so grug can turn on/off when need debug issue (many!) if possible make log level per user, so can debug specific user issue - https://grugbrain.dev/ The only one I'll add is…
Following this advice, I've seen service where you could say the main function was to produce logs, and the actual response to the user was only a small part of the traffic generated. What we really need is smart logging: only log the full span when an error is detected, otherwise no need for it. But it's not a very well supported case.
That, combined with a real, genuine devops scheme where the people implementing the system and the people keeping it running in production where on the same team and generally the same actual people, seemed to produce some of the most excellent and usable logging I've ever seen. Without needing a whole bunch of rules to try and force everyone to (still fail to) get there.
One neat thing that I think really facilitated this was the sense of empowerment that came with having exactly one rule (logging isn't configurable) combined with one goal (keep the system up). We did decide we wanted smart logging along those lines. And we did see that existing solutions didn't support this very well. So someone wrote one. And it was so dead simple, and easy to use. The 'user manual' for new hires was basically, "Here's 50 lines of code that you should read."
Re: Log by time, not by count
#65Earlier quoted context omitted.
My colleagues love to log as little as possible and most of the projects I’ve seen still treat logs as files instead of event streams that could have some search and filtering and categorization and automated alerting. It’s kind of unfortunate, because for example there’d be pushback against logging branches in code etc., except for trace logs (that others wouldn’t add) that are also off most of the time when problem…
I've had colleagues try this. It rarely works. Logging every if end up introducing a huge amount of overhead, both in terms of processing power, but especially in terms of storage. You almost always end up having to filter based on some sort of log level that you then turn off by default in production. The problem with that is that you're now required to reproduce the issue after turning on the logging, and if you al…
Probably due to no direct access to the environments, whereas there being less organizational resistance to toggling logging levels... assuming that the issue is even easily reproducible instead of "Okay, this happened once and cost us X$, it was pretty horrible, we don't know exactly why that happened but fix it before it happens again."
(not an exact case, but a pattern I've seen)
Re: Log by time, not by count
#66If you want to know if an application is running, implement health checks. I hope I never have to deal with the pattern suggested in this article in a production system.
Re: Log by time, not by count
#67As SRE/DevOps/Ops whatever, I'm screaming. Metrics should be emitted in separate stream and never by logs outside corner cases. Logs should be used to determine WHY the system is having issues but never IS the system having issues. Log alerting is a fools errand that looks like a great idea at start but quickly becomes a sand trap that will drive future people crazy and at scale, will overwhelm systems. Why is log al…
Re: Log by time, not by count
#68Earlier quoted context omitted.
> In the end, what's the difference between a log and a metric? Essentially, a log entry is the emission of state known by an individual code execution path at the point the log entry can be produced, whereas a metric is a measurement of a specific runtime execution performed by the system. For example, a log entry of: module_logger.info( f"Processed {num_events_processed_since_last_log} events." ) Emits a log entry…
This is a reasonable first pass answer, but there's more nuance to this... > What it does not do is separate this information Logging at scale should really be structured, which means that you can trivially differentiate between different types of log message. You also get more dimensions all represented in that structure. > limits the type of metrics which can be reported to be those expressible in a message text fi…
In my local fun projects that run on my machine I might dump metrics into the logs because it's practical, but it doesn't make it "right".
Re: Log by time, not by count
#69Earlier quoted context omitted.
No, the timer is still global (that's why you need the compare-and-swap). But the threads only need to do reads most of the time, and reads do not cause contention. Writes do. It looks something like this (pseudocode): static std::atomic deadline{0}; auto now = coarse_clock::now(); auto curDeadline = deadline.load(std::memory_order_relaxed); if (now >= curDeadline && deadline.compare_exchange_strong(curDeadline, now…
Your “actually log” is within one thread. Either the threads all do their separate “actually log”, or they have to synchronize their data into a single shared “actually log”.
But why? Often the purpose is just to log a "been here" signal with some additional details for diagnostics. You don't need to include an accumulation of everything that happened since the last log. All that you care about is that the log happens at most 1/period, say once per second.
If you do want to also log some data that accumulates everything that happened, you can accumulate the data in thread-local buffers, and in the "actually log" part collect all the buffers and log them. Since this only happens in the thread that "wins" the CAS, it is still very scalable. This is a very common technique.
If you throttle by count, you cannot avoid the contended atomic increment (you can with some sophistication and at the cost of some approximation).