1414// You should have received a copy of the GNU Affero General Public License
1515// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17- import React , { Fragment , useEffect , useState } from "react" ;
17+ import { Fragment , useEffect , useState } from "react" ;
1818import { DateTime } from "luxon" ;
1919import { useSelector } from "react-redux" ;
2020import {
@@ -37,20 +37,17 @@ import {
3737 traceMessageReceived ,
3838 traceResetMessages ,
3939} from "./traceSlice" ;
40- import { setHelpName } from "../../../ systemSlice" ;
40+ import { setHelpName } from "systemSlice" ;
4141import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper" ;
4242import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper" ;
4343import HelpMenu from "../HelpMenu" ;
44-
45- var socket : any = null ;
44+ import useWebSocket , { ReadyState } from "react-use-websocket" ;
4645
4746const Trace = ( ) => {
4847 const dispatch = useAppDispatch ( ) ;
4948
5049 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 ) ;
5451
5552 const [ statusCode , setStatusCode ] = useState < string > ( "" ) ;
5653 const [ method , setMethod ] = useState < string > ( "" ) ;
@@ -65,74 +62,66 @@ const Trace = () => {
6562 const [ errors , setErrors ] = useState < boolean > ( false ) ;
6663
6764 const [ toggleFilter , setToggleFilter ] = useState < boolean > ( false ) ;
65+ const [ logActive , setLogActive ] = useState ( false ) ;
66+ const [ wsUrl , setWsUrl ] = useState < string > ( "" ) ;
6867
69- const startTrace = ( ) => {
70- dispatch ( traceResetMessages ( ) ) ;
68+ useEffect ( ( ) => {
7169 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+ } ) ( ) ;
7880
79- if ( all ) {
80- calls = "all" ;
81- }
8281 // 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 ;
8583
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 ] ) ;
9494
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 ) ;
107101
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 ) ) ;
123109 }
124- } ;
110+ } , [ readyState , dispatch , sendMessage ] ) ;
125111
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 ] )
130119
131120 useEffect ( ( ) => {
132121 dispatch ( setHelpName ( "trace" ) ) ;
133122 // eslint-disable-next-line react-hooks/exhaustive-deps
134123 } , [ ] ) ;
135-
124+
136125 return (
137126 < Fragment >
138127 < PageHeaderWrapper label = { "Trace" } actions = { < HelpMenu /> } />
@@ -187,9 +176,7 @@ const Trace = () => {
187176 id = { "all_calls" }
188177 name = { "all_calls" }
189178 label = { "All" }
190- onChange = { ( ) => {
191- setAll ( ! all ) ;
192- } }
179+ onChange = { ( ) => setAll ( ! all ) }
193180 value = { "all" }
194181 disabled = { traceStarted }
195182 />
@@ -198,9 +185,7 @@ const Trace = () => {
198185 id = { "s3_calls" }
199186 name = { "s3_calls" }
200187 label = { "S3" }
201- onChange = { ( ) => {
202- setS3 ( ! s3 ) ;
203- } }
188+ onChange = { ( ) => setS3 ( ! s3 ) }
204189 value = { "s3" }
205190 disabled = { all || traceStarted }
206191 />
@@ -209,9 +194,7 @@ const Trace = () => {
209194 id = { "internal_calls" }
210195 name = { "internal_calls" }
211196 label = { "Internal" }
212- onChange = { ( ) => {
213- setInternal ( ! internal ) ;
214- } }
197+ onChange = { ( ) => setInternal ( ! internal ) }
215198 value = { "internal" }
216199 disabled = { all || traceStarted }
217200 />
@@ -220,9 +203,7 @@ const Trace = () => {
220203 id = { "storage_calls" }
221204 name = { "storage_calls" }
222205 label = { "Storage" }
223- onChange = { ( ) => {
224- setStorage ( ! storage ) ;
225- } }
206+ onChange = { ( ) => setStorage ( ! storage ) }
226207 value = { "storage" }
227208 disabled = { all || traceStarted }
228209 />
@@ -231,9 +212,7 @@ const Trace = () => {
231212 id = { "os_calls" }
232213 name = { "os_calls" }
233214 label = { "OS" }
234- onChange = { ( ) => {
235- setOS ( ! os ) ;
236- } }
215+ onChange = { ( ) => setOS ( ! os ) }
237216 value = { "os" }
238217 disabled = { all || traceStarted }
239218 />
@@ -249,9 +228,7 @@ const Trace = () => {
249228 < TooltipWrapper tooltip = { "More filter options" } >
250229 < Button
251230 id = { "filter-toggle" }
252- onClick = { ( ) => {
253- setToggleFilter ( ! toggleFilter ) ;
254- } }
231+ onClick = { ( ) => setToggleFilter ( ! toggleFilter ) }
255232 label = { "Filters" }
256233 icon = { < FilterIcon /> }
257234 variant = { "regular" }
@@ -269,7 +246,7 @@ const Trace = () => {
269246 label = { "Start" }
270247 data-test-id = { "trace-start-button" }
271248 variant = "callAction"
272- onClick = { startTrace }
249+ onClick = { ( ) => setLogActive ( true ) }
273250 style = { {
274251 width : "118px" ,
275252 } }
@@ -281,7 +258,7 @@ const Trace = () => {
281258 label = { "Stop Trace" }
282259 data-test-id = { "trace-stop-button" }
283260 variant = "callAction"
284- onClick = { stopTrace }
261+ onClick = { ( ) => setLogActive ( false ) }
285262 style = { {
286263 width : "118px" ,
287264 } }
@@ -330,9 +307,7 @@ const Trace = () => {
330307 label = "Status Code"
331308 placeholder = "e.g. 503"
332309 value = { statusCode }
333- onChange = { ( e ) => {
334- setStatusCode ( e . target . value ) ;
335- } }
310+ onChange = { ( e ) => setStatusCode ( e . target . value ) }
336311 disabled = { traceStarted }
337312 />
338313
@@ -343,9 +318,7 @@ const Trace = () => {
343318 label = "Function Name"
344319 placeholder = "e.g. FunctionName2055"
345320 value = { func }
346- onChange = { ( e ) => {
347- setFunc ( e . target . value ) ;
348- } }
321+ onChange = { ( e ) => setFunc ( e . target . value ) }
349322 disabled = { traceStarted }
350323 />
351324
@@ -356,9 +329,7 @@ const Trace = () => {
356329 label = "Method"
357330 placeholder = "e.g. Method 2056"
358331 value = { method }
359- onChange = { ( e ) => {
360- setMethod ( e . target . value ) ;
361- } }
332+ onChange = { ( e ) => setMethod ( e . target . value ) }
362333 disabled = { traceStarted }
363334 />
364335 </ Box >
@@ -384,9 +355,7 @@ const Trace = () => {
384355 label = "Path"
385356 placeholder = "e.g. my-bucket/my-prefix/*"
386357 value = { path }
387- onChange = { ( e ) => {
388- setPath ( e . target . value ) ;
389- } }
358+ onChange = { ( e ) => setPath ( e . target . value ) }
390359 disabled = { traceStarted }
391360 />
392361 </ Box >
@@ -403,9 +372,7 @@ const Trace = () => {
403372 type = "number"
404373 placeholder = "e.g. website.io.3249.114.12"
405374 value = { `${ threshold } ` }
406- onChange = { ( e ) => {
407- setThreshold ( parseInt ( e . target . value ) ) ;
408- } }
375+ onChange = { ( e ) => setThreshold ( parseInt ( e . target . value ) ) }
409376 disabled = { traceStarted }
410377 />
411378 </ Box >
@@ -423,9 +390,7 @@ const Trace = () => {
423390 id = { "only_errors" }
424391 name = { "only_errors" }
425392 label = { "Display only Errors" }
426- onChange = { ( ) => {
427- setErrors ( ! errors ) ;
428- } }
393+ onChange = { ( ) => setErrors ( ! errors ) }
429394 value = { "only_errors" }
430395 disabled = { traceStarted }
431396 />
0 commit comments