Improve logging #5
| @@ -4,6 +4,7 @@ import { createContext, useEffect, useState } from "react"; | ||||
| import { MediaContainer } from "./media"; | ||||
| import { MinistreamApiClient, StreamInfo } from "./api"; | ||||
| import React from "react"; | ||||
| import { Log } from "./log"; | ||||
|  | ||||
| interface AppProps { | ||||
|     api: MinistreamApiClient | ||||
| @@ -33,24 +34,10 @@ export function App({ api }: AppProps) { | ||||
|         setSelectedStream(item) | ||||
|     } | ||||
|  | ||||
|     const updateStreamList = () => { | ||||
|         api.listStreams().then((list) => { | ||||
|             setStreamList(list) | ||||
|             if (list.length != streamList.length) { | ||||
|                 setStreamList(list) | ||||
|                 return | ||||
|             } | ||||
|  | ||||
|             if (!list.every((_, idx) => { | ||||
|                 return list[idx].streamKey === streamList[idx].streamKey | ||||
|             })) { | ||||
|                 setStreamList(list) | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     const updateTitle = () => { | ||||
|             api.siteInfo().then((info) => { | ||||
|         api.siteInfo().then((info) => { | ||||
|             if (info.siteName != document.title) { | ||||
|                 setTitle(info.siteName) | ||||
|                 localStorage.setItem(titleKey, info.siteName) | ||||
| @@ -59,12 +46,32 @@ export function App({ api }: AppProps) { | ||||
|         return | ||||
|     } | ||||
|  | ||||
|     setInterval(() => { | ||||
|         updateStreamList() | ||||
|     }, 10000) | ||||
|  | ||||
|     useEffect(() => { | ||||
|         const updateStreamList = () => { | ||||
|             api.listStreams().then((list) => { | ||||
|                 setStreamList((current) => { | ||||
|                     if (list.length != current.length) { | ||||
|                         Log.Debug("Updated streamList!") | ||||
|                         return list | ||||
|                     } | ||||
|                     if (!list.every((_, idx) => { | ||||
|                         return list[idx].streamKey === current[idx].streamKey | ||||
|                     })) { | ||||
|                         Log.Debug("Updated streamList..") | ||||
|                         return list | ||||
|                     } | ||||
|                     return current | ||||
|                 }) | ||||
|             }) | ||||
|  | ||||
|         } | ||||
|  | ||||
|         updateStreamList() | ||||
|         const updateInterval = setInterval(() => { | ||||
|             updateStreamList() | ||||
|         }, 10000) | ||||
|         return () => clearInterval(updateInterval) | ||||
|     }, []) | ||||
|  | ||||
|     useEffect(() => { | ||||
|   | ||||
							
								
								
									
										61
									
								
								src/js/log.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/js/log.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
|  | ||||
|  | ||||
|  | ||||
| export namespace Log { | ||||
|     var currentLevel: Level = "INFO" | ||||
|  | ||||
|     if (process.env.NODE_ENV !== 'production') {  | ||||
|         currentLevel = "DEBUG" | ||||
|     } | ||||
|  | ||||
|     export type Level = "ERROR" | "WARN" | "INFO" | "DEBUG" | ||||
|  | ||||
|     export function setLevel(level: Level) { | ||||
|         currentLevel = level | ||||
|     } | ||||
|  | ||||
|  | ||||
|     export interface LogArgs { | ||||
|         [key: string]: string | ||||
|     } | ||||
|  | ||||
|     export function Error(message: string, extras?: LogArgs) { | ||||
|         doLog("ERROR", message, extras) | ||||
|     } | ||||
|     export function Warn(message: string, extras?: LogArgs) { | ||||
|         doLog("WARN", message, extras) | ||||
|     } | ||||
|     export function Info(message: string, extras?: LogArgs) { | ||||
|         doLog("INFO", message, extras) | ||||
|     } | ||||
|     export function Debug(message: string, extras?: LogArgs) { | ||||
|         doLog("DEBUG", message, extras) | ||||
|     } | ||||
|  | ||||
|     function doLog(level: Level, message: string, extras?: LogArgs) { | ||||
|         var logLine = `[${level}] ${message}` | ||||
|  | ||||
|         if (extras) { | ||||
|             Object.keys(extras).forEach((key) => { | ||||
|                 logLine = logLine + ` ${key}=${extras[key]}` | ||||
|             }) | ||||
|         } | ||||
|  | ||||
|         if (levelToNumber(level) >= levelToNumber(currentLevel)) { | ||||
|             console.log(logLine) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function levelToNumber(level: Level): number { | ||||
|         switch (level) { | ||||
|             case "DEBUG": | ||||
|                 return 0 | ||||
|             case "INFO": | ||||
|                 return 1 | ||||
|             case "ERROR": | ||||
|                 return 2 | ||||
|             case "WARN": | ||||
|                 return 3 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -2,6 +2,7 @@ import { ComponentProps, useRef, useEffect, useState } from "react" | ||||
| import { MinistreamApiClient } from "./api" | ||||
| import { resolve } from "path" | ||||
| import React from "react" | ||||
| import { Log } from "./log" | ||||
|  | ||||
| type MediaContainerProps = { | ||||
|     selectedStream: string | null | ||||
| @@ -16,7 +17,7 @@ export function MediaContainer({ selectedStream, api }: MediaContainerProps) { | ||||
|  | ||||
|     // if selected stream changed, recreate pc, and set all to not ready. | ||||
|     useEffect(() => { | ||||
|         console.log("effect: selectedStream") | ||||
|         Log.Debug("Ran useEffect.", { "because_state": "selectedStream" }) | ||||
|         setPC(new RTCPeerConnection({ | ||||
|             iceServers: [{ urls: "stun:stun.l.google.com:19302" }] | ||||
|         })) | ||||
| @@ -27,7 +28,7 @@ export function MediaContainer({ selectedStream, api }: MediaContainerProps) { | ||||
|     }, [selectedStream]) | ||||
|  | ||||
|     useEffect(() => { | ||||
|         console.log("effect: pc") | ||||
|         Log.Debug("Ran useEffect.", { "because_state": "pc" }) | ||||
|         pc.addTransceiver("video") | ||||
|         pc.addTransceiver("audio") | ||||
|         pc.ontrack = (event) => { | ||||
| @@ -38,30 +39,30 @@ export function MediaContainer({ selectedStream, api }: MediaContainerProps) { | ||||
|  | ||||
|         pc.onicecandidate = (event) => { | ||||
|             if (!event.candidate) { | ||||
|                 console.log("ICE gathering complete.") | ||||
|                 Log.Info("ICE gathering complete.") | ||||
|                 setICEReady(true) | ||||
|             } else { | ||||
|                 console.log("Adding ICE candidate: " + event.candidate) | ||||
|                 Log.Debug("Adding ICE candidate.", { "candidate": event.candidate.candidate }) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         pc.oniceconnectionstatechange = () => { | ||||
|             console.log("ICE state changed to " + pc.iceConnectionState) | ||||
|             Log.Info("ICE gathering complete.") | ||||
|         } | ||||
|  | ||||
|         pc.createOffer().then((offer) => { | ||||
|             pc.setLocalDescription(offer).then(() => { console.log("Local description set.") }) | ||||
|             pc.setLocalDescription(offer).then(() => { Log.Debug("Local description set.") }) | ||||
|         }) | ||||
|     }, [pc]) | ||||
|  | ||||
|     useEffect(() => { | ||||
|         console.log("effect: iceReady") | ||||
|         Log.Debug("Ran useEffect", { "because_state": "iceReady" }) | ||||
|         if (!iceReady || !selectedStream) { | ||||
|             return | ||||
|         } | ||||
|         const localOfferSdp = pc.localDescription?.sdp | ||||
|         if (!localOfferSdp) { | ||||
|             console.log("Unable to get local description") | ||||
|             Log.Error("Unable to get local description.") | ||||
|             return | ||||
|         } | ||||
|         const localOffer = new RTCSessionDescription({ type: "offer", sdp: localOfferSdp }) | ||||
| @@ -73,7 +74,7 @@ export function MediaContainer({ selectedStream, api }: MediaContainerProps) { | ||||
|     }, [iceReady]) | ||||
|  | ||||
|     useEffect(() => { | ||||
|         console.log("effect: remoteReady") | ||||
|         Log.Debug("Ran useEffect", { "because_state": "remoteReady" }) | ||||
|         if (!iceReady || !selectedStream || !remoteReady) { | ||||
|             return | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user