diff --git a/pkg/query-service/__debug_bin b/pkg/query-service/__debug_bin new file mode 100755 index 0000000000..b786eef17b Binary files /dev/null and b/pkg/query-service/__debug_bin differ diff --git a/pkg/query-service/app/clickhouseReader/reader.go b/pkg/query-service/app/clickhouseReader/reader.go index f83b8e73f4..2b1b319a1a 100644 --- a/pkg/query-service/app/clickhouseReader/reader.go +++ b/pkg/query-service/app/clickhouseReader/reader.go @@ -239,3 +239,33 @@ func (r *ClickHouseReader) SearchSpans(ctx context.Context, queryParams *model.S return &searchSpansResult, nil } + +func (r *ClickHouseReader) GetServiceDBOverview(ctx context.Context, queryParams *model.GetServiceOverviewParams) (*[]model.ServiceDBOverviewItem, error) { + + var serviceDBOverviewItem []model.ServiceDBOverviewItem + + query := fmt.Sprintf("SELECT toStartOfInterval(timestamp, INTERVAL %s minute) as time, avg(durationNano) as avgDuration, count(1) as numCalls, dbSystem FROM %s WHERE serviceName='%s' AND timestamp>='%s' AND timestamp<='%s' AND kind='3' AND dbName IS NOT NULL GROUP BY time, dbSystem ORDER BY time DESC", strconv.Itoa(int(queryParams.StepSeconds/60)), r.indexTable, queryParams.ServiceName, strconv.FormatInt(queryParams.Start.UnixNano(), 10), strconv.FormatInt(queryParams.End.UnixNano(), 10)) + + err := r.db.Select(&serviceDBOverviewItem, query) + + zap.S().Info(query) + + if err != nil { + zap.S().Debug("Error in processing sql query: ", err) + return nil, fmt.Errorf("Error in processing sql query") + } + + for i, _ := range serviceDBOverviewItem { + timeObj, _ := time.Parse(time.RFC3339Nano, serviceDBOverviewItem[i].Time) + serviceDBOverviewItem[i].Timestamp = int64(timeObj.UnixNano()) + serviceDBOverviewItem[i].Time = "" + serviceDBOverviewItem[i].CallRate = float32(serviceDBOverviewItem[i].NumCalls) / float32(queryParams.StepSeconds) + } + + if serviceDBOverviewItem == nil { + serviceDBOverviewItem = []model.ServiceDBOverviewItem{} + } + + return &serviceDBOverviewItem, nil + +} diff --git a/pkg/query-service/app/druidReader/reader.go b/pkg/query-service/app/druidReader/reader.go index 62043be8f6..27737ede2a 100644 --- a/pkg/query-service/app/druidReader/reader.go +++ b/pkg/query-service/app/druidReader/reader.go @@ -50,3 +50,7 @@ func (druid *DruidReader) GetServices(ctx context.Context, query *model.GetServi func (druid *DruidReader) SearchSpans(ctx context.Context, query *model.SpanSearchParams) (*[]model.SearchSpansResult, error) { return druidQuery.SearchSpans(druid.Client, query) } + +func (druid *DruidReader) GetServiceDBOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceDBOverviewItem, error) { + return druidQuery.GetServiceDBOverview(druid.SqlClient, query) +} diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index 084b8d57ac..2787cd9712 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -60,7 +60,7 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router) { router.HandleFunc("/api/v1/services", aH.getServices).Methods(http.MethodGet) // router.HandleFunc("/api/v1/services/list", aH.getServicesList).Methods(http.MethodGet) router.HandleFunc("/api/v1/service/overview", aH.getServiceOverview).Methods(http.MethodGet) - // router.HandleFunc("/api/v1/service/dbOverview", aH.getServiceDBOverview).Methods(http.MethodGet) + router.HandleFunc("/api/v1/service/dbOverview", aH.getServiceDBOverview).Methods(http.MethodGet) // router.HandleFunc("/api/v1/service/externalAvgDuration", aH.GetServiceExternalAvgDuration).Methods(http.MethodGet) // router.HandleFunc("/api/v1/service/externalErrors", aH.getServiceExternalErrors).Methods(http.MethodGet) // router.HandleFunc("/api/v1/service/external", aH.getServiceExternal).Methods(http.MethodGet) @@ -177,21 +177,22 @@ func (aH *APIHandler) user(w http.ResponseWriter, r *http.Request) { // } -// func (aH *APIHandler) getServiceDBOverview(w http.ResponseWriter, r *http.Request) { +func (aH *APIHandler) getServiceDBOverview(w http.ResponseWriter, r *http.Request) { -// query, err := parseGetServiceExternalRequest(r) -// if aH.handleError(w, err, http.StatusBadRequest) { -// return -// } + query, err := parseGetServiceExternalRequest(r) + if aH.handleError(w, err, http.StatusBadRequest) { + return + } -// result, err := druidQuery.GetServiceDBOverview(aH.sqlClient, query) -// if aH.handleError(w, err, http.StatusBadRequest) { -// return -// } + result, err := (*aH.reader).GetServiceDBOverview(context.Background(), query) -// aH.writeJSON(w, r, result) + if aH.handleError(w, err, http.StatusBadRequest) { + return + } -// } + aH.writeJSON(w, r, result) + +} // func (aH *APIHandler) getServiceExternal(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/query-service/app/interface.go b/pkg/query-service/app/interface.go index 6408422786..2705569053 100644 --- a/pkg/query-service/app/interface.go +++ b/pkg/query-service/app/interface.go @@ -11,4 +11,5 @@ type Reader interface { GetServices(ctx context.Context, query *model.GetServicesParams) (*[]model.ServiceItem, error) // GetApplicationPercentiles(ctx context.Context, query *model.ApplicationPercentileParams) ([]godruid.Timeseries, error) SearchSpans(ctx context.Context, query *model.SpanSearchParams) (*[]model.SearchSpansResult, error) + GetServiceDBOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceDBOverviewItem, error) } diff --git a/pkg/query-service/model/response.go b/pkg/query-service/model/response.go index fca92f5765..8c4915355e 100644 --- a/pkg/query-service/model/response.go +++ b/pkg/query-service/model/response.go @@ -78,12 +78,12 @@ type ServiceExternalItem struct { } type ServiceDBOverviewItem struct { - Time string `json:"time,omitempty"` - Timestamp int64 `json:"timestamp,omitempty"` - DBSystem string `json:"dbSystem,omitempty"` - AvgDuration float32 `json:"avgDuration,omitempty"` - NumCalls int `json:"numCalls,omitempty"` - CallRate float32 `json:"callRate,omitempty"` + Time string `json:"time,omitempty" db:"time,omitempty"` + Timestamp int64 `json:"timestamp,omitempty" db:"timestamp,omitempty"` + DBSystem string `json:"dbSystem,omitempty" db:"dbSystem,omitempty"` + AvgDuration float32 `json:"avgDuration,omitempty" db:"avgDuration,omitempty"` + NumCalls int `json:"numCalls,omitempty" db:"numCalls,omitempty"` + CallRate float32 `json:"callRate,omitempty" db:"callRate,omitempty"` } type ServiceMapDependencyItem struct {