github.com/splucs/witchcraft-go-server@v1.7.0/status/reporter/component.go (about)

     1  // Copyright (c) 2018 Palantir Technologies. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package reporter
    16  
    17  import (
    18  	"sync"
    19  
    20  	"github.com/palantir/witchcraft-go-server/conjure/witchcraft/api/health"
    21  )
    22  
    23  var _ HealthComponent = &healthComponent{}
    24  
    25  // HealthComponent is an extensible component that represents one part of the whole health picture for a service.
    26  type HealthComponent interface {
    27  	Healthy()
    28  	Warning(message string)
    29  	Error(err error)
    30  	SetHealth(healthState health.HealthState, message *string, params map[string]interface{})
    31  	Status() health.HealthState
    32  	GetHealthCheck() health.HealthCheckResult
    33  }
    34  
    35  const (
    36  	StartingState = health.HealthStateRepairing
    37  	HealthyState  = health.HealthStateHealthy
    38  	WarningState  = health.HealthStateWarning
    39  	ErrorState    = health.HealthStateError
    40  )
    41  
    42  type healthComponent struct {
    43  	sync.RWMutex
    44  
    45  	name    health.CheckType
    46  	state   health.HealthState
    47  	message *string
    48  	params  map[string]interface{}
    49  }
    50  
    51  func (r *healthComponent) Healthy() {
    52  	r.SetHealth(HealthyState, nil, nil)
    53  }
    54  
    55  func (r *healthComponent) Warning(warningMsg string) {
    56  	r.SetHealth(WarningState, &warningMsg, nil)
    57  }
    58  
    59  func (r *healthComponent) Error(err error) {
    60  	errorString := err.Error()
    61  	r.SetHealth(ErrorState, &errorString, nil)
    62  }
    63  
    64  func (r *healthComponent) SetHealth(healthState health.HealthState, message *string, params map[string]interface{}) {
    65  	r.Lock()
    66  	defer r.Unlock()
    67  
    68  	r.state = healthState
    69  	r.message = message
    70  	r.params = params
    71  }
    72  
    73  // Returns the health status for the health component
    74  func (r *healthComponent) Status() health.HealthState {
    75  	r.RLock()
    76  	defer r.RUnlock()
    77  
    78  	return r.state
    79  }
    80  
    81  // Returns the entire HealthCheckResult for the component
    82  func (r *healthComponent) GetHealthCheck() health.HealthCheckResult {
    83  	r.Lock()
    84  	defer r.Unlock()
    85  
    86  	var message *string
    87  	params := make(map[string]interface{}, len(r.params))
    88  
    89  	if r.message != nil {
    90  		messageCopy := *r.message
    91  		message = &messageCopy
    92  	}
    93  	for key, value := range r.params {
    94  		params[key] = value
    95  	}
    96  
    97  	return health.HealthCheckResult{
    98  		Type:    r.name,
    99  		State:   r.state,
   100  		Message: message,
   101  		Params:  params,
   102  	}
   103  }