aboutsummaryrefslogtreecommitdiff
path: root/internal/monitor/monitor.go
blob: 4f4ab0f964fe4f69f728c990a9698c81d5e57810 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package monitor

import (
	"context"
	"time"

	"github.com/Fuwn/kaze/internal/config"
	"github.com/Fuwn/kaze/internal/storage"
)

// Result represents the outcome of a monitor check
type Result struct {
	MonitorName  string
	Timestamp    time.Time
	Status       Status
	ResponseTime time.Duration
	StatusCode   int // HTTP status code (0 for non-HTTP)
	Error        error
	SSLExpiry    *time.Time
	SSLDaysLeft  int
}

// Status represents the status of a monitor
type Status string

const (
	StatusUp       Status = "up"
	StatusDown     Status = "down"
	StatusDegraded Status = "degraded"
)

// Monitor is the interface that all monitor types must implement
type Monitor interface {
	// Name returns the monitor's name
	Name() string

	// Type returns the monitor type (http, https, tcp)
	Type() string

	// Target returns the monitor target (URL or host:port)
	Target() string

	// Interval returns the check interval
	Interval() time.Duration

	// Check performs the monitoring check and returns the result
	Check(ctx context.Context) *Result
}

// New creates a new monitor based on the configuration
func New(cfg config.MonitorConfig) (Monitor, error) {
	switch cfg.Type {
	case "http", "https":
		return NewHTTPMonitor(cfg)
	case "tcp":
		return NewTCPMonitor(cfg)
	default:
		return nil, &UnsupportedTypeError{Type: cfg.Type}
	}
}

// UnsupportedTypeError is returned when an unknown monitor type is specified
type UnsupportedTypeError struct {
	Type string
}

func (e *UnsupportedTypeError) Error() string {
	return "unsupported monitor type: " + e.Type
}

// ToCheckResult converts a monitor Result to a storage CheckResult
func (r *Result) ToCheckResult() *storage.CheckResult {
	cr := &storage.CheckResult{
		MonitorName:  r.MonitorName,
		Timestamp:    r.Timestamp,
		Status:       string(r.Status),
		ResponseTime: r.ResponseTime.Milliseconds(),
		StatusCode:   r.StatusCode,
		SSLExpiry:    r.SSLExpiry,
		SSLDaysLeft:  r.SSLDaysLeft,
	}
	if r.Error != nil {
		cr.Error = r.Error.Error()
	}
	return cr
}