github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/operations/system.go (about) 1 /* 2 Copyright hechain All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package operations 8 9 import ( 10 "context" 11 "net" 12 "strings" 13 "time" 14 15 kitstatsd "github.com/go-kit/kit/metrics/statsd" 16 "github.com/hechain20/hechain/common/fabhttp" 17 "github.com/hechain20/hechain/common/flogging" 18 "github.com/hechain20/hechain/common/flogging/httpadmin" 19 "github.com/hechain20/hechain/common/metadata" 20 "github.com/hechain20/hechain/common/metrics" 21 "github.com/hechain20/hechain/common/metrics/disabled" 22 "github.com/hechain20/hechain/common/metrics/prometheus" 23 "github.com/hechain20/hechain/common/metrics/statsd" 24 "github.com/hechain20/hechain/common/metrics/statsd/goruntime" 25 "github.com/hyperledger/fabric-lib-go/healthz" 26 "github.com/prometheus/client_golang/prometheus/promhttp" 27 ) 28 29 //go:generate counterfeiter -o fakes/logger.go -fake-name Logger . Logger 30 31 type Logger interface { 32 Warn(args ...interface{}) 33 Warnf(template string, args ...interface{}) 34 } 35 36 type Statsd struct { 37 Network string 38 Address string 39 WriteInterval time.Duration 40 Prefix string 41 } 42 43 type MetricsOptions struct { 44 Provider string 45 Statsd *Statsd 46 } 47 48 type Options struct { 49 fabhttp.Options 50 Metrics MetricsOptions 51 Version string 52 } 53 54 type System struct { 55 *fabhttp.Server 56 metrics.Provider 57 58 logger Logger 59 healthHandler *healthz.HealthHandler 60 options Options 61 statsd *kitstatsd.Statsd 62 collectorTicker *time.Ticker 63 sendTicker *time.Ticker 64 versionGauge metrics.Gauge 65 } 66 67 func NewSystem(o Options) *System { 68 logger := o.Logger 69 if logger == nil { 70 logger = flogging.MustGetLogger("operations.runner") 71 } 72 73 s := fabhttp.NewServer(o.Options) 74 75 system := &System{ 76 Server: s, 77 logger: logger, 78 options: o, 79 } 80 81 system.initializeHealthCheckHandler() 82 system.initializeLoggingHandler() 83 system.initializeMetricsProvider() 84 system.initializeVersionInfoHandler() 85 86 return system 87 } 88 89 func (s *System) Start() error { 90 err := s.startMetricsTickers() 91 if err != nil { 92 return err 93 } 94 95 s.versionGauge.With("version", s.options.Version).Set(1) 96 97 return s.Server.Start() 98 } 99 100 func (s *System) Stop() error { 101 if s.collectorTicker != nil { 102 s.collectorTicker.Stop() 103 s.collectorTicker = nil 104 } 105 if s.sendTicker != nil { 106 s.sendTicker.Stop() 107 s.sendTicker = nil 108 } 109 return s.Server.Stop() 110 } 111 112 func (s *System) RegisterChecker(component string, checker healthz.HealthChecker) error { 113 return s.healthHandler.RegisterChecker(component, checker) 114 } 115 116 func (s *System) initializeMetricsProvider() error { 117 m := s.options.Metrics 118 providerType := m.Provider 119 switch providerType { 120 case "statsd": 121 prefix := m.Statsd.Prefix 122 if prefix != "" && !strings.HasSuffix(prefix, ".") { 123 prefix = prefix + "." 124 } 125 126 ks := kitstatsd.New(prefix, s) 127 s.Provider = &statsd.Provider{Statsd: ks} 128 s.statsd = ks 129 s.versionGauge = versionGauge(s.Provider) 130 return nil 131 132 case "prometheus": 133 s.Provider = &prometheus.Provider{} 134 s.versionGauge = versionGauge(s.Provider) 135 // swagger:operation GET /metrics operations metrics 136 // --- 137 // responses: 138 // '200': 139 // description: Ok. 140 s.RegisterHandler("/metrics", promhttp.Handler(), s.options.TLS.Enabled) 141 return nil 142 143 default: 144 if providerType != "disabled" { 145 s.logger.Warnf("Unknown provider type: %s; metrics disabled", providerType) 146 } 147 148 s.Provider = &disabled.Provider{} 149 s.versionGauge = versionGauge(s.Provider) 150 return nil 151 } 152 } 153 154 func (s *System) initializeLoggingHandler() { 155 // swagger:operation GET /logspec operations logspecget 156 // --- 157 // summary: Retrieves the active logging spec for a peer or orderer. 158 // responses: 159 // '200': 160 // description: Ok. 161 162 // swagger:operation PUT /logspec operations logspecput 163 // --- 164 // summary: Updates the active logging spec for a peer or orderer. 165 // 166 // parameters: 167 // - name: payload 168 // in: formData 169 // type: string 170 // description: The payload must consist of a single attribute named spec. 171 // required: true 172 // responses: 173 // '204': 174 // description: No content. 175 // '400': 176 // description: Bad request. 177 // consumes: 178 // - multipart/form-data 179 s.RegisterHandler("/logspec", httpadmin.NewSpecHandler(), s.options.TLS.Enabled) 180 } 181 182 func (s *System) initializeHealthCheckHandler() { 183 s.healthHandler = healthz.NewHealthHandler() 184 // swagger:operation GET /healthz operations healthz 185 // --- 186 // summary: Retrieves all registered health checkers for the process. 187 // responses: 188 // '200': 189 // description: Ok. 190 // '503': 191 // description: Service unavailable. 192 s.RegisterHandler("/healthz", s.healthHandler, false) 193 } 194 195 func (s *System) initializeVersionInfoHandler() { 196 versionInfo := &VersionInfoHandler{ 197 CommitSHA: metadata.CommitSHA, 198 Version: metadata.Version, 199 } 200 // swagger:operation GET /version operations version 201 // --- 202 // summary: Returns the orderer or peer version and the commit SHA on which the release was created. 203 // responses: 204 // '200': 205 // description: Ok. 206 s.RegisterHandler("/version", versionInfo, false) 207 } 208 209 func (s *System) startMetricsTickers() error { 210 m := s.options.Metrics 211 if s.statsd != nil { 212 network := m.Statsd.Network 213 address := m.Statsd.Address 214 c, err := net.Dial(network, address) 215 if err != nil { 216 return err 217 } 218 c.Close() 219 220 opts := s.options.Metrics.Statsd 221 writeInterval := opts.WriteInterval 222 223 s.collectorTicker = time.NewTicker(writeInterval / 2) 224 goCollector := goruntime.NewCollector(s.Provider) 225 go goCollector.CollectAndPublish(s.collectorTicker.C) 226 227 s.sendTicker = time.NewTicker(writeInterval) 228 go s.statsd.SendLoop(context.TODO(), s.sendTicker.C, network, address) 229 } 230 231 return nil 232 }