chore: add Open API spec defs for metrics explorer (#9934)

This commit is contained in:
Nikhil Mantri
2026-01-08 01:48:28 +05:30
committed by GitHub
parent c9cbc8d9ad
commit 1eba57b250
9 changed files with 871 additions and 48 deletions

View File

@@ -2067,6 +2067,431 @@ paths:
summary: Get features summary: Get features
tags: tags:
- features - features
/api/v2/metric/alerts:
get:
deprecated: false
description: This endpoint returns associated alerts for a specified metric
operationId: GetMetricAlerts
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/MetricsexplorertypesMetricAlertsResponse'
status:
type: string
type: object
description: OK
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- VIEWER
- tokenizer:
- VIEWER
summary: Get metric alerts
tags:
- metrics
/api/v2/metric/dashboards:
get:
deprecated: false
description: This endpoint returns associated dashboards for a specified metric
operationId: GetMetricDashboards
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/MetricsexplorertypesMetricDashboardsResponse'
status:
type: string
type: object
description: OK
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- VIEWER
- tokenizer:
- VIEWER
summary: Get metric dashboards
tags:
- metrics
/api/v2/metric/highlights:
get:
deprecated: false
description: This endpoint returns highlights like number of datapoints, totaltimeseries,
active time series, last received time for a specified metric
operationId: GetMetricHighlights
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/MetricsexplorertypesMetricHighlightsResponse'
status:
type: string
type: object
description: OK
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- VIEWER
- tokenizer:
- VIEWER
summary: Get metric highlights
tags:
- metrics
/api/v2/metrics/{metric_name}/metadata:
post:
deprecated: false
description: This endpoint helps to update metadata information like metric
description, unit, type, temporality, monotonicity for a specified metric
operationId: UpdateMetricMetadata
parameters:
- in: path
name: metric_name
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MetricsexplorertypesUpdateMetricMetadataRequest'
responses:
"200":
content:
application/json:
schema:
type: string
description: OK
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- EDITOR
- tokenizer:
- EDITOR
summary: Update metric metadata
tags:
- metrics
/api/v2/metrics/attributes:
post:
deprecated: false
description: This endpoint returns attribute keys and their unique values for
a specified metric
operationId: GetMetricAttributes
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MetricsexplorertypesMetricAttributesRequest'
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/MetricsexplorertypesMetricAttributesResponse'
status:
type: string
type: object
description: OK
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- VIEWER
- tokenizer:
- VIEWER
summary: Get metric attributes
tags:
- metrics
/api/v2/metrics/metadata:
get:
deprecated: false
description: This endpoint returns metadata information like metric description,
unit, type, temporality, monotonicity for a specified metric
operationId: GetMetricMetadata
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/MetricsexplorertypesMetricMetadata'
status:
type: string
type: object
description: OK
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"404":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Not Found
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- VIEWER
- tokenizer:
- VIEWER
summary: Get metric metadata
tags:
- metrics
/api/v2/metrics/stats:
post:
deprecated: false
description: This endpoint provides list of metrics with their number of samples
and timeseries for the given time range
operationId: GetMetricsStats
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MetricsexplorertypesStatsRequest'
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/MetricsexplorertypesStatsResponse'
status:
type: string
type: object
description: OK
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- VIEWER
- tokenizer:
- VIEWER
summary: Get metrics statistics
tags:
- metrics
/api/v2/metrics/treemap:
post:
deprecated: false
description: This endpoint returns a treemap visualization showing the proportional
distribution of metrics by sample count or time series count
operationId: GetMetricsTreemap
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MetricsexplorertypesTreemapRequest'
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/MetricsexplorertypesTreemapResponse'
status:
type: string
type: object
description: OK
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- VIEWER
- tokenizer:
- VIEWER
summary: Get metrics treemap
tags:
- metrics
/api/v2/orgs/me: /api/v2/orgs/me:
get: get:
deprecated: false deprecated: false
@@ -2586,6 +3011,202 @@ components:
nullable: true nullable: true
type: object type: object
type: object type: object
MetricsexplorertypesMetricAlert:
properties:
alertId:
type: string
alertName:
type: string
type: object
MetricsexplorertypesMetricAlertsResponse:
properties:
alerts:
items:
$ref: '#/components/schemas/MetricsexplorertypesMetricAlert'
nullable: true
type: array
type: object
MetricsexplorertypesMetricAttribute:
properties:
key:
type: string
valueCount:
minimum: 0
type: integer
values:
items:
type: string
nullable: true
type: array
type: object
MetricsexplorertypesMetricAttributesRequest:
properties:
end:
nullable: true
type: integer
metricName:
type: string
start:
nullable: true
type: integer
type: object
MetricsexplorertypesMetricAttributesResponse:
properties:
attributes:
items:
$ref: '#/components/schemas/MetricsexplorertypesMetricAttribute'
nullable: true
type: array
totalKeys:
format: int64
type: integer
type: object
MetricsexplorertypesMetricDashboard:
properties:
dashboardId:
type: string
dashboardName:
type: string
widgetId:
type: string
widgetName:
type: string
type: object
MetricsexplorertypesMetricDashboardsResponse:
properties:
dashboards:
items:
$ref: '#/components/schemas/MetricsexplorertypesMetricDashboard'
nullable: true
type: array
type: object
MetricsexplorertypesMetricHighlightsResponse:
properties:
activeTimeSeries:
minimum: 0
type: integer
dataPoints:
minimum: 0
type: integer
lastReceived:
minimum: 0
type: integer
totalTimeSeries:
minimum: 0
type: integer
type: object
MetricsexplorertypesMetricMetadata:
properties:
description:
type: string
isMonotonic:
type: boolean
temporality:
type: string
type:
type: string
unit:
type: string
type: object
MetricsexplorertypesStat:
properties:
description:
type: string
metricName:
type: string
samples:
minimum: 0
type: integer
timeseries:
minimum: 0
type: integer
type:
type: string
unit:
type: string
type: object
MetricsexplorertypesStatsRequest:
properties:
end:
format: int64
type: integer
filter:
$ref: '#/components/schemas/Querybuildertypesv5Filter'
limit:
type: integer
offset:
type: integer
orderBy:
$ref: '#/components/schemas/Querybuildertypesv5OrderBy'
start:
format: int64
type: integer
type: object
MetricsexplorertypesStatsResponse:
properties:
metrics:
items:
$ref: '#/components/schemas/MetricsexplorertypesStat'
nullable: true
type: array
total:
minimum: 0
type: integer
type: object
MetricsexplorertypesTreemapEntry:
properties:
metricName:
type: string
percentage:
format: double
type: number
totalValue:
minimum: 0
type: integer
type: object
MetricsexplorertypesTreemapRequest:
properties:
end:
format: int64
type: integer
filter:
$ref: '#/components/schemas/Querybuildertypesv5Filter'
limit:
type: integer
mode:
type: string
start:
format: int64
type: integer
type: object
MetricsexplorertypesTreemapResponse:
properties:
samples:
items:
$ref: '#/components/schemas/MetricsexplorertypesTreemapEntry'
nullable: true
type: array
timeseries:
items:
$ref: '#/components/schemas/MetricsexplorertypesTreemapEntry'
nullable: true
type: array
type: object
MetricsexplorertypesUpdateMetricMetadataRequest:
properties:
description:
type: string
isMonotonic:
type: boolean
metricName:
type: string
temporality:
type: string
type:
type: string
unit:
type: string
type: object
PreferencetypesPreference: PreferencetypesPreference:
properties: properties:
allowedScopes: allowedScopes:
@@ -2647,6 +3268,35 @@ components:
minimum: 0 minimum: 0
type: integer type: integer
type: object type: object
Querybuildertypesv5Filter:
properties:
expression:
type: string
type: object
Querybuildertypesv5OrderBy:
properties:
direction:
type: string
key:
$ref: '#/components/schemas/Querybuildertypesv5OrderByKey'
type: object
Querybuildertypesv5OrderByKey:
properties:
'-':
$ref: '#/components/schemas/TelemetrytypesJSONDataType'
description:
type: string
fieldContext:
type: string
fieldDataType:
type: string
name:
type: string
signal:
type: string
unit:
type: string
type: object
Querybuildertypesv5QueryData: Querybuildertypesv5QueryData:
properties: properties:
results: results:
@@ -2688,6 +3338,8 @@ components:
status: status:
type: string type: string
type: object type: object
TelemetrytypesJSONDataType:
type: object
TypesChangePasswordRequest: TypesChangePasswordRequest:
properties: properties:
newPassword: newPassword:

View File

@@ -0,0 +1,166 @@
package signozapiserver
import (
"net/http"
"github.com/SigNoz/signoz/pkg/http/handler"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/metricsexplorertypes"
"github.com/gorilla/mux"
)
func (provider *provider) addMetricsExplorerV2Routes(router *mux.Router) error {
if err := router.Handle("/api/v2/metrics/stats", handler.New(
provider.authZ.ViewAccess(provider.metricsExplorerHandler.GetStats),
handler.OpenAPIDef{
ID: "GetMetricsStats",
Tags: []string{"metrics"},
Summary: "Get metrics statistics",
Description: "This endpoint provides list of metrics with their number of samples and timeseries for the given time range",
Request: new(metricsexplorertypes.StatsRequest),
RequestContentType: "application/json",
Response: new(metricsexplorertypes.StatsResponse),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
})).Methods(http.MethodPost).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v2/metrics/treemap", handler.New(
provider.authZ.ViewAccess(provider.metricsExplorerHandler.GetTreemap),
handler.OpenAPIDef{
ID: "GetMetricsTreemap",
Tags: []string{"metrics"},
Summary: "Get metrics treemap",
Description: "This endpoint returns a treemap visualization showing the proportional distribution of metrics by sample count or time series count",
Request: new(metricsexplorertypes.TreemapRequest),
RequestContentType: "application/json",
Response: new(metricsexplorertypes.TreemapResponse),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
})).Methods(http.MethodPost).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v2/metrics/attributes", handler.New(
provider.authZ.ViewAccess(provider.metricsExplorerHandler.GetMetricAttributes),
handler.OpenAPIDef{
ID: "GetMetricAttributes",
Tags: []string{"metrics"},
Summary: "Get metric attributes",
Description: "This endpoint returns attribute keys and their unique values for a specified metric",
Request: new(metricsexplorertypes.MetricAttributesRequest),
RequestContentType: "application/json",
Response: new(metricsexplorertypes.MetricAttributesResponse),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
})).Methods(http.MethodPost).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v2/metrics/metadata", handler.New(
provider.authZ.ViewAccess(provider.metricsExplorerHandler.GetMetricMetadata),
handler.OpenAPIDef{
ID: "GetMetricMetadata",
Tags: []string{"metrics"},
Summary: "Get metric metadata",
Description: "This endpoint returns metadata information like metric description, unit, type, temporality, monotonicity for a specified metric",
Request: nil,
RequestContentType: "",
Response: new(metricsexplorertypes.MetricMetadata),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusNotFound, http.StatusInternalServerError},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
})).Methods(http.MethodGet).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v2/metrics/{metric_name}/metadata", handler.New(
provider.authZ.EditAccess(provider.metricsExplorerHandler.UpdateMetricMetadata),
handler.OpenAPIDef{
ID: "UpdateMetricMetadata",
Tags: []string{"metrics"},
Summary: "Update metric metadata",
Description: "This endpoint helps to update metadata information like metric description, unit, type, temporality, monotonicity for a specified metric",
Request: new(metricsexplorertypes.UpdateMetricMetadataRequest),
RequestContentType: "application/json",
Response: nil,
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleEditor),
})).Methods(http.MethodPost).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v2/metric/highlights", handler.New(
provider.authZ.ViewAccess(provider.metricsExplorerHandler.GetMetricHighlights),
handler.OpenAPIDef{
ID: "GetMetricHighlights",
Tags: []string{"metrics"},
Summary: "Get metric highlights",
Description: "This endpoint returns highlights like number of datapoints, totaltimeseries, active time series, last received time for a specified metric",
Request: nil,
RequestContentType: "",
Response: new(metricsexplorertypes.MetricHighlightsResponse),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
})).Methods(http.MethodGet).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v2/metric/alerts", handler.New(
provider.authZ.ViewAccess(provider.metricsExplorerHandler.GetMetricAlerts),
handler.OpenAPIDef{
ID: "GetMetricAlerts",
Tags: []string{"metrics"},
Summary: "Get metric alerts",
Description: "This endpoint returns associated alerts for a specified metric",
Request: nil,
RequestContentType: "",
Response: new(metricsexplorertypes.MetricAlertsResponse),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
})).Methods(http.MethodGet).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v2/metric/dashboards", handler.New(
provider.authZ.ViewAccess(provider.metricsExplorerHandler.GetMetricDashboards),
handler.OpenAPIDef{
ID: "GetMetricDashboards",
Tags: []string{"metrics"},
Summary: "Get metric dashboards",
Description: "This endpoint returns associated dashboards for a specified metric",
Request: nil,
RequestContentType: "",
Response: new(metricsexplorertypes.MetricDashboardsResponse),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusInternalServerError},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
})).Methods(http.MethodGet).GetError(); err != nil {
return err
}
return nil
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/SigNoz/signoz/pkg/http/middleware" "github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/modules/authdomain" "github.com/SigNoz/signoz/pkg/modules/authdomain"
"github.com/SigNoz/signoz/pkg/modules/dashboard" "github.com/SigNoz/signoz/pkg/modules/dashboard"
"github.com/SigNoz/signoz/pkg/modules/metricsexplorer"
"github.com/SigNoz/signoz/pkg/modules/organization" "github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/preference" "github.com/SigNoz/signoz/pkg/modules/preference"
"github.com/SigNoz/signoz/pkg/modules/promote" "github.com/SigNoz/signoz/pkg/modules/promote"
@@ -23,20 +24,21 @@ import (
) )
type provider struct { type provider struct {
config apiserver.Config config apiserver.Config
settings factory.ScopedProviderSettings settings factory.ScopedProviderSettings
router *mux.Router router *mux.Router
authZ *middleware.AuthZ authZ *middleware.AuthZ
orgHandler organization.Handler orgHandler organization.Handler
userHandler user.Handler userHandler user.Handler
sessionHandler session.Handler sessionHandler session.Handler
authDomainHandler authdomain.Handler authDomainHandler authdomain.Handler
preferenceHandler preference.Handler preferenceHandler preference.Handler
globalHandler global.Handler globalHandler global.Handler
promoteHandler promote.Handler promoteHandler promote.Handler
flaggerHandler flagger.Handler flaggerHandler flagger.Handler
dashboardModule dashboard.Module dashboardModule dashboard.Module
dashboardHandler dashboard.Handler dashboardHandler dashboard.Handler
metricsExplorerHandler metricsexplorer.Handler
} }
func NewFactory( func NewFactory(
@@ -52,9 +54,10 @@ func NewFactory(
flaggerHandler flagger.Handler, flaggerHandler flagger.Handler,
dashboardModule dashboard.Module, dashboardModule dashboard.Module,
dashboardHandler dashboard.Handler, dashboardHandler dashboard.Handler,
metricsExplorerHandler metricsexplorer.Handler,
) factory.ProviderFactory[apiserver.APIServer, apiserver.Config] { ) factory.ProviderFactory[apiserver.APIServer, apiserver.Config] {
return factory.NewProviderFactory(factory.MustNewName("signoz"), func(ctx context.Context, providerSettings factory.ProviderSettings, config apiserver.Config) (apiserver.APIServer, error) { return factory.NewProviderFactory(factory.MustNewName("signoz"), func(ctx context.Context, providerSettings factory.ProviderSettings, config apiserver.Config) (apiserver.APIServer, error) {
return newProvider(ctx, providerSettings, config, orgGetter, authz, orgHandler, userHandler, sessionHandler, authDomainHandler, preferenceHandler, globalHandler, promoteHandler, flaggerHandler, dashboardModule, dashboardHandler) return newProvider(ctx, providerSettings, config, orgGetter, authz, orgHandler, userHandler, sessionHandler, authDomainHandler, preferenceHandler, globalHandler, promoteHandler, flaggerHandler, dashboardModule, dashboardHandler, metricsExplorerHandler)
}) })
} }
@@ -74,24 +77,26 @@ func newProvider(
flaggerHandler flagger.Handler, flaggerHandler flagger.Handler,
dashboardModule dashboard.Module, dashboardModule dashboard.Module,
dashboardHandler dashboard.Handler, dashboardHandler dashboard.Handler,
metricsExplorerHandler metricsexplorer.Handler,
) (apiserver.APIServer, error) { ) (apiserver.APIServer, error) {
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/pkg/apiserver/signozapiserver") settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/pkg/apiserver/signozapiserver")
router := mux.NewRouter().UseEncodedPath() router := mux.NewRouter().UseEncodedPath()
provider := &provider{ provider := &provider{
config: config, config: config,
settings: settings, settings: settings,
router: router, router: router,
orgHandler: orgHandler, orgHandler: orgHandler,
userHandler: userHandler, userHandler: userHandler,
sessionHandler: sessionHandler, sessionHandler: sessionHandler,
authDomainHandler: authDomainHandler, authDomainHandler: authDomainHandler,
preferenceHandler: preferenceHandler, preferenceHandler: preferenceHandler,
globalHandler: globalHandler, globalHandler: globalHandler,
promoteHandler: promoteHandler, promoteHandler: promoteHandler,
flaggerHandler: flaggerHandler, flaggerHandler: flaggerHandler,
dashboardModule: dashboardModule, dashboardModule: dashboardModule,
dashboardHandler: dashboardHandler, dashboardHandler: dashboardHandler,
metricsExplorerHandler: metricsExplorerHandler,
} }
provider.authZ = middleware.NewAuthZ(settings.Logger(), orgGetter, authz) provider.authZ = middleware.NewAuthZ(settings.Logger(), orgGetter, authz)
@@ -144,6 +149,10 @@ func (provider *provider) AddToRouter(router *mux.Router) error {
return err return err
} }
if err := provider.addMetricsExplorerV2Routes(router); err != nil {
return err
}
return nil return nil
} }

