-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
status.go
160 lines (142 loc) · 5.71 KB
/
status.go
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
// Package componentstatus is an experimental module that defines how components should
// report health statues, how collector hosts should facilitate component status reporting,
// and how extensions should watch for new component statuses.
//
// This package is currently under development and is exempt from the Collector SIG's
// breaking change policy.
package componentstatus // import "go.opentelemetry.io/collector/component/componentstatus"
import (
"time"
"go.opentelemetry.io/collector/component"
)
// Reporter is an extra interface for `component.Host` implementations.
// A Reporter defines how to report a `componentstatus.Event`.
type Reporter interface {
// Report allows a component to report runtime changes in status. The service
// will automatically report status for a component during startup and shutdown. Components can
// use this method to report status after start and before shutdown. For more details about
// component status reporting see: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/component-status.md
Report(*Event)
}
// Watcher is an extra interface for Extension hosted by the OpenTelemetry
// Collector that is to be implemented by extensions interested in changes to component
// status.
//
// TODO: consider moving this interface to a new package/module like `extension/statuswatcher`
// https://github.com/open-telemetry/opentelemetry-collector/issues/10764
type Watcher interface {
// ComponentStatusChanged notifies about a change in the source component status.
// Extensions that implement this interface must be ready that the ComponentStatusChanged
// may be called before, after or concurrently with calls to Component.Start() and Component.Shutdown().
// The function may be called concurrently with itself.
ComponentStatusChanged(source *InstanceID, event *Event)
}
type Status int32
// Enumeration of possible component statuses
const (
// StatusNone indicates absence of component status.
StatusNone Status = iota
// StatusStarting indicates the component is starting.
StatusStarting
// StatusOK indicates the component is running without issues.
StatusOK
// StatusRecoverableError indicates that the component has experienced a transient error and may recover.
StatusRecoverableError
// StatusPermanentError indicates that the component has detected a condition at runtime that will need human intervention to fix. The collector will continue to run in a degraded mode.
StatusPermanentError
// StatusFatalError indicates that the collector has experienced a fatal runtime error and will shut down.
StatusFatalError
// StatusStopping indicates that the component is in the process of shutting down.
StatusStopping
// StatusStopped indicates that the component has completed shutdown.
StatusStopped
)
// String returns a string representation of a Status
func (s Status) String() string {
switch s {
case StatusStarting:
return "StatusStarting"
case StatusOK:
return "StatusOK"
case StatusRecoverableError:
return "StatusRecoverableError"
case StatusPermanentError:
return "StatusPermanentError"
case StatusFatalError:
return "StatusFatalError"
case StatusStopping:
return "StatusStopping"
case StatusStopped:
return "StatusStopped"
}
return "StatusNone"
}
// Event contains a status and timestamp, and can contain an error
type Event struct {
status Status
err error
// TODO: consider if a timestamp is necessary in the default Event struct or is needed only for the healthcheckv2 extension
// https://github.com/open-telemetry/opentelemetry-collector/issues/10763
timestamp time.Time
}
// Status returns the Status (enum) associated with the Event
func (ev *Event) Status() Status {
return ev.status
}
// Err returns the error associated with the Event.
func (ev *Event) Err() error {
return ev.err
}
// Timestamp returns the timestamp associated with the Event
func (ev *Event) Timestamp() time.Time {
return ev.timestamp
}
// NewEvent creates and returns a Event with the specified status and sets the timestamp
// time.Now(). To set an error on the event for an error status use one of the dedicated
// constructors (e.g. NewRecoverableErrorEvent, NewPermanentErrorEvent, NewFatalErrorEvent)
func NewEvent(status Status) *Event {
return &Event{
status: status,
timestamp: time.Now(),
}
}
// NewRecoverableErrorEvent wraps a transient error
// passed as argument as a Event with a status StatusRecoverableError
// and a timestamp set to time.Now().
func NewRecoverableErrorEvent(err error) *Event {
ev := NewEvent(StatusRecoverableError)
ev.err = err
return ev
}
// NewPermanentErrorEvent wraps an error requiring human intervention to fix
// passed as argument as a Event with a status StatusPermanentError
// and a timestamp set to time.Now().
func NewPermanentErrorEvent(err error) *Event {
ev := NewEvent(StatusPermanentError)
ev.err = err
return ev
}
// NewFatalErrorEvent wraps the fatal runtime error passed as argument as a Event
// with a status StatusFatalError and a timestamp set to time.Now().
func NewFatalErrorEvent(err error) *Event {
ev := NewEvent(StatusFatalError)
ev.err = err
return ev
}
// StatusIsError returns true for error statuses (e.g. StatusRecoverableError,
// StatusPermanentError, or StatusFatalError)
func StatusIsError(status Status) bool {
return status == StatusRecoverableError ||
status == StatusPermanentError ||
status == StatusFatalError
}
// ReportStatus is a helper function that handles checking if the component.Host has implemented Reporter.
// If it has, the Event is reported. Otherwise, nothing happens.
func ReportStatus(host component.Host, e *Event) {
statusReporter, ok := host.(Reporter)
if ok {
statusReporter.Report(e)
}
}