k6 icon indicating copy to clipboard operation
k6 copied to clipboard

`console.log`: Log `ArrayBuffer` and `TypedArray`

Open inancgumus opened this issue 3 weeks ago • 10 comments

What

Improve console.log for ArrayBuffer and TypedArray logging.

Why

#5460 has improved console.log with deep object traversal.

However, we use ArrayBuffer and TypedArray a lot in k6, and console.log doesn't print them.

Specific handling for these types would be extremely useful for debugging.

How

Currently the following script:

const buffer = new ArrayBuffer(8);
const view = new Int32Array(buffer);
view[0] = 4
view[1] = 2

const myObj = {
  b: buffer,
  v: view
}

export default function () {
    console.log(myObj);
}

Prints the following:

{
    "b": {},
    "v": { "0": 4, "1": 2 }
}

Whereas we would expect the ArrayBuffer and TypedArray to receive special treatment (like Deno does):

{
  b: ArrayBuffer {
    [Uint8Contents]: <00 00 00 00 00 00 00 00>,
    byteLength: 8
  },
  v: Int32Array(2) [ 4, 2 ]
}

Related

  • #5460

inancgumus avatar Dec 04 '25 13:12 inancgumus

@inancgumus may I work on this ?

pkalsi97 avatar Dec 09 '25 17:12 pkalsi97

@pkalsi97 Of course, please go ahead ❤️

inancgumus avatar Dec 09 '25 18:12 inancgumus

@inancgumus Thanks, as I am working on it, I just want to clarify:

Take a look at this implementation


         /\      Grafana   /‾‾/  
    /\  /  \     |\  __   /  /   
   /  \/    \    | |/ /  /   ‾‾\ 
  /          \   |   (  |  (‾)  |
 / __________ \  |_|\_\  \_____/ 

     execution: local
        script: test_simple.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

INFO[0000] --- Direct ---                                source=console
INFO[0000] Int32Array(2) [ 4, 2 ]                        source=console
INFO[0000] ArrayBuffer { [Uint8Contents]: <04 00 00 00 02 00 00 00>, byteLength: 8 }  source=console
INFO[0000] --- Nested ---                                source=console
INFO[0000] {"v":"Int32Array(2) [ 4, 2 ]"}                source=console
INFO[0000] {"b":"ArrayBuffer { [Uint8Contents]: \u003c04 00 00 00 02 00 00 00\u003e, byteLength: 8 }"}  source=console
  1. For simple objects of TypedArray and ArrayBuffer is the output satisfactory ?
  2. For nested cases, json.Marshal treats the formatted string as a JSON value, which adds quotes around it and escapes < > as \u003c \u003e . is this a satisfactory result as well ?

To fully Match Deno style, as per my understanding we need to replace https://github.com/grafana/k6/blob/83064bc674a91f00b5a8bbdc1a755f89e073fca0/internal/js/console.go#L113

Option 1: Usejson.Encoder with SetEscapeHTML(false) this will prevent the < > to \u003c \u003e conversion. but double quotes will still be present in the output.

Option 2: will prevent both < > to \u003c \u003e conversion and quotes With some changes in traverseValue and not call json.Marshal , we shall be able to

  1. Returns Deno-style output for ArrayBuffer/TypedArray without quotes
  2. Returns { key: value } style for objects (not JSON)
  3. Returns [ elem, elem ] style for arrays

let me know what you think, do you have an alternative solution in mind ?

pkalsi97 avatar Dec 10 '25 07:12 pkalsi97

Hi @pkalsi97, thanks for the nice explanation. Both options are fine! Still, I'm leaning more toward the second option.

@oleiade any thoughts? 🙇

inancgumus avatar Dec 11 '25 18:12 inancgumus

@inancgumus Thanks for looking into this. As of now I have implemented the Option 1 in the PR. I’m okay with moving to option 2 and will implement whichever option we decide on.

pkalsi97 avatar Dec 11 '25 18:12 pkalsi97

@pkalsi97 That's OK. You or I may create a new issue for Option 2. We can then send another PR.

inancgumus avatar Dec 11 '25 19:12 inancgumus

@inancgumus sure, please go ahead and create the issue. I'll send a PR on it with the implementation of Option 2.

pkalsi97 avatar Dec 11 '25 19:12 pkalsi97

I'm also leaning towards option 2.

My default stance towards implementing JS APIs and behaviors in k6, such as this one is that their user-facing "qualities" should be (as much as possible) unaffected by the Go implementation.

🙇🏻

oleiade avatar Dec 12 '25 07:12 oleiade

@oleiade Thanks for the input. I have Added the issue and raised PR for Option 2 as well. Shall I close the PR for Option 1?

pkalsi97 avatar Dec 12 '25 07:12 pkalsi97

@pkalsi97 Yes, we can close the option 1 PR and the option 2 issue (#5495), as this issue's resolution is now going towards option 2. Thanks ❤️

inancgumus avatar Dec 12 '25 15:12 inancgumus