12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394(** Emitters.
This is the composable abstraction we use to represent how signals are
emitted, from their origin point (a site in user code or library code that
was instrumented, and just created a span or log record or metric), down to
the actual SDK exporter installed in the application. *)exceptionClosedtype-'at={signal_name:string;(** Description of what signal is emitted *)enabled:unit->bool;(** Return [true] if [emit] has a chance of doing something with the
signals it's given. *)emit:'alist->unit;(** Emit signals. @raise Closed if the emitter is closed. *)tick:mtime:Mtime.t->unit;(** Call regularly to ensure background work is done. The current
monotonic timestamp is passed to improve testability. *)closed:unit->bool;(** True if the emitter is already closed. Beware TOCTOU bugs. *)flush_and_close:unit->unit;(** Flush internally buffered signals, then close. *)self_metrics:now:Opentelemetry_util.Timestamp_ns.t->unit->Opentelemetry_proto.Metrics.metriclist;(** metrics about the emitter itself. *)}(** An emitter for values of type ['a]. *)let[@inline]enabledself:bool=self.enabled()let[@inline]emit(self:_t)l:unit=ifl<>[]thenself.emitllet[@inline]tick(self:_t)~mtime:unit=self.tick~mtimelet[@inline]closedself:bool=self.closed()let[@inline]flush_and_close(self:_t):unit=self.flush_and_close()let[@inline]self_metricsself~now:_list=self.self_metrics~now()(** [map f emitter] returns a new emitter that applies [f] to signals item-wise
before passing them to [emitter] *)letmap(f:'a->'b)(self:'bt):'at={selfwithemit=(funl->self.emit(List.mapfl))}(** [map_l f emitter] applies [f] to incoming lists of signals, and emits the
resulting list (if non empty) *)letflat_map(f:'alist->'blist)(self:'bt):'at=letemitl=matchflwith|[]->()|fl->self.emitflin{selfwithemit}(** [tap f e] is like [e], but every signal is passed to [f] *)lettap(f:'a->unit)(self:'at):'at=letemitl=List.iterfl;self.emitlin{selfwithemit}(** [make ~emit ()] is an emitter that calls [emit]. *)letmake?tick?closed?enabled?(flush_and_close=ignore)?(self_metrics=fun~now:_()->[])~signal_name~emit():_t=lettick=matchtickwith|None->fun~mtime:_->()|Somef->finletclosed,enabled=matchclosed,enabledwith|None,None->(fun()->false),fun()->true|Somef,None->f,fun()->not(f())|None,Somef->(fun()->not(f())),f|Somef1,Somef2->f1,f2in{signal_name;tick;emit;flush_and_close;closed;enabled;self_metrics}(** Dummy emitter, doesn't accept or emit anything. *)letdummy:_t={signal_name="dummy";enabled=(fun()->false);emit=ignore;tick=(fun~mtime:_->());closed=(fun()->true);flush_and_close=ignore;self_metrics=(fun~now:_()->[]);}