github.com/thanos-io/thanos@v0.32.5/pkg/info/info.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package info 5 6 import ( 7 "context" 8 9 "github.com/thanos-io/thanos/pkg/info/infopb" 10 "github.com/thanos-io/thanos/pkg/store/labelpb" 11 "google.golang.org/grpc" 12 ) 13 14 // InfoServer implements the corresponding protobuf interface 15 // to provide information on which APIs are exposed by the given 16 // component. 17 type InfoServer struct { 18 infopb.UnimplementedInfoServer 19 20 component string 21 22 getLabelSet func() []labelpb.ZLabelSet 23 getStoreInfo func() *infopb.StoreInfo 24 getExemplarsInfo func() *infopb.ExemplarsInfo 25 getRulesInfo func() *infopb.RulesInfo 26 getTargetsInfo func() *infopb.TargetsInfo 27 getMetricMetadataInfo func() *infopb.MetricMetadataInfo 28 getQueryAPIInfo func() *infopb.QueryAPIInfo 29 } 30 31 // NewInfoServer creates a new server instance for given component 32 // and with the specified options. 33 func NewInfoServer( 34 component string, 35 options ...ServerOptionFunc, 36 ) *InfoServer { 37 srv := &InfoServer{ 38 component: component, 39 // By default, do not return info for any API. 40 getLabelSet: func() []labelpb.ZLabelSet { return nil }, 41 getStoreInfo: func() *infopb.StoreInfo { return nil }, 42 getExemplarsInfo: func() *infopb.ExemplarsInfo { return nil }, 43 getRulesInfo: func() *infopb.RulesInfo { return nil }, 44 getTargetsInfo: func() *infopb.TargetsInfo { return nil }, 45 getMetricMetadataInfo: func() *infopb.MetricMetadataInfo { return nil }, 46 getQueryAPIInfo: func() *infopb.QueryAPIInfo { return nil }, 47 } 48 49 for _, o := range options { 50 o(srv) 51 } 52 53 return srv 54 } 55 56 // ServerOptionFunc represents a functional option to configure info server. 57 type ServerOptionFunc func(*InfoServer) 58 59 // WithLabelSetFunc determines the function that should be executed to obtain 60 // the label set information. If no function is provided, the default empty 61 // label set is returned. Only the first function from the list is considered. 62 func WithLabelSetFunc(getLabelSet ...func() []labelpb.ZLabelSet) ServerOptionFunc { 63 if len(getLabelSet) == 0 { 64 return func(s *InfoServer) { 65 s.getLabelSet = func() []labelpb.ZLabelSet { return []labelpb.ZLabelSet{} } 66 } 67 } 68 69 return func(s *InfoServer) { 70 s.getLabelSet = getLabelSet[0] 71 } 72 } 73 74 // WithStoreInfoFunc determines the function that should be executed to obtain 75 // the store information. If no function is provided, the default empty 76 // store info is returned. Only the first function from the list is considered. 77 func WithStoreInfoFunc(getStoreInfo ...func() *infopb.StoreInfo) ServerOptionFunc { 78 if len(getStoreInfo) == 0 { 79 return func(s *InfoServer) { 80 s.getStoreInfo = func() *infopb.StoreInfo { return &infopb.StoreInfo{} } 81 } 82 } 83 84 return func(s *InfoServer) { 85 s.getStoreInfo = getStoreInfo[0] 86 } 87 } 88 89 // WithRulesInfoFunc determines the function that should be executed to obtain 90 // the rules information. If no function is provided, the default empty 91 // rules info is returned. Only the first function from the list is considered. 92 func WithRulesInfoFunc(getRulesInfo ...func() *infopb.RulesInfo) ServerOptionFunc { 93 if len(getRulesInfo) == 0 { 94 return func(s *InfoServer) { 95 s.getRulesInfo = func() *infopb.RulesInfo { return &infopb.RulesInfo{} } 96 } 97 } 98 99 return func(s *InfoServer) { 100 s.getRulesInfo = getRulesInfo[0] 101 } 102 } 103 104 // WithExemplarsInfoFunc determines the function that should be executed to obtain 105 // the exemplars information. If no function is provided, the default empty 106 // exemplars info is returned. Only the first function from the list is considered. 107 func WithExemplarsInfoFunc(getExemplarsInfo ...func() *infopb.ExemplarsInfo) ServerOptionFunc { 108 if len(getExemplarsInfo) == 0 { 109 return func(s *InfoServer) { 110 s.getExemplarsInfo = func() *infopb.ExemplarsInfo { return &infopb.ExemplarsInfo{} } 111 } 112 } 113 114 return func(s *InfoServer) { 115 s.getExemplarsInfo = getExemplarsInfo[0] 116 } 117 } 118 119 // WithTargetsInfoFunc determines the function that should be executed to obtain 120 // the targets information. If no function is provided, the default empty 121 // targets info is returned. Only the first function from the list is considered. 122 func WithTargetsInfoFunc(getTargetsInfo ...func() *infopb.TargetsInfo) ServerOptionFunc { 123 if len(getTargetsInfo) == 0 { 124 return func(s *InfoServer) { 125 s.getTargetsInfo = func() *infopb.TargetsInfo { return &infopb.TargetsInfo{} } 126 } 127 } 128 129 return func(s *InfoServer) { 130 s.getTargetsInfo = getTargetsInfo[0] 131 } 132 } 133 134 // WithTargetsInfoFunc determines the function that should be executed to obtain 135 // the targets information. If no function is provided, the default empty 136 // targets info is returned. Only the first function from the list is considered. 137 func WithMetricMetadataInfoFunc(getMetricMetadataInfo ...func() *infopb.MetricMetadataInfo) ServerOptionFunc { 138 if len(getMetricMetadataInfo) == 0 { 139 return func(s *InfoServer) { 140 s.getMetricMetadataInfo = func() *infopb.MetricMetadataInfo { return &infopb.MetricMetadataInfo{} } 141 } 142 } 143 144 return func(s *InfoServer) { 145 s.getMetricMetadataInfo = getMetricMetadataInfo[0] 146 } 147 } 148 149 // WithQueryAPIInfoFunc determines the function that should be executed to obtain 150 // the query information. If no function is provided, the default empty 151 // query info is returned. Only the first function from the list is considered. 152 func WithQueryAPIInfoFunc(queryInfo ...func() *infopb.QueryAPIInfo) ServerOptionFunc { 153 if len(queryInfo) == 0 { 154 return func(s *InfoServer) { 155 s.getQueryAPIInfo = func() *infopb.QueryAPIInfo { return &infopb.QueryAPIInfo{} } 156 } 157 } 158 159 return func(s *InfoServer) { 160 s.getQueryAPIInfo = queryInfo[0] 161 } 162 } 163 164 // RegisterInfoServer registers the info server. 165 func RegisterInfoServer(infoSrv infopb.InfoServer) func(*grpc.Server) { 166 return func(s *grpc.Server) { 167 infopb.RegisterInfoServer(s, infoSrv) 168 } 169 } 170 171 // Info returns the information about label set and available APIs exposed by the component. 172 func (srv *InfoServer) Info(ctx context.Context, req *infopb.InfoRequest) (*infopb.InfoResponse, error) { 173 return &infopb.InfoResponse{ 174 LabelSets: srv.getLabelSet(), 175 ComponentType: srv.component, 176 Store: srv.getStoreInfo(), 177 Exemplars: srv.getExemplarsInfo(), 178 Rules: srv.getRulesInfo(), 179 Targets: srv.getTargetsInfo(), 180 MetricMetadata: srv.getMetricMetadataInfo(), 181 Query: srv.getQueryAPIInfo(), 182 }, nil 183 }