diff --git a/pkg/query-service/__debug_bin b/pkg/query-service/__debug_bin deleted file mode 100755 index 2f81072b62..0000000000 Binary files a/pkg/query-service/__debug_bin and /dev/null differ diff --git a/pkg/query-service/app/druidReader/reader.go b/pkg/query-service/app/druidReader/reader.go index e3b92d82f4..b92ff0ddfe 100644 --- a/pkg/query-service/app/druidReader/reader.go +++ b/pkg/query-service/app/druidReader/reader.go @@ -1,22 +1,49 @@ package druidReader import ( + "context" + "go.signoz.io/query-service/druidQuery" + "go.signoz.io/query-service/godruid" "go.signoz.io/query-service/model" ) type DruidReader struct { - Client - SqlClient + Client *godruid.Client + SqlClient *druidQuery.SqlClient } -func NewSpanReader() { +func NewReader(druidClientUrl string) *DruidReader { + initialize() + + client := godruid.Client{ + Url: druidClientUrl, + Debug: true, + } + + sqlClient := druidQuery.SqlClient{ + Url: druidClientUrl, + Debug: true, + } + return &DruidReader{ + Client: &client, + SqlClient: &sqlClient, + } + } func initialize() { } -func (druid *Druid) GetServices(client, query *model.GetServicesParams) { - return druidQuery.GetServices(druid.sqlClient, query) +func (druid *DruidReader) GetServiceOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, error) { + 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) } diff --git a/pkg/query-service/app/fatory.go b/pkg/query-service/app/fatory.go deleted file mode 100644 index 42f42d2236..0000000000 --- a/pkg/query-service/app/fatory.go +++ /dev/null @@ -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() { - -} diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index 35798d374e..5401edab7f 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -1,14 +1,13 @@ package app import ( + "context" "encoding/json" "fmt" "net/http" "github.com/gorilla/mux" "github.com/posthog/posthog-go" - "go.signoz.io/query-service/druidQuery" - "go.signoz.io/query-service/godruid" "go.uber.org/zap" ) @@ -23,17 +22,15 @@ type APIHandler struct { // queryParser queryParser basePath string apiPrefix string - client *godruid.Client - sqlClient *druidQuery.SqlClient + reader *Reader pc *posthog.Client distinctId string } // 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{ - client: client, - sqlClient: sqlClient, + reader: reader, pc: pc, 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/get_percentiles", aH.getApplicationPercentiles).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/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) - 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/spans", aH.searchSpans).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/traces/{traceId}", aH.searchTraces).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/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) + // 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/spans", aH.searchSpans).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/traces/{traceId}", aH.searchTraces).Methods(http.MethodGet) + // router.HandleFunc("/api/v1/usage", aH.getUsage).Methods(http.MethodGet) + // router.HandleFunc("/api/v1/serviceMapDependencies", aH.serviceMapDependencies).Methods(http.MethodGet) } 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) - serviceName := vars["service"] +// vars := mux.Vars(r) +// serviceName := vars["service"] - var err error - if len(serviceName) == 0 { - err = fmt.Errorf("service param not found") - } - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// var err error +// if len(serviceName) == 0 { +// err = fmt.Errorf("service param not found") +// } +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - result, err := druidQuery.GetOperations(aH.sqlClient, serviceName) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.GetOperations(aH.sqlClient, serviceName) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.GetServicesList(aH.sqlClient) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.GetTags(aH.sqlClient, serviceName) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// query, err := parseGetTopEndpointsRequest(r) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - result, err := druidQuery.GetTopEndpoints(aH.sqlClient, query) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.GetTopEndpoints(aH.sqlClient, query) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// query, err := parseGetUsageRequest(r) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - result, err := druidQuery.GetUsage(aH.sqlClient, query) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.GetUsage(aH.sqlClient, query) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - 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 := druidQuery.GetServiceDBOverview(aH.sqlClient, query) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// query, err := parseGetServiceExternalRequest(r) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - result, err := druidQuery.GetServiceExternal(aH.sqlClient, query) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.GetServiceExternal(aH.sqlClient, query) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// query, err := parseGetServiceExternalRequest(r) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - result, err := druidQuery.GetServiceExternalAvgDuration(aH.sqlClient, query) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.GetServiceExternalAvgDuration(aH.sqlClient, query) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// query, err := parseGetServiceExternalRequest(r) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - result, err := druidQuery.GetServiceExternalErrors(aH.sqlClient, query) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.GetServiceExternalErrors(aH.sqlClient, query) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - aH.writeJSON(w, r, result) +// aH.writeJSON(w, r, result) -} +// } 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 } - result, err := druidQuery.GetServiceOverview(aH.sqlClient, query) + result, err := (*aH.reader).GetServiceOverview(context.Background(), query) if aH.handleError(w, err, http.StatusBadRequest) { return } @@ -267,7 +264,7 @@ func (aH *APIHandler) getServices(w http.ResponseWriter, r *http.Request) { return } - result, err := druidQuery.GetServices(aH.sqlClient, query) + result, err := (*aH.reader).GetServices(context.Background(), query) if aH.handleError(w, err, http.StatusBadRequest) { return } @@ -282,63 +279,63 @@ func (aH *APIHandler) getServices(w http.ResponseWriter, r *http.Request) { 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// query, err := parseGetServicesRequest(r) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - result, err := druidQuery.GetServiceMapDependencies(aH.sqlClient, query) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.GetServiceMapDependencies(aH.sqlClient, query) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - traceId := vars["traceId"] +// vars := mux.Vars(r) +// traceId := vars["traceId"] - result, err := druidQuery.SearchTraces(aH.client, traceId) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.SearchTraces(aH.client, traceId) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// query, err := parseSearchSpanAggregatesRequest(r) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - result, err := druidQuery.SearchSpansAggregate(aH.client, query) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.SearchSpansAggregate(aH.client, query) +// if aH.handleError(w, err, http.StatusBadRequest) { +// 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) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// query, err := parseSpanSearchRequest(r) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - result, err := druidQuery.SearchSpans(aH.client, query) - if aH.handleError(w, err, http.StatusBadRequest) { - return - } +// result, err := druidQuery.SearchSpans(aH.client, query) +// if aH.handleError(w, err, http.StatusBadRequest) { +// return +// } - aH.writeJSON(w, r, result) -} +// aH.writeJSON(w, r, result) +// } func (aH *APIHandler) getApplicationPercentiles(w http.ResponseWriter, r *http.Request) { // vars := mux.Vars(r) @@ -348,7 +345,7 @@ func (aH *APIHandler) getApplicationPercentiles(w http.ResponseWriter, r *http.R return } - result, err := druidQuery.GetApplicationPercentiles(aH.client, query) + result, err := (*aH.reader).GetApplicationPercentiles(context.Background(), query) if aH.handleError(w, err, http.StatusBadRequest) { return } diff --git a/pkg/query-service/app/interface.go b/pkg/query-service/app/interface.go new file mode 100644 index 0000000000..d268820a04 --- /dev/null +++ b/pkg/query-service/app/interface.go @@ -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) +} diff --git a/pkg/query-service/app/server.go b/pkg/query-service/app/server.go index 4abf7b7e5a..0030fbae21 100644 --- a/pkg/query-service/app/server.go +++ b/pkg/query-service/app/server.go @@ -1,8 +1,10 @@ package app import ( + "fmt" "net" "net/http" + "os" "time" "github.com/google/uuid" @@ -11,16 +13,15 @@ import ( "github.com/posthog/posthog-go" "github.com/rs/cors" "github.com/soheilhy/cmux" - "go.signoz.io/query-service/druidQuery" - "go.signoz.io/query-service/godruid" + "go.signoz.io/query-service/app/druidReader" "go.signoz.io/query-service/healthcheck" "go.signoz.io/query-service/utils" "go.uber.org/zap" ) type ServerOptions struct { - HTTPHostPort string - DruidClientUrl string + HTTPHostPort string + // DruidClientUrl string } // Server runs HTTP, Mux and a grpc server @@ -28,11 +29,10 @@ type Server struct { // logger *zap.Logger // querySvc *querysvc.QueryService // queryOptions *QueryOptions - serverOptions *ServerOptions // tracer opentracing.Tracer // TODO make part of flags.Service - - conn net.Listener + serverOptions *ServerOptions + conn net.Listener // grpcConn net.Listener httpConn net.Listener // grpcServer *grpc.Server @@ -64,6 +64,11 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) { // if err != nil { // return nil, err // } + httpServer, err := createHTTPServer() + + if err != nil { + return nil, err + } return &Server{ // logger: logger, @@ -72,7 +77,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) { // tracer: tracer, // grpcServer: grpcServer, serverOptions: serverOptions, - httpServer: createHTTPServer(serverOptions.DruidClientUrl), + httpServer: httpServer, separatePorts: true, // separatePorts: grpcPort != httpPort, unavailableChannel: make(chan healthcheck.Status), @@ -82,22 +87,25 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) { var posthogClient posthog.Client var distinctId string -func createHTTPServer(druidClientUrl string) *http.Server { +func createHTTPServer() (*http.Server, error) { posthogClient = posthog.New("H-htDCae7CR3RV57gUzmol6IAKtm5IMCvbcm_fwnL-w") distinctId = uuid.New().String() - client := godruid.Client{ - Url: druidClientUrl, - Debug: true, + var reader Reader + + 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{ - Url: druidClientUrl, - Debug: true, - } - - apiHandler := NewAPIHandler(&client, &sqlClient, &posthogClient, distinctId) + apiHandler := NewAPIHandler(&reader, &posthogClient, distinctId) r := NewRouter() r.Use(analyticsMiddleware) @@ -118,7 +126,7 @@ func createHTTPServer(druidClientUrl string) *http.Server { return &http.Server{ Handler: handler, - } + }, nil } func loggingMiddleware(next http.Handler) http.Handler { diff --git a/pkg/query-service/druidQuery/mysql-query.go b/pkg/query-service/druidQuery/mysql-query.go index ff43dac6e1..4465a9b51b 100644 --- a/pkg/query-service/druidQuery/mysql-query.go +++ b/pkg/query-service/druidQuery/mysql-query.go @@ -11,92 +11,6 @@ import ( "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) { 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 } -func GetTags(client *SqlClient, serviceName string) (*[]TagItem, error) { +func GetTags(client *SqlClient, serviceName string) (*[]model.TagItem, error) { var sqlQuery string @@ -176,7 +90,7 @@ func GetTags(client *SqlClient, serviceName string) (*[]TagItem, error) { // zap.S().Info(string(response)) - res := new([]TagItem) + res := new([]model.TagItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -187,7 +101,7 @@ func GetTags(client *SqlClient, serviceName string) (*[]TagItem, error) { 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) @@ -202,7 +116,7 @@ func GetTopEndpoints(client *SqlClient, query *model.GetTopEndpointsParams) (*[] // zap.S().Info(string(response)) - res := new([]TopEnpointsItem) + res := new([]model.TopEnpointsItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -213,7 +127,7 @@ func GetTopEndpoints(client *SqlClient, query *model.GetTopEndpointsParams) (*[] 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 @@ -236,7 +150,7 @@ func GetUsage(client *SqlClient, query *model.GetUsageParams) (*[]UsageItem, err // zap.S().Info(string(response)) - res := new([]UsageItem) + res := new([]model.UsageItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -253,7 +167,7 @@ func GetUsage(client *SqlClient, query *model.GetUsageParams) (*[]UsageItem, err 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' 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) // zap.S().Info(responseStr) - res := new([]ServiceExternalItem) + res := new([]model.ServiceExternalItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -289,7 +203,7 @@ func GetServiceExternalAvgDuration(client *SqlClient, query *model.GetServiceOve 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' 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) // zap.S().Info(responseStr) - res := new([]ServiceExternalItem) + res := new([]model.ServiceExternalItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -328,7 +242,7 @@ func GetServiceExternalErrors(client *SqlClient, query *model.GetServiceOverview // responseStr := string(response) // zap.S().Info(responseStr) - resTotal := new([]ServiceExternalItem) + resTotal := new([]model.ServiceExternalItem) err = json.Unmarshal(responseTotal, resTotal) if err != nil { zap.S().Error(err) @@ -361,7 +275,7 @@ func GetServiceExternalErrors(client *SqlClient, query *model.GetServiceOverview 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 != '' AND "__time" >= '%s' AND "__time" <= '%s' @@ -379,7 +293,7 @@ func GetServiceExternal(client *SqlClient, query *model.GetServiceOverviewParams // responseStr := string(response) // zap.S().Info(responseStr) - res := new([]ServiceExternalItem) + res := new([]model.ServiceExternalItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -398,7 +312,7 @@ func GetServiceExternal(client *SqlClient, query *model.GetServiceOverviewParams 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 AND "__time" >= '%s' AND "__time" <= '%s' @@ -416,7 +330,7 @@ func GetServiceDBOverview(client *SqlClient, query *model.GetServiceOverviewPara // responseStr := string(response) // zap.S().Info(responseStr) - res := new([]ServiceDBOverviewItem) + res := new([]model.ServiceDBOverviewItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -435,7 +349,7 @@ func GetServiceDBOverview(client *SqlClient, query *model.GetServiceOverviewPara 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, 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)) - res := new([]ServiceOverviewItem) + res := new([]model.ServiceOverviewItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -471,7 +385,7 @@ func GetServiceOverview(client *SqlClient, query *model.GetServiceOverviewParams // zap.S().Info(string(response)) - resError := new([]ServiceErrorItem) + resError := new([]model.ServiceErrorItem) err = json.Unmarshal(responseError, resError) if err != nil { zap.S().Error(err) @@ -501,7 +415,7 @@ func GetServiceOverview(client *SqlClient, query *model.GetServiceOverviewParams 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) @@ -516,7 +430,7 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI // zap.S().Info(string(response)) - res := new([]ServiceItem) + res := new([]model.ServiceItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -538,7 +452,7 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI // zap.S().Info(string(response)) - resError := new([]ServiceListErrorItem) + resError := new([]model.ServiceListErrorItem) err = json.Unmarshal(responseError, resError) if err != nil { zap.S().Error(err) @@ -568,7 +482,7 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI // zap.S().Info(string(response)) - res4xx := new([]ServiceListErrorItem) + res4xx := new([]model.ServiceListErrorItem) err = json.Unmarshal(response4xx, res4xx) if err != nil { zap.S().Error(err) @@ -601,7 +515,7 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI 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) @@ -617,7 +531,7 @@ func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams // responseStr := string(response) // zap.S().Info(responseStr) - res := new([]ServiceMapDependencyItem) + res := new([]model.ServiceMapDependencyItem) err = json.Unmarshal(response, res) if err != nil { zap.S().Error(err) @@ -626,7 +540,7 @@ func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams // resCount := len(*res) // fmt.Println(resCount) - serviceMap := make(map[string]*ServiceMapDependencyResponseItem) + serviceMap := make(map[string]*model.ServiceMapDependencyResponseItem) spanId2ServiceNameMap := make(map[string]string) for i, _ := range *res { @@ -635,7 +549,7 @@ func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams for i, _ := range *res { parent2childServiceName := spanId2ServiceNameMap[(*res)[i].ParentSpanId] + "-" + spanId2ServiceNameMap[(*res)[i].SpanId] if _, ok := serviceMap[parent2childServiceName]; !ok { - serviceMap[parent2childServiceName] = &ServiceMapDependencyResponseItem{ + serviceMap[parent2childServiceName] = &model.ServiceMapDependencyResponseItem{ Parent: spanId2ServiceNameMap[(*res)[i].ParentSpanId], Child: spanId2ServiceNameMap[(*res)[i].SpanId], 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 { if dependency.Parent == "" { continue diff --git a/pkg/query-service/go.mod b/pkg/query-service/go.mod index 2cf5d0eccf..152baafac1 100644 --- a/pkg/query-service/go.mod +++ b/pkg/query-service/go.mod @@ -3,10 +3,12 @@ module go.signoz.io/query-service go 1.14 require ( + github.com/gogo/protobuf v1.2.1 github.com/google/uuid v1.1.1 github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.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/posthog/posthog-go v0.0.0-20200525173953-e46dc8e6b89b github.com/rs/cors v1.7.0 diff --git a/pkg/query-service/main.go b/pkg/query-service/main.go index 5749921770..e261ebf9e6 100644 --- a/pkg/query-service/main.go +++ b/pkg/query-service/main.go @@ -57,14 +57,12 @@ func main() { logger := loggerMgr.Sugar() logger.Debug("START!") - // v := initViper() - serverOptions := &app.ServerOptions{ // HTTPHostPort: v.GetString(app.HTTPHostPort), // DruidClientUrl: v.GetString(app.DruidClientUrl), - HTTPHostPort: constants.HTTPHostPort, - DruidClientUrl: constants.DruidClientUrl, + HTTPHostPort: constants.HTTPHostPort, + // DruidClientUrl: constants.DruidClientUrl, } server, err := app.NewServer(serverOptions) diff --git a/pkg/query-service/model/model.go b/pkg/query-service/model/queryParams.go similarity index 100% rename from pkg/query-service/model/model.go rename to pkg/query-service/model/queryParams.go diff --git a/pkg/query-service/model/response.go b/pkg/query-service/model/response.go new file mode 100644 index 0000000000..ba87757346 --- /dev/null +++ b/pkg/query-service/model/response.go @@ -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"` +}