Files
tyto/backend/internal/collectors/network.go
vikingowl a2504c1327 feat: rename project to Tyto with owl branding
- Rename project from system-monitor to Tyto (barn owl themed)
- Update Go module name and all import paths
- Update Docker container names (tyto-backend, tyto-frontend)
- Update localStorage keys (tyto-settings, tyto-hosts)
- Create barn owl SVG favicon and PWA icons (192, 512)
- Update header with owl logo icon
- Update manifest.json and app.html with Tyto branding

Named after Tyto alba, the barn owl — nature's silent, watchful guardian

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 06:36:01 +01:00

121 lines
2.3 KiB
Go

package collectors
import (
"bufio"
"os"
"path/filepath"
"strconv"
"strings"
"tyto/internal/models"
)
type NetworkCollector struct {
procPath string
}
func NewNetworkCollector(procPath string) *NetworkCollector {
return &NetworkCollector{procPath: procPath}
}
func (c *NetworkCollector) Collect() (models.NetworkStats, error) {
stats := models.NetworkStats{
Interfaces: []models.InterfaceStats{},
}
interfaces, err := c.getInterfaceStats()
if err == nil && interfaces != nil {
stats.Interfaces = interfaces
}
stats.ConnectionCount = c.getConnectionCount()
return stats, nil
}
func (c *NetworkCollector) getInterfaceStats() ([]models.InterfaceStats, error) {
file, err := os.Open(filepath.Join(c.procPath, "net/dev"))
if err != nil {
return nil, err
}
defer file.Close()
var interfaces []models.InterfaceStats
scanner := bufio.NewScanner(file)
lineNum := 0
for scanner.Scan() {
lineNum++
// Skip header lines
if lineNum <= 2 {
continue
}
line := scanner.Text()
// Format: "iface: rx_bytes rx_packets ... tx_bytes tx_packets ..."
parts := strings.SplitN(line, ":", 2)
if len(parts) != 2 {
continue
}
name := strings.TrimSpace(parts[0])
// Skip loopback
if name == "lo" {
continue
}
fields := strings.Fields(parts[1])
if len(fields) < 10 {
continue
}
rxBytes, _ := strconv.ParseUint(fields[0], 10, 64)
rxPackets, _ := strconv.ParseUint(fields[1], 10, 64)
txBytes, _ := strconv.ParseUint(fields[8], 10, 64)
txPackets, _ := strconv.ParseUint(fields[9], 10, 64)
interfaces = append(interfaces, models.InterfaceStats{
Name: name,
RxBytes: rxBytes,
TxBytes: txBytes,
RxPackets: rxPackets,
TxPackets: txPackets,
})
}
return interfaces, nil
}
func (c *NetworkCollector) getConnectionCount() int {
count := 0
// Count TCP connections
tcpFile, err := os.Open(filepath.Join(c.procPath, "net/tcp"))
if err == nil {
scanner := bufio.NewScanner(tcpFile)
for scanner.Scan() {
count++
}
tcpFile.Close()
count-- // Subtract header line
}
// Count TCP6 connections
tcp6File, err := os.Open(filepath.Join(c.procPath, "net/tcp6"))
if err == nil {
scanner := bufio.NewScanner(tcp6File)
for scanner.Scan() {
count++
}
tcp6File.Close()
count-- // Subtract header line
}
if count < 0 {
count = 0
}
return count
}