diff options
| author | Fuwn <[email protected]> | 2026-01-17 23:17:49 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-01-17 23:17:49 -0800 |
| commit | 4bc6165258cd7b5b76ccb01aa75c7cefdc35d143 (patch) | |
| tree | e7c3bb335a1efd48f82d365169e8b4a66b7abe1d /internal/monitor/tcp.go | |
| download | kaze-4bc6165258cd7b5b76ccb01aa75c7cefdc35d143.tar.xz kaze-4bc6165258cd7b5b76ccb01aa75c7cefdc35d143.zip | |
feat: Initial commit
Diffstat (limited to 'internal/monitor/tcp.go')
| -rw-r--r-- | internal/monitor/tcp.go | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/internal/monitor/tcp.go b/internal/monitor/tcp.go new file mode 100644 index 0000000..f93ae10 --- /dev/null +++ b/internal/monitor/tcp.go @@ -0,0 +1,89 @@ +package monitor + +import ( + "context" + "fmt" + "net" + "time" + + "github.com/Fuwn/kaze/internal/config" +) + +// TCPMonitor monitors TCP endpoints +type TCPMonitor struct { + name string + target string + interval time.Duration + timeout time.Duration +} + +// NewTCPMonitor creates a new TCP monitor +func NewTCPMonitor(cfg config.MonitorConfig) (*TCPMonitor, error) { + // Validate target format (should be host:port) + _, _, err := net.SplitHostPort(cfg.Target) + if err != nil { + return nil, fmt.Errorf("invalid TCP target %q: must be host:port format: %w", cfg.Target, err) + } + + return &TCPMonitor{ + name: cfg.Name, + target: cfg.Target, + interval: cfg.Interval.Duration, + timeout: cfg.Timeout.Duration, + }, nil +} + +// Name returns the monitor's name +func (m *TCPMonitor) Name() string { + return m.name +} + +// Type returns the monitor type +func (m *TCPMonitor) Type() string { + return "tcp" +} + +// Target returns the monitor target +func (m *TCPMonitor) Target() string { + return m.target +} + +// Interval returns the check interval +func (m *TCPMonitor) Interval() time.Duration { + return m.interval +} + +// Check performs the TCP connection check +func (m *TCPMonitor) Check(ctx context.Context) *Result { + result := &Result{ + MonitorName: m.name, + Timestamp: time.Now(), + } + + // Create a dialer with timeout + dialer := &net.Dialer{ + Timeout: m.timeout, + } + + // Attempt to connect + start := time.Now() + conn, err := dialer.DialContext(ctx, "tcp", m.target) + result.ResponseTime = time.Since(start) + + if err != nil { + result.Status = StatusDown + result.Error = fmt.Errorf("connection failed: %w", err) + return result + } + defer conn.Close() + + result.Status = StatusUp + + // Check for slow response (degraded if > 1 second for TCP) + if result.ResponseTime > 1*time.Second { + result.Status = StatusDegraded + result.Error = fmt.Errorf("slow connection: %v", result.ResponseTime) + } + + return result +} |