123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351moduleList=ListLabelsmoduleString=StringLabelsmoduleJson=structtypet=[`Intofint|`Floatoffloat|`Stringofstring|`Listoftlist|`Boolofbool|`Assocof(string*t)list|`Null]endmoduleTimestamp:sigtypetvalto_json:t->Json.tvalof_float_seconds:float->tvalto_float_seconds:t->floatend=structtypet=floatletof_float_secondsx=xletto_float_secondsx=xletto_jsonf=letn=int_of_float@@(f*.1_000_000.)in`Intn;;endmoduleId=structtypet=[`Intofint|`Stringofstring]letcreatex=xletto_string=function|`Strings->s|`Inti->string_of_inti;;letto_json(t:t)=(t:>Json.t)letfieldid="id",to_jsonidendmoduleStack_frame=structmoduleRaw=structtypet=stringlistletcreatet=tletto_jsont=`List(List.mapt~f:(funs->`Strings))endtypet={parent:Id.toption;name:string;category:string}letcreate?parent~name~category()={parent;name;category}letto_json{parent;name;category}:Json.t=letjson=["name",`Stringname;"category",`Stringcategory]inletjson=matchparentwith|None->json|Someid->("parent",Id.to_jsonid)::jsonin`Assocjson;;endmoduleEvent=struct[@@@ocaml.warning"-37"]moduleTimestamp=Timestamptypecommon_fields={name:string;cat:stringlist;ts:Timestamp.t;tts:Timestamp.toption;pid:int;tid:int;cname:stringoption;stackframe:[`IdofId.t|`RawofStack_frame.Raw.t]option}letcommon_fields?tts?cname?(cat=[])?(pid=0)?(tid=0)?stackframe~ts~name()={tts;cname;cat;ts;pid;tid;name;stackframe};;letset_tstts={twithts}lettst=t.tstypescope=|Global|Process|Threadtypeasync=|Start|Instant|Endtypeargs=(string*Json.t)listtypeobject_kind=|New|Snapshotof{cat:stringlistoption;args:args}|Destroytypemetadata=|Process_nameof{pid:int;name:string}|Process_labelsof{pid:int;labels:string}|Thread_nameof{tid:int;pid:int;name:string}|Process_sort_indexof{pid:int;sort_index:int}|Thread_sort_indexof{pid:int;tid:int;sort_index:int}(* TODO support flow, samples, references, memory dumps *)typet=|Counterofcommon_fields*args*Id.toption|Duration_startofcommon_fields*args*Id.toption|Duration_endof{pid:int;tid:int;ts:float;args:argsoption}|Completeof{common:common_fields;args:argsoption;dur:Timestamp.t;tdur:Timestamp.toption}|Instantofcommon_fields*scopeoption*argsoption|Asyncof{common:common_fields;async:async;scope:stringoption;id:Id.t;args:argsoption}|Objectof{common:common_fields;object_kind:object_kind;id:Id.t;scope:stringoption}|Metadataofmetadataletphases="ph",`Stringsletadd_field_optto_fieldfieldfields=matchfieldwith|None->fields|Somef->to_fieldf::fields;;letjson_fields_of_common_fields{name;cat;ts;tts;pid;tid;cname;stackframe}=letfields=["name",`Stringname;"cat",`String(String.concat~sep:","cat);"ts",Timestamp.to_jsonts;"pid",`Intpid;"tid",`Inttid]inletfields=add_field_opt(funcname->"cname",`Stringcname)cnamefieldsinletfields=add_field_opt(funtts->"tts",Timestamp.to_jsontts)ttsfieldsinadd_field_opt(funstackframe->matchstackframewith|`Idid->"sf",Id.to_jsonid|`Rawr->"stack",Stack_frame.Raw.to_jsonr)stackframefields;;letjson_of_scope=function|Global->`String"g"|Process->`String"p"|Thread->`String"t";;letargs_fieldfields="args",`Assocfieldsletjson_fields_of_metadatam=letfields=letcommonpidname=["name",`Stringname;"pid",`Intpid]inmatchmwith|Process_name{pid;name}->args_field["name",`Stringname]::commonpid"thread_name"|Process_labels{pid;labels}->args_field["labels",`Stringlabels]::commonpid"process_labels"|Thread_name{tid;pid;name}->("tid",`Inttid)::args_field["name",`Stringname]::commonpid"process_name"|Process_sort_index{pid;sort_index}->args_field["sort_index",`Intsort_index]::commonpid"process_sort_index"|Thread_sort_index{pid;sort_index;tid}->("tid",`Inttid)::args_field["sort_index",`Intsort_index]::commonpid"thread_sort_index"inphase"M"::fields;;letto_json_fields:t->(string*Json.t)list=function|Counter(common,args,id)->letfields=json_fields_of_common_fieldscommoninletfields=phase"C"::args_fieldargs::fieldsinadd_field_optId.fieldidfields|Duration_start(common,args,id)->letfields=json_fields_of_common_fieldscommoninletfields=phase"B"::args_fieldargs::fieldsinadd_field_optId.fieldidfields|Duration_end{pid;tid;ts;args}->letfields=["tid",`Inttid;"pid",`Intpid;"ts",`Floatts;phase"E"]inadd_field_optargs_fieldargsfields|Complete{common;dur;args;tdur}->letfields=json_fields_of_common_fieldscommoninletfields=phase"X"::("dur",Timestamp.to_jsondur)::fieldsinletfields=add_field_opt(funtdur->"tdur",Timestamp.to_jsontdur)tdurfieldsinadd_field_optargs_fieldargsfields|Instant(common,scope,args)->letfields=json_fields_of_common_fieldscommoninletfields=phase"i"::fieldsinletfields=add_field_opt(funs->"s",json_of_scopes)scopefieldsinadd_field_optargs_fieldargsfields|Async{common;async;scope;id;args}->letfields=json_fields_of_common_fieldscommoninletfields=Id.fieldid::fieldsinletfields=letph=lets=matchasyncwith|Start->"b"|Instant->"n"|End->"e"inphasesinph::fieldsinletfields=add_field_opt(funs->"scope",`Strings)scopefieldsinadd_field_optargs_fieldargsfields|Object{common;object_kind;id;scope}->letfields=json_fields_of_common_fieldscommoninletfields=Id.fieldid::fieldsinletfields=letph,args=matchobject_kindwith|New->"N",None|Destroy->"D",None|Snapshot{cat;args}->letsnapshot=add_field_opt(funcat->"cat",`String(String.concat~sep:","cat))catargsin"O",Some["snapshot",`Assocsnapshot]inletfields=phaseph::fieldsinadd_field_optargs_fieldargsfieldsinadd_field_opt(funs->"scope",`Strings)scopefields|Metadatam->json_fields_of_metadatam;;letto_jsont=`Assoc(to_json_fieldst)letcounter?idcommonargs=Counter(common,args,id)letcomplete?tdur?args~durcommon=Complete{common;tdur;dur;args}letasync?scope?argsidasynccommon=Async{common;args;scope;id;async}letinstant?args?scopecommon=Instant(common,scope,args)endmoduleOutput_object=structtypet={displayTimeUnit:[`Ms|`Ns]option;traceEvents:Event.tlist;stackFrames:(Id.t*Stack_frame.t)listoption;extra_fields:(string*Json.t)listoption}letto_json{displayTimeUnit;traceEvents;extra_fields;stackFrames}=letjson=["traceEvents",`List(List.maptraceEvents~f:Event.to_json)]inletjson=matchdisplayTimeUnitwith|None->json|Someu->("displayTimeUnit",`String(matchuwith|`Ms->"ms"|`Ns->"ns"))::jsoninletjson:(string*Json.t)list=matchstackFrameswith|None->json|Someframes->letframes=List.mapframes~f:(fun(id,frame)->letid=Id.to_stringidinid,Stack_frame.to_jsonframe)in("stackFrames",`Assocframes)::jsoninletjson=matchextra_fieldswith|None->json|Someextra_fields->json@extra_fieldsin`Assocjson;;letcreate?displayTimeUnit?extra_fields?stackFrames~traceEvents()={displayTimeUnit;extra_fields;traceEvents;stackFrames};;end