View File

@@ -626,15 +626,6 @@ func (ah *APIHandler) MetricExplorerRoutes(router *mux.Router, am *middleware.Au
router.HandleFunc("/api/v1/metrics/{metric_name}/metadata", router.HandleFunc("/api/v1/metrics/{metric_name}/metadata",
am.ViewAccess(ah.UpdateMetricsMetadata)). am.ViewAccess(ah.UpdateMetricsMetadata)).
Methods(http.MethodPost) Methods(http.MethodPost)
// v2 endpoints
router.HandleFunc("/api/v2/metrics/stats", am.ViewAccess(ah.Signoz.Handlers.MetricsExplorer.GetStats)).Methods(http.MethodPost)
router.HandleFunc("/api/v2/metrics/treemap", am.ViewAccess(ah.Signoz.Handlers.MetricsExplorer.GetTreemap)).Methods(http.MethodPost)
router.HandleFunc("/api/v2/metrics/attributes", am.ViewAccess(ah.Signoz.Handlers.MetricsExplorer.GetMetricAttributes)).Methods(http.MethodPost)
router.HandleFunc("/api/v2/metrics/metadata", am.ViewAccess(ah.Signoz.Handlers.MetricsExplorer.GetMetricMetadata)).Methods(http.MethodGet)
router.HandleFunc("/api/v2/metrics/{metric_name}/metadata", am.EditAccess(ah.Signoz.Handlers.MetricsExplorer.UpdateMetricMetadata)).Methods(http.MethodPost)
router.HandleFunc("/api/v2/metric/highlights", am.ViewAccess(ah.Signoz.Handlers.MetricsExplorer.GetMetricHighlights)).Methods(http.MethodGet)
router.HandleFunc("/api/v2/metric/alerts", am.ViewAccess(ah.Signoz.Handlers.MetricsExplorer.GetMetricAlerts)).Methods(http.MethodGet)
router.HandleFunc("/api/v2/metric/dashboards", am.ViewAccess(ah.Signoz.Handlers.MetricsExplorer.GetMetricDashboards)).Methods(http.MethodGet)
} }
func Intersection(a, b []int) (c []int) { func Intersection(a, b []int) (c []int) {

View File

@@ -16,14 +16,13 @@ type provider struct {
ruleStore ruletypes.RuleStore ruleStore ruletypes.RuleStore
} }
func NewFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[ruler.Ruler, ruler.Config] { func NewFactory(sqlstore sqlstore.SQLStore, queryParser queryparser.QueryParser) factory.ProviderFactory[ruler.Ruler, ruler.Config] {
return factory.NewProviderFactory(factory.MustNewName("signoz"), func(ctx context.Context, settings factory.ProviderSettings, config ruler.Config) (ruler.Ruler, error) { return factory.NewProviderFactory(factory.MustNewName("signoz"), func(ctx context.Context, settings factory.ProviderSettings, config ruler.Config) (ruler.Ruler, error) {
return New(ctx, settings, config, sqlstore) return New(ctx, settings, config, sqlstore, queryParser)
}) })
} }
func New(ctx context.Context, settings factory.ProviderSettings, config ruler.Config, sqlstore sqlstore.SQLStore) (ruler.Ruler, error) { func New(ctx context.Context, settings factory.ProviderSettings, config ruler.Config, sqlstore sqlstore.SQLStore, queryParser queryparser.QueryParser) (ruler.Ruler, error) {
queryParser := queryparser.New(settings)
return &provider{ruleStore: sqlrulestore.NewRuleStore(sqlstore, queryParser, settings)}, nil return &provider{ruleStore: sqlrulestore.NewRuleStore(sqlstore, queryParser, settings)}, nil
} }

View File

@@ -14,6 +14,7 @@ import (
"github.com/SigNoz/signoz/pkg/instrumentation" "github.com/SigNoz/signoz/pkg/instrumentation"
"github.com/SigNoz/signoz/pkg/modules/authdomain" "github.com/SigNoz/signoz/pkg/modules/authdomain"
"github.com/SigNoz/signoz/pkg/modules/dashboard" "github.com/SigNoz/signoz/pkg/modules/dashboard"
"github.com/SigNoz/signoz/pkg/modules/metricsexplorer"
"github.com/SigNoz/signoz/pkg/modules/organization" "github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/preference" "github.com/SigNoz/signoz/pkg/modules/preference"
"github.com/SigNoz/signoz/pkg/modules/promote" "github.com/SigNoz/signoz/pkg/modules/promote"
@@ -45,6 +46,7 @@ func NewOpenAPI(ctx context.Context, instrumentation instrumentation.Instrumenta
struct{ flagger.Handler }{}, struct{ flagger.Handler }{},
struct{ dashboard.Module }{}, struct{ dashboard.Module }{},
struct{ dashboard.Handler }{}, struct{ dashboard.Handler }{},
struct{ metricsexplorer.Handler }{},
).New(ctx, instrumentation.ToProviderSettings(), apiserver.Config{}) ).New(ctx, instrumentation.ToProviderSettings(), apiserver.Config{})
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -34,6 +34,7 @@ import (
"github.com/SigNoz/signoz/pkg/prometheus/clickhouseprometheus" "github.com/SigNoz/signoz/pkg/prometheus/clickhouseprometheus"
"github.com/SigNoz/signoz/pkg/querier" "github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/querier/signozquerier" "github.com/SigNoz/signoz/pkg/querier/signozquerier"
"github.com/SigNoz/signoz/pkg/queryparser"
"github.com/SigNoz/signoz/pkg/ruler" "github.com/SigNoz/signoz/pkg/ruler"
"github.com/SigNoz/signoz/pkg/ruler/signozruler" "github.com/SigNoz/signoz/pkg/ruler/signozruler"
"github.com/SigNoz/signoz/pkg/sharder" "github.com/SigNoz/signoz/pkg/sharder"
@@ -197,9 +198,9 @@ func NewAlertmanagerProviderFactories(sqlstore sqlstore.SQLStore, orgGetter orga
) )
} }
func NewRulerProviderFactories(sqlstore sqlstore.SQLStore) factory.NamedMap[factory.ProviderFactory[ruler.Ruler, ruler.Config]] { func NewRulerProviderFactories(sqlstore sqlstore.SQLStore, queryParser queryparser.QueryParser) factory.NamedMap[factory.ProviderFactory[ruler.Ruler, ruler.Config]] {
return factory.MustNewNamedMap( return factory.MustNewNamedMap(
signozruler.NewFactory(sqlstore), signozruler.NewFactory(sqlstore, queryParser),
) )
} }
@@ -245,6 +246,7 @@ func NewAPIServerProviderFactories(orgGetter organization.Getter, authz authz.Au
handlers.FlaggerHandler, handlers.FlaggerHandler,
modules.Dashboard, modules.Dashboard,
handlers.Dashboard, handlers.Dashboard,
handlers.MetricsExplorer,
), ),
) )
} }

