@@ -18,109 +18,134 @@ import { encode } from 'js-base64';
1818import uuid from '../../services/uuid' ;
1919import { SegmentFields , SpanFields } from '../type' ;
2020import { CustomOptionsType } from '../../types' ;
21- import { ComponentId , ReportTypes , ServiceTag , SpanLayer , SpanType } from '../../services/constant' ;
21+ import Base from '../../services/base' ;
22+ import {
23+ ComponentId ,
24+ ReportTypes ,
25+ ServiceTag ,
26+ SpanLayer ,
27+ SpanType ,
28+ ErrorsCategory ,
29+ GradeTypeEnum ,
30+ } from '../../services/constant' ;
2231
2332export default function windowFetch ( options : CustomOptionsType , segments : SegmentFields [ ] ) {
24- const fetch : any = window . fetch ;
25- let segment = {
26- traceId : '' ,
27- service : options . service + ServiceTag ,
28- spans : [ ] ,
29- serviceInstance : options . serviceVersion ,
30- traceSegmentId : '' ,
31- } as SegmentFields ;
32- let url = { } as URL ;
33+ const origFetch : any = window . fetch ;
3334
34- window . fetch = ( ...args ) =>
35- ( async ( args : any ) => {
36- const startTime = new Date ( ) . getTime ( ) ;
37- const traceId = uuid ( ) ;
38- const traceSegmentId = uuid ( ) ;
35+ window . fetch = async ( ...args : any ) => {
36+ const startTime = new Date ( ) . getTime ( ) ;
37+ const traceId = uuid ( ) ;
38+ const traceSegmentId = uuid ( ) ;
39+ let segment = {
40+ traceId : '' ,
41+ service : options . service + ServiceTag ,
42+ spans : [ ] ,
43+ serviceInstance : options . serviceVersion ,
44+ traceSegmentId : '' ,
45+ } as SegmentFields ;
46+ let url = { } as URL ;
3947
40- if ( args [ 0 ] . startsWith ( 'http://' ) || args [ 0 ] . startsWith ( 'https://' ) ) {
41- url = new URL ( args [ 0 ] ) ;
42- } else if ( args [ 0 ] . startsWith ( '//' ) ) {
43- url = new URL ( `${ window . location . protocol } ${ args [ 0 ] } ` ) ;
44- } else {
45- url = new URL ( window . location . href ) ;
46- url . pathname = args [ 0 ] ;
47- }
48-
49- const noTrace = options . noTraceOrigins . some ( ( rule : string | RegExp ) => {
50- if ( typeof rule === 'string' ) {
51- if ( rule === url . origin ) {
52- return true ;
53- }
54- } else if ( rule instanceof RegExp ) {
55- if ( rule . test ( url . origin ) ) {
56- return true ;
57- }
58- }
59- } ) ;
60- const hasTrace = ! (
61- noTrace ||
62- ( ( [ ReportTypes . ERROR , ReportTypes . ERRORS , ReportTypes . PERF , ReportTypes . SEGMENTS ] as string [ ] ) . includes (
63- url . pathname ,
64- ) &&
65- ! options . traceSDKInternal )
66- ) ;
48+ if ( args [ 0 ] . startsWith ( 'http://' ) || args [ 0 ] . startsWith ( 'https://' ) ) {
49+ url = new URL ( args [ 0 ] ) ;
50+ } else if ( args [ 0 ] . startsWith ( '//' ) ) {
51+ url = new URL ( `${ window . location . protocol } ${ args [ 0 ] } ` ) ;
52+ } else {
53+ url = new URL ( window . location . href ) ;
54+ url . pathname = args [ 0 ] ;
55+ }
6756
68- if ( hasTrace ) {
69- const traceIdStr = String ( encode ( traceId ) ) ;
70- const segmentId = String ( encode ( traceSegmentId ) ) ;
71- const service = String ( encode ( segment . service ) ) ;
72- const instance = String ( encode ( segment . serviceInstance ) ) ;
73- const endpoint = String ( encode ( options . pagePath ) ) ;
74- const peer = String ( encode ( url . host ) ) ;
75- const index = segment . spans . length ;
76- const values = `${ 1 } -${ traceIdStr } -${ segmentId } -${ index } -${ service } -${ instance } -${ endpoint } -${ peer } ` ;
77-
78- if ( ! args [ 1 ] ) {
79- args [ 1 ] = { } ;
57+ const noTrace = options . noTraceOrigins . some ( ( rule : string | RegExp ) => {
58+ if ( typeof rule === 'string' ) {
59+ if ( rule === url . origin ) {
60+ return true ;
8061 }
81- if ( ! args [ 1 ] . headers ) {
82- args [ 1 ] . headers = { } ;
62+ } else if ( rule instanceof RegExp ) {
63+ if ( rule . test ( url . origin ) ) {
64+ return true ;
8365 }
84- args [ 1 ] . headers [ 'sw8' ] = values ;
8566 }
67+ } ) ;
68+ const hasTrace = ! (
69+ noTrace ||
70+ ( ( [ ReportTypes . ERROR , ReportTypes . ERRORS , ReportTypes . PERF , ReportTypes . SEGMENTS ] as string [ ] ) . includes (
71+ url . pathname ,
72+ ) &&
73+ ! options . traceSDKInternal )
74+ ) ;
8675
87- const result = await fetch ( ...args ) ;
76+ if ( hasTrace ) {
77+ const traceIdStr = String ( encode ( traceId ) ) ;
78+ const segmentId = String ( encode ( traceSegmentId ) ) ;
79+ const service = String ( encode ( segment . service ) ) ;
80+ const instance = String ( encode ( segment . serviceInstance ) ) ;
81+ const endpoint = String ( encode ( options . pagePath ) ) ;
82+ const peer = String ( encode ( url . host ) ) ;
83+ const index = segment . spans . length ;
84+ const values = `${ 1 } -${ traceIdStr } -${ segmentId } -${ index } -${ service } -${ instance } -${ endpoint } -${ peer } ` ;
8885
89- if ( hasTrace ) {
90- const endTime = new Date ( ) . getTime ( ) ;
91- const exitSpan : SpanFields = {
92- operationName : options . pagePath ,
93- startTime : startTime ,
94- endTime,
95- spanId : segment . spans . length ,
96- spanLayer : SpanLayer ,
97- spanType : SpanType ,
98- isError : result . status === 0 || result . status >= 400 , // when requests failed, the status is 0
99- parentSpanId : segment . spans . length - 1 ,
100- componentId : ComponentId ,
101- peer : url . host ,
102- tags : options . detailMode
103- ? [
104- {
105- key : 'http.method' ,
106- value : args [ 1 ] . method ,
107- } ,
108- {
109- key : 'url' ,
110- value : result . url ,
111- } ,
112- ]
113- : undefined ,
114- } ;
115- segment = {
116- ...segment ,
117- traceId : traceId ,
118- traceSegmentId : traceSegmentId ,
119- } ;
120- segment . spans . push ( exitSpan ) ;
121- segments . push ( segment ) ;
86+ if ( ! args [ 1 ] ) {
87+ args [ 1 ] = { } ;
88+ }
89+ if ( ! args [ 1 ] . headers ) {
90+ args [ 1 ] . headers = { } ;
12291 }
92+ args [ 1 ] . headers [ 'sw8' ] = values ;
93+ }
94+
95+ const response = await origFetch ( ...args ) ;
96+ const result = response
97+ . clone ( )
98+ . json ( )
99+ . then ( ( body : any ) => body )
100+ . catch ( ( err : any ) => err ) ;
101+ const logInfo = {
102+ uniqueId : uuid ( ) ,
103+ service : options . service ,
104+ serviceVersion : options . serviceVersion ,
105+ pagePath : options . pagePath ,
106+ category : ErrorsCategory . AJAX_ERROR ,
107+ grade : GradeTypeEnum . ERROR ,
108+ errorUrl : response . url || location . href ,
109+ message : `status: ${ response . status } ; statusText: ${ response . statusText } ;` ,
110+ collector : options . collector ,
111+ stack : 'Fetch: ' + response . statusText ,
112+ } ;
113+ new Base ( ) . traceInfo ( logInfo ) ;
114+ if ( hasTrace ) {
115+ const endTime = new Date ( ) . getTime ( ) ;
116+ const exitSpan : SpanFields = {
117+ operationName : options . pagePath ,
118+ startTime : startTime ,
119+ endTime,
120+ spanId : segment . spans . length ,
121+ spanLayer : SpanLayer ,
122+ spanType : SpanType ,
123+ isError : response . status === 0 || response . status >= 400 , // when requests failed, the status is 0
124+ parentSpanId : segment . spans . length - 1 ,
125+ componentId : ComponentId ,
126+ peer : url . host ,
127+ tags : options . detailMode
128+ ? [
129+ {
130+ key : 'http.method' ,
131+ value : args [ 1 ] . method || 'GET' ,
132+ } ,
133+ {
134+ key : 'url' ,
135+ value : response . url ,
136+ } ,
137+ ]
138+ : undefined ,
139+ } ;
140+ segment = {
141+ ...segment ,
142+ traceId : traceId ,
143+ traceSegmentId : traceSegmentId ,
144+ } ;
145+ segment . spans . push ( exitSpan ) ;
146+ segments . push ( segment ) ;
147+ }
123148
124- return result ;
125- } ) ( args ) ;
149+ return result ;
150+ } ;
126151}
0 commit comments