Skip to content
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

Metric for http sent/recv size #2283

Closed
msaf1980 opened this issue Dec 3, 2021 · 4 comments
Closed

Metric for http sent/recv size #2283

msaf1980 opened this issue Dec 3, 2021 · 4 comments
Labels
evaluation needed proposal needs to be validated or tested before fully implementing it in k6 feature new-http issues that would require (or benefit from) a new HTTP API

Comments

@msaf1980
Copy link

msaf1980 commented Dec 3, 2021

What can you say about the sent/recv metric (with the Trend type for min/max/percentiles) for all protocols (for example, http_req_send_size/http_req_recv_size) ?
It's useful for some cases, when data_received/data_sent is not enough.

@na-- na-- added evaluation needed proposal needs to be validated or tested before fully implementing it in k6 feature labels Dec 3, 2021
@na--
Copy link
Member

na-- commented Dec 3, 2021

This is going to be tricky to implement, since right now the data_sent and data_received are measured by a custom Dialer implementation we have in every VU:

k6/js/runner.go

Line 180 in 5c14dae

dialer := &netext.Dialer{

and

k6/lib/netext/dialer.go

Lines 97 to 115 in 5c14dae

func (d *Dialer) GetTrail(
startTime, endTime time.Time, fullIteration bool, emitIterations bool, tags *stats.SampleTags,
builtinMetrics *metrics.BuiltinMetrics,
) *NetTrail {
bytesWritten := atomic.SwapInt64(&d.BytesWritten, 0)
bytesRead := atomic.SwapInt64(&d.BytesRead, 0)
samples := []stats.Sample{
{
Time: endTime,
Metric: builtinMetrics.DataSent,
Value: float64(bytesWritten),
Tags: tags,
},
{
Time: endTime,
Metric: builtinMetrics.DataReceived,
Value: float64(bytesRead),
Tags: tags,
},

So all of the traffic, regardless of protocol, passes through that... I guess we could expose the creation of custom Dialer implementations in JavaScript, and add a way for them to attach custom tags to their data_sent and data_received metrics 🤔 Then we can allow custom HTTP Client / Transport implementations, gRPC clients, etc. to use these custom dialers instead of the default one. So some refactoring needs to happen before this is possible, but all of that looks to be for the better 🎉

Making the default data_sent and data_received metrics into a Trend is somewhat unlikely at this point though 🤔 It will be somewhat of a breaking change. But maybe these Dialer objects could have a method that returns their current counters, which would allow you to query that and expose it as a custom Trend metric? 🤔

For now, as a partial workaround, you could use per-scenario tags or the new execution.vu.tags feature that was recently introduced in k6 v0.35.0. Changing the VU tags in the middle of the iteration won't help, since data_sent and data_received are sent at the end of it. But if you have multiple scenarios, one for each protocol, or just have a single protocol used in every iteration with some if or switch, you can use this trick to expose the sub-metrics of data_sent and data_received at the end, one line per scenario/protocol 🤷‍♂️ Not ideal, but something

Also, please use the issue templates instead of creating blank issues in the future 🙏

@msaf1980
Copy link
Author

msaf1980 commented Dec 3, 2021

Thank you for the detailed answer. I will try some variants.

@msaf1980 msaf1980 closed this as completed Dec 3, 2021
@na--
Copy link
Member

na-- commented Dec 3, 2021

No need to close this, it's a valid feature request!

And actually, this might be more easily (and immediately) solved by an addition to #2260. We should be able to easily and atomically expose the BytesWritten and BytesRead counters from the current global VU Dialer through k6/execution.vu 💡 We could (and probably should) implement both, eventually, but this will be simpler and already partially required for #1250.

So, users will be able to do something like this:

import http from "k6/http";
import ws from 'k6/ws';
import exec from 'k6/execution';
import { Trend } from "k6/metrics";

const bytesWrittenHTTP = new Trend('bytes_writen_http');
const bytesWrittenWS = new Trend('bytes_writen_ws');

export default function () {
    http.get('https://test.k6.io')
    // ... a bunch of other HTTP requests
    
    let bytesWrittenBeforeWSConn = exec.vu.dataSentInIteration;
    bytesWrittenHTTP.add(bytesWrittenBeforeWSConn);
    
    ws.connect(url, params, function (socket) { /* ... */});
    bytesWrittenWS.add(exec.vu.dataSentInIteration - bytesWrittenBeforeWSConn);
    
    // ... anything else you want ...
    // we can take snapshots of dataSentInIteration at any point in the iteration :)
}

It's a bit tricky to keep track, but it should allow pretty much everything you want. And it will get especially tricky when you have asynchronous things happening in a single VU (#2228), there the initial approach I suggested will probably be much easier to use, but I still think this is probably worth it 🤷‍♂️

@na-- na-- reopened this Dec 3, 2021
@na-- na-- added the new-http issues that would require (or benefit from) a new HTTP API label Dec 3, 2021
@imiric
Copy link
Contributor

imiric commented Mar 28, 2023

We have decided not to implement this via the k6/execution module and custom metrics after all, and feel these should be default metrics of whatever protocol is sending/receiving data.

We won't be implementing this in the current HTTP API, but it will be part of the new API (initial design document), which we're starting to work on now.

I'll close this issue in the meantime, since we want to work with a clear roadmap.

@imiric imiric closed this as completed Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
evaluation needed proposal needs to be validated or tested before fully implementing it in k6 feature new-http issues that would require (or benefit from) a new HTTP API
Projects
None yet
Development

No branches or pull requests

3 participants