RFR: 7393: Add vanilla Java JSON serializer for IItemCollections

Marcus Hirt hirt at openjdk.java.net
Tue Sep 7 12:57:51 UTC 2021


On Wed, 21 Jul 2021 16:42:41 GMT, Alex Ciminian <github.com+348973+cimi at openjdk.org> wrote:

> ## What is this?
> 
> This PR adds a JSON serialiser for IItemCollections, with no other library dependencies. This implementation was originally done in #225 with the goal of providing JSON data directly to the browser over a WebSocket. 
> 
> We could use this as a generic representation of events to drive all visualisations we display in JMC since all structures (tree, graph etc) can be constructed from this base format. This would ensure a uniform interface for all visualisations (they could all expect event JSON data). 
> 
> ## Serialized event structure
> 
> The serialized recording currently looks like this:
> 
> 
> {
>   "events": [{
>     "eventType": "<type name>",
>     "attributes": {
>       "<attr1_name>": "<attr1_value>",
>       "<attr2_name>": "<attr2_value>"
>     }
>   }]
> } 
> 
> 
> We've previously discussed having a `metadata` section in the JSON file in order to avoid repeating the attribute names - this is not implemented yet and I'd like to understand better how we want it to look like. It would be good to have a consistent representation of the event types and attributes across recordings so i.e. we don't encode them to different symbols and then have the same item represented in different ways. Since the encoding table will be shipped with the serialised items, in practice they can be decoded to the same thing but I'm not sure the benefit is worth the complexity. The only benefit I see for this is having a smaller document size, but we can probably get better compression if we just use zip.
> 
> ## Testing and benchmarking
> 
> This PR currently has no tests because I wasn't sure how we want to run them here and what test data I can use. [This project, jmc-json-benchmarks](https://github.com/cimi/jmc-json-benchmarks), has the same code with tests and also has logic to benchmark different JSON serialisation implementations using JMH. While doing the JMH analysis, we found that FastJSON is significantly faster compared to this ad-hoc implementation, but for simplicity we can start with this implementation and replace later if performance becomes an issue.
> 
> You can see the benchmark results here: https://jmh.morethan.io/?source=https://raw.githubusercontent.com/cimi/jmc-json-benchmarks/master/all-results.json
> 
> ## Examples of serialised events
> 
> These examples were taken from the test cases used to validate the implementation, you can see the full test output here:
> 
> * https://github.com/cimi/jmc-json-benchmarks/blob/master/src/test/resources/latency_before.json
> * https://github.com/cimi/jmc-json-benchmarks/blob/master/src/test/resources/wldf.json
> 
> (The number of events serialised from the recording was truncated).
> 
> <details>
>   <summary>EJB_Pool_Manager_Pre_Invoke</summary>
>   
> 
> {
>     "eventType": "http://www.oracle.com/wls/flightrecorder/medium/wls/EJB/EJB_Pool_Manager_Pre_Invoke",
>     "attributes": {
>       "(endTime)": 1384767793251009019,
>       "eventThread": "[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'",
>       "stackTrace": {
>         "frames": [{
>           "name": "weblogic.diagnostics.instrumentation.gathering.FlightRecorderEventHelper#recordStatelessEvent(Lweblogic/diagnostics/instrumentation/DiagnosticMonitor;Lweblogic/diagnostics/instrumentation/JoinPoint;)V",
>           "line": 92,
>           "type": "INTERPRETED"
>         }, {
>           "name": "weblogic.diagnostics.instrumentation.action.FlightRecorderStatelessAction#process(Lweblogic/diagnostics/instrumentation/JoinPoint;)V",
>           "line": 51,
>           "type": "INTERPRETED"
>         }, [... many others ...], {
>           "name": "weblogic.work.ExecuteThread#run()V",
>           "line": 248,
>           "type": "INTERPRETED"
>         }]
>       },
>       "userID": "<anonymous>",
>       "returnValue": "",
>       "methodName": "preInvoke",
>       "className": "weblogic.ejb.container.manager.StatelessManager",
>       "transactionID": "BEA1-000217F1E993CDB6E1F6",
>       "RCID": null,
>       "RID": null,
>       "ECID": "8ec006a7-30e9-4fac-be7f-716f42d3cbc8-0000001c",
>       "ejbMethodName": null,
>       "ejbName": null,
>       "componentName": null,
>       "applicationName": null,
>       "subsystem": "EJB"
>     }
> 
> </details>
> 
> <details>
>   <summary>jdk.PSHeapSummary</summary>
> 
> 
> {
>     "eventType": "jdk.PSHeapSummary",
>     "attributes": {
>       "(endTime)": 1384767779307774408,
>       "gcId": 4,
>       "when": "After GC",
>       "oldSpace:start": 3758096384,
>       "oldSpace:committedEnd": 3937402880,
>       "oldSpace:committedSize": 179306496,
>       "oldSpace:reservedEnd": 4115660800,
>       "oldSpace:reservedSize": 357564416,
>       "oldObjectSpace:start": 3758096384,
>       "oldObjectSpace:end": 3937402880,
>       "oldObjectSpace:used": 50007536,
>       "oldObjectSpace:size": 179306496,
>       "youngSpace:start": 4115660800,
>       "youngSpace:committedEnd": 4294967296,
>       "youngSpace:committedSize": 179306496,
>       "youngSpace:reservedEnd": 4294967296,
>       "youngSpace:reservedSize": 179306496,
>       "edenSpace:start": 4115660800,
>       "edenSpace:end": 4272947200,
>       "edenSpace:used": 0,
>       "edenSpace:size": 157286400,
>       "fromSpace:start": 4272947200,
>       "fromSpace:end": 4283957248,
>       "fromSpace:used": 10977416,
>       "fromSpace:size": 11010048,
>       "toSpace:start": 4283957248,
>       "toSpace:end": 4294967296,
>       "toSpace:used": 0,
>       "toSpace:size": 11010048
>     }
> 
> </details>
> 
> <details>
>   <summary>jdk.NetworkUtilization</summary>
> 
> 
> {
>     "eventType": "jdk.NetworkUtilization",
>     "attributes": {
>       "startTime": 1541771978642206341,
>       "networkInterface": "Hyper-V Virtual Ethernet Adapter #15",
>       "readRate": 3349,
>       "writeRate": 461
>     }
> }

Changes requested by hirt (Lead).

HI Cimi! For the tests, simply see flightrecorder.serializers.test. Even a few trivial tests validating the expected results is better than nothing.

core/org.openjdk.jmc.flightrecorder.serializers/src/main/java/org/openjdk/jmc/flightrecorder/serializers/json/IItemCollectionJsonSerializer.java line 1:

> 1: package org.openjdk.jmc.flightrecorder.serializers.json;

Lacks standard JMC license header (Oracle + Datadog).

core/org.openjdk.jmc.flightrecorder.serializers/src/main/java/org/openjdk/jmc/flightrecorder/serializers/json/JsonWriter.java line 1:

> 1: package org.openjdk.jmc.flightrecorder.serializers.json;

Lacks standard JMC license header (Oracle + Datadog).

core/org.openjdk.jmc.flightrecorder.serializers/src/main/java/org/openjdk/jmc/flightrecorder/serializers/json/StructuredWriter.java line 1:

> 1: package org.openjdk.jmc.flightrecorder.serializers.json;

Lacks standard JMC license header (Oracle + Datadog).

core/tests/org.openjdk.jmc.flightrecorder.serializers.test/src/test/java/org/openjdk/jmc/flightrecorder/serializers/json/test/IItemCollectionJsonSerializerTest.java line 1:

> 1: package org.openjdk.jmc.flightrecorder.serializers.json.test;

Lacks standard JMC license header (Oracle + Datadog).

-------------

PR: https://git.openjdk.java.net/jmc/pull/279


More information about the jmc-dev mailing list