Custom Panel - JSON Rendering

Hi,
I have a server that is sending me traces which are in JSON format, with an undefined number of nested nodes. So it will be something like [(t1,JSON1),(t2,JSON2),…]. The depth of the JSON nodes is variable.
I would like to construct a panel where each JSON is represented as a tree that can be navigated through (for example, when I select a node, it expands and the sub-nodes are displayed which I can drill down as well etc.). I thought the JSONExplorer API (JsonExplorer | Grafana documentation) is an class that can be used for that purpose (you provide the JSON and it displays the searchable tree) but I did not manage to do it. Has anyone done something and could provide guidance.
Many thanks - Christian

Welcome

Please post usable json sample with obfuscated data?
Can your data be considered nodes/edges?

Below is a sample JSON. The nested calledComponents are making up the JSON tree:

{
“event”: {
“duration”: “62”,
“ComponentType”: “Frontends”,
“resource”: “Frontends|Apps|YYY Proxy xxx.com.com|URLs|AAA Test YYY [/AAA/test]”,
“param”: [{
“name”: “ATTR_Proxy Host”,
“value”: “xxx”
}, {
“name”: “ATTR_Proxy Cluster”,
“value”: “machine10”
}, {
“name”: “ATTR_Proxy Folder”,
“value”: “Videos”
}, {
“name”: “ATTR_Proxy YYY”,
“value”: “AAA Test YYY [/AAA/test]”
}, {
“name”: “ATTR_Client IP”,
“value”: “192.168.225.1”
}, {
“name”: “Request Size (bytes)”,
“value”: “0”
}, {
“name”: “Response Size (bytes)”,
“value”: “298”
}, {
“name”: “TTPlugin.correlation.proxy.1.source.host”,
“value”: “machine10dev”
}, {
“name”: “TTPlugin.correlation.proxy.1.source.ip”,
“value”: “a.b.c.d”
}, {
“name”: “TTPlugin.correlation.proxy.1.source.port”,
“value”: “8080”
}, {
“name”: “Application”,
“value”: “AAA Test YYY [/AAA/test]”
}, {
“name”: “Proxy Host”,
“value”: “xxx.com.com
}, {
“name”: “CorCrossProcessData”,
“value”: “00000180b8f6dc19.6abde”
}, {
“name”: “ATTR_Proxy Host”,
“value”: “xxx.com.com
}, {
“name”: “ATTR_Proxy Cluster”,
“value”: “machine10”
}, {
“name”: “ATTR_Proxy Folder”,
“value”: “Videos”
}, {
“name”: “TTPlugin.correlation.proxy.1.source.host”,
“value”: “machine10dev”
}, {
“name”: “TTPlugin.correlation.proxy.1.source.ip”,
“value”: “a.b.c.d”
}, {
“name”: “TTPlugin.correlation.proxy.1.source.port”,
“value”: “8080”
}, {
“name”: “Trace Type”,
“value”: “Normal”
}],
“calledComponent”: [{
“duration”: “0”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-received-rule|1|All Asserts must evaluate”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “compound”
},
“calledComponent”: [{
“duration”: “0”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-received-rule|2|Include rule Frog”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “simple”
},
“startTime”: “1654179925373”
}, {
“duration”: “0”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-received-rule|3|Include rule Frog”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “simple”
},
“startTime”: “1654179925373”
}],
“startTime”: “1654179925373”
}, {
“duration”: “0”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|MTOM Global rule|1|All Asserts must evaluate”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “compound”
},
“calledComponent”: {
“duration”: “0”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|MTOM Global rule|2|Decode MTOM in”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “simple”
},
“startTime”: “1654179925374”
},
“startTime”: “1654179925374”
}, {
“duration”: “60”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|AAA Test YYY|1|All Asserts must evaluate”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “compound”
},
“calledComponent”: [{
“duration”: “0”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|AAA Test YYY|2|Set Context Variable”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “simple”
},
“startTime”: “1654179925374”
}, {
“duration”: “60”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|AAA Test YYY|3|route”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “backend”
},
“calledComponent”: {
“duration”: “60”,
“ComponentType”: “Backends”,
“resource”: “Backends|AAA Test YYY|route|https-//localhost-8443/hello?name=”,
“param”: [{
“name”: “ATTR_Proxy YYY”,
“value”: “AAA Test YYY [/AAA/test]”
}, {
“name”: “ATTR_Uri”,
“value”: “http”
}, {
“name”: “Status Code”,
“value”: “200”
}],
“startTime”: “1654179925374”
},
“startTime”: “1654179925374”
}],
“startTime”: “1654179925374”
}, {
“duration”: “1”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-completed-rule|1|All Asserts must evaluate”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “compound”
},
“calledComponent”: [{
“duration”: “0”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-completed-rule|2|Include rule Frog”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “compound”
},
“calledComponent”: {
“duration”: “0”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|custom-in-completed|2.1|All Asserts must evaluate”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “simple”
},
“startTime”: “1654179925434”
},
“startTime”: “1654179925434”
}, {
“duration”: “1”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-completed-rule|3|Include rule Frog”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “compound”
},
“calledComponent”: {
“duration”: “1”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-completed|3.1|All Asserts must evaluate”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “compound”
},
“calledComponent”: {
“duration”: “1”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-completed|3.3|At least one Assert must evaluate”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “compound”
},
“calledComponent”: [{
“duration”: “1”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-completed|3.4|All Asserts must evaluate”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “compound”
},
“calledComponent”: {
“duration”: “1”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-completed|3.5|Compare Expression”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “simple”
},
“startTime”: “1654179925434”
},
“startTime”: “1654179925434”
}, {
“duration”: “0”,
“ComponentType”: “Asserts”,
“resource”: “Asserts|in-completed|3.120|Continue Processing”,
“param”: {
“name”: “Proxy Assert Type”,
“value”: “simple”
},
“startTime”: “1654179925435”
}],
“startTime”: “1654179925434”
},
“startTime”: “1654179925434”
},
“startTime”: “1654179925434”
}],
“startTime”: “1654179925434”
}],
“ComponentName”: “YYY Proxy”,
“startTime”: “1654179925373”
}
}

So using infinity plugin we get the following. Could you please now explain the tree using the sample data?

Hi,
Thanks for your reply. As you can see, there are nested “calledComponent”. A calledComponent can have an array of other calledComponents, which itself can have other calledComponents. The number of “calledComponents” at a given level is not always the same, as well as the depth of the JSON tree. Hence the need for having the ability to display and tree and navigate through it.
Thanks - C

Check this out. Might be a good start?

Thanks a lot. I’ve been playing around a bit and I believe TreeView expects the JSON to be of fixed sized/number of nodes … In a nutshell, I have not achieved what I’m look for yet. Given that Grafana is using React in the background, I came across this GitHub - chenglou/react-treeview: Easy, light, flexible tree view made with React. which could be of value for what I want to achieve …

sorry to hear that :frowning: if push comes to shove, branch that tree view puppy and customize it.