14
14
// You should have received a copy of the GNU Affero General Public License
15
15
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
17
- import React , { Fragment , useEffect , useState } from "react" ;
17
+ import { Fragment , useEffect , useState } from "react" ;
18
18
import { DateTime } from "luxon" ;
19
19
import { useSelector } from "react-redux" ;
20
20
import {
@@ -37,20 +37,17 @@ import {
37
37
traceMessageReceived ,
38
38
traceResetMessages ,
39
39
} from "./traceSlice" ;
40
- import { setHelpName } from "../../../ systemSlice" ;
40
+ import { setHelpName } from "systemSlice" ;
41
41
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper" ;
42
42
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper" ;
43
43
import HelpMenu from "../HelpMenu" ;
44
-
45
- var socket : any = null ;
44
+ import useWebSocket , { ReadyState } from "react-use-websocket" ;
46
45
47
46
const Trace = ( ) => {
48
47
const dispatch = useAppDispatch ( ) ;
49
48
50
49
const messages = useSelector ( ( state : AppState ) => state . trace . messages ) ;
51
- const traceStarted = useSelector (
52
- ( state : AppState ) => state . trace . traceStarted ,
53
- ) ;
50
+ const traceStarted = useSelector ( ( state : AppState ) => state . trace . traceStarted ) ;
54
51
55
52
const [ statusCode , setStatusCode ] = useState < string > ( "" ) ;
56
53
const [ method , setMethod ] = useState < string > ( "" ) ;
@@ -65,74 +62,66 @@ const Trace = () => {
65
62
const [ errors , setErrors ] = useState < boolean > ( false ) ;
66
63
67
64
const [ toggleFilter , setToggleFilter ] = useState < boolean > ( false ) ;
65
+ const [ logActive , setLogActive ] = useState ( false ) ;
66
+ const [ wsUrl , setWsUrl ] = useState < string > ( "" ) ;
68
67
69
- const startTrace = ( ) => {
70
- dispatch ( traceResetMessages ( ) ) ;
68
+ useEffect ( ( ) => {
71
69
const url = new URL ( window . location . toString ( ) ) ;
72
- const isDev = process . env . NODE_ENV === "development" ;
73
- const port = isDev ? "9090" : url . port ;
74
-
75
- let calls = `${ s3 ? "s3," : "" } ${ internal ? "internal," : "" } ${
76
- storage ? "storage," : ""
77
- } ${ os ? "os," : "" } `;
70
+ const wsProt = wsProtocol ( url . protocol ) ;
71
+ const port = process . env . NODE_ENV === "development" ? "9090" : url . port ;
72
+ const calls = all ? "all" : ( ( ) => {
73
+ const c = [ ] ;
74
+ if ( s3 ) c . push ( "s3" ) ;
75
+ if ( internal ) c . push ( "internal" ) ;
76
+ if ( storage ) c . push ( "storage" ) ;
77
+ if ( os ) c . push ( "os" ) ;
78
+ return c . join ( ',' ) ;
79
+ } ) ( ) ;
78
80
79
- if ( all ) {
80
- calls = "all" ;
81
- }
82
81
// check if we are using base path, if not this always is `/`
83
- const baseLocation = new URL ( document . baseURI ) ;
84
- const baseUrl = baseLocation . pathname ;
82
+ const baseLocation = new URL ( document . baseURI ) . pathname ;
85
83
86
- const wsProt = wsProtocol ( url . protocol ) ;
87
- socket = new WebSocket (
88
- `${ wsProt } ://${
89
- url . hostname
90
- } :${ port } ${ baseUrl } ws/trace?calls=${ calls } &threshold=${ threshold } &onlyErrors=${
91
- errors ? "yes" : "no"
92
- } &statusCode=${ statusCode } &method=${ method } &funcname=${ func } &path=${ path } `,
93
- ) ;
84
+ const wsUrl = new URL ( `${ wsProt } ://${ url . hostname } :${ port } ${ baseLocation } ws/trace` ) ;
85
+ wsUrl . searchParams . append ( "calls" , calls ) ;
86
+ wsUrl . searchParams . append ( "threshold" , threshold . toString ( ) ) ;
87
+ wsUrl . searchParams . append ( "onlyErrors" , errors ? "yes" : "no" ) ;
88
+ wsUrl . searchParams . append ( "statusCode" , statusCode ) ;
89
+ wsUrl . searchParams . append ( "method" , method ) ;
90
+ wsUrl . searchParams . append ( "funcname" , func ) ;
91
+ wsUrl . searchParams . append ( "path" , path ) ;
92
+ setWsUrl ( wsUrl . href ) ;
93
+ } , [ all , s3 , internal , storage , os , threshold , errors , statusCode , method , func , path ] ) ;
94
94
95
- let interval : any | null = null ;
96
- if ( socket !== null ) {
97
- socket . onopen = ( ) => {
98
- console . log ( "WebSocket Client Connected" ) ;
99
- dispatch ( setTraceStarted ( true ) ) ;
100
- socket . send ( "ok" ) ;
101
- interval = setInterval ( ( ) => {
102
- socket . send ( "ok" ) ;
103
- } , 10 * 1000 ) ;
104
- } ;
105
- socket . onmessage = ( message : MessageEvent ) => {
106
- let m : TraceMessage = JSON . parse ( message . data . toString ( ) ) ;
95
+ const { sendMessage, lastJsonMessage, readyState} = useWebSocket < TraceMessage > ( wsUrl , {
96
+ heartbeat : {
97
+ message : "ok" , interval : 10 * 1000 , // send ok every 10 seconds
98
+ timeout : 365 * 24 * 60 * 60 * 1000 , // disconnect after 365 days (workaround, because heartbeat gets no response)
99
+ }
100
+ } , logActive ) ;
107
101
108
- m . ptime = DateTime . fromISO ( m . time ) . toJSDate ( ) ;
109
- m . key = Math . random ( ) ;
110
- dispatch ( traceMessageReceived ( m ) ) ;
111
- } ;
112
- socket . onclose = ( ) => {
113
- clearInterval ( interval ) ;
114
- console . log ( "connection closed by server" ) ;
115
- dispatch ( setTraceStarted ( false ) ) ;
116
- } ;
117
- return ( ) => {
118
- socket . close ( 1000 ) ;
119
- clearInterval ( interval ) ;
120
- console . log ( "closing websockets" ) ;
121
- setTraceStarted ( false ) ;
122
- } ;
102
+ useEffect ( ( ) => {
103
+ if ( readyState === ReadyState . CONNECTING ) {
104
+ dispatch ( traceResetMessages ( ) ) ;
105
+ } else if ( readyState === ReadyState . OPEN ) {
106
+ dispatch ( setTraceStarted ( true ) ) ;
107
+ } else if ( readyState === ReadyState . CLOSED ) {
108
+ dispatch ( setTraceStarted ( false ) ) ;
123
109
}
124
- } ;
110
+ } , [ readyState , dispatch , sendMessage ] ) ;
125
111
126
- const stopTrace = ( ) => {
127
- socket . close ( 1000 ) ;
128
- dispatch ( setTraceStarted ( false ) ) ;
129
- } ;
112
+ useEffect ( ( ) => {
113
+ if ( lastJsonMessage ) {
114
+ lastJsonMessage . ptime = DateTime . fromISO ( lastJsonMessage . time ) . toJSDate ( ) ;
115
+ lastJsonMessage . key = Math . random ( ) ;
116
+ dispatch ( traceMessageReceived ( lastJsonMessage ) ) ;
117
+ }
118
+ } , [ lastJsonMessage , dispatch ] )
130
119
131
120
useEffect ( ( ) => {
132
121
dispatch ( setHelpName ( "trace" ) ) ;
133
122
// eslint-disable-next-line react-hooks/exhaustive-deps
134
123
} , [ ] ) ;
135
-
124
+
136
125
return (
137
126
< Fragment >
138
127
< PageHeaderWrapper label = { "Trace" } actions = { < HelpMenu /> } />
@@ -187,9 +176,7 @@ const Trace = () => {
187
176
id = { "all_calls" }
188
177
name = { "all_calls" }
189
178
label = { "All" }
190
- onChange = { ( ) => {
191
- setAll ( ! all ) ;
192
- } }
179
+ onChange = { ( ) => setAll ( ! all ) }
193
180
value = { "all" }
194
181
disabled = { traceStarted }
195
182
/>
@@ -198,9 +185,7 @@ const Trace = () => {
198
185
id = { "s3_calls" }
199
186
name = { "s3_calls" }
200
187
label = { "S3" }
201
- onChange = { ( ) => {
202
- setS3 ( ! s3 ) ;
203
- } }
188
+ onChange = { ( ) => setS3 ( ! s3 ) }
204
189
value = { "s3" }
205
190
disabled = { all || traceStarted }
206
191
/>
@@ -209,9 +194,7 @@ const Trace = () => {
209
194
id = { "internal_calls" }
210
195
name = { "internal_calls" }
211
196
label = { "Internal" }
212
- onChange = { ( ) => {
213
- setInternal ( ! internal ) ;
214
- } }
197
+ onChange = { ( ) => setInternal ( ! internal ) }
215
198
value = { "internal" }
216
199
disabled = { all || traceStarted }
217
200
/>
@@ -220,9 +203,7 @@ const Trace = () => {
220
203
id = { "storage_calls" }
221
204
name = { "storage_calls" }
222
205
label = { "Storage" }
223
- onChange = { ( ) => {
224
- setStorage ( ! storage ) ;
225
- } }
206
+ onChange = { ( ) => setStorage ( ! storage ) }
226
207
value = { "storage" }
227
208
disabled = { all || traceStarted }
228
209
/>
@@ -231,9 +212,7 @@ const Trace = () => {
231
212
id = { "os_calls" }
232
213
name = { "os_calls" }
233
214
label = { "OS" }
234
- onChange = { ( ) => {
235
- setOS ( ! os ) ;
236
- } }
215
+ onChange = { ( ) => setOS ( ! os ) }
237
216
value = { "os" }
238
217
disabled = { all || traceStarted }
239
218
/>
@@ -249,9 +228,7 @@ const Trace = () => {
249
228
< TooltipWrapper tooltip = { "More filter options" } >
250
229
< Button
251
230
id = { "filter-toggle" }
252
- onClick = { ( ) => {
253
- setToggleFilter ( ! toggleFilter ) ;
254
- } }
231
+ onClick = { ( ) => setToggleFilter ( ! toggleFilter ) }
255
232
label = { "Filters" }
256
233
icon = { < FilterIcon /> }
257
234
variant = { "regular" }
@@ -269,7 +246,7 @@ const Trace = () => {
269
246
label = { "Start" }
270
247
data-test-id = { "trace-start-button" }
271
248
variant = "callAction"
272
- onClick = { startTrace }
249
+ onClick = { ( ) => setLogActive ( true ) }
273
250
style = { {
274
251
width : "118px" ,
275
252
} }
@@ -281,7 +258,7 @@ const Trace = () => {
281
258
label = { "Stop Trace" }
282
259
data-test-id = { "trace-stop-button" }
283
260
variant = "callAction"
284
- onClick = { stopTrace }
261
+ onClick = { ( ) => setLogActive ( false ) }
285
262
style = { {
286
263
width : "118px" ,
287
264
} }
@@ -330,9 +307,7 @@ const Trace = () => {
330
307
label = "Status Code"
331
308
placeholder = "e.g. 503"
332
309
value = { statusCode }
333
- onChange = { ( e ) => {
334
- setStatusCode ( e . target . value ) ;
335
- } }
310
+ onChange = { ( e ) => setStatusCode ( e . target . value ) }
336
311
disabled = { traceStarted }
337
312
/>
338
313
@@ -343,9 +318,7 @@ const Trace = () => {
343
318
label = "Function Name"
344
319
placeholder = "e.g. FunctionName2055"
345
320
value = { func }
346
- onChange = { ( e ) => {
347
- setFunc ( e . target . value ) ;
348
- } }
321
+ onChange = { ( e ) => setFunc ( e . target . value ) }
349
322
disabled = { traceStarted }
350
323
/>
351
324
@@ -356,9 +329,7 @@ const Trace = () => {
356
329
label = "Method"
357
330
placeholder = "e.g. Method 2056"
358
331
value = { method }
359
- onChange = { ( e ) => {
360
- setMethod ( e . target . value ) ;
361
- } }
332
+ onChange = { ( e ) => setMethod ( e . target . value ) }
362
333
disabled = { traceStarted }
363
334
/>
364
335
</ Box >
@@ -384,9 +355,7 @@ const Trace = () => {
384
355
label = "Path"
385
356
placeholder = "e.g. my-bucket/my-prefix/*"
386
357
value = { path }
387
- onChange = { ( e ) => {
388
- setPath ( e . target . value ) ;
389
- } }
358
+ onChange = { ( e ) => setPath ( e . target . value ) }
390
359
disabled = { traceStarted }
391
360
/>
392
361
</ Box >
@@ -403,9 +372,7 @@ const Trace = () => {
403
372
type = "number"
404
373
placeholder = "e.g. website.io.3249.114.12"
405
374
value = { `${ threshold } ` }
406
- onChange = { ( e ) => {
407
- setThreshold ( parseInt ( e . target . value ) ) ;
408
- } }
375
+ onChange = { ( e ) => setThreshold ( parseInt ( e . target . value ) ) }
409
376
disabled = { traceStarted }
410
377
/>
411
378
</ Box >
@@ -423,9 +390,7 @@ const Trace = () => {
423
390
id = { "only_errors" }
424
391
name = { "only_errors" }
425
392
label = { "Display only Errors" }
426
- onChange = { ( ) => {
427
- setErrors ( ! errors ) ;
428
- } }
393
+ onChange = { ( ) => setErrors ( ! errors ) }
429
394
value = { "only_errors" }
430
395
disabled = { traceStarted }
431
396
/>
0 commit comments