fetch_ml/internal/telemetry/telemetry.go
Jeremie Fraeys 803677be57 feat: implement Go backend with comprehensive API and internal packages
- Add API server with WebSocket support and REST endpoints
- Implement authentication system with API keys and permissions
- Add task queue system with Redis backend and error handling
- Include storage layer with database migrations and schemas
- Add comprehensive logging, metrics, and telemetry
- Implement security middleware and network utilities
- Add experiment management and container orchestration
- Include configuration management with smart defaults
2025-12-04 16:53:53 -05:00

77 lines
1.6 KiB
Go

package telemetry
import (
"bufio"
"os"
"strconv"
"strings"
"time"
"github.com/jfraeys/fetch_ml/internal/logging"
)
type IOStats struct {
ReadBytes uint64
WriteBytes uint64
}
func ReadProcessIO() (IOStats, error) {
f, err := os.Open("/proc/self/io")
if err != nil {
return IOStats{}, err
}
defer f.Close()
var stats IOStats
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "read_bytes:") {
stats.ReadBytes = parseUintField(line)
}
if strings.HasPrefix(line, "write_bytes:") {
stats.WriteBytes = parseUintField(line)
}
}
if err := scanner.Err(); err != nil {
return IOStats{}, err
}
return stats, nil
}
func DiffIO(before, after IOStats) IOStats {
var delta IOStats
if after.ReadBytes >= before.ReadBytes {
delta.ReadBytes = after.ReadBytes - before.ReadBytes
}
if after.WriteBytes >= before.WriteBytes {
delta.WriteBytes = after.WriteBytes - before.WriteBytes
}
return delta
}
func parseUintField(line string) uint64 {
parts := strings.Split(line, ":")
if len(parts) != 2 {
return 0
}
value, err := strconv.ParseUint(strings.TrimSpace(parts[1]), 10, 64)
if err != nil {
return 0
}
return value
}
func ExecWithMetrics(logger *logging.Logger, description string, threshold time.Duration, fn func() (string, error)) (string, error) {
start := time.Now()
out, err := fn()
duration := time.Since(start)
if duration > threshold {
fields := []any{"latency_ms", duration.Milliseconds(), "command", description}
if err != nil {
fields = append(fields, "error", err)
}
logger.Debug("ssh exec", fields...)
}
return out, err
}