mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 03:05:56 +08:00
interface working with druid APIs
This commit is contained in:
parent
606fa6591d
commit
9c83319143
Binary file not shown.
@ -1,22 +1,49 @@
|
|||||||
package druidReader
|
package druidReader
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"go.signoz.io/query-service/druidQuery"
|
"go.signoz.io/query-service/druidQuery"
|
||||||
|
"go.signoz.io/query-service/godruid"
|
||||||
"go.signoz.io/query-service/model"
|
"go.signoz.io/query-service/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DruidReader struct {
|
type DruidReader struct {
|
||||||
Client
|
Client *godruid.Client
|
||||||
SqlClient
|
SqlClient *druidQuery.SqlClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSpanReader() {
|
func NewReader(druidClientUrl string) *DruidReader {
|
||||||
|
|
||||||
initialize()
|
initialize()
|
||||||
|
|
||||||
|
client := godruid.Client{
|
||||||
|
Url: druidClientUrl,
|
||||||
|
Debug: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlClient := druidQuery.SqlClient{
|
||||||
|
Url: druidClientUrl,
|
||||||
|
Debug: true,
|
||||||
|
}
|
||||||
|
return &DruidReader{
|
||||||
|
Client: &client,
|
||||||
|
SqlClient: &sqlClient,
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
func initialize() {
|
func initialize() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (druid *Druid) GetServices(client, query *model.GetServicesParams) {
|
func (druid *DruidReader) GetServiceOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, error) {
|
||||||
return druidQuery.GetServices(druid.sqlClient, query)
|
return druidQuery.GetServiceOverview(druid.SqlClient, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (druid *DruidReader) GetServices(ctx context.Context, query *model.GetServicesParams) (*[]model.ServiceItem, error) {
|
||||||
|
return druidQuery.GetServices(druid.SqlClient, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (druid *DruidReader) GetApplicationPercentiles(ctx context.Context, query *model.ApplicationPercentileParams) ([]godruid.Timeseries, error) {
|
||||||
|
return druidQuery.GetApplicationPercentiles(druid.Client, query)
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
// Reader finds and loads traces and other data from storage.
|
|
||||||
type QueryReader interface {
|
|
||||||
// GetTrace(ctx context.Context, traceID model.TraceID) (*model.Trace, error)
|
|
||||||
GetServices(ctx context.Context)
|
|
||||||
// GetOperations(ctx context.Context, query OperationQueryParameters) ([]Operation, error)
|
|
||||||
// FindTraces(ctx context.Context, query *TraceQueryParameters) ([]*model.Trace, error)
|
|
||||||
// FindTraceIDs(ctx context.Context, query *TraceQueryParameters) ([]model.TraceID, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewQueryReader() {
|
|
||||||
|
|
||||||
}
|
|
@ -1,14 +1,13 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/posthog/posthog-go"
|
"github.com/posthog/posthog-go"
|
||||||
"go.signoz.io/query-service/druidQuery"
|
|
||||||
"go.signoz.io/query-service/godruid"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,17 +22,15 @@ type APIHandler struct {
|
|||||||
// queryParser queryParser
|
// queryParser queryParser
|
||||||
basePath string
|
basePath string
|
||||||
apiPrefix string
|
apiPrefix string
|
||||||
client *godruid.Client
|
reader *Reader
|
||||||
sqlClient *druidQuery.SqlClient
|
|
||||||
pc *posthog.Client
|
pc *posthog.Client
|
||||||
distinctId string
|
distinctId string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAPIHandler returns an APIHandler
|
// NewAPIHandler returns an APIHandler
|
||||||
func NewAPIHandler(client *godruid.Client, sqlClient *druidQuery.SqlClient, pc *posthog.Client, distinctId string) *APIHandler {
|
func NewAPIHandler(reader *Reader, pc *posthog.Client, distinctId string) *APIHandler {
|
||||||
aH := &APIHandler{
|
aH := &APIHandler{
|
||||||
client: client,
|
reader: reader,
|
||||||
sqlClient: sqlClient,
|
|
||||||
pc: pc,
|
pc: pc,
|
||||||
distinctId: distinctId,
|
distinctId: distinctId,
|
||||||
}
|
}
|
||||||
@ -61,20 +58,20 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router) {
|
|||||||
router.HandleFunc("/api/v1/user", aH.user).Methods(http.MethodPost)
|
router.HandleFunc("/api/v1/user", aH.user).Methods(http.MethodPost)
|
||||||
router.HandleFunc("/api/v1/get_percentiles", aH.getApplicationPercentiles).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/get_percentiles", aH.getApplicationPercentiles).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/services", aH.getServices).Methods(http.MethodGet)
|
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/services/list", aH.getServicesList).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/service/overview", aH.getServiceOverview).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/externalAvgDuration", aH.GetServiceExternalAvgDuration).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/service/externalErrors", aH.getServiceExternalErrors).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)
|
// router.HandleFunc("/api/v1/service/external", aH.getServiceExternal).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/service/{service}/operations", aH.getOperations).Methods(http.MethodGet)
|
// router.HandleFunc("/api/v1/service/{service}/operations", aH.getOperations).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/service/top_endpoints", aH.getTopEndpoints).Methods(http.MethodGet)
|
// router.HandleFunc("/api/v1/service/top_endpoints", aH.getTopEndpoints).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/spans", aH.searchSpans).Methods(http.MethodGet)
|
// router.HandleFunc("/api/v1/spans", aH.searchSpans).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/spans/aggregates", aH.searchSpansAggregates).Methods(http.MethodGet)
|
// router.HandleFunc("/api/v1/spans/aggregates", aH.searchSpansAggregates).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/tags", aH.searchTags).Methods(http.MethodGet)
|
// router.HandleFunc("/api/v1/tags", aH.searchTags).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/traces/{traceId}", aH.searchTraces).Methods(http.MethodGet)
|
// router.HandleFunc("/api/v1/traces/{traceId}", aH.searchTraces).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/usage", aH.getUsage).Methods(http.MethodGet)
|
// router.HandleFunc("/api/v1/usage", aH.getUsage).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/serviceMapDependencies", aH.serviceMapDependencies).Methods(http.MethodGet)
|
// router.HandleFunc("/api/v1/serviceMapDependencies", aH.serviceMapDependencies).Methods(http.MethodGet)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aH *APIHandler) user(w http.ResponseWriter, r *http.Request) {
|
func (aH *APIHandler) user(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -102,147 +99,147 @@ func (aH *APIHandler) user(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aH *APIHandler) getOperations(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) getOperations(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
// vars := mux.Vars(r)
|
||||||
serviceName := vars["service"]
|
// serviceName := vars["service"]
|
||||||
|
|
||||||
var err error
|
// var err error
|
||||||
if len(serviceName) == 0 {
|
// if len(serviceName) == 0 {
|
||||||
err = fmt.Errorf("service param not found")
|
// err = fmt.Errorf("service param not found")
|
||||||
}
|
// }
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.GetOperations(aH.sqlClient, serviceName)
|
// result, err := druidQuery.GetOperations(aH.sqlClient, serviceName)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) getServicesList(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) getServicesList(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
result, err := druidQuery.GetServicesList(aH.sqlClient)
|
// result, err := druidQuery.GetServicesList(aH.sqlClient)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) searchTags(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) searchTags(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
serviceName := r.URL.Query().Get("service")
|
// serviceName := r.URL.Query().Get("service")
|
||||||
|
|
||||||
result, err := druidQuery.GetTags(aH.sqlClient, serviceName)
|
// result, err := druidQuery.GetTags(aH.sqlClient, serviceName)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) getTopEndpoints(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) getTopEndpoints(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
query, err := parseGetTopEndpointsRequest(r)
|
// query, err := parseGetTopEndpointsRequest(r)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.GetTopEndpoints(aH.sqlClient, query)
|
// result, err := druidQuery.GetTopEndpoints(aH.sqlClient, query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) getUsage(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) getUsage(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
query, err := parseGetUsageRequest(r)
|
// query, err := parseGetUsageRequest(r)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.GetUsage(aH.sqlClient, query)
|
// result, err := druidQuery.GetUsage(aH.sqlClient, query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) getServiceDBOverview(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) getServiceDBOverview(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
query, err := parseGetServiceExternalRequest(r)
|
// query, err := parseGetServiceExternalRequest(r)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.GetServiceDBOverview(aH.sqlClient, query)
|
// result, err := druidQuery.GetServiceDBOverview(aH.sqlClient, query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) getServiceExternal(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) getServiceExternal(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
query, err := parseGetServiceExternalRequest(r)
|
// query, err := parseGetServiceExternalRequest(r)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.GetServiceExternal(aH.sqlClient, query)
|
// result, err := druidQuery.GetServiceExternal(aH.sqlClient, query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) GetServiceExternalAvgDuration(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) GetServiceExternalAvgDuration(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
query, err := parseGetServiceExternalRequest(r)
|
// query, err := parseGetServiceExternalRequest(r)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.GetServiceExternalAvgDuration(aH.sqlClient, query)
|
// result, err := druidQuery.GetServiceExternalAvgDuration(aH.sqlClient, query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) getServiceExternalErrors(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) getServiceExternalErrors(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
query, err := parseGetServiceExternalRequest(r)
|
// query, err := parseGetServiceExternalRequest(r)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.GetServiceExternalErrors(aH.sqlClient, query)
|
// result, err := druidQuery.GetServiceExternalErrors(aH.sqlClient, query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) getServiceOverview(w http.ResponseWriter, r *http.Request) {
|
func (aH *APIHandler) getServiceOverview(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
@ -251,7 +248,7 @@ func (aH *APIHandler) getServiceOverview(w http.ResponseWriter, r *http.Request)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := druidQuery.GetServiceOverview(aH.sqlClient, query)
|
result, err := (*aH.reader).GetServiceOverview(context.Background(), query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -267,7 +264,7 @@ func (aH *APIHandler) getServices(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := druidQuery.GetServices(aH.sqlClient, query)
|
result, err := (*aH.reader).GetServices(context.Background(), query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -282,63 +279,63 @@ func (aH *APIHandler) getServices(w http.ResponseWriter, r *http.Request) {
|
|||||||
aH.writeJSON(w, r, result)
|
aH.writeJSON(w, r, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aH *APIHandler) serviceMapDependencies(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) serviceMapDependencies(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
query, err := parseGetServicesRequest(r)
|
// query, err := parseGetServicesRequest(r)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.GetServiceMapDependencies(aH.sqlClient, query)
|
// result, err := druidQuery.GetServiceMapDependencies(aH.sqlClient, query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) searchTraces(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) searchTraces(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
// vars := mux.Vars(r)
|
||||||
traceId := vars["traceId"]
|
// traceId := vars["traceId"]
|
||||||
|
|
||||||
result, err := druidQuery.SearchTraces(aH.client, traceId)
|
// result, err := druidQuery.SearchTraces(aH.client, traceId)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
|
|
||||||
}
|
// }
|
||||||
func (aH *APIHandler) searchSpansAggregates(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) searchSpansAggregates(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
query, err := parseSearchSpanAggregatesRequest(r)
|
// query, err := parseSearchSpanAggregatesRequest(r)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.SearchSpansAggregate(aH.client, query)
|
// result, err := druidQuery.SearchSpansAggregate(aH.client, query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) searchSpans(w http.ResponseWriter, r *http.Request) {
|
// func (aH *APIHandler) searchSpans(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
query, err := parseSpanSearchRequest(r)
|
// query, err := parseSpanSearchRequest(r)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
result, err := druidQuery.SearchSpans(aH.client, query)
|
// result, err := druidQuery.SearchSpans(aH.client, query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
// if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
aH.writeJSON(w, r, result)
|
// aH.writeJSON(w, r, result)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (aH *APIHandler) getApplicationPercentiles(w http.ResponseWriter, r *http.Request) {
|
func (aH *APIHandler) getApplicationPercentiles(w http.ResponseWriter, r *http.Request) {
|
||||||
// vars := mux.Vars(r)
|
// vars := mux.Vars(r)
|
||||||
@ -348,7 +345,7 @@ func (aH *APIHandler) getApplicationPercentiles(w http.ResponseWriter, r *http.R
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := druidQuery.GetApplicationPercentiles(aH.client, query)
|
result, err := (*aH.reader).GetApplicationPercentiles(context.Background(), query)
|
||||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
if aH.handleError(w, err, http.StatusBadRequest) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
14
pkg/query-service/app/interface.go
Normal file
14
pkg/query-service/app/interface.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"go.signoz.io/query-service/godruid"
|
||||||
|
"go.signoz.io/query-service/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Reader interface {
|
||||||
|
GetServiceOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, error)
|
||||||
|
GetServices(ctx context.Context, query *model.GetServicesParams) (*[]model.ServiceItem, error)
|
||||||
|
GetApplicationPercentiles(ctx context.Context, query *model.ApplicationPercentileParams) ([]godruid.Timeseries, error)
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@ -11,16 +13,15 @@ import (
|
|||||||
"github.com/posthog/posthog-go"
|
"github.com/posthog/posthog-go"
|
||||||
"github.com/rs/cors"
|
"github.com/rs/cors"
|
||||||
"github.com/soheilhy/cmux"
|
"github.com/soheilhy/cmux"
|
||||||
"go.signoz.io/query-service/druidQuery"
|
"go.signoz.io/query-service/app/druidReader"
|
||||||
"go.signoz.io/query-service/godruid"
|
|
||||||
"go.signoz.io/query-service/healthcheck"
|
"go.signoz.io/query-service/healthcheck"
|
||||||
"go.signoz.io/query-service/utils"
|
"go.signoz.io/query-service/utils"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerOptions struct {
|
type ServerOptions struct {
|
||||||
HTTPHostPort string
|
HTTPHostPort string
|
||||||
DruidClientUrl string
|
// DruidClientUrl string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server runs HTTP, Mux and a grpc server
|
// Server runs HTTP, Mux and a grpc server
|
||||||
@ -28,11 +29,10 @@ type Server struct {
|
|||||||
// logger *zap.Logger
|
// logger *zap.Logger
|
||||||
// querySvc *querysvc.QueryService
|
// querySvc *querysvc.QueryService
|
||||||
// queryOptions *QueryOptions
|
// queryOptions *QueryOptions
|
||||||
serverOptions *ServerOptions
|
|
||||||
|
|
||||||
// tracer opentracing.Tracer // TODO make part of flags.Service
|
// tracer opentracing.Tracer // TODO make part of flags.Service
|
||||||
|
serverOptions *ServerOptions
|
||||||
conn net.Listener
|
conn net.Listener
|
||||||
// grpcConn net.Listener
|
// grpcConn net.Listener
|
||||||
httpConn net.Listener
|
httpConn net.Listener
|
||||||
// grpcServer *grpc.Server
|
// grpcServer *grpc.Server
|
||||||
@ -64,6 +64,11 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
|||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return nil, err
|
// return nil, err
|
||||||
// }
|
// }
|
||||||
|
httpServer, err := createHTTPServer()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &Server{
|
return &Server{
|
||||||
// logger: logger,
|
// logger: logger,
|
||||||
@ -72,7 +77,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
|||||||
// tracer: tracer,
|
// tracer: tracer,
|
||||||
// grpcServer: grpcServer,
|
// grpcServer: grpcServer,
|
||||||
serverOptions: serverOptions,
|
serverOptions: serverOptions,
|
||||||
httpServer: createHTTPServer(serverOptions.DruidClientUrl),
|
httpServer: httpServer,
|
||||||
separatePorts: true,
|
separatePorts: true,
|
||||||
// separatePorts: grpcPort != httpPort,
|
// separatePorts: grpcPort != httpPort,
|
||||||
unavailableChannel: make(chan healthcheck.Status),
|
unavailableChannel: make(chan healthcheck.Status),
|
||||||
@ -82,22 +87,25 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
|||||||
var posthogClient posthog.Client
|
var posthogClient posthog.Client
|
||||||
var distinctId string
|
var distinctId string
|
||||||
|
|
||||||
func createHTTPServer(druidClientUrl string) *http.Server {
|
func createHTTPServer() (*http.Server, error) {
|
||||||
|
|
||||||
posthogClient = posthog.New("H-htDCae7CR3RV57gUzmol6IAKtm5IMCvbcm_fwnL-w")
|
posthogClient = posthog.New("H-htDCae7CR3RV57gUzmol6IAKtm5IMCvbcm_fwnL-w")
|
||||||
distinctId = uuid.New().String()
|
distinctId = uuid.New().String()
|
||||||
|
|
||||||
client := godruid.Client{
|
var reader Reader
|
||||||
Url: druidClientUrl,
|
|
||||||
Debug: true,
|
storage := os.Getenv("STORAGE")
|
||||||
|
if storage == "druid" {
|
||||||
|
druidClientUrl := os.Getenv("DruidClientUrl")
|
||||||
|
reader = druidReader.NewReader(druidClientUrl)
|
||||||
|
} else if storage == "clickhouse" {
|
||||||
|
// clickHouseClientUrl := os.Getenv("clickHouseClientUrl")
|
||||||
|
// reader = clickHouseReader.NewTraceReader()
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("Storage type: %s is not supported in query service", storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlClient := druidQuery.SqlClient{
|
apiHandler := NewAPIHandler(&reader, &posthogClient, distinctId)
|
||||||
Url: druidClientUrl,
|
|
||||||
Debug: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
apiHandler := NewAPIHandler(&client, &sqlClient, &posthogClient, distinctId)
|
|
||||||
r := NewRouter()
|
r := NewRouter()
|
||||||
|
|
||||||
r.Use(analyticsMiddleware)
|
r.Use(analyticsMiddleware)
|
||||||
@ -118,7 +126,7 @@ func createHTTPServer(druidClientUrl string) *http.Server {
|
|||||||
|
|
||||||
return &http.Server{
|
return &http.Server{
|
||||||
Handler: handler,
|
Handler: handler,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loggingMiddleware(next http.Handler) http.Handler {
|
func loggingMiddleware(next http.Handler) http.Handler {
|
||||||
|
@ -11,92 +11,6 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServiceItem struct {
|
|
||||||
ServiceName string `json:"serviceName"`
|
|
||||||
Percentile99 float32 `json:"p99"`
|
|
||||||
AvgDuration float32 `json:"avgDuration"`
|
|
||||||
NumCalls int `json:"numCalls"`
|
|
||||||
CallRate float32 `json:"callRate"`
|
|
||||||
NumErrors int `json:"numErrors"`
|
|
||||||
ErrorRate float32 `json:"errorRate"`
|
|
||||||
Num4XX int `json:"num4XX"`
|
|
||||||
FourXXRate float32 `json:"fourXXRate"`
|
|
||||||
}
|
|
||||||
type ServiceListErrorItem struct {
|
|
||||||
ServiceName string `json:"serviceName"`
|
|
||||||
NumErrors int `json:"numErrors"`
|
|
||||||
Num4xx int `json:"num4xx"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceErrorItem struct {
|
|
||||||
Time string `json:"time,omitempty"`
|
|
||||||
Timestamp int64 `json:"timestamp"`
|
|
||||||
NumErrors int `json:"numErrors"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceOverviewItem struct {
|
|
||||||
Time string `json:"time,omitempty"`
|
|
||||||
Timestamp int64 `json:"timestamp"`
|
|
||||||
Percentile50 float32 `json:"p50"`
|
|
||||||
Percentile95 float32 `json:"p95"`
|
|
||||||
Percentile99 float32 `json:"p99"`
|
|
||||||
NumCalls int `json:"numCalls"`
|
|
||||||
CallRate float32 `json:"callRate"`
|
|
||||||
NumErrors int `json:"numErrors"`
|
|
||||||
ErrorRate float32 `json:"errorRate"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceExternalItem struct {
|
|
||||||
Time string `json:"time,omitempty"`
|
|
||||||
Timestamp int64 `json:"timestamp,omitempty"`
|
|
||||||
ExternalHttpUrl string `json:"externalHttpUrl,omitempty"`
|
|
||||||
AvgDuration float32 `json:"avgDuration,omitempty"`
|
|
||||||
NumCalls int `json:"numCalls,omitempty"`
|
|
||||||
CallRate float32 `json:"callRate,omitempty"`
|
|
||||||
NumErrors int `json:"numErrors"`
|
|
||||||
ErrorRate float32 `json:"errorRate"`
|
|
||||||
}
|
|
||||||
|
|
||||||
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"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceMapDependencyItem struct {
|
|
||||||
SpanId string `json:"spanId,omitempty"`
|
|
||||||
ParentSpanId string `json:"parentSpanId,omitempty"`
|
|
||||||
ServiceName string `json:"serviceName,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type UsageItem struct {
|
|
||||||
Time string `json:"time,omitempty"`
|
|
||||||
Timestamp int64 `json:"timestamp"`
|
|
||||||
Count int64 `json:"count"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TopEnpointsItem struct {
|
|
||||||
Percentile50 float32 `json:"p50"`
|
|
||||||
Percentile90 float32 `json:"p90"`
|
|
||||||
Percentile99 float32 `json:"p99"`
|
|
||||||
NumCalls int `json:"numCalls"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TagItem struct {
|
|
||||||
TagKeys string `json:"tagKeys"`
|
|
||||||
TagCount int `json:"tagCount"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceMapDependencyResponseItem struct {
|
|
||||||
Parent string `json:"parent,omitempty"`
|
|
||||||
Child string `json:"child,omitempty"`
|
|
||||||
CallCount int `json:"callCount,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetOperations(client *SqlClient, serviceName string) (*[]string, error) {
|
func GetOperations(client *SqlClient, serviceName string) (*[]string, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT DISTINCT(Name) FROM %s WHERE ServiceName='%s' AND __time > CURRENT_TIMESTAMP - INTERVAL '1' DAY`, constants.DruidDatasource, serviceName)
|
sqlQuery := fmt.Sprintf(`SELECT DISTINCT(Name) FROM %s WHERE ServiceName='%s' AND __time > CURRENT_TIMESTAMP - INTERVAL '1' DAY`, constants.DruidDatasource, serviceName)
|
||||||
@ -155,7 +69,7 @@ func GetServicesList(client *SqlClient) (*[]string, error) {
|
|||||||
return &servicesListReponse, nil
|
return &servicesListReponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTags(client *SqlClient, serviceName string) (*[]TagItem, error) {
|
func GetTags(client *SqlClient, serviceName string) (*[]model.TagItem, error) {
|
||||||
|
|
||||||
var sqlQuery string
|
var sqlQuery string
|
||||||
|
|
||||||
@ -176,7 +90,7 @@ func GetTags(client *SqlClient, serviceName string) (*[]TagItem, error) {
|
|||||||
|
|
||||||
// zap.S().Info(string(response))
|
// zap.S().Info(string(response))
|
||||||
|
|
||||||
res := new([]TagItem)
|
res := new([]model.TagItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -187,7 +101,7 @@ func GetTags(client *SqlClient, serviceName string) (*[]TagItem, error) {
|
|||||||
return &tagResponse, nil
|
return &tagResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTopEndpoints(client *SqlClient, query *model.GetTopEndpointsParams) (*[]TopEnpointsItem, error) {
|
func GetTopEndpoints(client *SqlClient, query *model.GetTopEndpointsParams) (*[]model.TopEnpointsItem, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT APPROX_QUANTILE_DS("QuantileDuration", 0.5) as p50, APPROX_QUANTILE_DS("QuantileDuration", 0.9) as p90, APPROX_QUANTILE_DS("QuantileDuration", 0.99) as p99, COUNT(SpanId) as numCalls, Name FROM "%s" WHERE "__time" >= '%s' AND "__time" <= '%s' AND "Kind"='2' and "ServiceName"='%s' GROUP BY Name`, constants.DruidDatasource, query.StartTime, query.EndTime, query.ServiceName)
|
sqlQuery := fmt.Sprintf(`SELECT APPROX_QUANTILE_DS("QuantileDuration", 0.5) as p50, APPROX_QUANTILE_DS("QuantileDuration", 0.9) as p90, APPROX_QUANTILE_DS("QuantileDuration", 0.99) as p99, COUNT(SpanId) as numCalls, Name FROM "%s" WHERE "__time" >= '%s' AND "__time" <= '%s' AND "Kind"='2' and "ServiceName"='%s' GROUP BY Name`, constants.DruidDatasource, query.StartTime, query.EndTime, query.ServiceName)
|
||||||
|
|
||||||
@ -202,7 +116,7 @@ func GetTopEndpoints(client *SqlClient, query *model.GetTopEndpointsParams) (*[]
|
|||||||
|
|
||||||
// zap.S().Info(string(response))
|
// zap.S().Info(string(response))
|
||||||
|
|
||||||
res := new([]TopEnpointsItem)
|
res := new([]model.TopEnpointsItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -213,7 +127,7 @@ func GetTopEndpoints(client *SqlClient, query *model.GetTopEndpointsParams) (*[]
|
|||||||
return &topEnpointsResponse, nil
|
return &topEnpointsResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUsage(client *SqlClient, query *model.GetUsageParams) (*[]UsageItem, error) {
|
func GetUsage(client *SqlClient, query *model.GetUsageParams) (*[]model.UsageItem, error) {
|
||||||
|
|
||||||
var sqlQuery string
|
var sqlQuery string
|
||||||
|
|
||||||
@ -236,7 +150,7 @@ func GetUsage(client *SqlClient, query *model.GetUsageParams) (*[]UsageItem, err
|
|||||||
|
|
||||||
// zap.S().Info(string(response))
|
// zap.S().Info(string(response))
|
||||||
|
|
||||||
res := new([]UsageItem)
|
res := new([]model.UsageItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -253,7 +167,7 @@ func GetUsage(client *SqlClient, query *model.GetUsageParams) (*[]UsageItem, err
|
|||||||
return &usageResponse, nil
|
return &usageResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetServiceExternalAvgDuration(client *SqlClient, query *model.GetServiceOverviewParams) (*[]ServiceExternalItem, error) {
|
func GetServiceExternalAvgDuration(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", AVG(DurationNano) as "avgDuration" FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != '' AND "__time" >= '%s' AND "__time" <= '%s'
|
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", AVG(DurationNano) as "avgDuration" FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != '' AND "__time" >= '%s' AND "__time" <= '%s'
|
||||||
GROUP BY TIME_FLOOR(__time, '%s')`, query.Period, constants.DruidDatasource, query.ServiceName, query.StartTime, query.EndTime, query.Period)
|
GROUP BY TIME_FLOOR(__time, '%s')`, query.Period, constants.DruidDatasource, query.ServiceName, query.StartTime, query.EndTime, query.Period)
|
||||||
@ -270,7 +184,7 @@ func GetServiceExternalAvgDuration(client *SqlClient, query *model.GetServiceOve
|
|||||||
// responseStr := string(response)
|
// responseStr := string(response)
|
||||||
// zap.S().Info(responseStr)
|
// zap.S().Info(responseStr)
|
||||||
|
|
||||||
res := new([]ServiceExternalItem)
|
res := new([]model.ServiceExternalItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -289,7 +203,7 @@ func GetServiceExternalAvgDuration(client *SqlClient, query *model.GetServiceOve
|
|||||||
return &servicesExternalResponse, nil
|
return &servicesExternalResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetServiceExternalErrors(client *SqlClient, query *model.GetServiceOverviewParams) (*[]ServiceExternalItem, error) {
|
func GetServiceExternalErrors(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", COUNT(SpanId) as "numCalls", ExternalHttpUrl as externalHttpUrl FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != '' AND StatusCode >= 500 AND "__time" >= '%s' AND "__time" <= '%s'
|
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", COUNT(SpanId) as "numCalls", ExternalHttpUrl as externalHttpUrl FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != '' AND StatusCode >= 500 AND "__time" >= '%s' AND "__time" <= '%s'
|
||||||
GROUP BY TIME_FLOOR(__time, '%s'), ExternalHttpUrl`, query.Period, constants.DruidDatasource, query.ServiceName, query.StartTime, query.EndTime, query.Period)
|
GROUP BY TIME_FLOOR(__time, '%s'), ExternalHttpUrl`, query.Period, constants.DruidDatasource, query.ServiceName, query.StartTime, query.EndTime, query.Period)
|
||||||
@ -306,7 +220,7 @@ func GetServiceExternalErrors(client *SqlClient, query *model.GetServiceOverview
|
|||||||
// responseStr := string(response)
|
// responseStr := string(response)
|
||||||
// zap.S().Info(responseStr)
|
// zap.S().Info(responseStr)
|
||||||
|
|
||||||
res := new([]ServiceExternalItem)
|
res := new([]model.ServiceExternalItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -328,7 +242,7 @@ func GetServiceExternalErrors(client *SqlClient, query *model.GetServiceOverview
|
|||||||
// responseStr := string(response)
|
// responseStr := string(response)
|
||||||
// zap.S().Info(responseStr)
|
// zap.S().Info(responseStr)
|
||||||
|
|
||||||
resTotal := new([]ServiceExternalItem)
|
resTotal := new([]model.ServiceExternalItem)
|
||||||
err = json.Unmarshal(responseTotal, resTotal)
|
err = json.Unmarshal(responseTotal, resTotal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -361,7 +275,7 @@ func GetServiceExternalErrors(client *SqlClient, query *model.GetServiceOverview
|
|||||||
return &servicesExternalResponse, nil
|
return &servicesExternalResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetServiceExternal(client *SqlClient, query *model.GetServiceOverviewParams) (*[]ServiceExternalItem, error) {
|
func GetServiceExternal(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceExternalItem, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", AVG(DurationNano) as "avgDuration", COUNT(SpanId) as "numCalls", ExternalHttpUrl as externalHttpUrl FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != ''
|
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", AVG(DurationNano) as "avgDuration", COUNT(SpanId) as "numCalls", ExternalHttpUrl as externalHttpUrl FROM %s WHERE ServiceName='%s' AND Kind='3' AND ExternalHttpUrl != ''
|
||||||
AND "__time" >= '%s' AND "__time" <= '%s'
|
AND "__time" >= '%s' AND "__time" <= '%s'
|
||||||
@ -379,7 +293,7 @@ func GetServiceExternal(client *SqlClient, query *model.GetServiceOverviewParams
|
|||||||
// responseStr := string(response)
|
// responseStr := string(response)
|
||||||
// zap.S().Info(responseStr)
|
// zap.S().Info(responseStr)
|
||||||
|
|
||||||
res := new([]ServiceExternalItem)
|
res := new([]model.ServiceExternalItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -398,7 +312,7 @@ func GetServiceExternal(client *SqlClient, query *model.GetServiceOverviewParams
|
|||||||
return &servicesExternalResponse, nil
|
return &servicesExternalResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetServiceDBOverview(client *SqlClient, query *model.GetServiceOverviewParams) (*[]ServiceDBOverviewItem, error) {
|
func GetServiceDBOverview(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceDBOverviewItem, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", AVG(DurationNano) as "avgDuration", COUNT(SpanId) as "numCalls", DBSystem as "dbSystem" FROM %s WHERE ServiceName='%s' AND Kind='3' AND DBName IS NOT NULL
|
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", AVG(DurationNano) as "avgDuration", COUNT(SpanId) as "numCalls", DBSystem as "dbSystem" FROM %s WHERE ServiceName='%s' AND Kind='3' AND DBName IS NOT NULL
|
||||||
AND "__time" >= '%s' AND "__time" <= '%s'
|
AND "__time" >= '%s' AND "__time" <= '%s'
|
||||||
@ -416,7 +330,7 @@ func GetServiceDBOverview(client *SqlClient, query *model.GetServiceOverviewPara
|
|||||||
// responseStr := string(response)
|
// responseStr := string(response)
|
||||||
// zap.S().Info(responseStr)
|
// zap.S().Info(responseStr)
|
||||||
|
|
||||||
res := new([]ServiceDBOverviewItem)
|
res := new([]model.ServiceDBOverviewItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -435,7 +349,7 @@ func GetServiceDBOverview(client *SqlClient, query *model.GetServiceOverviewPara
|
|||||||
return &servicesDBOverviewResponse, nil
|
return &servicesDBOverviewResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetServiceOverview(client *SqlClient, query *model.GetServiceOverviewParams) (*[]ServiceOverviewItem, error) {
|
func GetServiceOverview(client *SqlClient, query *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", APPROX_QUANTILE_DS("QuantileDuration", 0.5) as p50, APPROX_QUANTILE_DS("QuantileDuration", 0.95) as p95,
|
sqlQuery := fmt.Sprintf(`SELECT TIME_FLOOR(__time, '%s') as "time", APPROX_QUANTILE_DS("QuantileDuration", 0.5) as p50, APPROX_QUANTILE_DS("QuantileDuration", 0.95) as p95,
|
||||||
APPROX_QUANTILE_DS("QuantileDuration", 0.99) as p99, COUNT("SpanId") as "numCalls" FROM "%s" WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' and "ServiceName"='%s' GROUP BY TIME_FLOOR(__time, '%s') `, query.Period, constants.DruidDatasource, query.StartTime, query.EndTime, query.ServiceName, query.Period)
|
APPROX_QUANTILE_DS("QuantileDuration", 0.99) as p99, COUNT("SpanId") as "numCalls" FROM "%s" WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' and "ServiceName"='%s' GROUP BY TIME_FLOOR(__time, '%s') `, query.Period, constants.DruidDatasource, query.StartTime, query.EndTime, query.ServiceName, query.Period)
|
||||||
@ -451,7 +365,7 @@ func GetServiceOverview(client *SqlClient, query *model.GetServiceOverviewParams
|
|||||||
|
|
||||||
// zap.S().Info(string(response))
|
// zap.S().Info(string(response))
|
||||||
|
|
||||||
res := new([]ServiceOverviewItem)
|
res := new([]model.ServiceOverviewItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -471,7 +385,7 @@ func GetServiceOverview(client *SqlClient, query *model.GetServiceOverviewParams
|
|||||||
|
|
||||||
// zap.S().Info(string(response))
|
// zap.S().Info(string(response))
|
||||||
|
|
||||||
resError := new([]ServiceErrorItem)
|
resError := new([]model.ServiceErrorItem)
|
||||||
err = json.Unmarshal(responseError, resError)
|
err = json.Unmarshal(responseError, resError)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -501,7 +415,7 @@ func GetServiceOverview(client *SqlClient, query *model.GetServiceOverviewParams
|
|||||||
return &servicesOverviewResponse, nil
|
return &servicesOverviewResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceItem, error) {
|
func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]model.ServiceItem, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT APPROX_QUANTILE_DS("QuantileDuration", 0.99) as "p99", AVG("DurationNano") as "avgDuration", COUNT(SpanId) as numCalls, "ServiceName" as "serviceName" FROM %s WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' GROUP BY "ServiceName" ORDER BY "p99" DESC`, constants.DruidDatasource, query.StartTime, query.EndTime)
|
sqlQuery := fmt.Sprintf(`SELECT APPROX_QUANTILE_DS("QuantileDuration", 0.99) as "p99", AVG("DurationNano") as "avgDuration", COUNT(SpanId) as numCalls, "ServiceName" as "serviceName" FROM %s WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' GROUP BY "ServiceName" ORDER BY "p99" DESC`, constants.DruidDatasource, query.StartTime, query.EndTime)
|
||||||
|
|
||||||
@ -516,7 +430,7 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI
|
|||||||
|
|
||||||
// zap.S().Info(string(response))
|
// zap.S().Info(string(response))
|
||||||
|
|
||||||
res := new([]ServiceItem)
|
res := new([]model.ServiceItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -538,7 +452,7 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI
|
|||||||
|
|
||||||
// zap.S().Info(string(response))
|
// zap.S().Info(string(response))
|
||||||
|
|
||||||
resError := new([]ServiceListErrorItem)
|
resError := new([]model.ServiceListErrorItem)
|
||||||
err = json.Unmarshal(responseError, resError)
|
err = json.Unmarshal(responseError, resError)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -568,7 +482,7 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI
|
|||||||
|
|
||||||
// zap.S().Info(string(response))
|
// zap.S().Info(string(response))
|
||||||
|
|
||||||
res4xx := new([]ServiceListErrorItem)
|
res4xx := new([]model.ServiceListErrorItem)
|
||||||
err = json.Unmarshal(response4xx, res4xx)
|
err = json.Unmarshal(response4xx, res4xx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -601,7 +515,7 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI
|
|||||||
return &servicesResponse, nil
|
return &servicesResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams) (*[]ServiceMapDependencyResponseItem, error) {
|
func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams) (*[]model.ServiceMapDependencyResponseItem, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT SpanId, ParentSpanId, ServiceName FROM %s WHERE "__time" >= '%s' AND "__time" <= '%s' ORDER BY __time DESC LIMIT 100000`, constants.DruidDatasource, query.StartTime, query.EndTime)
|
sqlQuery := fmt.Sprintf(`SELECT SpanId, ParentSpanId, ServiceName FROM %s WHERE "__time" >= '%s' AND "__time" <= '%s' ORDER BY __time DESC LIMIT 100000`, constants.DruidDatasource, query.StartTime, query.EndTime)
|
||||||
|
|
||||||
@ -617,7 +531,7 @@ func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams
|
|||||||
// responseStr := string(response)
|
// responseStr := string(response)
|
||||||
// zap.S().Info(responseStr)
|
// zap.S().Info(responseStr)
|
||||||
|
|
||||||
res := new([]ServiceMapDependencyItem)
|
res := new([]model.ServiceMapDependencyItem)
|
||||||
err = json.Unmarshal(response, res)
|
err = json.Unmarshal(response, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Error(err)
|
zap.S().Error(err)
|
||||||
@ -626,7 +540,7 @@ func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams
|
|||||||
// resCount := len(*res)
|
// resCount := len(*res)
|
||||||
// fmt.Println(resCount)
|
// fmt.Println(resCount)
|
||||||
|
|
||||||
serviceMap := make(map[string]*ServiceMapDependencyResponseItem)
|
serviceMap := make(map[string]*model.ServiceMapDependencyResponseItem)
|
||||||
|
|
||||||
spanId2ServiceNameMap := make(map[string]string)
|
spanId2ServiceNameMap := make(map[string]string)
|
||||||
for i, _ := range *res {
|
for i, _ := range *res {
|
||||||
@ -635,7 +549,7 @@ func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams
|
|||||||
for i, _ := range *res {
|
for i, _ := range *res {
|
||||||
parent2childServiceName := spanId2ServiceNameMap[(*res)[i].ParentSpanId] + "-" + spanId2ServiceNameMap[(*res)[i].SpanId]
|
parent2childServiceName := spanId2ServiceNameMap[(*res)[i].ParentSpanId] + "-" + spanId2ServiceNameMap[(*res)[i].SpanId]
|
||||||
if _, ok := serviceMap[parent2childServiceName]; !ok {
|
if _, ok := serviceMap[parent2childServiceName]; !ok {
|
||||||
serviceMap[parent2childServiceName] = &ServiceMapDependencyResponseItem{
|
serviceMap[parent2childServiceName] = &model.ServiceMapDependencyResponseItem{
|
||||||
Parent: spanId2ServiceNameMap[(*res)[i].ParentSpanId],
|
Parent: spanId2ServiceNameMap[(*res)[i].ParentSpanId],
|
||||||
Child: spanId2ServiceNameMap[(*res)[i].SpanId],
|
Child: spanId2ServiceNameMap[(*res)[i].SpanId],
|
||||||
CallCount: 1,
|
CallCount: 1,
|
||||||
@ -645,7 +559,7 @@ func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
retMe := make([]ServiceMapDependencyResponseItem, 0, len(serviceMap))
|
retMe := make([]model.ServiceMapDependencyResponseItem, 0, len(serviceMap))
|
||||||
for _, dependency := range serviceMap {
|
for _, dependency := range serviceMap {
|
||||||
if dependency.Parent == "" {
|
if dependency.Parent == "" {
|
||||||
continue
|
continue
|
||||||
|
@ -3,10 +3,12 @@ module go.signoz.io/query-service
|
|||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/gogo/protobuf v1.2.1
|
||||||
github.com/google/uuid v1.1.1
|
github.com/google/uuid v1.1.1
|
||||||
github.com/gorilla/handlers v1.5.1
|
github.com/gorilla/handlers v1.5.1
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/jaegertracing/jaeger v1.21.0
|
github.com/jaegertracing/jaeger v1.21.0
|
||||||
|
github.com/opentracing/opentracing-go v1.1.0
|
||||||
github.com/ory/viper v1.7.5
|
github.com/ory/viper v1.7.5
|
||||||
github.com/posthog/posthog-go v0.0.0-20200525173953-e46dc8e6b89b
|
github.com/posthog/posthog-go v0.0.0-20200525173953-e46dc8e6b89b
|
||||||
github.com/rs/cors v1.7.0
|
github.com/rs/cors v1.7.0
|
||||||
|
@ -57,14 +57,12 @@ func main() {
|
|||||||
logger := loggerMgr.Sugar()
|
logger := loggerMgr.Sugar()
|
||||||
logger.Debug("START!")
|
logger.Debug("START!")
|
||||||
|
|
||||||
// v := initViper()
|
|
||||||
|
|
||||||
serverOptions := &app.ServerOptions{
|
serverOptions := &app.ServerOptions{
|
||||||
// HTTPHostPort: v.GetString(app.HTTPHostPort),
|
// HTTPHostPort: v.GetString(app.HTTPHostPort),
|
||||||
// DruidClientUrl: v.GetString(app.DruidClientUrl),
|
// DruidClientUrl: v.GetString(app.DruidClientUrl),
|
||||||
|
|
||||||
HTTPHostPort: constants.HTTPHostPort,
|
HTTPHostPort: constants.HTTPHostPort,
|
||||||
DruidClientUrl: constants.DruidClientUrl,
|
// DruidClientUrl: constants.DruidClientUrl,
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := app.NewServer(serverOptions)
|
server, err := app.NewServer(serverOptions)
|
||||||
|
87
pkg/query-service/model/response.go
Normal file
87
pkg/query-service/model/response.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type ServiceItem struct {
|
||||||
|
ServiceName string `json:"serviceName"`
|
||||||
|
Percentile99 float32 `json:"p99"`
|
||||||
|
AvgDuration float32 `json:"avgDuration"`
|
||||||
|
NumCalls int `json:"numCalls"`
|
||||||
|
CallRate float32 `json:"callRate"`
|
||||||
|
NumErrors int `json:"numErrors"`
|
||||||
|
ErrorRate float32 `json:"errorRate"`
|
||||||
|
Num4XX int `json:"num4XX"`
|
||||||
|
FourXXRate float32 `json:"fourXXRate"`
|
||||||
|
}
|
||||||
|
type ServiceListErrorItem struct {
|
||||||
|
ServiceName string `json:"serviceName"`
|
||||||
|
NumErrors int `json:"numErrors"`
|
||||||
|
Num4xx int `json:"num4xx"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceErrorItem struct {
|
||||||
|
Time string `json:"time,omitempty"`
|
||||||
|
Timestamp int64 `json:"timestamp"`
|
||||||
|
NumErrors int `json:"numErrors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceOverviewItem struct {
|
||||||
|
Time string `json:"time,omitempty"`
|
||||||
|
Timestamp int64 `json:"timestamp"`
|
||||||
|
Percentile50 float32 `json:"p50"`
|
||||||
|
Percentile95 float32 `json:"p95"`
|
||||||
|
Percentile99 float32 `json:"p99"`
|
||||||
|
NumCalls int `json:"numCalls"`
|
||||||
|
CallRate float32 `json:"callRate"`
|
||||||
|
NumErrors int `json:"numErrors"`
|
||||||
|
ErrorRate float32 `json:"errorRate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceExternalItem struct {
|
||||||
|
Time string `json:"time,omitempty"`
|
||||||
|
Timestamp int64 `json:"timestamp,omitempty"`
|
||||||
|
ExternalHttpUrl string `json:"externalHttpUrl,omitempty"`
|
||||||
|
AvgDuration float32 `json:"avgDuration,omitempty"`
|
||||||
|
NumCalls int `json:"numCalls,omitempty"`
|
||||||
|
CallRate float32 `json:"callRate,omitempty"`
|
||||||
|
NumErrors int `json:"numErrors"`
|
||||||
|
ErrorRate float32 `json:"errorRate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceMapDependencyItem struct {
|
||||||
|
SpanId string `json:"spanId,omitempty"`
|
||||||
|
ParentSpanId string `json:"parentSpanId,omitempty"`
|
||||||
|
ServiceName string `json:"serviceName,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UsageItem struct {
|
||||||
|
Time string `json:"time,omitempty"`
|
||||||
|
Timestamp int64 `json:"timestamp"`
|
||||||
|
Count int64 `json:"count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TopEnpointsItem struct {
|
||||||
|
Percentile50 float32 `json:"p50"`
|
||||||
|
Percentile90 float32 `json:"p90"`
|
||||||
|
Percentile99 float32 `json:"p99"`
|
||||||
|
NumCalls int `json:"numCalls"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TagItem struct {
|
||||||
|
TagKeys string `json:"tagKeys"`
|
||||||
|
TagCount int `json:"tagCount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceMapDependencyResponseItem struct {
|
||||||
|
Parent string `json:"parent,omitempty"`
|
||||||
|
Child string `json:"child,omitempty"`
|
||||||
|
CallCount int `json:"callCount,omitempty"`
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user