Conversation
…r into improve-error-reporting
169bb2e to
fad8658
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
internal/run/metrics/aggregator.go
Outdated
| // mergedHistogram builds a combined histogram from all windows. | ||
| func (e *EndpointStats) mergedHistogram() *hdrhistogram.Histogram { | ||
| merged := hdrhistogram.New(1, 60000000, 3) | ||
| for i := range e.windows { |
There was a problem hiding this comment.
If you’re using the counter to index into the array, the expended range loop is more concise, ie for _, elem := range e.windows
| return nil, err | ||
| } | ||
| fmt.Fprintf(&buf, "\n %q: ", name) | ||
| buf.Write(epJson) |
There was a problem hiding this comment.
I’m almost certain that if you give each endpoint (and timeline) structure a custom marshalling routine that doesn’t do indentation, you can eliminate most if not all of the byte-by-byte serialization here.
There was a problem hiding this comment.
I'd love that, I was unsuccessful in trying this before but I'll give that approach a shot. Thanks!
There was a problem hiding this comment.
Spent some time looking into this, and I'm not confident it's possible (or, at this point, worthwhile).
The main issue is that any notion of "marshal + indent" happens in those two, disjoint steps: marshal things to bytes, then write those bytes. The latter step is a standalone json function rather than something we can implement, and encoding/json's MarshalJSON interface only lets us control what gets serialized rather than how it's formatted. json.Indent, seemingly, is completely agnostic to types or any idea higher-level than "is this a { or [ character"?
Separately, I really wanted this to be true, as it's a bit baffling that this doesn't natively exist. The alternative to this Fprintf byte-by-byte approach is to make MarshalJSON do our marshaling, then have a custom indenter that does what we want at the byte level (i.e. not adding newlines + indents to things in an array). Which is still ugly + more work than it should be, but I do feel like digging my heels in on keeping timeline entries on one line. But if there's some way of doing this that I missed, let me know!
What
Following the stepped-pacer redesign (#23):
step-intervaltimeline of windows/snapshots to the final JSON results. Each entry captures target RPS, success/error counts, error rate (%), and latency percentiles (p50, p95, p99, p99.9) for that window only--error-percentwhich specifies the tolerance for errors (e.g.--error-percent 60would kill the test after receiving over 60% error/timeout in any 5s window).Visually, the results JSON now looks like:
The
timelineintervals default to 5s when noramp-upis provided as there's no natural "RPS phase" notion without aramp-upthat steps through various RPS levels. Degradation still occurs with a fixed RPS level, so this allows for atimeline-d degradation curve without aramp-upperiod.Why
Conceptually, this is a minor rework of the aggregator: stats are accumulated in windows which are deposited into the aggregator and are reset thereafter. This allows for the aggregation of stats by their current RPS level, which provides useful/digestible instantaneous info (as opposed to relying on cumulative stats).
The richer JSON gives operators a clear view of how the RPC degraded as load increased. Previously, the results JSON flattened all metrics into a single summary bucket per endpoint without any notion of an RPS-timeline, so there was no way to tell at what RPS the RPC buckled. This gives an operator running a load test a concise/minimal degradation curve (e.g. when errors started, how latency + error rates changed at each step) without requiring them to dig through through logs.
Known limitations
N/A