Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file opentelemetry_cohttp_lwt.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232moduleOtel=OpentelemetrymoduleOtel_lwt=Opentelemetry_lwtopenCohttpopenCohttp_lwtmoduleServer:sigvaltrace:?service_name:string->?attrs:Otel.Span.key_valuelist->('conn->Request.t->'body->(Response.t*'body)Lwt.t)->'conn->Request.t->'body->(Response.t*'body)Lwt.t(** Trace requests to a Cohttp server.
Use it like this:
{[
let my_server callback =
let callback_traced =
Opentelemetry_cohttp_lwt.Server.trace
~service_name:"my-service"
(fun _scope -> callback)
in
Cohttp_lwt_unix.Server.create
~mode:(`TCP (`Port 8080))
(Server.make () ~callback:callback_traced)
]}
*)valwith_:?trace_state:string->?service_name:string->?attrs:Otel.Span.key_valuelist->?kind:Otel.Span.kind->?links:Otel.Span_link.tlist->string->Request.t->(Request.t->'aLwt.t)->'aLwt.t(** Trace a new internal span.
Identical to [Opentelemetry_lwt.Trace.with_], but fetches/stores the trace
scope in the [x-ocaml-otel-traceparent] header in the request for
convenience.
*)valget_trace_context:?from:[`Internal|`External]->Request.t->Otel.Scope.toption(** Get the tracing scope from the custom [x-ocaml-otel-traceparent] header
added by [trace] and [with_].
*)valset_trace_context:Otel.Scope.t->Request.t->Request.t(** Set the tracing scope in the custom [x-ocaml-otel-traceparent] header used
by [trace] and [with_].
*)valremove_trace_context:Request.t->Request.t(** Strip the custom [x-ocaml-otel-traceparent] header added by [trace] and
[with_].
*)end=structletattrs_of_request(req:Request.t)=letmeth=req|>Request.meth|>Code.string_of_methodinletreferer=Header.get(Request.headersreq)"referer"inlethost=Header.get(Request.headersreq)"host"inletua=Header.get(Request.headersreq)"user-agent"inleturi=Request.urireqinList.concat[["http.method",`Stringmeth];(matchhostwith|None->[]|Someh->["http.host",`Stringh]);["http.url",`String(Uri.to_stringuri)];(matchuawith|None->[]|Someua->["http.user_agent",`Stringua]);(matchrefererwith|None->[]|Somer->["http.request.header.referer",`Stringr]);]letattrs_of_response(res:Response.t)=letcode=Response.statusresinletcode=Code.code_of_statuscodein["http.status_code",`Intcode]letheader_x_ocaml_otel_traceparent="x-ocaml-otel-traceparent"letset_trace_context(scope:Otel.Scope.t)req=letmoduleTraceparent=Otel.Trace_context.Traceparentinletheaders=Header.add(Request.headersreq)header_x_ocaml_otel_traceparent(Traceparent.to_value~trace_id:scope.trace_id~parent_id:scope.span_id())in{reqwithheaders}letget_trace_context?(from=`Internal)req=letmoduleTraceparent=Otel.Trace_context.Traceparentinletname=matchfromwith|`Internal->header_x_ocaml_otel_traceparent|`External->Traceparent.nameinmatchHeader.get(Request.headersreq)namewith|None->None|Somev->(matchTraceparent.of_valuevwith|Ok(trace_id,parent_id)->SomeOtel.Trace.{trace_id;span_id=parent_id;events=[];attrs=[]}|Error_->None)letremove_trace_contextreq=letheaders=Header.remove(Request.headersreq)header_x_ocaml_otel_traceparentin{reqwithheaders}lettrace?service_name?(attrs=[])callbackconnreqbody=letscope=get_trace_context~from:`ExternalreqinOtel_lwt.Trace.with_?service_name"request"~kind:Span_kind_server?trace_id:(Option.map(funscope->scope.Otel.Trace.trace_id)scope)?parent:(Option.map(funscope->scope.Otel.Trace.span_id)scope)~attrs:(attrs@attrs_of_requestreq)(funscope->letopenLwt.Syntaxinletreq=set_trace_contextscopereqinlet*res,body=callbackconnreqbodyinOtel.Trace.add_attrsscope(fun()->attrs_of_responseres);Lwt.return(res,body))letwith_?trace_state?service_name?attrs?(kind=Otel.Span.Span_kind_internal)?linksnamereq(f:Request.t->'aLwt.t)=letscope=get_trace_context~from:`InternalreqinOtel_lwt.Trace.with_?trace_state?service_name?attrs~kind?trace_id:(Option.map(funscope->scope.Otel.Trace.trace_id)scope)?parent:(Option.map(funscope->scope.Otel.Trace.span_id)scope)?linksname(funscope->letreq=set_trace_contextscopereqinfreq)endletclient?(scope:Otel.Scope.toption)(moduleC:Cohttp_lwt.S.Client)=letmoduleTraced=structopenLwt.Syntaxletattrs_for~uri~meth:_()=["http.method",`String(Code.string_of_method`GET);"http.url",`String(Uri.to_stringuri);]letcontext_for~uri~meth=lettrace_id=matchscopewith|Somescope->Somescope.trace_id|None->Noneinletparent=matchscopewith|Somescope->Somescope.span_id|None->Noneinletattrs=attrs_for~uri~meth()intrace_id,parent,attrsletadd_traceparent(scope:Otel.Scope.t)headers=letmoduleTraceparent=Otel.Trace_context.Traceparentinletheaders=matchheaderswith|None->Header.init()|Someheaders->headersinHeader.addheadersTraceparent.name(Traceparent.to_value~trace_id:scope.trace_id~parent_id:scope.span_id())typectx=C.ctxletcall?ctx?headers?body?chunkedmeth(uri:Uri.t):(Response.t*Cohttp_lwt.Body.t)Lwt.t=lettrace_id,parent,attrs=context_for~uri~methinOtel_lwt.Trace.with_"request"~kind:Span_kind_client?trace_id?parent~attrs(funscope->letheaders=add_traceparentscopeheadersinlet*res,body=C.call?ctx~headers?body?chunkedmethuriinOtel.Trace.add_attrsscope(fun()->letcode=Response.statusresinletcode=Code.code_of_statuscodein["http.status_code",`Intcode]);Lwt.return(res,body))lethead?ctx?headersuri=letopenLwt.Infixincall?ctx?headers`HEADuri>|=fstletget?ctx?headersuri=call?ctx?headers`GETuriletdelete?ctx?body?chunked?headersuri=call?ctx?headers?body?chunked`DELETEuriletpost?ctx?body?chunked?headersuri=call?ctx?headers?body?chunked`POSTuriletput?ctx?body?chunked?headersuri=call?ctx?headers?body?chunked`PUTuriletpatch?ctx?body?chunked?headersuri=call?ctx?headers?body?chunked`PATCHuriletpost_form?ctx?headers~paramsuri=lettrace_id,parent,attrs=context_for~uri~meth:`POSTinOtel_lwt.Trace.with_"request"~kind:Span_kind_client?trace_id?parent~attrs(funscope->letheaders=add_traceparentscopeheadersinlet*res,body=C.post_form?ctx~headers~paramsuriinOtel.Trace.add_attrsscope(fun()->letcode=Response.statusresinletcode=Code.code_of_statuscodein["http.status_code",`Intcode]);Lwt.return(res,body))letcallv=C.callv(* TODO *)endin(moduleTraced:Cohttp_lwt.S.Client)