aboutsummaryrefslogtreecommitdiff
path: root/internal/monitor/tcp.go
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-01-17 23:17:49 -0800
committerFuwn <[email protected]>2026-01-17 23:17:49 -0800
commit4bc6165258cd7b5b76ccb01aa75c7cefdc35d143 (patch)
treee7c3bb335a1efd48f82d365169e8b4a66b7abe1d /internal/monitor/tcp.go
downloadkaze-4bc6165258cd7b5b76ccb01aa75c7cefdc35d143.tar.xz
kaze-4bc6165258cd7b5b76ccb01aa75c7cefdc35d143.zip
feat: Initial commit
Diffstat (limited to 'internal/monitor/tcp.go')
-rw-r--r--internal/monitor/tcp.go89
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
+}