github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/observability/probe/prober.go (about) 1 // Copyright 2022 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package probe 5 6 import ( 7 "github.com/juju/errors" 8 ) 9 10 // LivenessProber is an interface for probing targets that implement liveness 11 // probe support. 12 type LivenessProber interface { 13 // LivenessProbe returns the Prober to use for Liveness probes. 14 LivenessProbe() Prober 15 } 16 17 // Prober represents something that can be probed and return a true or false 18 // statement about it's success or optionally error if it's not able to 19 // assertain a probes success. 20 type Prober interface { 21 // Probe this thing and return true or false as to it's success. 22 // Alternatively an error can be raise when making this decision in which 23 // case the probe should be considered a failed with extra context through 24 // the error. 25 Probe() (bool, error) 26 } 27 28 // ProberProvider is implemented by entities that wish to controbute probes to 29 // the overall applications probe support. 30 type ProbeProvider interface { 31 SupportedProbes() SupportedProbes 32 } 33 34 type probeProvider struct { 35 Probes SupportedProbes 36 } 37 38 // ProbeType is an alias type to describe the type of probe in question. 39 type ProbeType string 40 41 // SupportedProbes provides a map of supported probes to the caller referenced 42 // on ProbeType. 43 type SupportedProbes map[ProbeType]Prober 44 45 const ( 46 // ProbeLiveness represents a liveness probe 47 ProbeLiveness = ProbeType("liveness") 48 49 // ProbeLiveness represents a readiness probe 50 ProbeReadiness = ProbeType("readiness") 51 52 // ProbeLiveness represents a startup probe 53 ProbeStartup = ProbeType("startup") 54 ) 55 56 // ProberFn is a convenience wrapper to transform a function into a Prober 57 // interface 58 type ProberFn func() (bool, error) 59 60 var ( 61 // Failure is a convenience wrapper probe that always evaluates to failure. 62 Failure Prober = ProberFn(func() (bool, error) { 63 return false, nil 64 }) 65 66 // NotImplemented is a convenience wrapper for supplying a probe that 67 // indiciates to it's caller that it's not implemented. Resulting error 68 // should hold true with errors.IsNotImplemented(err) 69 NotImplemented Prober = ProberFn(func() (bool, error) { 70 return false, errors.NotImplementedf("probe not implemented") 71 }) 72 73 // Success is a convenience wrapper probe that always evaluates to success. 74 Success Prober = ProberFn(func() (bool, error) { 75 return true, nil 76 }) 77 ) 78 79 // LivenessProvider is a utility function for returning a ProbeProvider for the 80 // provided liveness probe. 81 func LivenessProvider(probe Prober) ProbeProvider { 82 return Provider(SupportedProbes{ 83 ProbeLiveness: probe, 84 }) 85 } 86 87 // ReadinessProvider is a utility function for returning a ProbeProvider for the 88 // provided readiness probe. 89 func ReadinessProvider(probe Prober) ProbeProvider { 90 return Provider(SupportedProbes{ 91 ProbeReadiness: probe, 92 }) 93 } 94 95 // Probe implements Prober interface 96 func (p ProberFn) Probe() (bool, error) { 97 return p() 98 } 99 100 // Provider is a utility function for returning a ProbeProvider based on the 101 // SupportedProbes passed in. 102 func Provider(supported SupportedProbes) ProbeProvider { 103 return &probeProvider{ 104 Probes: supported, 105 } 106 } 107 108 // Supports indicates if the supplied ProbeType is in the map of supported 109 // probe types. 110 func (s SupportedProbes) Supports(t ProbeType) bool { 111 _, has := s[t] 112 return has 113 } 114 115 // SupportedProbes implements ProbeProvider interface. 116 func (p *probeProvider) SupportedProbes() SupportedProbes { 117 return p.Probes 118 }