Skip to content

Commit da407f7

Browse files
committed
feat(logging): Create log attributes for common groups
1 parent 9bbdf76 commit da407f7

File tree

6 files changed

+61
-24
lines changed

6 files changed

+61
-24
lines changed

config/endpoint/endpoint.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"errors"
88
"fmt"
99
"io"
10+
"log/slog"
1011
"math/rand"
1112
"net"
1213
"net/http"
@@ -151,6 +152,16 @@ type Endpoint struct {
151152
AlwaysRun bool `yaml:"always-run,omitempty"`
152153
}
153154

155+
func (e *Endpoint) GetLogAttribute() slog.Attr {
156+
return slog.Attr{
157+
Key: "endpoint",
158+
Value: slog.GroupValue(
159+
slog.String("name", e.Name),
160+
slog.String("group", e.Group),
161+
),
162+
}
163+
}
164+
154165
// IsEnabled returns whether the endpoint is enabled or not
155166
func (e *Endpoint) IsEnabled() bool {
156167
if e.Enabled == nil {

config/endpoint/external_endpoint.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package endpoint
22

33
import (
44
"errors"
5+
"log/slog"
56
"time"
67

78
"github.com/TwiN/gatus/v5/alerting/alert"
@@ -50,6 +51,16 @@ type ExternalEndpoint struct {
5051
NumberOfSuccessesInARow int `yaml:"-"`
5152
}
5253

54+
func (ee *ExternalEndpoint) GetLogAttribute() slog.Attr {
55+
return slog.Attr{
56+
Key: "external-endpoint",
57+
Value: slog.GroupValue(
58+
slog.String("group", ee.Group),
59+
slog.String("name", ee.Name),
60+
),
61+
}
62+
}
63+
5364
// ValidateAndSetDefaults validates the ExternalEndpoint and sets the default values
5465
func (externalEndpoint *ExternalEndpoint) ValidateAndSetDefaults() error {
5566
if err := validateEndpointNameGroupAndAlerts(externalEndpoint.Name, externalEndpoint.Group, externalEndpoint.Alerts); err != nil {

config/suite/suite.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package suite
33
import (
44
"errors"
55
"fmt"
6+
"log/slog"
67
"strconv"
78
"strings"
89
"time"
@@ -56,6 +57,16 @@ type Suite struct {
5657
Endpoints []*endpoint.Endpoint `yaml:"endpoints"`
5758
}
5859

60+
func (s *Suite) GetLogAttribute() slog.Attr {
61+
return slog.Attr{
62+
Key: "suite",
63+
Value: slog.GroupValue(
64+
slog.String("name", s.Name),
65+
slog.String("group", s.Group),
66+
),
67+
}
68+
}
69+
5970
// IsEnabled returns whether the suite is enabled
6071
func (s *Suite) IsEnabled() bool {
6172
if s.Enabled == nil {

watchdog/endpoint.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,44 +34,45 @@ func monitorEndpoint(ep *endpoint.Endpoint, cfg *config.Config, extraLabels []st
3434
}
3535

3636
func executeEndpoint(ep *endpoint.Endpoint, cfg *config.Config, extraLabels []string) {
37+
logger := slog.With(ep.GetLogAttribute())
38+
3739
// Acquire semaphore to limit concurrent endpoint monitoring
3840
if err := monitoringSemaphore.Acquire(ctx, 1); err != nil {
3941
// Only fails if context is cancelled (during shutdown)
40-
slog.Debug("Context cancelled, skipping execution", "error", err.Error())
42+
logger.Debug("Context cancelled; skipping execution", "error", err.Error())
4143
return
4244
}
4345
defer monitoringSemaphore.Release(1)
4446
// If there's a connectivity checker configured, check if Gatus has internet connectivity
4547
if cfg.Connectivity != nil && cfg.Connectivity.Checker != nil && !cfg.Connectivity.Checker.IsConnected() {
46-
slog.Info("No connectivity; skipping execution")
48+
logger.Info("No connectivity, skipping execution")
4749
return
4850
}
4951

50-
// TODO#1185 This might be a good method to create a logger with added fields for group, endpoint, key, etc. and use that logger throughout the method.
51-
slog.Debug("Monitoring endpoint", "group", ep.Group, "endpoint", ep.Name, "key", ep.Key())
52+
logger.Debug("Monitoring start")
5253
result := ep.EvaluateHealth()
5354
if cfg.Metrics {
5455
metrics.PublishMetricsForEndpoint(ep, result, extraLabels)
5556
}
5657
UpdateEndpointStatus(ep, result)
57-
if logging.Level() == slog.LevelDebug && !result.Success { // TODO: Check if it is possible to get the configured level directly from slog
58-
slog.Debug("Monitored endpoint", "group", ep.Group, "name", ep.Name, "key", ep.Key(), "success", result.Success, "errors", len(result.Errors), "duration", result.Duration.Round(time.Millisecond), "body", result.Body)
58+
if logging.Level() == slog.LevelDebug && !result.Success { // TODO#1185 Check if it is possible to get the configured level directly from slog
59+
logger.Debug("Monitoring done with errors", "errors", len(result.Errors), "duration", result.Duration.Round(time.Millisecond), "body", result.Body)
5960
} else {
60-
slog.Info("Monitored endpoint", "group", ep.Group, "name", ep.Name, "key", ep.Key(), "success", result.Success, "errors", len(result.Errors), "duration", result.Duration.Round(time.Millisecond))
61+
logger.Info("Monitoring done", "success", result.Success, "errors", len(result.Errors), "duration", result.Duration.Round(time.Millisecond))
6162
}
6263
inEndpointMaintenanceWindow := false
6364
for _, maintenanceWindow := range ep.MaintenanceWindows {
6465
if maintenanceWindow.IsUnderMaintenance() {
65-
slog.Debug("Under endpoint maintenance window")
66+
logger.Debug("Under endpoint maintenance window")
6667
inEndpointMaintenanceWindow = true
6768
}
6869
}
6970
if !cfg.Maintenance.IsUnderMaintenance() && !inEndpointMaintenanceWindow {
7071
HandleAlerting(ep, result, cfg.Alerting)
7172
} else {
72-
slog.Debug("Not handling alerting because currently in the maintenance window")
73+
logger.Debug("Not handling alerting due to maintenance window")
7374
}
74-
slog.Debug("Waiting for next execution", "group", ep.Group, "endpoint", ep.Name, "key", ep.Key(), "interval", ep.Interval)
75+
logger.Debug("Wait for next monitoring", "interval", ep.Interval)
7576
}
7677

7778
// UpdateEndpointStatus persists the endpoint result in the storage

watchdog/external_endpoint.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,34 @@ func monitorExternalEndpointHeartbeat(ee *endpoint.ExternalEndpoint, cfg *config
2626
}
2727

2828
func executeExternalEndpointHeartbeat(ee *endpoint.ExternalEndpoint, cfg *config.Config, extraLabels []string) {
29+
logger := slog.With(ee.GetLogAttribute())
30+
2931
// Acquire semaphore to limit concurrent external endpoint monitoring
3032
if err := monitoringSemaphore.Acquire(ctx, 1); err != nil {
3133
// Only fails if context is cancelled (during shutdown)
32-
slog.Debug("Context cancelled, skipping execution", "error", err.Error())
34+
logger.Debug("Context cancelled; skipping execution", "error", err.Error())
3335
return
3436
}
3537
defer monitoringSemaphore.Release(1)
3638
// If there's a connectivity checker configured, check if Gatus has internet connectivity
3739
if cfg.Connectivity != nil && cfg.Connectivity.Checker != nil && !cfg.Connectivity.Checker.IsConnected() {
38-
slog.Info("No connectivity; skipping external endpoint execution")
40+
logger.Info("No connectivity, skipping execution")
3941
return
4042
}
41-
slog.Debug("Monitoring external endpoint", "group", ee.Group, "name", ee.Name, "key", ee.Key())
43+
logger.Debug("Monitoring start")
4244
convertedEndpoint := ee.ToEndpoint()
4345
hasReceivedResultWithinHeartbeatInterval, err := store.Get().HasEndpointStatusNewerThan(ee.Key(), time.Now().Add(-ee.Heartbeat.Interval))
4446
if err != nil {
4547
slog.Error("Failed to check if external endpoint has received a result within the heartbeat interval", "group", ee.Group, "name", ee.Name, "key", ee.Key(), "error", err.Error())
48+
logger.Error("Monitoring error", "error", err.Error())
4649
return
4750
}
4851
if hasReceivedResultWithinHeartbeatInterval {
4952
// If we received a result within the heartbeat interval, we don't want to create a successful result, so we
5053
// skip the rest. We don't have to worry about alerting or metrics, because if the previous heartbeat failed
5154
// while this one succeeds, it implies that there was a new result pushed, and that result being pushed
5255
// should've resolved the alert.
53-
slog.Info("External endpint heartbeat received within interval", "group", ee.Group, "name", ee.Name, "key", ee.Key(), "success", hasReceivedResultWithinHeartbeatInterval, "errors", 0)
56+
logger.Info("Monitoring success, heartbeat received within interval", "success", hasReceivedResultWithinHeartbeatInterval, "errors", 0)
5457
return
5558
}
5659
// All code after this point assumes the heartbeat failed
@@ -63,7 +66,7 @@ func executeExternalEndpointHeartbeat(ee *endpoint.ExternalEndpoint, cfg *config
6366
metrics.PublishMetricsForEndpoint(convertedEndpoint, result, extraLabels)
6467
}
6568
UpdateEndpointStatus(convertedEndpoint, result)
66-
slog.Info("Heartbeat checked for external endpoint", "group", ee.Group, "name", ee.Name, "key", ee.Key(), "success", result.Success, "errors", len(result.Errors), "duration", result.Duration.Round(time.Millisecond))
69+
logger.Info("Monitoring done", "success", result.Success, "errors", len(result.Errors), "duration", result.Duration.Round(time.Millisecond))
6770
inEndpointMaintenanceWindow := false
6871
for _, maintenanceWindow := range ee.MaintenanceWindows {
6972
if maintenanceWindow.IsUnderMaintenance() {
@@ -77,7 +80,6 @@ func executeExternalEndpointHeartbeat(ee *endpoint.ExternalEndpoint, cfg *config
7780
ee.NumberOfSuccessesInARow = convertedEndpoint.NumberOfSuccessesInARow
7881
ee.NumberOfFailuresInARow = convertedEndpoint.NumberOfFailuresInARow
7982
} else {
80-
slog.Debug("Not handling alerting because currently in the maintenance window")
83+
logger.Debug("Not handling alerting due to maintenance window")
8184
}
82-
slog.Debug("Waiting for next external endpoint execution", "group", ee.Group, "name", ee.Name, "key", ee.Key(), "interval", ee.Heartbeat.Interval)
8385
}

watchdog/suite.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,21 @@ func monitorSuite(s *suite.Suite, cfg *config.Config, extraLabels []string, ctx
3131

3232
// executeSuite executes a suite with proper concurrency control
3333
func executeSuite(s *suite.Suite, cfg *config.Config, extraLabels []string) {
34+
logger := slog.With(s.GetLogAttribute())
35+
3436
// Acquire semaphore to limit concurrent suite monitoring
3537
if err := monitoringSemaphore.Acquire(ctx, 1); err != nil {
3638
// Only fails if context is cancelled (during shutdown)
37-
slog.Debug("Context cancelled, skipping execution", "suite", s.Name, "error", err.Error())
39+
logger.Debug("Context cancelled; skipping execution", "error", err.Error())
3840
return
3941
}
4042
defer monitoringSemaphore.Release(1)
4143
// Check connectivity if configured
4244
if cfg.Connectivity != nil && cfg.Connectivity.Checker != nil && !cfg.Connectivity.Checker.IsConnected() {
43-
slog.Info("No connectivity; skipping suite execution", "name", s.Name)
45+
logger.Info("No connectivity, skipping execution")
4446
return
4547
}
46-
slog.Debug("Monitoring suite", "group", s.Group, "name", s.Name, "key", s.Key())
48+
logger.Debug("Monitoring start")
4749
// Execute the suite using its Execute method
4850
result := s.Execute()
4951
// Publish metrics for the suite execution
@@ -62,7 +64,7 @@ func executeSuite(s *suite.Suite, cfg *config.Config, extraLabels []string) {
6264
inEndpointMaintenanceWindow := false
6365
for _, maintenanceWindow := range ep.MaintenanceWindows {
6466
if maintenanceWindow.IsUnderMaintenance() {
65-
slog.Debug("Endpoint under maintenance window", "suite", s.Name, "endpoint", ep.Name)
67+
logger.Debug("Under endpoint maintenance window", ep.GetLogAttribute())
6668
inEndpointMaintenanceWindow = true
6769
break
6870
}
@@ -73,14 +75,13 @@ func executeSuite(s *suite.Suite, cfg *config.Config, extraLabels []string) {
7375
}
7476
}
7577
}
76-
slog.Info("Completed suite execution", slog.Group("details",
77-
slog.String("name", s.Name),
78+
logger.Info("Completed suite execution",
7879
slog.Bool("success", result.Success),
7980
slog.Int("errors", len(result.Errors)),
8081
slog.Duration("duration", result.Duration),
8182
slog.Int("endpoints_executed", len(result.EndpointResults)),
8283
slog.Int("total_endpoints", len(s.Endpoints)),
83-
))
84+
)
8485
}
8586

8687
// UpdateSuiteStatus persists the suite result in the database

0 commit comments

Comments
 (0)