@@ -41,26 +41,14 @@ func NewPrometheusQueryExecutor(url string, startTime, endTime time.Time, querie
4141}
4242
4343func NewStandardPrometheusQueryExecutor (url string , startTime , endTime time.Time , nameRegexPattern string ) (* PrometheusQueryExecutor , error ) {
44- c , err := client .NewPrometheusClient (url )
45- if err != nil {
46- return nil , errors .Wrapf (err , "failed to create Prometheus client" )
47- }
44+ p := & PrometheusQueryExecutor {}
4845
49- pr := & PrometheusQueryExecutor {
50- client : c ,
51- startTime : startTime ,
52- endTime : endTime ,
53- QueryResults : make (map [string ]interface {}),
54- }
55-
56- standardQueries , queryErr := pr .generateStandardQueries (nameRegexPattern , startTime , endTime )
46+ standardQueries , queryErr := p .generateStandardQueries (nameRegexPattern , startTime , endTime )
5747 if queryErr != nil {
5848 return nil , errors .Wrapf (queryErr , "failed to generate standard queries for %s" , nameRegexPattern )
5949 }
6050
61- pr .Queries = standardQueries
62-
63- return pr , nil
51+ return NewPrometheusQueryExecutor (url , startTime , endTime , standardQueries )
6452}
6553
6654func (r * PrometheusQueryExecutor ) Execute (ctx context.Context ) error {
@@ -189,26 +177,92 @@ func (r *PrometheusQueryExecutor) generateStandardQueries(nameRegexPattern strin
189177 return standardQueries , nil
190178}
191179
180+ type TypedMetric struct {
181+ model.Value
182+ MetricType string `json:"metric_type"`
183+ }
184+
185+ func (g * PrometheusQueryExecutor ) MarshalJSON () ([]byte , error ) {
186+ // we need custom marshalling to only include some parts of the metrics
187+ type QueryExecutor struct {
188+ Kind string `json:"kind"`
189+ Queries map [string ]string `json:"queries"`
190+ QueryResults map [string ]TypedMetric `json:"query_results"`
191+ }
192+
193+ q := & QueryExecutor {
194+ Kind : g .KindName ,
195+ Queries : g .Queries ,
196+ QueryResults : func () map [string ]TypedMetric {
197+ simplifiedMetrics := make (map [string ]TypedMetric )
198+ for name , value := range g .MustResultsAsValue () {
199+ simplifiedMetrics [name ] = TypedMetric {
200+ MetricType : value .Type ().String (),
201+ Value : value ,
202+ }
203+ }
204+ return simplifiedMetrics
205+ }(),
206+ }
207+
208+ return json .Marshal (q )
209+ }
210+
192211func (r * PrometheusQueryExecutor ) UnmarshalJSON (data []byte ) error {
193212 // helper struct with QueryResults map[string]interface{}
194213 type Alias PrometheusQueryExecutor
195214 var raw struct {
196215 Alias
197- QueryResults map [string ]interface {} `json:"query_results"`
216+ QueryResults map [string ]json. RawMessage `json:"query_results"`
198217 }
199218
200219 // unmarshal into the helper struct to populate other fields automatically
201220 if err := json .Unmarshal (data , & raw ); err != nil {
202221 return err
203222 }
204223
205- // convert map[string]interface{} to map[string]actualType
206- convertedTypes , conversionErr := convertQueryResults (raw .QueryResults )
207- if conversionErr != nil {
208- return conversionErr
224+ var convertedQueryResults = make (map [string ]interface {})
225+
226+ for name , rawResult := range raw .QueryResults {
227+ var rawTypedMetric struct {
228+ MetricType string `json:"metric_type"`
229+ Value json.RawMessage `json:"Value"`
230+ }
231+ if err := json .Unmarshal (rawResult , & rawTypedMetric ); err != nil {
232+ return errors .Wrapf (err , "failed to unmarshal query result for %s" , name )
233+ }
234+
235+ switch rawTypedMetric .MetricType {
236+ case "scalar" :
237+ var scalar model.Scalar
238+ if err := json .Unmarshal (rawTypedMetric .Value , & scalar ); err != nil {
239+ return errors .Wrapf (err , "failed to unmarshal scalar value for %s" , name )
240+ }
241+ convertedQueryResults [name ] = scalar
242+ case "vector" :
243+ var vector model.Vector
244+ if err := json .Unmarshal (rawTypedMetric .Value , & vector ); err != nil {
245+ return errors .Wrapf (err , "failed to unmarshal vector value for %s" , name )
246+ }
247+ convertedQueryResults [name ] = vector
248+ case "matrix" :
249+ var matrix model.Matrix
250+ if err := json .Unmarshal (rawTypedMetric .Value , & matrix ); err != nil {
251+ return errors .Wrapf (err , "failed to unmarshal matrix value for %s" , name )
252+ }
253+ convertedQueryResults [name ] = matrix
254+ case "string" :
255+ var str model.String
256+ if err := json .Unmarshal (rawTypedMetric .Value , & str ); err != nil {
257+ return errors .Wrapf (err , "failed to unmarshal string value for %s" , name )
258+ }
259+ convertedQueryResults [name ] = str
260+ default :
261+ return fmt .Errorf ("unknown metric type %s" , rawTypedMetric .MetricType )
262+ }
209263 }
210264
211265 * r = PrometheusQueryExecutor (raw .Alias )
212- r .QueryResults = convertedTypes
266+ r .QueryResults = convertedQueryResults
213267 return nil
214268}
0 commit comments