@@ -7,6 +7,23 @@ import {
77 op_otel_instrumentation_scope_enter ,
88 op_otel_instrumentation_scope_enter_builtin ,
99 op_otel_log ,
10+ op_otel_metrics_data_point_attribute ,
11+ op_otel_metrics_data_point_attribute2 ,
12+ op_otel_metrics_data_point_attribute3 ,
13+ op_otel_metrics_gauge ,
14+ op_otel_metrics_histogram ,
15+ op_otel_metrics_histogram_data_point ,
16+ op_otel_metrics_histogram_data_point_entry1 ,
17+ op_otel_metrics_histogram_data_point_entry2 ,
18+ op_otel_metrics_histogram_data_point_entry3 ,
19+ op_otel_metrics_histogram_data_point_entry_final ,
20+ op_otel_metrics_resource_attribute ,
21+ op_otel_metrics_resource_attribute2 ,
22+ op_otel_metrics_resource_attribute3 ,
23+ op_otel_metrics_scope ,
24+ op_otel_metrics_submit ,
25+ op_otel_metrics_sum ,
26+ op_otel_metrics_sum_or_gauge_data_point ,
1027 op_otel_span_attribute ,
1128 op_otel_span_attribute2 ,
1229 op_otel_span_attribute3 ,
@@ -186,7 +203,7 @@ const instrumentationScopes = new SafeWeakMap<
186203> ( ) ;
187204let activeInstrumentationLibrary : WeakRef < InstrumentationLibrary > | null = null ;
188205
189- function submit (
206+ function submitSpan (
190207 spanId : string | Uint8Array ,
191208 traceId : string | Uint8Array ,
192209 traceFlags : number ,
@@ -411,7 +428,7 @@ export class Span {
411428
412429 endSpan = ( span : Span ) => {
413430 const endTime = now ( ) ;
414- submit (
431+ submitSpan (
415432 span . #spanId,
416433 span . #traceId,
417434 span . #traceFlags,
@@ -571,7 +588,7 @@ class SpanExporter {
571588 for ( let i = 0 ; i < spans . length ; i += 1 ) {
572589 const span = spans [ i ] ;
573590 const context = span . spanContext ( ) ;
574- submit (
591+ submitSpan (
575592 context . spanId ,
576593 context . traceId ,
577594 context . traceFlags ,
@@ -671,6 +688,262 @@ class ContextManager {
671688 }
672689}
673690
691+ function attributeValue ( value : IAnyValue ) {
692+ return value . boolValue ?? value . stringValue ?? value . doubleValue ??
693+ value . intValue ;
694+ }
695+
696+ function submitMetrics ( resource , scopeMetrics ) {
697+ let i = 0 ;
698+ while ( i < resource . attributes . length ) {
699+ if ( i + 2 < resource . attributes . length ) {
700+ op_otel_metrics_resource_attribute3 (
701+ resource . attributes . length ,
702+ resource . attributes [ i ] . key ,
703+ attributeValue ( resource . attributes [ i ] . value ) ,
704+ resource . attributes [ i + 1 ] . key ,
705+ attributeValue ( resource . attributes [ i + 1 ] . value ) ,
706+ resource . attributes [ i + 2 ] . key ,
707+ attributeValue ( resource . attributes [ i + 2 ] . value ) ,
708+ ) ;
709+ i += 3 ;
710+ } else if ( i + 1 < resource . attributes . length ) {
711+ op_otel_metrics_resource_attribute2 (
712+ resource . attributes . length ,
713+ resource . attributes [ i ] . key ,
714+ attributeValue ( resource . attributes [ i ] . value ) ,
715+ resource . attributes [ i + 1 ] . key ,
716+ attributeValue ( resource . attributes [ i + 1 ] . value ) ,
717+ ) ;
718+ i += 2 ;
719+ } else {
720+ op_otel_metrics_resource_attribute (
721+ resource . attributes . length ,
722+ resource . attributes [ i ] . key ,
723+ attributeValue ( resource . attributes [ i ] . value ) ,
724+ ) ;
725+ i += 1 ;
726+ }
727+ }
728+
729+ for ( let smi = 0 ; smi < scopeMetrics . length ; smi += 1 ) {
730+ const { scope, metrics } = scopeMetrics [ smi ] ;
731+
732+ op_otel_metrics_scope ( scope . name , scope . schemaUrl , scope . version ) ;
733+
734+ for ( let mi = 0 ; mi < metrics . length ; mi += 1 ) {
735+ const metric = metrics [ mi ] ;
736+ switch ( metric . dataPointType ) {
737+ case 3 :
738+ op_otel_metrics_sum (
739+ metric . descriptor . name ,
740+ // deno-lint-ignore prefer-primordials
741+ metric . descriptor . description ,
742+ metric . descriptor . unit ,
743+ metric . aggregationTemporality ,
744+ metric . isMonotonic ,
745+ ) ;
746+ for ( let di = 0 ; di < metric . dataPoints . length ; di += 1 ) {
747+ const dataPoint = metric . dataPoints [ di ] ;
748+ op_otel_metrics_sum_or_gauge_data_point (
749+ dataPoint . value ,
750+ hrToSecs ( dataPoint . startTime ) ,
751+ hrToSecs ( dataPoint . endTime ) ,
752+ ) ;
753+ const attributes = ObjectEntries ( dataPoint . attributes ) ;
754+ let i = 0 ;
755+ while ( i < attributes . length ) {
756+ if ( i + 2 < attributes . length ) {
757+ op_otel_metrics_data_point_attribute3 (
758+ attributes . length ,
759+ attributes [ i ] [ 0 ] ,
760+ attributes [ i ] [ 1 ] ,
761+ attributes [ i + 1 ] [ 0 ] ,
762+ attributes [ i + 1 ] [ 1 ] ,
763+ attributes [ i + 2 ] [ 0 ] ,
764+ attributes [ i + 2 ] [ 1 ] ,
765+ ) ;
766+ i += 3 ;
767+ } else if ( i + 1 < attributes . length ) {
768+ op_otel_metrics_data_point_attribute2 (
769+ attributes . length ,
770+ attributes [ i ] [ 0 ] ,
771+ attributes [ i ] [ 1 ] ,
772+ attributes [ i + 1 ] [ 0 ] ,
773+ attributes [ i + 1 ] [ 1 ] ,
774+ ) ;
775+ i += 2 ;
776+ } else {
777+ op_otel_metrics_data_point_attribute (
778+ attributes . length ,
779+ attributes [ i ] [ 0 ] ,
780+ attributes [ i ] [ 1 ] ,
781+ ) ;
782+ i += 1 ;
783+ }
784+ }
785+ }
786+ break ;
787+ case 2 :
788+ op_otel_metrics_gauge (
789+ metric . descriptor . name ,
790+ // deno-lint-ignore prefer-primordials
791+ metric . descriptor . description ,
792+ metric . descriptor . unit ,
793+ ) ;
794+ for ( let di = 0 ; di < metric . dataPoints . length ; di += 1 ) {
795+ const dataPoint = metric . dataPoints [ di ] ;
796+ op_otel_metrics_sum_or_gauge_data_point (
797+ dataPoint . value ,
798+ hrToSecs ( dataPoint . startTime ) ,
799+ hrToSecs ( dataPoint . endTime ) ,
800+ ) ;
801+ const attributes = ObjectEntries ( dataPoint . attributes ) ;
802+ let i = 0 ;
803+ while ( i < attributes . length ) {
804+ if ( i + 2 < attributes . length ) {
805+ op_otel_metrics_data_point_attribute3 (
806+ attributes . length ,
807+ attributes [ i ] [ 0 ] ,
808+ attributes [ i ] [ 1 ] ,
809+ attributes [ i + 1 ] [ 0 ] ,
810+ attributes [ i + 1 ] [ 1 ] ,
811+ attributes [ i + 2 ] [ 0 ] ,
812+ attributes [ i + 2 ] [ 1 ] ,
813+ ) ;
814+ i += 3 ;
815+ } else if ( i + 1 < attributes . length ) {
816+ op_otel_metrics_data_point_attribute2 (
817+ attributes . length ,
818+ attributes [ i ] [ 0 ] ,
819+ attributes [ i ] [ 1 ] ,
820+ attributes [ i + 1 ] [ 0 ] ,
821+ attributes [ i + 1 ] [ 1 ] ,
822+ ) ;
823+ i += 2 ;
824+ } else {
825+ op_otel_metrics_data_point_attribute (
826+ attributes . length ,
827+ attributes [ i ] [ 0 ] ,
828+ attributes [ i ] [ 1 ] ,
829+ ) ;
830+ i += 1 ;
831+ }
832+ }
833+ }
834+ break ;
835+ case 0 :
836+ op_otel_metrics_histogram (
837+ metric . descriptor . name ,
838+ // deno-lint-ignore prefer-primordials
839+ metric . descriptor . description ,
840+ metric . descriptor . unit ,
841+ metric . aggregationTemporality ,
842+ ) ;
843+ for ( let di = 0 ; di < metric . dataPoints . length ; di += 1 ) {
844+ const dataPoint = metric . dataPoints [ di ] ;
845+ const { boundaries, counts } = dataPoint . value . buckets ;
846+ op_otel_metrics_histogram_data_point (
847+ dataPoint . value . count ,
848+ dataPoint . value . min ?? NaN ,
849+ dataPoint . value . max ?? NaN ,
850+ dataPoint . value . sum ,
851+ hrToSecs ( dataPoint . startTime ) ,
852+ hrToSecs ( dataPoint . endTime ) ,
853+ boundaries . length ,
854+ ) ;
855+ let j = 0 ;
856+ while ( j < boundaries . length ) {
857+ if ( j + 3 < boundaries . length ) {
858+ op_otel_metrics_histogram_data_point_entry3 (
859+ counts [ j ] ,
860+ boundaries [ j ] ,
861+ counts [ j + 1 ] ,
862+ boundaries [ j + 1 ] ,
863+ counts [ j + 2 ] ,
864+ boundaries [ j + 2 ] ,
865+ ) ;
866+ j += 3 ;
867+ } else if ( j + 2 < boundaries . length ) {
868+ op_otel_metrics_histogram_data_point_entry2 (
869+ counts [ j ] ,
870+ boundaries [ j ] ,
871+ counts [ j + 1 ] ,
872+ boundaries [ j + 1 ] ,
873+ ) ;
874+ j += 2 ;
875+ } else {
876+ op_otel_metrics_histogram_data_point_entry1 (
877+ counts [ j ] ,
878+ boundaries [ j ] ,
879+ ) ;
880+ j += 1 ;
881+ }
882+ }
883+ op_otel_metrics_histogram_data_point_entry_final ( counts [ j ] ) ;
884+ const attributes = ObjectEntries ( dataPoint . attributes ) ;
885+ let i = 0 ;
886+ while ( i < attributes . length ) {
887+ if ( i + 2 < attributes . length ) {
888+ op_otel_metrics_data_point_attribute3 (
889+ attributes . length ,
890+ attributes [ i ] [ 0 ] ,
891+ attributes [ i ] [ 1 ] ,
892+ attributes [ i + 1 ] [ 0 ] ,
893+ attributes [ i + 1 ] [ 1 ] ,
894+ attributes [ i + 2 ] [ 0 ] ,
895+ attributes [ i + 2 ] [ 1 ] ,
896+ ) ;
897+ i += 3 ;
898+ } else if ( i + 1 < attributes . length ) {
899+ op_otel_metrics_data_point_attribute2 (
900+ attributes . length ,
901+ attributes [ i ] [ 0 ] ,
902+ attributes [ i ] [ 1 ] ,
903+ attributes [ i + 1 ] [ 0 ] ,
904+ attributes [ i + 1 ] [ 1 ] ,
905+ ) ;
906+ i += 2 ;
907+ } else {
908+ op_otel_metrics_data_point_attribute (
909+ attributes . length ,
910+ attributes [ i ] [ 0 ] ,
911+ attributes [ i ] [ 1 ] ,
912+ ) ;
913+ i += 1 ;
914+ }
915+ }
916+ }
917+ break ;
918+ default :
919+ continue ;
920+ }
921+ }
922+ }
923+
924+ op_otel_metrics_submit ( ) ;
925+ }
926+
927+ class MetricExporter {
928+ export ( metrics , resultCallback : ( result : ExportResult ) => void ) {
929+ try {
930+ submitMetrics ( metrics . resource , metrics . scopeMetrics ) ;
931+ resultCallback ( { code : 0 } ) ;
932+ } catch ( error ) {
933+ resultCallback ( {
934+ code : 1 ,
935+ error : ObjectPrototypeIsPrototypeOf ( error , Error )
936+ ? error as Error
937+ : new Error ( String ( error ) ) ,
938+ } ) ;
939+ }
940+ }
941+
942+ async forceFlush ( ) { }
943+
944+ async shutdown ( ) { }
945+ }
946+
674947const otelConsoleConfig = {
675948 ignore : 0 ,
676949 capture : 1 ,
@@ -708,4 +981,5 @@ export function bootstrap(
708981export const telemetry = {
709982 SpanExporter,
710983 ContextManager,
984+ MetricExporter,
711985} ;
0 commit comments