Skip to content

Commit 1e56a3f

Browse files
committed
feat: log information regarding network updates
1 parent e5ae295 commit 1e56a3f

File tree

1 file changed

+98
-47
lines changed

1 file changed

+98
-47
lines changed

src/remote.ts

+98-47
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { computeSSHProperties, sshSupportsSetEnv } from "./sshSupport"
2121
import { Storage } from "./storage"
2222
import { AuthorityPrefix, expandPath, parseRemoteAuthority } from "./util"
2323
import { WorkspaceMonitor } from "./workspaceMonitor"
24+
import { getMemoryLogger } from "./memoryLogger"
2425

2526
export interface RemoteDetails extends vscode.Disposable {
2627
url: string
@@ -688,9 +689,20 @@ export class Remote {
688689
// showNetworkUpdates finds the SSH process ID that is being used by this
689690
// workspace and reads the file being created by the Coder CLI.
690691
private showNetworkUpdates(sshPid: number): vscode.Disposable {
692+
const logger = getMemoryLogger()
693+
logger.trackResourceCreated("NetworkStatusBar")
694+
logger.info(`Starting network updates monitor for SSH PID: ${sshPid}`)
695+
691696
const networkStatus = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1000)
697+
networkStatus.name = "Coder Workspace Update"
692698
const networkInfoFile = path.join(this.storage.getNetworkInfoPath(), `${sshPid}.json`)
693699

700+
logger.debug(`Network info file path: ${networkInfoFile}`)
701+
702+
let refreshCount = 0
703+
let disposed = false
704+
let lastFileSize = 0
705+
694706
const updateStatus = (network: {
695707
p2p: boolean
696708
latency: number
@@ -699,78 +711,117 @@ export class Remote {
699711
upload_bytes_sec: number
700712
download_bytes_sec: number
701713
}) => {
702-
let statusText = "$(globe) "
703-
if (network.p2p) {
704-
statusText += "Direct "
705-
networkStatus.tooltip = "You're connected peer-to-peer ✨."
706-
} else {
707-
statusText += network.preferred_derp + " "
708-
networkStatus.tooltip =
709-
"You're connected through a relay 🕵.\nWe'll switch over to peer-to-peer when available."
710-
}
711-
networkStatus.tooltip +=
712-
"\n\nDownload ↓ " +
713-
prettyBytes(network.download_bytes_sec, {
714-
bits: true,
715-
}) +
716-
"/s • Upload ↑ " +
717-
prettyBytes(network.upload_bytes_sec, {
718-
bits: true,
719-
}) +
720-
"/s\n"
721-
722-
if (!network.p2p) {
723-
const derpLatency = network.derp_latency[network.preferred_derp]
724-
725-
networkStatus.tooltip += `You ↔ ${derpLatency.toFixed(2)}ms ↔ ${network.preferred_derp}${(network.latency - derpLatency).toFixed(2)}ms ↔ Workspace`
726-
727-
let first = true
728-
Object.keys(network.derp_latency).forEach((region) => {
729-
if (region === network.preferred_derp) {
730-
return
731-
}
732-
if (first) {
733-
networkStatus.tooltip += `\n\nOther regions:`
734-
first = false
735-
}
736-
networkStatus.tooltip += `\n${region}: ${Math.round(network.derp_latency[region] * 100) / 100}ms`
737-
})
738-
}
714+
try {
715+
let statusText = "$(globe) "
716+
if (network.p2p) {
717+
statusText += "Direct "
718+
networkStatus.tooltip = "You're connected peer-to-peer ✨."
719+
} else {
720+
statusText += network.preferred_derp + " "
721+
networkStatus.tooltip =
722+
"You're connected through a relay 🕵.\nWe'll switch over to peer-to-peer when available."
723+
}
724+
networkStatus.tooltip +=
725+
"\n\nDownload ↓ " +
726+
prettyBytes(network.download_bytes_sec, {
727+
bits: true,
728+
}) +
729+
"/s • Upload ↑ " +
730+
prettyBytes(network.upload_bytes_sec, {
731+
bits: true,
732+
}) +
733+
"/s\n"
734+
735+
if (!network.p2p) {
736+
const derpLatency = network.derp_latency[network.preferred_derp]
737+
738+
networkStatus.tooltip += `You ↔ ${derpLatency.toFixed(2)}ms ↔ ${network.preferred_derp}${(
739+
network.latency - derpLatency
740+
).toFixed(2)}ms ↔ Workspace`
741+
742+
let first = true
743+
Object.keys(network.derp_latency).forEach((region) => {
744+
if (region === network.preferred_derp) {
745+
return
746+
}
747+
if (first) {
748+
networkStatus.tooltip += `\n\nOther regions:`
749+
first = false
750+
}
751+
networkStatus.tooltip += `\n${region}: ${Math.round(network.derp_latency[region] * 100) / 100}ms`
752+
})
753+
}
739754

740-
statusText += "(" + network.latency.toFixed(2) + "ms)"
741-
networkStatus.text = statusText
742-
networkStatus.show()
755+
statusText += "(" + network.latency.toFixed(2) + "ms)"
756+
networkStatus.text = statusText
757+
networkStatus.show()
758+
759+
// Log occasional network stats updates (every 20 refreshes)
760+
if (refreshCount % 20 === 0) {
761+
logger.debug(
762+
`Network stats update #${refreshCount}: p2p=${network.p2p}, latency=${network.latency.toFixed(2)}ms`,
763+
)
764+
}
765+
} catch (ex) {
766+
// Replace silent error ignoring with proper logging
767+
logger.error("Error updating network status", ex)
768+
}
743769
}
744-
let disposed = false
770+
745771
const periodicRefresh = () => {
746772
if (disposed) {
773+
logger.debug("Network updates: Skipping refresh as disposed=true")
747774
return
748775
}
776+
777+
refreshCount++
778+
779+
// Log every 100 refreshes to track long-term operation
780+
if (refreshCount % 100 === 0) {
781+
logger.info(`Network updates: Completed ${refreshCount} refresh cycles for SSH PID: ${sshPid}`)
782+
logger.logMemoryUsage("NETWORK_REFRESH")
783+
}
784+
749785
fs.readFile(networkInfoFile, "utf8")
750786
.then((content) => {
787+
const currentSize = content.length
788+
if (lastFileSize !== currentSize) {
789+
logger.debug(`Network info file size changed: ${lastFileSize} -> ${currentSize} bytes`)
790+
lastFileSize = currentSize
791+
}
751792
return JSON.parse(content)
752793
})
753794
.then((parsed) => {
754795
try {
755796
updateStatus(parsed)
756797
} catch (ex) {
757-
// Ignore
798+
logger.error(`Failed to update status from parsed network info`, ex)
758799
}
759800
})
760-
.catch(() => {
761-
// TODO: Log a failure here!
801+
.catch((error) => {
802+
// Replace empty catch with proper error logging
803+
logger.error(`Failed to read or parse network info file: ${networkInfoFile}`, error)
762804
})
763805
.finally(() => {
764806
// This matches the write interval of `coder vscodessh`.
765-
setTimeout(periodicRefresh, 3000)
807+
if (!disposed) {
808+
setTimeout(periodicRefresh, 3000)
809+
}
766810
})
767811
}
812+
813+
// Log the first refresh
814+
logger.debug(`Starting initial network refresh for SSH PID: ${sshPid}`)
768815
periodicRefresh()
769816

770817
return {
771818
dispose: () => {
772-
disposed = true
773-
networkStatus.dispose()
819+
if (!disposed) {
820+
logger.info(`Disposing network updates monitor for SSH PID: ${sshPid} after ${refreshCount} refreshes`)
821+
disposed = true
822+
networkStatus.dispose()
823+
logger.trackResourceDisposed("NetworkStatusBar")
824+
}
774825
},
775826
}
776827
}

0 commit comments

Comments
 (0)