mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 17:35:55 +08:00
added service map api and 4xx rate in /services api
This commit is contained in:
parent
daebe83e32
commit
baedfa62d2
@ -74,6 +74,7 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router) {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aH *APIHandler) user(w http.ResponseWriter, r *http.Request) {
|
func (aH *APIHandler) user(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -280,6 +281,22 @@ 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) {
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
@ -18,10 +18,13 @@ type ServiceItem struct {
|
|||||||
CallRate float32 `json:"callRate"`
|
CallRate float32 `json:"callRate"`
|
||||||
NumErrors int `json:"numErrors"`
|
NumErrors int `json:"numErrors"`
|
||||||
ErrorRate float32 `json:"errorRate"`
|
ErrorRate float32 `json:"errorRate"`
|
||||||
|
Num4XX int `json:"num4XX"`
|
||||||
|
FourXXRate float32 `json:"fourXXRate"`
|
||||||
}
|
}
|
||||||
type ServiceListErrorItem struct {
|
type ServiceListErrorItem struct {
|
||||||
ServiceName string `json:"serviceName"`
|
ServiceName string `json:"serviceName"`
|
||||||
NumErrors int `json:"numErrors"`
|
NumErrors int `json:"numErrors"`
|
||||||
|
Num4xx int `json:"num4xx"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServiceErrorItem struct {
|
type ServiceErrorItem struct {
|
||||||
@ -62,6 +65,12 @@ type ServiceDBOverviewItem struct {
|
|||||||
CallRate float32 `json:"callRate,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 {
|
type UsageItem struct {
|
||||||
Time string `json:"time,omitempty"`
|
Time string `json:"time,omitempty"`
|
||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
@ -81,6 +90,12 @@ type TagItem struct {
|
|||||||
TagCount int `json:"tagCount"`
|
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)
|
||||||
@ -112,7 +127,7 @@ func GetOperations(client *SqlClient, serviceName string) (*[]string, error) {
|
|||||||
|
|
||||||
func GetServicesList(client *SqlClient) (*[]string, error) {
|
func GetServicesList(client *SqlClient) (*[]string, error) {
|
||||||
|
|
||||||
sqlQuery := fmt.Sprintf(`SELECT DISTINCT(ServiceName) FROM %s`, constants.DruidDatasource)
|
sqlQuery := fmt.Sprintf(`SELECT DISTINCT(ServiceName) FROM %s WHERE __time > CURRENT_TIMESTAMP - INTERVAL '1' DAY`, constants.DruidDatasource)
|
||||||
// zap.S().Debug(sqlQuery)
|
// zap.S().Debug(sqlQuery)
|
||||||
|
|
||||||
response, err := client.Query(sqlQuery, "array")
|
response, err := client.Query(sqlQuery, "array")
|
||||||
@ -507,6 +522,8 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI
|
|||||||
return nil, fmt.Errorf("Error in unmarshalling response from druid")
|
return nil, fmt.Errorf("Error in unmarshalling response from druid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////// Below block gets 5xx of services
|
||||||
|
|
||||||
sqlQuery = fmt.Sprintf(`SELECT COUNT(SpanId) as numErrors, "ServiceName" as "serviceName" FROM %s WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' and "StatusCode">=500 GROUP BY "ServiceName"`, constants.DruidDatasource, query.StartTime, query.EndTime)
|
sqlQuery = fmt.Sprintf(`SELECT COUNT(SpanId) as numErrors, "ServiceName" as "serviceName" FROM %s WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' and "StatusCode">=500 GROUP BY "ServiceName"`, constants.DruidDatasource, query.StartTime, query.EndTime)
|
||||||
|
|
||||||
responseError, err := client.Query(sqlQuery, "object")
|
responseError, err := client.Query(sqlQuery, "object")
|
||||||
@ -533,12 +550,48 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI
|
|||||||
m[(*resError)[j].ServiceName] = (*resError)[j].NumErrors
|
m[(*resError)[j].ServiceName] = (*resError)[j].NumErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////// Below block gets 4xx of services
|
||||||
|
|
||||||
|
sqlQuery = fmt.Sprintf(`SELECT COUNT(SpanId) as numErrors, "ServiceName" as "serviceName" FROM %s WHERE "__time" >= '%s' and "__time" <= '%s' and "Kind"='2' and "StatusCode">=400 and "StatusCode" < 500 GROUP BY "ServiceName"`, constants.DruidDatasource, query.StartTime, query.EndTime)
|
||||||
|
|
||||||
|
response4xx, err := client.Query(sqlQuery, "object")
|
||||||
|
|
||||||
|
// zap.S().Debug(sqlQuery)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Error(query, err)
|
||||||
|
return nil, fmt.Errorf("Something went wrong in druid query")
|
||||||
|
}
|
||||||
|
|
||||||
|
// zap.S().Info(string(response))
|
||||||
|
|
||||||
|
res4xx := new([]ServiceListErrorItem)
|
||||||
|
err = json.Unmarshal(response4xx, res4xx)
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Error(err)
|
||||||
|
return nil, fmt.Errorf("Error in unmarshalling response from druid")
|
||||||
|
}
|
||||||
|
|
||||||
|
m4xx := make(map[string]int)
|
||||||
|
|
||||||
|
for j, _ := range *res4xx {
|
||||||
|
m4xx[(*res4xx)[j].ServiceName] = (*res4xx)[j].Num4xx
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
for i, _ := range *res {
|
for i, _ := range *res {
|
||||||
|
|
||||||
if val, ok := m[(*res)[i].ServiceName]; ok {
|
if val, ok := m[(*res)[i].ServiceName]; ok {
|
||||||
(*res)[i].NumErrors = val
|
(*res)[i].NumErrors = val
|
||||||
}
|
}
|
||||||
|
if val, ok := m4xx[(*res)[i].ServiceName]; ok {
|
||||||
|
(*res)[i].Num4XX = val
|
||||||
|
}
|
||||||
|
|
||||||
|
(*res)[i].FourXXRate = (float32((*res)[i].Num4XX) + 12) * 100 / float32((*res)[i].NumCalls)
|
||||||
(*res)[i].ErrorRate = float32((*res)[i].NumErrors) * 100 / float32((*res)[i].NumCalls)
|
(*res)[i].ErrorRate = float32((*res)[i].NumErrors) * 100 / float32((*res)[i].NumCalls)
|
||||||
(*res)[i].CallRate = float32((*res)[i].NumCalls) / float32(query.Period)
|
(*res)[i].CallRate = float32((*res)[i].NumCalls) / float32(query.Period)
|
||||||
|
|
||||||
@ -546,3 +599,58 @@ func GetServices(client *SqlClient, query *model.GetServicesParams) (*[]ServiceI
|
|||||||
servicesResponse := (*res)[1:]
|
servicesResponse := (*res)[1:]
|
||||||
return &servicesResponse, nil
|
return &servicesResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetServiceMapDependencies(client *SqlClient, query *model.GetServicesParams) (*[]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)
|
||||||
|
|
||||||
|
// zap.S().Debug(sqlQuery)
|
||||||
|
|
||||||
|
response, err := client.Query(sqlQuery, "object")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Error(query, err)
|
||||||
|
return nil, fmt.Errorf("Something went wrong in druid query")
|
||||||
|
}
|
||||||
|
|
||||||
|
// responseStr := string(response)
|
||||||
|
// zap.S().Info(responseStr)
|
||||||
|
|
||||||
|
res := new([]ServiceMapDependencyItem)
|
||||||
|
err = json.Unmarshal(response, res)
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Error(err)
|
||||||
|
return nil, fmt.Errorf("Error in unmarshalling response from druid")
|
||||||
|
}
|
||||||
|
// resCount := len(*res)
|
||||||
|
// fmt.Println(resCount)
|
||||||
|
|
||||||
|
serviceMap := make(map[string]*ServiceMapDependencyResponseItem)
|
||||||
|
|
||||||
|
spanId2ServiceNameMap := make(map[string]string)
|
||||||
|
for i, _ := range *res {
|
||||||
|
spanId2ServiceNameMap[(*res)[i].SpanId] = (*res)[i].ServiceName
|
||||||
|
}
|
||||||
|
for i, _ := range *res {
|
||||||
|
parent2childServiceName := spanId2ServiceNameMap[(*res)[i].ParentSpanId] + "-" + spanId2ServiceNameMap[(*res)[i].SpanId]
|
||||||
|
if _, ok := serviceMap[parent2childServiceName]; !ok {
|
||||||
|
serviceMap[parent2childServiceName] = &ServiceMapDependencyResponseItem{
|
||||||
|
Parent: spanId2ServiceNameMap[(*res)[i].ParentSpanId],
|
||||||
|
Child: spanId2ServiceNameMap[(*res)[i].SpanId],
|
||||||
|
CallCount: 1,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
serviceMap[parent2childServiceName].CallCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retMe := make([]ServiceMapDependencyResponseItem, 0, len(serviceMap))
|
||||||
|
for _, dependency := range serviceMap {
|
||||||
|
if dependency.Parent == dependency.Child || dependency.Parent == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
retMe = append(retMe, *dependency)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &retMe, nil
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user