View File

@@ -9,6 +9,7 @@ import (
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest" "github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
"github.com/SigNoz/signoz/pkg/modules/organization/implorganization" "github.com/SigNoz/signoz/pkg/modules/organization/implorganization"
"github.com/SigNoz/signoz/pkg/modules/user/impluser" "github.com/SigNoz/signoz/pkg/modules/user/impluser"
"github.com/SigNoz/signoz/pkg/queryparser"
"github.com/SigNoz/signoz/pkg/sqlschema" "github.com/SigNoz/signoz/pkg/sqlschema"
"github.com/SigNoz/signoz/pkg/sqlschema/sqlschematest" "github.com/SigNoz/signoz/pkg/sqlschema/sqlschematest"
"github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/sqlstore"
@@ -61,7 +62,8 @@ func TestNewProviderFactories(t *testing.T) {
}) })
assert.NotPanics(t, func() { assert.NotPanics(t, func() {
NewRulerProviderFactories(sqlstoretest.New(sqlstore.Config{Provider: "sqlite"}, sqlmock.QueryMatcherEqual)) queryParser := queryparser.New(instrumentationtest.New().ToProviderSettings())
NewRulerProviderFactories(sqlstoretest.New(sqlstore.Config{Provider: "sqlite"}, sqlmock.QueryMatcherEqual), queryParser)
}) })
assert.NotPanics(t, func() { assert.NotPanics(t, func() {

View File

@@ -311,12 +311,15 @@ func New(
return nil, err return nil, err
} }
// Initialize query parser
queryParser := queryparser.New(providerSettings)
// Initialize ruler from the available ruler provider factories // Initialize ruler from the available ruler provider factories
ruler, err := factory.NewProviderFromNamedMap( ruler, err := factory.NewProviderFromNamedMap(
ctx, ctx,
providerSettings, providerSettings,
config.Ruler, config.Ruler,
NewRulerProviderFactories(sqlstore), NewRulerProviderFactories(sqlstore, queryParser),
"signoz", "signoz",
) )
if err != nil { if err != nil {
@@ -333,9 +336,6 @@ func New(
return nil, err return nil, err
} }
// Initialize query parser
queryParser := queryparser.New(providerSettings)
// Initialize authns // Initialize authns
store := sqlauthnstore.NewStore(sqlstore) store := sqlauthnstore.NewStore(sqlstore)
authNs, err := authNsCallback(ctx, providerSettings, store, licensing) authNs, err := authNsCallback(ctx, providerSettings, store, licensing)