Skip to content

Commit

Permalink
[statistics] Adds API to query multiple indicators in batch
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiyanliu authored and Jack47 committed Dec 29, 2017
1 parent efa2adc commit d5680c5
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
55 changes: 55 additions & 0 deletions doc/statistics_api_ref.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,39 @@ paths:
description: The description of statistics indicator.
schema:
$ref: '#/definitions/PipelineIndicatorDescription'
/pipelines/{pipelineName}/indicators/value:
get:
summary: Retrieves Pipeline Statistics Values From Multiple Indicators
description: |
The Pipeline Statistics Indicators Value retrieve endpoint returns the values of given
multiple statistics indicators pipeline instance exposed.
parameters:
- name: pipelineName
in: path
description: Pipeline instance name to query.
required: true
type: string
- name: pipelineIndicatorsValueRetrieveRequest
in: body
schema:
$ref: '#/definitions/PipelineIndicatorsValueRetrieveRequest'
required: true
description: Statistics indicator names to query.
responses:
400:
description: |
Invalid statistics values retrieve request parameter. Including,
invalid pipeline instance name or invalid indicator names.
schema:
$ref: '#/definitions/Error'
404:
description: The statistics of pipeline instance not found by given name.
schema:
$ref: '#/definitions/Error'
200:
description: The values of statistics indicators.
schema:
$ref: '#/definitions/PipelineIndicatorsValue'
/pipelines/{pipelineName}/task/indicators:
get:
summary: Retrieves Task Statistics Indicator Names
Expand Down Expand Up @@ -450,6 +483,28 @@ definitions:
description: |
A human readable description of the special plugin indicator type.
Check Pipeline Reference document for more information.
PipelineIndicatorsValueRetrieveRequest:
type: object
required:
- indicator_names
properties:
indicator_names:
type: array
items:
type: string
description: The name of the indicator to query statistics value.
PipelineIndicatorsValue:
type: object
required:
- values
properties:
values:
type: object
additionalProperties:
type: object
description: |
A special value object of the pipeline indicator type.
Check Pipeline Reference document for more information.
TaskIndicatorNames:
type: object
required:
Expand Down
32 changes: 32 additions & 0 deletions src/model/statistics.go
Original file line number Diff line number Diff line change
Expand Up @@ -950,11 +950,43 @@ func (ps *PipelineStatistics) PipelineIndicatorValue(indicatorName string) (inte
}

}()

ret, err = indicator.Evaluate()
}()
return ret, err
}

func (ps *PipelineStatistics) PipelineIndicatorsValue(indicatorNames []string) map[string]interface{} {
ps.RLock()
defer ps.RUnlock()

values := make(map[string]interface{}, len(indicatorNames))

for _, indicatorName := range indicatorNames {
indicator, exists := ps.pipelineIndicators[indicatorName]
if !exists {
values[indicatorName] = nil
continue
}

var err error

func() {
defer func() { // defensive
recover()
}()

values[indicatorName], err = indicator.Evaluate()
if err != nil {
logger.Warnf("[evaluate pipeline %s statistics indicator %s failed: %v]",
ps.pipelineName, indicatorName, err)
}
}()
}

return values
}

func (ps *PipelineStatistics) PipelineIndicatorDescription(indicatorName string) (string, error) {
ps.RLock()
defer ps.RUnlock()
Expand Down
13 changes: 13 additions & 0 deletions src/rest/param.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ type pipelineTypesRetrieveResponse struct {
// Statistics API
//

type indicatorsValueRetrieveRequest struct {
IndicatorNames []string `json:"indicator_names"`
}

type indicatorNamesRetrieveResponse struct {
Names []string `json:"names"`
}
Expand All @@ -72,6 +76,10 @@ type indicatorValueRetrieveResponse struct {
Value interface{} `json:"value"`
}

type indicatorsValueRetrieveResponse struct {
Values map[string]interface{} `json:"values"`
}

type indicatorDescriptionRetrieveResponse struct {
Description interface{} `json:"desc"`
}
Expand Down Expand Up @@ -195,6 +203,11 @@ type statisticsClusterRequest struct {
Details bool `json:"details"`
}

type indicatorsValueRetrieveClusterRequest struct {
statisticsClusterRequest
indicatorsValueRetrieveRequest
}

//
// Health check API
//
Expand Down
37 changes: 37 additions & 0 deletions src/rest/statistics.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ func (s *statisticsServer) Api() (*rest.Api, error) {
s.retrievePipelineIndicatorValue),
rest.Get(pav("/pipelines/#pipelineName/indicators/#indicatorName/desc"),
s.retrievePipelineIndicatorDesc),
rest.Get(pav("/pipelines/#pipelineName/indicators/value"),
s.retrievePipelineIndicatorsValue),

rest.Get(pav("/pipelines/#pipelineName/task/indicators"),
s.retrievePipelineTaskIndicatorNames),
Expand Down Expand Up @@ -367,6 +369,41 @@ func (s *statisticsServer) retrievePipelineIndicatorDesc(w rest.ResponseWriter,
}
}

func (s *statisticsServer) retrievePipelineIndicatorsValue(w rest.ResponseWriter, r *rest.Request) {
logger.Debugf("[retrieve pipeline statistics values from multiple indicators]")

pipelineName, err := url.QueryUnescape(r.PathParam("pipelineName"))
if err != nil || len(pipelineName) == 0 {
msg := "invalid pipeline name"
rest.Error(w, msg, http.StatusBadRequest)
logger.Errorf("[%s]", msg)
return
}

req := new(indicatorsValueRetrieveRequest)
err = r.DecodeJsonPayload(req)
if err != nil {
rest.Error(w, err.Error(), http.StatusBadRequest)
logger.Errorf("[%v]", err)
return
}

statistics := s.gateway.Model().StatRegistry().GetPipelineStatistics(pipelineName)
if statistics == nil {
msg := fmt.Sprintf("pipeline %s statistics not found", pipelineName)
rest.Error(w, msg, http.StatusNotFound)
logger.Warnf("[%s]", msg)
return
}

indicatorsValue := statistics.PipelineIndicatorsValue(req.IndicatorNames)
w.WriteJson(&indicatorsValueRetrieveResponse{
Values: indicatorsValue,
})

logger.Debugf("[statistics values of multiple indicators of pipeline %s returned]", pipelineName)
}

func (s *statisticsServer) retrievePipelineTaskIndicatorNames(w rest.ResponseWriter, r *rest.Request) {
logger.Debugf("[retrieve pipeline task indicator names]")

Expand Down

0 comments on commit d5680c5

Please sign in to comment.