github.com/blend/go-sdk@v1.20220411.3/status/tracked_action_aggregator.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package status 9 10 import ( 11 "net/http" 12 "sort" 13 14 "github.com/blend/go-sdk/async" 15 "github.com/blend/go-sdk/logger" 16 "github.com/blend/go-sdk/web" 17 ) 18 19 // NewTrackedActionAggregator returns a new tracked action aggregator. 20 func NewTrackedActionAggregator(trackedActions ...*TrackedAction) *TrackedActionAggregator { 21 taa := &TrackedActionAggregator{ 22 TrackedActions: make(map[string]*TrackedAction), 23 } 24 for index := range trackedActions { 25 trackedAction := trackedActions[index] 26 taa.TrackedActions[trackedAction.ServiceName] = trackedAction 27 } 28 return taa 29 } 30 31 // TrackedActionAggregator aggregates tracker results. 32 type TrackedActionAggregator struct { 33 TrackedActions map[string]*TrackedAction 34 Log logger.Log 35 } 36 37 // Interceptor returns a new tracked action. 38 func (taa *TrackedActionAggregator) Interceptor(serviceName string, opts ...TrackedActionOption) async.Interceptor { 39 trackedAction := NewTrackedAction(serviceName, opts...) 40 taa.TrackedActions[serviceName] = trackedAction 41 return trackedAction 42 } 43 44 // Endpoint implements the endpoint. 45 func (taa *TrackedActionAggregator) Endpoint(servicesToCheck ...string) web.Action { 46 return func(r *web.Ctx) web.Result { 47 statuses := make(map[string]Info) 48 for _, serviceName := range taa.servicesOrDefault(servicesToCheck...) { 49 if tracker, ok := taa.TrackedActions[serviceName]; ok { 50 statuses[serviceName] = tracker.GetStatus() 51 } 52 } 53 statusCode := http.StatusOK 54 status := taa.getSummarySignal(statuses) 55 if status != SignalGreen { 56 statusCode = http.StatusServiceUnavailable 57 } 58 return web.JSON.Status(statusCode, TrackedActionsResult{ 59 Status: status, 60 SubSystems: statuses, 61 }) 62 } 63 } 64 65 // 66 // Private / Internal 67 // 68 69 // getSummarySignal implements a this or that (green | red) based on if _any_ of the infos aren't green. 70 func (taa TrackedActionAggregator) getSummarySignal(statuses map[string]Info) (signal Signal) { 71 signal = SignalGreen 72 for _, status := range statuses { 73 if status.Status != SignalGreen { 74 signal = SignalRed 75 return 76 } 77 } 78 return 79 } 80 81 // servicesOrDefault returns either the servicesToCheck list if it is set 82 // or all the keys in the detailed service checks. 83 func (taa TrackedActionAggregator) servicesOrDefault(servicesToCheck ...string) []string { 84 if len(servicesToCheck) > 0 { 85 return servicesToCheck 86 } 87 var output []string 88 for key := range taa.TrackedActions { 89 output = append(output, key) 90 } 91 sort.Strings(output) 92 return output 93 }