-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Addition of internal consumer metrics #52
Conversation
(By the way, acknowledging that Prometheus will not be a good way to monitor metrics that have a unique attribute created every few minutes. This instrumentation maybe too expensive to run in practice, depending on vendor support for delta temporality and SDK support for "forgetting", but I would encourage us to over-instrument now and reduce later. |
} | ||
} | ||
|
||
// MetricsFrom produces an array of [pmetric.Metrics] from a BatchArrowRecords message. | ||
func (c *Consumer) MetricsFrom(bar *colarspb.BatchArrowRecords) ([]pmetric.Metrics, error) { | ||
defer c.inuseChangeObserve(c.inuseChangeByCaller()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
basic question: what is the purpose of nesting these calls? i.e. what is the reason for returning placeholder{}
and what is the difference between this and function signatures that allow sequential defers like
defer c.unuseChangeObserve()
defer c.inuseChangeByCaller()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://go.dev/doc/effective_go#defer for some detail.
The arguments to the deferred function (which include the receiver if the function is a method) are evaluated when the defer executes, not when the call executes.
This idiom allows me to use 1 line. The equivalent would be:
c.inuseChangeByCaller()
defer c.inuseChangeObserve()
if after learning about defer's evaluation order you think that's more readable, I'll change it!
attrs := metric.WithAttributes(c.uniqueAttr, attribute.String("where", where)) | ||
|
||
c.memoryCounter.Add(ctx, int64(inuse-last), attrs) | ||
c.lastInuseValue = inuse |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this function thread safe? i.e. will setting c.lastInuseValue here have a risk of overwriting/being overwritten or are all consumers isolated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The consumers are isolated. During an earlier discussion @lquerel asked me to avoid using asynchronous instruments, which would have required additional concurrency, so presently we have no atomic variables and no concurrent use. That's why we're wrangling a synchronous instrument to do what is ordinarily done through an observer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
ipcReader, err := ipc.NewReader( | ||
sc.bufReader, | ||
ipc.WithAllocator(common.NewLimitedAllocator(memory.NewGoAllocator(), c.config.memLimit)), | ||
ipc.WithAllocator(c.allocator), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not strictly equivalent to the previous code. With this modification we have a single allocator for all the payloads instead of one allocator per payload type. It's probably ok but that could explain why we observe a different behavior with the previous approach.
Adds three OTel metric instruments with instrumentation on:
Note that I have not added tests, which would delay us a lot for little benefit. There are existing debug-level assertions that cover the memory accounting. To test this experimentally, I used a recorded data file and a configuration like:
Then I see metrics (via Prometheus) at :8889/metrics, like:
Note that memory inuse appears to rise slowly.