mirror of
https://github.com/SigNoz/signoz.git
synced 2026-02-14 21:32:04 +00:00
Compare commits
105 Commits
merge-json
...
perses
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54b429acae | ||
|
|
2c948ef9f6 | ||
|
|
3c30114642 | ||
|
|
d042fad1e3 | ||
|
|
235c606b44 | ||
|
|
a49d7e1662 | ||
|
|
b3e41b5520 | ||
|
|
83bb97cc58 | ||
|
|
68ea28cf6b | ||
|
|
3726c0aac1 | ||
|
|
dae2d3239b | ||
|
|
0c660f8618 | ||
|
|
97cffbc20a | ||
|
|
8317eb1735 | ||
|
|
b1789ea3f7 | ||
|
|
3b41d0a731 | ||
|
|
a171f7122f | ||
|
|
4a20e93b20 | ||
|
|
d4dc709aa5 | ||
|
|
cd014652a1 | ||
|
|
538351131f | ||
|
|
a3bd72ad86 | ||
|
|
786070d90b | ||
|
|
e699ad8122 | ||
|
|
a1cc05848c | ||
|
|
6d78df2275 | ||
|
|
df49484bea | ||
|
|
72b0f27494 | ||
|
|
e36b647bc7 | ||
|
|
b491772eaa | ||
|
|
128497f27a | ||
|
|
9e466b56b2 | ||
|
|
4ad0baa2a2 | ||
|
|
24b588bfba | ||
|
|
e5867cc2ad | ||
|
|
b420ca494e | ||
|
|
e4693ce64c | ||
|
|
ca9b3a910a | ||
|
|
9dc7d2389a | ||
|
|
da5860297f | ||
|
|
54fca5ba44 | ||
|
|
66f4c3d6ec | ||
|
|
a0f407a848 | ||
|
|
3562de8fbb | ||
|
|
ef80fb39fd | ||
|
|
594d4dc737 | ||
|
|
01415b58be | ||
|
|
f7728c9019 | ||
|
|
3fffe6e198 | ||
|
|
4594f4ffe3 | ||
|
|
b660dc8573 | ||
|
|
c7b9c0d36c | ||
|
|
4433d22c09 | ||
|
|
9443c42334 | ||
|
|
9387c96023 | ||
|
|
ff2555d8dd | ||
|
|
85953c9a4c | ||
|
|
0155cc38cb | ||
|
|
c217cc96c3 | ||
|
|
580cf32eb5 | ||
|
|
6d3580cbfa | ||
|
|
6c5d36caa9 | ||
|
|
c4a6c7e277 | ||
|
|
c9cd974dca | ||
|
|
5b3f121431 | ||
|
|
c79373314a | ||
|
|
858cd287fa | ||
|
|
afdb674068 | ||
|
|
30a6721472 | ||
|
|
518dfcbe59 | ||
|
|
424127c27c | ||
|
|
2dcb817de1 | ||
|
|
f6f8c78aaf | ||
|
|
3c99dfdfa5 | ||
|
|
6ed72519b8 | ||
|
|
fe910aaa0f | ||
|
|
0d362b3ba8 | ||
|
|
51e9ffb847 | ||
|
|
f497a154a2 | ||
|
|
659fa361ef | ||
|
|
84e77182f6 | ||
|
|
32619869e7 | ||
|
|
e9093126b2 | ||
|
|
195f44802d | ||
|
|
948bdb7881 | ||
|
|
7274d51236 | ||
|
|
5b580f8e63 | ||
|
|
5ce1f0b855 | ||
|
|
291e6a2af8 | ||
|
|
3a34fb4813 | ||
|
|
189781748a | ||
|
|
e7c812e07f | ||
|
|
c0e2dad3b5 | ||
|
|
bb3ccfae3b | ||
|
|
08f261b0f0 | ||
|
|
9b4fd46d2c | ||
|
|
f348f47951 | ||
|
|
9d700563c1 | ||
|
|
54b80c3949 | ||
|
|
1c815b130c | ||
|
|
9e9879fc8d | ||
|
|
af87c2e80b | ||
|
|
e1ac992e5a | ||
|
|
15161c09e8 | ||
|
|
ee5fbe41eb |
@@ -42,7 +42,7 @@ services:
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
schema-migrator-sync:
|
||||
image: signoz/signoz-schema-migrator:v0.129.12
|
||||
image: signoz/signoz-schema-migrator:v0.142.0
|
||||
container_name: schema-migrator-sync
|
||||
command:
|
||||
- sync
|
||||
@@ -55,7 +55,7 @@ services:
|
||||
condition: service_healthy
|
||||
restart: on-failure
|
||||
schema-migrator-async:
|
||||
image: signoz/signoz-schema-migrator:v0.129.12
|
||||
image: signoz/signoz-schema-migrator:v0.142.0
|
||||
container_name: schema-migrator-async
|
||||
command:
|
||||
- async
|
||||
|
||||
@@ -4,7 +4,6 @@ services:
|
||||
container_name: signoz-otel-collector-dev
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
- --feature-gates=-pkg.translator.prometheus.NormalizeName
|
||||
volumes:
|
||||
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
|
||||
environment:
|
||||
|
||||
7
.github/CODEOWNERS
vendored
7
.github/CODEOWNERS
vendored
@@ -110,6 +110,7 @@
|
||||
# Dashboard Owners
|
||||
|
||||
/frontend/src/hooks/dashboard/ @SigNoz/pulse-frontend
|
||||
/frontend/src/providers/Dashboard/ @SigNoz/pulse-frontend
|
||||
|
||||
## Dashboard Types
|
||||
|
||||
@@ -131,3 +132,9 @@
|
||||
|
||||
/frontend/src/pages/PublicDashboard/ @SigNoz/pulse-frontend
|
||||
/frontend/src/container/PublicDashboardContainer/ @SigNoz/pulse-frontend
|
||||
|
||||
## Dashboard Libs + Components
|
||||
/frontend/src/lib/uPlotV2/ @SigNoz/pulse-frontend
|
||||
/frontend/src/lib/dashboard/ @SigNoz/pulse-frontend
|
||||
/frontend/src/lib/dashboardVariables/ @SigNoz/pulse-frontend
|
||||
/frontend/src/components/NewSelect/ @SigNoz/pulse-frontend
|
||||
|
||||
1
.github/workflows/build-enterprise.yaml
vendored
1
.github/workflows/build-enterprise.yaml
vendored
@@ -70,6 +70,7 @@ jobs:
|
||||
echo 'PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> frontend/.env
|
||||
echo 'APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> frontend/.env
|
||||
echo 'PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> frontend/.env
|
||||
echo 'DOCS_BASE_URL="https://signoz.io"' >> frontend/.env
|
||||
- name: cache-dotenv
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
|
||||
1
.github/workflows/build-staging.yaml
vendored
1
.github/workflows/build-staging.yaml
vendored
@@ -69,6 +69,7 @@ jobs:
|
||||
echo 'PYLON_APP_ID="${{ secrets.NP_PYLON_APP_ID }}"' >> frontend/.env
|
||||
echo 'APPCUES_APP_ID="${{ secrets.NP_APPCUES_APP_ID }}"' >> frontend/.env
|
||||
echo 'PYLON_IDENTITY_SECRET="${{ secrets.NP_PYLON_IDENTITY_SECRET }}"' >> frontend/.env
|
||||
echo 'DOCS_BASE_URL="https://staging.signoz.io"' >> frontend/.env
|
||||
- name: cache-dotenv
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
|
||||
10
.github/workflows/goci.yaml
vendored
10
.github/workflows/goci.yaml
vendored
@@ -93,3 +93,13 @@ jobs:
|
||||
run: |
|
||||
go run cmd/enterprise/*.go generate openapi
|
||||
git diff --compact-summary --exit-code || (echo; echo "Unexpected difference in openapi spec. Run go run cmd/enterprise/*.go generate openapi locally and commit."; exit 1)
|
||||
- name: node-install
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: "22"
|
||||
- name: install-frontend
|
||||
run: cd frontend && yarn install
|
||||
- name: generate-api-clients
|
||||
run: |
|
||||
cd frontend && yarn generate:api
|
||||
git diff --compact-summary --exit-code || (echo; echo "Unexpected difference in generated api clients. Run yarn generate:api in frontend/ locally and commit."; exit 1)
|
||||
|
||||
12
.github/workflows/gor-signoz-community.yaml
vendored
12
.github/workflows/gor-signoz-community.yaml
vendored
@@ -3,8 +3,8 @@ name: gor-signoz-community
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+'
|
||||
- "v[0-9]+.[0-9]+.[0-9]+"
|
||||
- "v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -21,6 +21,10 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
- name: node-setup
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: "22"
|
||||
- name: build-frontend
|
||||
run: make js-build
|
||||
- name: upload-frontend-artifact
|
||||
@@ -89,7 +93,7 @@ jobs:
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser-pro
|
||||
version: '~> v2'
|
||||
version: "~> v2"
|
||||
args: release --config ${{ env.CONFIG_PATH }} --clean --split
|
||||
workdir: .
|
||||
env:
|
||||
@@ -147,7 +151,7 @@ jobs:
|
||||
if: steps.cache-linux.outputs.cache-hit == 'true' && steps.cache-darwin.outputs.cache-hit == 'true' # only run if caches hit
|
||||
with:
|
||||
distribution: goreleaser-pro
|
||||
version: '~> v2'
|
||||
version: "~> v2"
|
||||
args: continue --merge
|
||||
workdir: .
|
||||
env:
|
||||
|
||||
15
.github/workflows/gor-signoz.yaml
vendored
15
.github/workflows/gor-signoz.yaml
vendored
@@ -3,8 +3,8 @@ name: gor-signoz
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+'
|
||||
- "v[0-9]+.[0-9]+.[0-9]+"
|
||||
- "v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -36,8 +36,13 @@ jobs:
|
||||
echo 'PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> .env
|
||||
echo 'APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> .env
|
||||
echo 'PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> .env
|
||||
echo 'DOCS_BASE_URL="https://signoz.io"' >> .env
|
||||
- name: node-setup
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: "22"
|
||||
- name: build-frontend
|
||||
run: make js-build
|
||||
run: make js-build
|
||||
- name: upload-frontend-artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -104,7 +109,7 @@ jobs:
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser-pro
|
||||
version: '~> v2'
|
||||
version: "~> v2"
|
||||
args: release --config ${{ env.CONFIG_PATH }} --clean --split
|
||||
workdir: .
|
||||
env:
|
||||
@@ -161,7 +166,7 @@ jobs:
|
||||
if: steps.cache-linux.outputs.cache-hit == 'true' && steps.cache-darwin.outputs.cache-hit == 'true' # only run if caches hit
|
||||
with:
|
||||
distribution: goreleaser-pro
|
||||
version: '~> v2'
|
||||
version: "~> v2"
|
||||
args: continue --merge
|
||||
workdir: .
|
||||
env:
|
||||
|
||||
8
.github/workflows/integrationci.yaml
vendored
8
.github/workflows/integrationci.yaml
vendored
@@ -42,10 +42,12 @@ jobs:
|
||||
- callbackauthn
|
||||
- cloudintegrations
|
||||
- dashboard
|
||||
- querier
|
||||
- ttl
|
||||
- preference
|
||||
- logspipelines
|
||||
- preference
|
||||
- querier
|
||||
- role
|
||||
- ttl
|
||||
- alerts
|
||||
sqlstore-provider:
|
||||
- postgres
|
||||
- sqlite
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -57,7 +57,6 @@ bin/
|
||||
.local/
|
||||
*/query-service/queries.active
|
||||
ee/query-service/db
|
||||
|
||||
# e2e
|
||||
|
||||
e2e/node_modules/
|
||||
|
||||
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"eslint.workingDirectories": ["./frontend"],
|
||||
"eslint.workingDirectories": [
|
||||
"./frontend"
|
||||
],
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
@@ -9,5 +11,8 @@
|
||||
"[go]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "golang.go"
|
||||
},
|
||||
"[sql]": {
|
||||
"editor.defaultFormatter": "adpyke.vscode-sql-formatter"
|
||||
}
|
||||
}
|
||||
|
||||
11
README.md
11
README.md
@@ -66,6 +66,17 @@ Read [more](https://signoz.io/metrics-and-dashboards/).
|
||||
|
||||

|
||||
|
||||
### LLM Observability
|
||||
|
||||
Monitor and debug your LLM applications with comprehensive observability. Track LLM calls, analyze token usage, monitor performance, and gain insights into your AI application's behavior in production.
|
||||
|
||||
SigNoz LLM observability helps you understand how your language models are performing, identify issues with prompts and responses, track token usage and costs, and optimize your AI applications for better performance and reliability.
|
||||
|
||||
[Get started with LLM Observability →](https://signoz.io/docs/llm-observability/)
|
||||
|
||||

|
||||
|
||||
|
||||
### Alerts
|
||||
|
||||
Use alerts in SigNoz to get notified when anything unusual happens in your application. You can set alerts on any type of telemetry signal (logs, metrics, traces), create thresholds and set up a notification channel to get notified. Advanced features like alert history and anomaly detection can help you create smarter alerts.
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/modules/dashboard"
|
||||
"github.com/SigNoz/signoz/pkg/modules/dashboard/impldashboard"
|
||||
"github.com/SigNoz/signoz/pkg/modules/organization"
|
||||
"github.com/SigNoz/signoz/pkg/modules/role"
|
||||
"github.com/SigNoz/signoz/pkg/querier"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/app"
|
||||
"github.com/SigNoz/signoz/pkg/queryparser"
|
||||
@@ -77,10 +76,10 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
|
||||
func(ctx context.Context, providerSettings factory.ProviderSettings, store authtypes.AuthNStore, licensing licensing.Licensing) (map[authtypes.AuthNProvider]authn.AuthN, error) {
|
||||
return signoz.NewAuthNs(ctx, providerSettings, store, licensing)
|
||||
},
|
||||
func(ctx context.Context, sqlstore sqlstore.SQLStore) factory.ProviderFactory[authz.AuthZ, authz.Config] {
|
||||
func(ctx context.Context, sqlstore sqlstore.SQLStore, _ licensing.Licensing, _ dashboard.Module) factory.ProviderFactory[authz.AuthZ, authz.Config] {
|
||||
return openfgaauthz.NewProviderFactory(sqlstore, openfgaschema.NewSchema().Get(ctx))
|
||||
},
|
||||
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, _ role.Module, queryParser queryparser.QueryParser, _ querier.Querier, _ licensing.Licensing) dashboard.Module {
|
||||
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, _ querier.Querier, _ licensing.Licensing) dashboard.Module {
|
||||
return impldashboard.NewModule(impldashboard.NewStore(store), settings, analytics, orgGetter, queryParser)
|
||||
},
|
||||
func(_ licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
|
||||
|
||||
@@ -28,7 +28,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/modules/dashboard"
|
||||
pkgimpldashboard "github.com/SigNoz/signoz/pkg/modules/dashboard/impldashboard"
|
||||
"github.com/SigNoz/signoz/pkg/modules/organization"
|
||||
"github.com/SigNoz/signoz/pkg/modules/role"
|
||||
"github.com/SigNoz/signoz/pkg/querier"
|
||||
"github.com/SigNoz/signoz/pkg/queryparser"
|
||||
"github.com/SigNoz/signoz/pkg/signoz"
|
||||
@@ -116,16 +115,17 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
|
||||
|
||||
return authNs, nil
|
||||
},
|
||||
func(ctx context.Context, sqlstore sqlstore.SQLStore) factory.ProviderFactory[authz.AuthZ, authz.Config] {
|
||||
return openfgaauthz.NewProviderFactory(sqlstore, openfgaschema.NewSchema().Get(ctx))
|
||||
func(ctx context.Context, sqlstore sqlstore.SQLStore, licensing licensing.Licensing, dashboardModule dashboard.Module) factory.ProviderFactory[authz.AuthZ, authz.Config] {
|
||||
return openfgaauthz.NewProviderFactory(sqlstore, openfgaschema.NewSchema().Get(ctx), licensing, dashboardModule)
|
||||
},
|
||||
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, role role.Module, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing) dashboard.Module {
|
||||
return impldashboard.NewModule(pkgimpldashboard.NewStore(store), settings, analytics, orgGetter, role, queryParser, querier, licensing)
|
||||
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing) dashboard.Module {
|
||||
return impldashboard.NewModule(pkgimpldashboard.NewStore(store), settings, analytics, orgGetter, queryParser, querier, licensing)
|
||||
},
|
||||
func(licensing licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
|
||||
return httpgateway.NewProviderFactory(licensing)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.ErrorContext(ctx, "failed to create signoz", "error", err)
|
||||
return err
|
||||
|
||||
@@ -291,3 +291,12 @@ flagger:
|
||||
float:
|
||||
integer:
|
||||
object:
|
||||
|
||||
##################### User #####################
|
||||
user:
|
||||
password:
|
||||
reset:
|
||||
# Whether to allow users to reset their password themselves.
|
||||
allow_self: true
|
||||
# The duration within which a user can reset their password.
|
||||
max_token_lifetime: 6h
|
||||
|
||||
@@ -176,7 +176,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:v0.108.0
|
||||
image: signoz/signoz:v0.111.0
|
||||
command:
|
||||
- --config=/root/config/prometheus.yml
|
||||
ports:
|
||||
@@ -209,12 +209,11 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:v0.129.12
|
||||
image: signoz/signoz-otel-collector:v0.142.0
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
- --manager-config=/etc/manager-config.yaml
|
||||
- --copy-path=/var/tmp/collector-config.yaml
|
||||
- --feature-gates=-pkg.translator.prometheus.NormalizeName
|
||||
volumes:
|
||||
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
|
||||
- ../common/signoz/otel-collector-opamp-config.yaml:/etc/manager-config.yaml
|
||||
@@ -233,7 +232,7 @@ services:
|
||||
- signoz
|
||||
schema-migrator:
|
||||
!!merge <<: *common
|
||||
image: signoz/signoz-schema-migrator:v0.129.12
|
||||
image: signoz/signoz-schema-migrator:v0.142.0
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
||||
@@ -117,7 +117,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:v0.108.0
|
||||
image: signoz/signoz:v0.111.0
|
||||
command:
|
||||
- --config=/root/config/prometheus.yml
|
||||
ports:
|
||||
@@ -150,12 +150,11 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:v0.129.12
|
||||
image: signoz/signoz-otel-collector:v0.142.0
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
- --manager-config=/etc/manager-config.yaml
|
||||
- --copy-path=/var/tmp/collector-config.yaml
|
||||
- --feature-gates=-pkg.translator.prometheus.NormalizeName
|
||||
configs:
|
||||
- source: otel-collector-config
|
||||
target: /etc/otel-collector-config.yaml
|
||||
@@ -176,7 +175,7 @@ services:
|
||||
- signoz
|
||||
schema-migrator:
|
||||
!!merge <<: *common
|
||||
image: signoz/signoz-schema-migrator:v0.129.12
|
||||
image: signoz/signoz-schema-migrator:v0.142.0
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
||||
@@ -179,7 +179,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:${VERSION:-v0.108.0}
|
||||
image: signoz/signoz:${VERSION:-v0.111.0}
|
||||
container_name: signoz
|
||||
command:
|
||||
- --config=/root/config/prometheus.yml
|
||||
@@ -213,13 +213,12 @@ services:
|
||||
# TODO: support otel-collector multiple replicas. Nginx/Traefik for loadbalancing?
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.129.12}
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.142.0}
|
||||
container_name: signoz-otel-collector
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
- --manager-config=/etc/manager-config.yaml
|
||||
- --copy-path=/var/tmp/collector-config.yaml
|
||||
- --feature-gates=-pkg.translator.prometheus.NormalizeName
|
||||
volumes:
|
||||
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
|
||||
- ../common/signoz/otel-collector-opamp-config.yaml:/etc/manager-config.yaml
|
||||
@@ -239,7 +238,7 @@ services:
|
||||
condition: service_healthy
|
||||
schema-migrator-sync:
|
||||
!!merge <<: *common
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.12}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.142.0}
|
||||
container_name: schema-migrator-sync
|
||||
command:
|
||||
- sync
|
||||
@@ -250,7 +249,7 @@ services:
|
||||
condition: service_healthy
|
||||
schema-migrator-async:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.12}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.142.0}
|
||||
container_name: schema-migrator-async
|
||||
command:
|
||||
- async
|
||||
|
||||
@@ -111,7 +111,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:${VERSION:-v0.108.0}
|
||||
image: signoz/signoz:${VERSION:-v0.111.0}
|
||||
container_name: signoz
|
||||
command:
|
||||
- --config=/root/config/prometheus.yml
|
||||
@@ -144,13 +144,12 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.129.12}
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.142.0}
|
||||
container_name: signoz-otel-collector
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
- --manager-config=/etc/manager-config.yaml
|
||||
- --copy-path=/var/tmp/collector-config.yaml
|
||||
- --feature-gates=-pkg.translator.prometheus.NormalizeName
|
||||
volumes:
|
||||
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
|
||||
- ../common/signoz/otel-collector-opamp-config.yaml:/etc/manager-config.yaml
|
||||
@@ -166,7 +165,7 @@ services:
|
||||
condition: service_healthy
|
||||
schema-migrator-sync:
|
||||
!!merge <<: *common
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.12}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.142.0}
|
||||
container_name: schema-migrator-sync
|
||||
command:
|
||||
- sync
|
||||
@@ -178,7 +177,7 @@ services:
|
||||
restart: on-failure
|
||||
schema-migrator-async:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.12}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.142.0}
|
||||
container_name: schema-migrator-async
|
||||
command:
|
||||
- async
|
||||
|
||||
@@ -209,7 +209,7 @@ paths:
|
||||
/api/v1/dashboards/{id}/public:
|
||||
delete:
|
||||
deprecated: false
|
||||
description: This endpoints deletes the public sharing config and disables the
|
||||
description: This endpoint deletes the public sharing config and disables the
|
||||
public sharing of a dashboard
|
||||
operationId: DeletePublicDashboard
|
||||
parameters:
|
||||
@@ -253,7 +253,7 @@ paths:
|
||||
- dashboard
|
||||
get:
|
||||
deprecated: false
|
||||
description: This endpoints returns public sharing config for a dashboard
|
||||
description: This endpoint returns public sharing config for a dashboard
|
||||
operationId: GetPublicDashboard
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -301,7 +301,7 @@ paths:
|
||||
- dashboard
|
||||
post:
|
||||
deprecated: false
|
||||
description: This endpoints creates public sharing config and enables public
|
||||
description: This endpoint creates public sharing config and enables public
|
||||
sharing of the dashboard
|
||||
operationId: CreatePublicDashboard
|
||||
parameters:
|
||||
@@ -355,7 +355,7 @@ paths:
|
||||
- dashboard
|
||||
put:
|
||||
deprecated: false
|
||||
description: This endpoints updates the public sharing config for a dashboard
|
||||
description: This endpoint updates the public sharing config for a dashboard
|
||||
operationId: UpdatePublicDashboard
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -607,6 +607,178 @@ paths:
|
||||
summary: Update auth domain
|
||||
tags:
|
||||
- authdomains
|
||||
/api/v1/fields/keys:
|
||||
get:
|
||||
deprecated: false
|
||||
description: This endpoint returns field keys
|
||||
operationId: GetFieldsKeys
|
||||
parameters:
|
||||
- in: query
|
||||
name: signal
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: source
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: limit
|
||||
schema:
|
||||
type: integer
|
||||
- in: query
|
||||
name: startUnixMilli
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: endUnixMilli
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: fieldContext
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: fieldDataType
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: metricName
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: searchText
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/TelemetrytypesGettableFieldKeys'
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
description: OK
|
||||
"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 field keys
|
||||
tags:
|
||||
- fields
|
||||
/api/v1/fields/values:
|
||||
get:
|
||||
deprecated: false
|
||||
description: This endpoint returns field values
|
||||
operationId: GetFieldsValues
|
||||
parameters:
|
||||
- in: query
|
||||
name: signal
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: source
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: limit
|
||||
schema:
|
||||
type: integer
|
||||
- in: query
|
||||
name: startUnixMilli
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: endUnixMilli
|
||||
schema:
|
||||
format: int64
|
||||
type: integer
|
||||
- in: query
|
||||
name: fieldContext
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: fieldDataType
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: metricName
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: searchText
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: name
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: existingQuery
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/TelemetrytypesGettableFieldValues'
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
description: OK
|
||||
"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 field values
|
||||
tags:
|
||||
- fields
|
||||
/api/v1/getResetPasswordToken/{id}:
|
||||
get:
|
||||
deprecated: false
|
||||
@@ -671,7 +843,7 @@ paths:
|
||||
/api/v1/global/config:
|
||||
get:
|
||||
deprecated: false
|
||||
description: This endpoints returns global config
|
||||
description: This endpoint returns global config
|
||||
operationId: GetGlobalConfig
|
||||
responses:
|
||||
"200":
|
||||
@@ -1447,8 +1619,7 @@ paths:
|
||||
/api/v1/public/dashboards/{id}:
|
||||
get:
|
||||
deprecated: false
|
||||
description: This endpoints returns the sanitized dashboard data for public
|
||||
access
|
||||
description: This endpoint returns the sanitized dashboard data for public access
|
||||
operationId: GetPublicDashboardData
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1579,6 +1750,228 @@ paths:
|
||||
summary: Reset password
|
||||
tags:
|
||||
- users
|
||||
/api/v1/roles:
|
||||
get:
|
||||
deprecated: false
|
||||
description: This endpoint lists all roles
|
||||
operationId: ListRoles
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
items:
|
||||
$ref: '#/components/schemas/RoletypesRole'
|
||||
type: array
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
description: OK
|
||||
"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:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: List roles
|
||||
tags:
|
||||
- role
|
||||
post:
|
||||
deprecated: false
|
||||
description: This endpoint creates a role
|
||||
operationId: CreateRole
|
||||
responses:
|
||||
"201":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/TypesIdentifiable'
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
description: Created
|
||||
"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:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Create role
|
||||
tags:
|
||||
- role
|
||||
/api/v1/roles/{id}:
|
||||
delete:
|
||||
deprecated: false
|
||||
description: This endpoint deletes a role
|
||||
operationId: DeleteRole
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"204":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
description: No Content
|
||||
"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:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Delete role
|
||||
tags:
|
||||
- role
|
||||
get:
|
||||
deprecated: false
|
||||
description: This endpoint gets a role
|
||||
operationId: GetRole
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/RoletypesRole'
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
description: OK
|
||||
"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:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Get role
|
||||
tags:
|
||||
- role
|
||||
patch:
|
||||
deprecated: false
|
||||
description: This endpoint patches a role
|
||||
operationId: PatchRole
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"204":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
description: No Content
|
||||
"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:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Patch role
|
||||
tags:
|
||||
- role
|
||||
/api/v1/user:
|
||||
get:
|
||||
deprecated: false
|
||||
@@ -1985,6 +2378,41 @@ paths:
|
||||
summary: Update user preference
|
||||
tags:
|
||||
- preferences
|
||||
/api/v2/factor_password/forgot:
|
||||
post:
|
||||
deprecated: false
|
||||
description: This endpoint initiates the forgot password flow by sending a reset
|
||||
password email
|
||||
operationId: ForgotPassword
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TypesPostableForgotPassword'
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"422":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unprocessable Entity
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
summary: Forgot password
|
||||
tags:
|
||||
- users
|
||||
/api/v2/features:
|
||||
get:
|
||||
deprecated: false
|
||||
@@ -2035,6 +2463,15 @@ paths:
|
||||
deprecated: false
|
||||
description: This endpoint returns the ingestion keys for a workspace
|
||||
operationId: GetIngestionKeys
|
||||
parameters:
|
||||
- in: query
|
||||
name: page
|
||||
schema:
|
||||
type: integer
|
||||
- in: query
|
||||
name: per_page
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
@@ -2347,6 +2784,19 @@ paths:
|
||||
deprecated: false
|
||||
description: This endpoint returns the ingestion keys for a workspace
|
||||
operationId: SearchIngestionKeys
|
||||
parameters:
|
||||
- in: query
|
||||
name: name
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: page
|
||||
schema:
|
||||
type: integer
|
||||
- in: query
|
||||
name: per_page
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
@@ -2393,6 +2843,7 @@ paths:
|
||||
parameters:
|
||||
- in: query
|
||||
name: metricName
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
@@ -2447,6 +2898,7 @@ paths:
|
||||
parameters:
|
||||
- in: query
|
||||
name: metricName
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
@@ -2502,6 +2954,7 @@ paths:
|
||||
parameters:
|
||||
- in: query
|
||||
name: metricName
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
@@ -2668,6 +3121,7 @@ paths:
|
||||
parameters:
|
||||
- in: query
|
||||
name: metricName
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
@@ -3535,6 +3989,9 @@ components:
|
||||
type: string
|
||||
alertName:
|
||||
type: string
|
||||
required:
|
||||
- alertName
|
||||
- alertId
|
||||
type: object
|
||||
MetricsexplorertypesMetricAlertsResponse:
|
||||
properties:
|
||||
@@ -3543,6 +4000,8 @@ components:
|
||||
$ref: '#/components/schemas/MetricsexplorertypesMetricAlert'
|
||||
nullable: true
|
||||
type: array
|
||||
required:
|
||||
- alerts
|
||||
type: object
|
||||
MetricsexplorertypesMetricAttribute:
|
||||
properties:
|
||||
@@ -3556,6 +4015,10 @@ components:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- values
|
||||
- valueCount
|
||||
type: object
|
||||
MetricsexplorertypesMetricAttributesRequest:
|
||||
properties:
|
||||
@@ -3567,6 +4030,8 @@ components:
|
||||
start:
|
||||
nullable: true
|
||||
type: integer
|
||||
required:
|
||||
- metricName
|
||||
type: object
|
||||
MetricsexplorertypesMetricAttributesResponse:
|
||||
properties:
|
||||
@@ -3578,6 +4043,9 @@ components:
|
||||
totalKeys:
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- attributes
|
||||
- totalKeys
|
||||
type: object
|
||||
MetricsexplorertypesMetricDashboard:
|
||||
properties:
|
||||
@@ -3589,6 +4057,11 @@ components:
|
||||
type: string
|
||||
widgetName:
|
||||
type: string
|
||||
required:
|
||||
- dashboardName
|
||||
- dashboardId
|
||||
- widgetId
|
||||
- widgetName
|
||||
type: object
|
||||
MetricsexplorertypesMetricDashboardsResponse:
|
||||
properties:
|
||||
@@ -3597,6 +4070,8 @@ components:
|
||||
$ref: '#/components/schemas/MetricsexplorertypesMetricDashboard'
|
||||
nullable: true
|
||||
type: array
|
||||
required:
|
||||
- dashboards
|
||||
type: object
|
||||
MetricsexplorertypesMetricHighlightsResponse:
|
||||
properties:
|
||||
@@ -3612,6 +4087,11 @@ components:
|
||||
totalTimeSeries:
|
||||
minimum: 0
|
||||
type: integer
|
||||
required:
|
||||
- dataPoints
|
||||
- lastReceived
|
||||
- totalTimeSeries
|
||||
- activeTimeSeries
|
||||
type: object
|
||||
MetricsexplorertypesMetricMetadata:
|
||||
properties:
|
||||
@@ -3620,11 +4100,17 @@ components:
|
||||
isMonotonic:
|
||||
type: boolean
|
||||
temporality:
|
||||
type: string
|
||||
$ref: '#/components/schemas/MetrictypesTemporality'
|
||||
type:
|
||||
type: string
|
||||
$ref: '#/components/schemas/MetrictypesType'
|
||||
unit:
|
||||
type: string
|
||||
required:
|
||||
- description
|
||||
- type
|
||||
- unit
|
||||
- temporality
|
||||
- isMonotonic
|
||||
type: object
|
||||
MetricsexplorertypesStat:
|
||||
properties:
|
||||
@@ -3639,9 +4125,16 @@ components:
|
||||
minimum: 0
|
||||
type: integer
|
||||
type:
|
||||
type: string
|
||||
$ref: '#/components/schemas/MetrictypesType'
|
||||
unit:
|
||||
type: string
|
||||
required:
|
||||
- metricName
|
||||
- description
|
||||
- type
|
||||
- unit
|
||||
- timeseries
|
||||
- samples
|
||||
type: object
|
||||
MetricsexplorertypesStatsRequest:
|
||||
properties:
|
||||
@@ -3659,6 +4152,10 @@ components:
|
||||
start:
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- start
|
||||
- end
|
||||
- limit
|
||||
type: object
|
||||
MetricsexplorertypesStatsResponse:
|
||||
properties:
|
||||
@@ -3670,6 +4167,9 @@ components:
|
||||
total:
|
||||
minimum: 0
|
||||
type: integer
|
||||
required:
|
||||
- metrics
|
||||
- total
|
||||
type: object
|
||||
MetricsexplorertypesTreemapEntry:
|
||||
properties:
|
||||
@@ -3681,7 +4181,16 @@ components:
|
||||
totalValue:
|
||||
minimum: 0
|
||||
type: integer
|
||||
required:
|
||||
- metricName
|
||||
- percentage
|
||||
- totalValue
|
||||
type: object
|
||||
MetricsexplorertypesTreemapMode:
|
||||
enum:
|
||||
- timeseries
|
||||
- samples
|
||||
type: string
|
||||
MetricsexplorertypesTreemapRequest:
|
||||
properties:
|
||||
end:
|
||||
@@ -3692,10 +4201,15 @@ components:
|
||||
limit:
|
||||
type: integer
|
||||
mode:
|
||||
type: string
|
||||
$ref: '#/components/schemas/MetricsexplorertypesTreemapMode'
|
||||
start:
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- start
|
||||
- end
|
||||
- limit
|
||||
- mode
|
||||
type: object
|
||||
MetricsexplorertypesTreemapResponse:
|
||||
properties:
|
||||
@@ -3709,6 +4223,9 @@ components:
|
||||
$ref: '#/components/schemas/MetricsexplorertypesTreemapEntry'
|
||||
nullable: true
|
||||
type: array
|
||||
required:
|
||||
- timeseries
|
||||
- samples
|
||||
type: object
|
||||
MetricsexplorertypesUpdateMetricMetadataRequest:
|
||||
properties:
|
||||
@@ -3719,12 +4236,33 @@ components:
|
||||
metricName:
|
||||
type: string
|
||||
temporality:
|
||||
type: string
|
||||
$ref: '#/components/schemas/MetrictypesTemporality'
|
||||
type:
|
||||
type: string
|
||||
$ref: '#/components/schemas/MetrictypesType'
|
||||
unit:
|
||||
type: string
|
||||
required:
|
||||
- metricName
|
||||
- type
|
||||
- description
|
||||
- unit
|
||||
- temporality
|
||||
- isMonotonic
|
||||
type: object
|
||||
MetrictypesTemporality:
|
||||
enum:
|
||||
- delta
|
||||
- cumulative
|
||||
- unspecified
|
||||
type: string
|
||||
MetrictypesType:
|
||||
enum:
|
||||
- gauge
|
||||
- sum
|
||||
- histogram
|
||||
- summary
|
||||
- exponentialhistogram
|
||||
type: string
|
||||
PreferencetypesPreference:
|
||||
properties:
|
||||
allowedScopes:
|
||||
@@ -3817,6 +4355,8 @@ components:
|
||||
type: string
|
||||
unit:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
Querybuildertypesv5QueryData:
|
||||
properties:
|
||||
@@ -3859,6 +4399,87 @@ components:
|
||||
status:
|
||||
type: string
|
||||
type: object
|
||||
RoletypesRole:
|
||||
properties:
|
||||
createdAt:
|
||||
format: date-time
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
orgId:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
updatedAt:
|
||||
format: date-time
|
||||
type: string
|
||||
type: object
|
||||
TelemetrytypesGettableFieldKeys:
|
||||
properties:
|
||||
complete:
|
||||
type: boolean
|
||||
keys:
|
||||
additionalProperties:
|
||||
items:
|
||||
$ref: '#/components/schemas/TelemetrytypesTelemetryFieldKey'
|
||||
type: array
|
||||
nullable: true
|
||||
type: object
|
||||
required:
|
||||
- keys
|
||||
- complete
|
||||
type: object
|
||||
TelemetrytypesGettableFieldValues:
|
||||
properties:
|
||||
complete:
|
||||
type: boolean
|
||||
values:
|
||||
$ref: '#/components/schemas/TelemetrytypesTelemetryFieldValues'
|
||||
required:
|
||||
- values
|
||||
- complete
|
||||
type: object
|
||||
TelemetrytypesTelemetryFieldKey:
|
||||
properties:
|
||||
description:
|
||||
type: string
|
||||
fieldContext:
|
||||
type: string
|
||||
fieldDataType:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
signal:
|
||||
type: string
|
||||
unit:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
TelemetrytypesTelemetryFieldValues:
|
||||
properties:
|
||||
boolValues:
|
||||
items:
|
||||
type: boolean
|
||||
type: array
|
||||
numberValues:
|
||||
items:
|
||||
format: double
|
||||
type: number
|
||||
type: array
|
||||
relatedValues:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
stringValues:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
TypesChangePasswordRequest:
|
||||
properties:
|
||||
newPassword:
|
||||
@@ -3979,6 +4600,18 @@ components:
|
||||
token:
|
||||
type: string
|
||||
type: object
|
||||
TypesPostableForgotPassword:
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
frontendBaseURL:
|
||||
type: string
|
||||
orgId:
|
||||
type: string
|
||||
required:
|
||||
- orgId
|
||||
- email
|
||||
type: object
|
||||
TypesPostableInvite:
|
||||
properties:
|
||||
email:
|
||||
@@ -3999,6 +4632,9 @@ components:
|
||||
type: object
|
||||
TypesResetPasswordToken:
|
||||
properties:
|
||||
expiresAt:
|
||||
format: date-time
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
passwordId:
|
||||
|
||||
@@ -24,7 +24,7 @@ The configuration file is a JSON array containing data source objects. Each obje
|
||||
| `label` | `string` | Display name shown to users (e.g., `"AWS EC2"`) |
|
||||
| `tags` | `string[]` | Array of category tags for grouping (e.g., `["AWS"]`, `["database"]`) |
|
||||
| `module` | `string` | Destination module after onboarding completion |
|
||||
| `imgUrl` | `string` | Path to the logo/icon (e.g., `"/Logos/ec2.svg"`) |
|
||||
| `imgUrl` | `string` | Path to the logo/icon **(SVG required)** (e.g., `"/Logos/ec2.svg"`) |
|
||||
|
||||
### Optional Keys
|
||||
|
||||
|
||||
1466
docs/earlier-thoughts/dashboard-v6-schema.json
Normal file
1466
docs/earlier-thoughts/dashboard-v6-schema.json
Normal file
File diff suppressed because it is too large
Load Diff
436
docs/earlier-thoughts/perses-feasibility-analysis.md
Normal file
436
docs/earlier-thoughts/perses-feasibility-analysis.md
Normal file
@@ -0,0 +1,436 @@
|
||||
# Feasibility Analysis: Adopting Perses.dev Specification for SigNoz Dashboards
|
||||
|
||||
## Executive Summary
|
||||
|
||||
SigNoz's dashboard JSON has been a free-form `map[string]interface{}` with no schema enforcement. This document evaluates adopting [Perses.dev](https://perses.dev/) (a CNCF Sandbox project) as a structured dashboard specification. The conclusion is that **wholesale adoption is not recommended**, but several Perses design patterns should be borrowed into a SigNoz-native v6 dashboard schema.
|
||||
|
||||
---
|
||||
|
||||
## 1. Current State: SigNoz Dashboard JSON
|
||||
|
||||
### 1.1 Structure Overview
|
||||
|
||||
The dashboard is stored as `StorableDashboardData = map[string]interface{}` in Go (see `pkg/types/dashboardtypes/dashboard.go`). Top-level fields:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `title` | `string` | Dashboard display name |
|
||||
| `description` | `string` | Dashboard description text |
|
||||
| `tags` | `string[]` | Categorization tags (e.g., `["redis", "database"]`) |
|
||||
| `image` | `string` | Base64 or URL-encoded SVG for dashboard icon/thumbnail |
|
||||
| `version` | `string` | Schema version: `"v4"` or `"v5"` |
|
||||
| `layout` | `Layout[]` | React-grid-layout positioning for each widget |
|
||||
| `panelMap` | `Record<string, {widgets: Layout[], collapsed: boolean}>` | Groups panels under row widgets for collapsible sections |
|
||||
| `widgets` | `Widget[]` | Array of panel/widget definitions |
|
||||
| `variables` | `Record<string, IDashboardVariable>` | Dashboard variable definitions |
|
||||
| `uploadedGrafana` | `boolean` | Flag indicating if imported from Grafana |
|
||||
|
||||
### 1.2 Panel/Widget Types
|
||||
|
||||
| Panel Type | Constant | API Request Type |
|
||||
|-----------|----------|-----------------|
|
||||
| Time Series | `graph` | `time_series` |
|
||||
| Bar Chart | `bar` | `time_series` |
|
||||
| Table | `table` | `scalar` |
|
||||
| Pie Chart | `pie` | `scalar` |
|
||||
| Single Value | `value` | `scalar` |
|
||||
| List/Logs | `list` | `raw` |
|
||||
| Trace | `trace` | `trace` |
|
||||
| Histogram | `histogram` | `distribution` |
|
||||
| Row (group header) | `row` | N/A |
|
||||
|
||||
### 1.3 Query System
|
||||
|
||||
Each widget carries a `query` object with three modes simultaneously:
|
||||
|
||||
```json
|
||||
{
|
||||
"queryType": "builder|clickhouse_sql|promql",
|
||||
"builder": {
|
||||
"queryData": [],
|
||||
"queryFormulas": []
|
||||
},
|
||||
"clickhouse_sql": [],
|
||||
"promql": []
|
||||
}
|
||||
```
|
||||
|
||||
Only `queryType` determines which mode is active; the other sections carry empty placeholder defaults.
|
||||
|
||||
#### Builder Query v4 (legacy, widely used)
|
||||
- `aggregateOperator` + `aggregateAttribute` as separate fields
|
||||
- `filters` with structured `items[]` containing key objects with synthetic IDs
|
||||
- `having: []` as array
|
||||
|
||||
#### Builder Query v5 (newer, integration dashboards)
|
||||
- `aggregations[]` array with `metricName`, `timeAggregation`, `spaceAggregation` combined
|
||||
- `filter` with expression string (e.g., `"host_name IN $host_name"`)
|
||||
- `having: {expression: ""}` as object
|
||||
|
||||
### 1.4 Query Range V5 API
|
||||
|
||||
The V5 execution API wraps queries in a `QueryEnvelope` discriminated union:
|
||||
|
||||
```
|
||||
QueryEnvelope = {type: QueryType, spec: any}
|
||||
```
|
||||
|
||||
Seven query types: `builder_query`, `builder_formula`, `builder_sub_query`, `builder_join`, `builder_trace_operator`, `promql`, `clickhouse_sql`
|
||||
|
||||
Six request types: `scalar`, `time_series`, `raw`, `raw_stream`, `trace`, `distribution`
|
||||
|
||||
Three signals with distinct aggregation models:
|
||||
- **Metrics**: `metricName + temporality + timeAggregation + spaceAggregation`
|
||||
- **Traces**: Expression-based (e.g., `"COUNT()"`, `"p99(duration_nano)"`)
|
||||
- **Logs**: Expression-based (e.g., `"COUNT()"`, `"count_distinct(host.name)"`)
|
||||
|
||||
17 post-processing functions, server-side formula evaluation, SQL-style joins, and trace span relationship operators.
|
||||
|
||||
### 1.5 Documented Pain Points
|
||||
|
||||
1. **`StorableDashboardData` is `map[string]interface{}`**: All nested property access requires manual type assertions with fragile `ok` checks.
|
||||
|
||||
2. **Two incompatible query schema versions coexisting**: v4 and v5 query formats coexist in the same codebase. The backend migration layer (`pkg/transition/migrate_common.go`) converts at execution time.
|
||||
|
||||
3. **Massive boilerplate**: Every widget carries `selectedLogFields` and `selectedTracesFields` arrays even for metrics-only panels. Identical 5-element arrays copy-pasted hundreds of times.
|
||||
|
||||
4. **Duplicate query slots**: Every widget carries all three query types (`builder`, `clickhouse_sql`, `promql`) with empty placeholders for inactive types.
|
||||
|
||||
5. **Variable key inconsistency**: Variables keyed by human-readable name (e.g., `"Account"`) OR UUID depending on dashboard.
|
||||
|
||||
6. **Variables coupled to ClickHouse SQL**: Variable queries use raw `SELECT ... FROM signoz_metrics.distributed_time_series_v4_1day`, coupling dashboard definitions to internal storage schema.
|
||||
|
||||
7. **Redundant synthetic IDs**: Filter keys contain derived `id` fields like `"cloud_account_id--string--tag--false"`.
|
||||
|
||||
8. **Spelling errors baked in**: `"timePreferance"` (misspelled) is embedded in the serialized JSON contract.
|
||||
|
||||
9. **Layout/widget coupling implicit**: Layout items reference widgets by matching `i` to `id` with no schema enforcement. `panelMap` adds another implicit layer.
|
||||
|
||||
10. **No schema validation**: Dashboard data has no Go struct for validation. Relies entirely on frontend TypeScript types with extensive optional markers.
|
||||
|
||||
---
|
||||
|
||||
## 2. Perses.dev Specification Overview
|
||||
|
||||
### 2.1 What is Perses?
|
||||
|
||||
Perses is a CNCF Sandbox project providing:
|
||||
- An **open dashboard specification** (implemented in Go, CUE, TypeScript)
|
||||
- A **plugin-based extension model** for panels, queries, datasources, and variables
|
||||
- **Dashboard-as-Code** via CUE and Go SDKs
|
||||
- **Static validation** via `percli` CLI
|
||||
- **Grafana migration** tooling
|
||||
|
||||
Adopters: Chronosphere, RedHat, SAP, Amadeus.
|
||||
|
||||
### 2.2 Dashboard Structure
|
||||
|
||||
```yaml
|
||||
kind: Dashboard
|
||||
metadata:
|
||||
name: "..."
|
||||
project: "..."
|
||||
spec:
|
||||
display: {name, description}
|
||||
datasources: {name: DatasourceSpec} # inline or referenced
|
||||
variables: [Variable] # ordered list
|
||||
panels: {id: Panel} # map of panel definitions
|
||||
layouts: [Layout] # separate from panels
|
||||
duration: "5m"
|
||||
refreshInterval: "30s"
|
||||
```
|
||||
|
||||
### 2.3 Core Design: Plugin = `{kind: string, spec: any}`
|
||||
|
||||
The universal extension point. Panels, queries, datasources, and variables are all plugins:
|
||||
|
||||
```go
|
||||
type Plugin struct {
|
||||
Kind string `json:"kind"`
|
||||
Metadata *PluginMetadata `json:"metadata,omitempty"`
|
||||
Spec any `json:"spec"`
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 Panel Structure
|
||||
|
||||
```yaml
|
||||
kind: Panel
|
||||
spec:
|
||||
display: {name, description}
|
||||
plugin: {kind: "TimeSeriesChart", spec: {...}}
|
||||
queries:
|
||||
- kind: TimeSeriesQuery
|
||||
spec:
|
||||
plugin:
|
||||
kind: PrometheusTimeSeriesQuery
|
||||
spec: {query: "up", datasource: "$ds"}
|
||||
```
|
||||
|
||||
### 2.5 Layout System
|
||||
|
||||
Panels separated from layout. Grid-based positioning with JSON `$ref` pointers:
|
||||
|
||||
```yaml
|
||||
kind: Grid
|
||||
spec:
|
||||
display:
|
||||
title: "Section Name"
|
||||
collapse: {open: true}
|
||||
items:
|
||||
- x: 0, y: 0, width: 6, height: 6
|
||||
content: {"$ref": "#/spec/panels/my_panel"}
|
||||
```
|
||||
|
||||
### 2.6 Supported Datasources
|
||||
|
||||
| Datasource | Plugin Kind | Protocol |
|
||||
|---|---|---|
|
||||
| Prometheus | `PrometheusDatasource` | PromQL |
|
||||
| Tempo | `TempoDatasource` | TraceQL |
|
||||
| Loki | `LokiDatasource` | LogQL |
|
||||
| Pyroscope | `PyroscopeDatasource` | Pyroscope API |
|
||||
| ClickHouse | Community plugin | SQL |
|
||||
| VictoriaLogs | Community plugin | VictoriaLogs API |
|
||||
|
||||
### 2.7 Plugin System
|
||||
|
||||
Five plugin categories: datasource, query, panel, variable, explore. Each distributes as a compressed archive with CUE schemas, React components (via module federation), and optional Grafana migration logic.
|
||||
|
||||
---
|
||||
|
||||
## 3. Feasibility Assessment
|
||||
|
||||
### 3.1 Support for Logs/Metrics/Traces/Events/Profiles
|
||||
|
||||
| Signal | Perses Status | SigNoz Requirement | Gap |
|
||||
|---|---|---|---|
|
||||
| **Metrics** | Prometheus plugin (mature) | ClickHouse-backed with dual aggregation model (time + space) | **Significant** - Perses assumes PromQL |
|
||||
| **Traces** | Tempo plugin (exists) | ClickHouse-backed with trace operators, span-level queries, joins | **Significant** - Perses Tempo does basic TraceQL |
|
||||
| **Logs** | Loki plugin (exists) | ClickHouse-backed with builder queries, raw list views, streaming | **Moderate** - Perses Loki uses LogQL |
|
||||
| **Profiles** | Pyroscope plugin (exists) | Not yet core in SigNoz dashboards | Low gap |
|
||||
| **Events** | No plugin | Future SigNoz need | Would require custom plugin |
|
||||
|
||||
Perses has plugins for all four pillars, but each assumes a specific backend protocol (PromQL, TraceQL, LogQL). SigNoz uses a **unified query builder** abstracting over ClickHouse. This is a fundamental architectural mismatch.
|
||||
|
||||
### 3.2 Extensibility
|
||||
|
||||
Perses's plugin architecture is genuinely extensible. SigNoz could create custom plugins (`SigNozDatasource`, `SigNozBuilderQuery`, etc.). However, this means:
|
||||
- Writing and maintaining a **full Perses plugin ecosystem** for SigNoz
|
||||
- Plugin must handle all 7 query types and 3 signal types
|
||||
- CUE schema definitions for all SigNoz query structures
|
||||
- Tracking Perses upstream changes (still a Sandbox project, not graduated)
|
||||
|
||||
### 3.3 Coupling Analysis
|
||||
|
||||
| Dimension | Current SigNoz | With Perses | Assessment |
|
||||
|---|---|---|---|
|
||||
| Dashboard to Storage | Variables use raw ClickHouse SQL | Would need SigNoz query plugin | Improvement possible |
|
||||
| Dashboard to Frontend | Widget types tightly coupled to React | Perses separates panel spec from rendering | Improvement |
|
||||
| Dashboard to Query API | Widgets carry full query objects | Plugin-typed, referenced via datasource | Improvement, but adds indirection |
|
||||
| Dashboard to Perses | N/A | Depends on Perses versioning, plugin compat, CUE toolchain | **New coupling** |
|
||||
|
||||
### 3.4 Support for Query Range V5
|
||||
|
||||
This is the **most critical gap**:
|
||||
|
||||
| SigNoz V5 Feature | Perses Equivalent | Plugin Solvable? |
|
||||
|---|---|---|
|
||||
| `builder_query` with signal-specific aggregation | Plugin `spec: any` | Yes, but SigNoz-specific |
|
||||
| `builder_formula` (cross-query math) | No formula concept | **Partially** - needs custom panel logic |
|
||||
| `builder_join` (SQL-style cross-signal joins) | No equivalent | **No** - fundamentally different model |
|
||||
| `builder_trace_operator` (span relationships) | No equivalent | **No** - unique to SigNoz |
|
||||
| `builder_sub_query` (nested queries) | No equivalent | Would need plugin extension |
|
||||
| Multiple query types per panel | Single-typed queries | Would need wrapper plugin |
|
||||
| Post-processing functions (ewma, anomaly, timeShift) | No equivalent | Would need to be in plugin spec |
|
||||
|
||||
---
|
||||
|
||||
## 4. Why NOT Adopt Perses Wholesale
|
||||
|
||||
### 4.1 SigNoz-inside-Perses
|
||||
|
||||
Every SigNoz query feature would live inside `spec: any` blobs within Perses plugin wrappers:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "TimeSeriesQuery",
|
||||
"spec": {
|
||||
"plugin": {
|
||||
"kind": "SigNozBuilderQuery",
|
||||
"spec": { /* ALL SigNoz-specific content here */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Perses validates the envelope (`kind: TimeSeriesQuery` exists, `plugin.kind` is registered). But the actual content is opaque to Perses. You'd still need your own validation for everything inside `spec`.
|
||||
|
||||
### 4.2 Formulas, Joins, and Trace Operators Have No Home
|
||||
|
||||
Perses model: `Panel -> queries[] -> Query`. Each query is independent.
|
||||
|
||||
SigNoz model: `Panel -> compositeQuery -> {queries[], formulas[], joins[], traceOperators[]}`. Queries reference each other by name. Formulas combine results. Joins cross signals.
|
||||
|
||||
You'd have to either:
|
||||
- Shove the entire compositeQuery into a single plugin spec (making Perses query structure meaningless)
|
||||
- Fork/extend Perses core spec (ongoing merge conflicts)
|
||||
|
||||
### 4.3 Plugin Maintenance Burden
|
||||
|
||||
Required custom plugins:
|
||||
|
||||
| Plugin | Purpose |
|
||||
|---|---|
|
||||
| `SigNozDatasource` | Points to SigNoz query-service |
|
||||
| `SigNozBuilderQuery` | Wraps v5 builder queries for metrics/logs/traces |
|
||||
| `SigNozFormulaQuery` | Wraps formula evaluation |
|
||||
| `SigNozTraceOperatorQuery` | Wraps trace structural operators |
|
||||
| `SigNozJoinQuery` | Wraps cross-signal joins |
|
||||
| `SigNozSubQuery` | Wraps nested queries |
|
||||
| `SigNozAttributeValuesVariable` | Variable from attribute values |
|
||||
| `SigNozQueryVariable` | Variable from query results |
|
||||
|
||||
Each needs: CUE schema, React component, Grafana migration handler, and tests. Every v5 feature addition requires plugin schema updates.
|
||||
|
||||
### 4.4 Community Mismatch
|
||||
|
||||
Perses adopters are primarily Prometheus-centric. A `SigNozDatasource` plugin is useful only to SigNoz. You'd be the sole maintainer of the plugin suite.
|
||||
|
||||
### 4.5 The Counterargument
|
||||
|
||||
The one strong argument FOR wholesale adoption: **you get out of the "dashboard spec" business entirely**. Even if 80% is SigNoz-specific plugins, the 20% Perses handles (metadata, layout, display, variable ordering, versioning, RBAC scoping) is real work you don't have to maintain. If Perses graduates from CNCF sandbox, ecosystem benefits compound.
|
||||
|
||||
This trade-off doesn't justify the ongoing plugin maintenance tax, especially since those patterns are straightforward to implement natively. However, if SigNoz plans to eventually expose PromQL/TraceQL/LogQL-compatible endpoints, the calculus changes significantly.
|
||||
|
||||
---
|
||||
|
||||
## 5. Recommendation: Borrow Patterns, Build Native
|
||||
|
||||
### 5.1 Patterns to Adopt from Perses
|
||||
|
||||
| Perses Pattern | SigNoz Adoption |
|
||||
|---|---|
|
||||
| **`kind` + `spec` envelope** | Use for query types, panel types, variables. Consistent with v5 `QueryEnvelope`. |
|
||||
| **Panels separated from Layout** | `panels: {}` map + `layouts: []` referencing by ID. |
|
||||
| **Ordered variables as array** | Move from `variables: {name: {...}}` to `variables: [...]`. |
|
||||
| **CUE or JSON Schema validation** | Define formal schema for dashboards. Use for CI and import/export. |
|
||||
| **Dashboard-as-Code SDK** | Go/TypeScript SDK for programmatic dashboard generation. |
|
||||
| **Metadata structure** | `kind` + `apiVersion` + `metadata` + `spec` top-level (Kubernetes-style). |
|
||||
|
||||
### 5.2 Proposed v6 Dashboard Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Dashboard",
|
||||
"apiVersion": "signoz.io/v1",
|
||||
"metadata": {
|
||||
"name": "redis-overview",
|
||||
"title": "Redis Overview",
|
||||
"description": "...",
|
||||
"tags": ["redis", "database"],
|
||||
"image": "..."
|
||||
},
|
||||
"spec": {
|
||||
"defaults": {
|
||||
"timeRange": "5m",
|
||||
"refreshInterval": "30s"
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"kind": "QueryVariable",
|
||||
"spec": {
|
||||
"name": "host_name",
|
||||
"signal": "metrics",
|
||||
"attributeName": "host_name",
|
||||
"multiSelect": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"panels": {
|
||||
"hit_rate": {
|
||||
"kind": "TimeSeriesPanel",
|
||||
"spec": {
|
||||
"title": "Hit Rate",
|
||||
"description": "Cache hit rate across hosts",
|
||||
"display": {
|
||||
"yAxisUnit": "percent",
|
||||
"legend": {"position": "bottom"}
|
||||
},
|
||||
"query": {
|
||||
"type": "composite",
|
||||
"spec": {
|
||||
"queries": [
|
||||
{
|
||||
"type": "builder_query",
|
||||
"spec": {
|
||||
"name": "A",
|
||||
"signal": "metrics",
|
||||
"aggregations": [{"metricName": "redis_keyspace_hits", "timeAggregation": "rate", "spaceAggregation": "sum"}],
|
||||
"filter": {"expression": "host_name IN $host_name"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"formulas": [
|
||||
{"type": "builder_formula", "spec": {"expression": "A / (A + B) * 100"}}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"layouts": [
|
||||
{
|
||||
"kind": "Grid",
|
||||
"spec": {
|
||||
"title": "Overview",
|
||||
"collapsible": true,
|
||||
"collapsed": false,
|
||||
"items": [
|
||||
{"panel": "hit_rate", "x": 0, "y": 0, "w": 6, "h": 6}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 Key Improvements Over Current Format
|
||||
|
||||
| Issue | Current | v6 |
|
||||
|---|---|---|
|
||||
| No validation | `map[string]interface{}` | JSON Schema enforced |
|
||||
| Boilerplate | Every widget has selectedLogFields, all query modes | Only active query mode stored, display options per panel type |
|
||||
| Variable ordering | `order` field inside map entries | Array position |
|
||||
| Variable keys | Name or UUID inconsistently | `name` field in spec, array position |
|
||||
| Layout coupling | Implicit `i` matches `id` | Explicit `panel` reference in layout items |
|
||||
| Spelling errors | `timePreferance` | `timePreference` (fixed) |
|
||||
| Query structure | Flat list of all queries + formulas | Typed envelope matching v5 API |
|
||||
| Row grouping | Separate `panelMap` with duplicate layout entries | Integrated into `layouts[]` with `collapsible` flag |
|
||||
|
||||
### 5.4 Migration Path
|
||||
|
||||
1. **v4/v5 to v6 migration**: Build a Go migration function that transforms existing dashboards to v6 format. Handle both v4 and v5 query formats.
|
||||
2. **Backward compatibility**: Support reading v4/v5 dashboards with automatic upgrade to v6 on save.
|
||||
3. **Frontend**: Update TypeScript interfaces to match v6 schema. Remove legacy response converters once v5 API is fully adopted.
|
||||
4. **Validation**: Add JSON Schema validation on dashboard create/update API endpoints.
|
||||
5. **Integration dashboards**: Regenerate all dashboards in `SigNoz/dashboards` repo using v6 format.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Perses Homepage](https://perses.dev/)
|
||||
- [Perses Dashboard API](https://perses.dev/perses/docs/api/dashboard/)
|
||||
- [Perses Open Specification](https://perses.dev/perses/docs/concepts/open-specification/)
|
||||
- [Perses Plugin Creation](https://perses.dev/perses/docs/plugins/creation/)
|
||||
- [Perses Prometheus Plugin Model](https://perses.dev/plugins/docs/prometheus/model/)
|
||||
- [Perses GitHub Repository](https://github.com/perses/perses)
|
||||
- [SigNoz Dashboards Repository](https://github.com/SigNoz/dashboards)
|
||||
- SigNoz source: `pkg/types/dashboardtypes/dashboard.go`
|
||||
- SigNoz source: `pkg/types/querybuildertypes/querybuildertypesv5/`
|
||||
- SigNoz source: `frontend/src/types/api/dashboard/getAll.ts`
|
||||
- SigNoz source: `frontend/src/types/api/queryBuilder/queryBuilderData.ts`
|
||||
- SigNoz source: `frontend/src/types/api/v5/queryRange.ts`
|
||||
- SigNoz source: `pkg/transition/migrate_common.go`
|
||||
1463
docs/rfc-perses-native-dashboard.md
Normal file
1463
docs/rfc-perses-native-dashboard.md
Normal file
File diff suppressed because it is too large
Load Diff
378
docs/signoz-perses-plugins.cue
Normal file
378
docs/signoz-perses-plugins.cue
Normal file
@@ -0,0 +1,378 @@
|
||||
// SigNoz Perses Plugin Schemas
|
||||
//
|
||||
// CUE schemas for all SigNoz-specific Perses plugin types.
|
||||
// These define the `spec` shape inside Perses Plugin wrappers:
|
||||
// { "kind": "<PluginKind>", "spec": <validated by this file> }
|
||||
//
|
||||
// Perses core types (Dashboard, Panel, Layout, Variable envelopes)
|
||||
// are validated by Perses itself. This file only covers SigNoz plugins.
|
||||
//
|
||||
// Usage:
|
||||
// percli lint --schema-dir ./signoz-perses-plugins dashboard.json
|
||||
//
|
||||
// Reference: https://perses.dev/perses/docs/api/plugin/
|
||||
|
||||
package signoz
|
||||
|
||||
// ============================================================================
|
||||
// Datasource Plugin
|
||||
// ============================================================================
|
||||
|
||||
// SigNozDatasource configures the connection to a SigNoz query service.
|
||||
// Used inside: DatasourceSpec.plugin { kind: "SigNozDatasource", spec: ... }
|
||||
#SigNozDatasource: {
|
||||
// Direct URL for embedded mode (SigNoz serves its own dashboards).
|
||||
// The frontend calls SigNoz APIs directly at this base URL.
|
||||
directUrl?: string & =~"^/|^https?://"
|
||||
|
||||
// HTTP proxy config for external mode (standalone Perses connecting to SigNoz).
|
||||
proxy?: #HTTPProxy
|
||||
}
|
||||
|
||||
#HTTPProxy: {
|
||||
kind: "HTTPProxy"
|
||||
spec: {
|
||||
url: string & =~"^https?://"
|
||||
allowedEndpoints?: [...#AllowedEndpoint]
|
||||
}
|
||||
}
|
||||
|
||||
#AllowedEndpoint: {
|
||||
endpointPattern: string
|
||||
method: "GET" | "POST" | "PUT" | "DELETE"
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Query Plugins
|
||||
// ============================================================================
|
||||
|
||||
// SigNozBuilderQuery is a single builder query for one signal.
|
||||
// Used inside: TimeSeriesQuery.spec.plugin { kind: "SigNozBuilderQuery", spec: ... }
|
||||
// Use this when the panel has independent queries (no formulas, joins, or trace operators).
|
||||
#SigNozBuilderQuery: {
|
||||
name: #QueryName
|
||||
signal: #Signal
|
||||
source?: string
|
||||
|
||||
disabled?: bool | *false
|
||||
|
||||
// Metrics use structured aggregations; traces/logs use expression aggregations
|
||||
aggregations?: [...#MetricAggregation | #ExpressionAggregation]
|
||||
|
||||
filter?: #Filter
|
||||
groupBy?: [...#GroupByKey]
|
||||
order?: [...#OrderBy]
|
||||
having?: #Having
|
||||
|
||||
selectFields?: [...#TelemetryFieldKey]
|
||||
|
||||
limit?: int & >=0 & <=10000
|
||||
limitBy?: #LimitBy
|
||||
offset?: int & >=0
|
||||
cursor?: string
|
||||
|
||||
secondaryAggregations?: [...#SecondaryAggregation]
|
||||
functions?: [...#PostProcessingFunction]
|
||||
|
||||
legend?: string
|
||||
reduceTo?: #ReduceTo
|
||||
stepInterval?: #StepInterval
|
||||
}
|
||||
|
||||
// SigNozCompositeQuery bundles multiple queries with formulas, joins, or trace operators.
|
||||
// Used inside: TimeSeriesQuery.spec.plugin { kind: "SigNozCompositeQuery", spec: ... }
|
||||
// Use this when a panel needs cross-query references (A/B formulas, joins, trace operators).
|
||||
#SigNozCompositeQuery: {
|
||||
queries: [...#CompositeQueryEntry] & [_, ...] // at least one query
|
||||
|
||||
formulas?: [...#FormulaEntry]
|
||||
joins?: [...#JoinEntry]
|
||||
traceOperators?: [...#TraceOperatorEntry]
|
||||
}
|
||||
|
||||
// A query within a composite. Same shape as SigNozBuilderQuery.
|
||||
#CompositeQueryEntry: #SigNozBuilderQuery
|
||||
|
||||
// A formula referencing other queries by name.
|
||||
#FormulaEntry: {
|
||||
name: #QueryName
|
||||
expression: string & !="" // e.g. "A/B * 100"
|
||||
|
||||
disabled?: bool | *false
|
||||
|
||||
order?: [...#OrderBy]
|
||||
limit?: int & >=0 & <=10000
|
||||
having?: #Having
|
||||
functions?: [...#PostProcessingFunction]
|
||||
legend?: string
|
||||
}
|
||||
|
||||
// A join combining results from two queries.
|
||||
#JoinEntry: {
|
||||
name: #QueryName
|
||||
|
||||
disabled?: bool | *false
|
||||
|
||||
left: #QueryRef
|
||||
right: #QueryRef
|
||||
joinType: "inner" | "left" | "right" | "full" | "cross"
|
||||
on: string & !="" // join condition expression
|
||||
|
||||
aggregations?: [...#MetricAggregation | #ExpressionAggregation]
|
||||
selectFields?: [...#TelemetryFieldKey]
|
||||
filter?: #Filter
|
||||
groupBy?: [...#GroupByKey]
|
||||
having?: #Having
|
||||
order?: [...#OrderBy]
|
||||
limit?: int & >=0 & <=10000
|
||||
|
||||
secondaryAggregations?: [...#SecondaryAggregation]
|
||||
functions?: [...#PostProcessingFunction]
|
||||
}
|
||||
|
||||
// A trace operator expressing span relationships.
|
||||
#TraceOperatorEntry: {
|
||||
name: #QueryName
|
||||
|
||||
disabled?: bool | *false
|
||||
|
||||
// Operators: => (direct descendant), -> (indirect descendant),
|
||||
// && (AND), || (OR), NOT (exclude). Example: "A => B && C"
|
||||
expression: string & !=""
|
||||
|
||||
filter?: #Filter
|
||||
returnSpansFrom?: string
|
||||
|
||||
order?: [...#TraceOrderBy]
|
||||
aggregations?: [...#ExpressionAggregation]
|
||||
stepInterval?: #StepInterval
|
||||
groupBy?: [...#GroupByKey]
|
||||
having?: #Having
|
||||
limit?: int & >=0 & <=10000
|
||||
offset?: int & >=0
|
||||
cursor?: string
|
||||
legend?: string
|
||||
selectFields?: [...#TelemetryFieldKey]
|
||||
functions?: [...#PostProcessingFunction]
|
||||
}
|
||||
|
||||
// SigNozPromQL wraps a raw PromQL query.
|
||||
// Used inside: TimeSeriesQuery.spec.plugin { kind: "SigNozPromQL", spec: ... }
|
||||
#SigNozPromQL: {
|
||||
name: string
|
||||
query: string & !=""
|
||||
|
||||
disabled?: bool | *false
|
||||
step?: #StepInterval
|
||||
stats?: bool | *false
|
||||
legend?: string
|
||||
}
|
||||
|
||||
// SigNozClickHouseSQL wraps a raw ClickHouse SQL query.
|
||||
// Used inside: TimeSeriesQuery.spec.plugin { kind: "SigNozClickHouseSQL", spec: ... }
|
||||
#SigNozClickHouseSQL: {
|
||||
name: string
|
||||
query: string & !=""
|
||||
|
||||
disabled?: bool | *false
|
||||
legend?: string
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Variable Plugins
|
||||
// ============================================================================
|
||||
|
||||
// SigNozQueryVariable resolves variable values using a builder query.
|
||||
// Used inside: ListVariable.spec.plugin { kind: "SigNozQueryVariable", spec: ... }
|
||||
#SigNozQueryVariable: {
|
||||
// The query that produces variable values.
|
||||
// Uses the same builder query model as panels.
|
||||
query: #SigNozBuilderQuery | #SigNozCompositeQuery | #SigNozPromQL | #SigNozClickHouseSQL
|
||||
}
|
||||
|
||||
// SigNozAttributeValues resolves variable values from attribute autocomplete.
|
||||
// Used inside: ListVariable.spec.plugin { kind: "SigNozAttributeValues", spec: ... }
|
||||
// This is a simpler alternative to SigNozQueryVariable for common cases
|
||||
// like "list all values of host.name for metric X".
|
||||
#SigNozAttributeValues: {
|
||||
signal: #Signal
|
||||
metricName?: string // required when signal is "metrics"
|
||||
attributeName: string & !=""
|
||||
|
||||
filter?: #Filter // optional pre-filter
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Signals
|
||||
// ============================================================================
|
||||
|
||||
#Signal: "metrics" | "traces" | "logs"
|
||||
// Extensible to "events" | "profiles" in future
|
||||
|
||||
// ============================================================================
|
||||
// Aggregations
|
||||
// ============================================================================
|
||||
|
||||
// MetricAggregation defines the two-level aggregation model for metrics:
|
||||
// time aggregation (within each time bucket) then space aggregation (across dimensions).
|
||||
#MetricAggregation: {
|
||||
metricName: string & !=""
|
||||
|
||||
temporality?: #MetricTemporality
|
||||
timeAggregation?: #TimeAggregation
|
||||
spaceAggregation?: #SpaceAggregation
|
||||
reduceTo?: #ReduceTo
|
||||
}
|
||||
|
||||
// ExpressionAggregation uses ClickHouse aggregate function syntax for traces/logs.
|
||||
// Examples: "count()", "sum(item_price)", "p99(duration_nano)", "countIf(day > 10)"
|
||||
#ExpressionAggregation: {
|
||||
expression: string & !=""
|
||||
alias?: string
|
||||
}
|
||||
|
||||
#MetricTemporality: "delta" | "cumulative" | "unspecified"
|
||||
|
||||
#TimeAggregation:
|
||||
"latest" | "sum" | "avg" | "min" | "max" |
|
||||
"count" | "count_distinct" | "rate" | "increase"
|
||||
|
||||
#SpaceAggregation:
|
||||
"sum" | "avg" | "min" | "max" | "count" |
|
||||
"p50" | "p75" | "p90" | "p95" | "p99"
|
||||
|
||||
#ReduceTo: "sum" | "count" | "avg" | "min" | "max" | "last" | "median"
|
||||
|
||||
// ============================================================================
|
||||
// Filters
|
||||
// ============================================================================
|
||||
|
||||
// Filter uses expression syntax instead of structured items with synthetic IDs.
|
||||
// Supports: =, !=, >, >=, <, <=, IN, NOT IN, LIKE, NOT LIKE, ILIKE, NOT ILIKE,
|
||||
// BETWEEN, NOT BETWEEN, EXISTS, NOT EXISTS, REGEXP, NOT REGEXP, CONTAINS, NOT CONTAINS.
|
||||
// Variable interpolation: $variable_name
|
||||
#Filter: {
|
||||
expression: string
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Group By, Order By, Having
|
||||
// ============================================================================
|
||||
|
||||
#GroupByKey: {
|
||||
name: string & !=""
|
||||
signal?: #Signal
|
||||
fieldContext?: #FieldContext
|
||||
fieldDataType?: #FieldDataType
|
||||
}
|
||||
|
||||
#OrderBy: {
|
||||
key: #OrderByKey
|
||||
direction: "asc" | "desc"
|
||||
}
|
||||
|
||||
#OrderByKey: {
|
||||
name: string & !=""
|
||||
signal?: #Signal
|
||||
fieldContext?: #FieldContext
|
||||
fieldDataType?: #FieldDataType
|
||||
}
|
||||
|
||||
#TraceOrderBy: {
|
||||
key: {
|
||||
name: "span_count" | "trace_duration"
|
||||
}
|
||||
direction: "asc" | "desc"
|
||||
}
|
||||
|
||||
// Having applies a post-aggregation filter.
|
||||
// Example: "count() > 100"
|
||||
#Having: {
|
||||
expression: string & !=""
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Secondary Aggregations & Limits
|
||||
// ============================================================================
|
||||
|
||||
#SecondaryAggregation: {
|
||||
expression: string
|
||||
alias?: string
|
||||
|
||||
stepInterval?: #StepInterval
|
||||
groupBy?: [...#GroupByKey]
|
||||
order?: [...#OrderBy]
|
||||
limit?: int & >=0 & <=10000
|
||||
limitBy?: #LimitBy
|
||||
}
|
||||
|
||||
#LimitBy: {
|
||||
keys: [...string] & [_, ...] // at least one key
|
||||
value: string // max rows per group (string for compatibility)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Post-Processing Functions
|
||||
// ============================================================================
|
||||
|
||||
#PostProcessingFunction: {
|
||||
name: #FunctionName
|
||||
args?: [...#FunctionArg]
|
||||
}
|
||||
|
||||
#FunctionName:
|
||||
// Threshold functions
|
||||
"cutOffMin" | "cutOffMax" | "clampMin" | "clampMax" |
|
||||
// Math functions
|
||||
"absolute" | "runningDiff" | "log2" | "log10" | "cumulativeSum" |
|
||||
// Smoothing functions (exponentially weighted moving average)
|
||||
"ewma3" | "ewma5" | "ewma7" |
|
||||
// Smoothing functions (sliding median window)
|
||||
"median3" | "median5" | "median7" |
|
||||
// Time functions
|
||||
"timeShift" |
|
||||
// Analysis functions
|
||||
"anomaly" |
|
||||
// Gap filling
|
||||
"fillZero"
|
||||
|
||||
#FunctionArg: {
|
||||
name?: string
|
||||
value: number | string | bool
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Telemetry Field References
|
||||
// ============================================================================
|
||||
|
||||
#TelemetryFieldKey: {
|
||||
name: string & !=""
|
||||
description?: string
|
||||
unit?: string
|
||||
signal?: #Signal
|
||||
fieldContext?: #FieldContext
|
||||
fieldDataType?: #FieldDataType
|
||||
}
|
||||
|
||||
#FieldContext:
|
||||
"resource" | "scope" | "span" | "event" | "link" |
|
||||
"log" | "metric" | "body" | "trace"
|
||||
|
||||
#FieldDataType:
|
||||
"string" | "int64" | "float64" | "bool" |
|
||||
"array(string)" | "array(int64)" | "array(float64)" | "array(bool)"
|
||||
|
||||
// ============================================================================
|
||||
// Common Types
|
||||
// ============================================================================
|
||||
|
||||
// QueryName must be a valid identifier: starts with letter, contains letters/digits/underscores.
|
||||
#QueryName: =~"^[A-Za-z][A-Za-z0-9_]*$"
|
||||
|
||||
// QueryRef references another query by name within a composite query.
|
||||
#QueryRef: {
|
||||
name: string & !=""
|
||||
}
|
||||
|
||||
// StepInterval accepts seconds (numeric) or duration string ("15s", "1m", "1h").
|
||||
#StepInterval: number & >=0 | =~"^[0-9]+(ns|us|ms|s|m|h)$"
|
||||
@@ -2,12 +2,18 @@ package openfgaauthz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/authz/openfgaserver"
|
||||
"github.com/SigNoz/signoz/pkg/authz"
|
||||
"github.com/SigNoz/signoz/pkg/authz/authzstore/sqlauthzstore"
|
||||
pkgopenfgaauthz "github.com/SigNoz/signoz/pkg/authz/openfgaauthz"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/licensing"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/roletypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
openfgav1 "github.com/openfga/api/proto/openfga/v1"
|
||||
openfgapkgtransformer "github.com/openfga/language/pkg/go/transformer"
|
||||
@@ -15,84 +21,320 @@ import (
|
||||
|
||||
type provider struct {
|
||||
pkgAuthzService authz.AuthZ
|
||||
openfgaServer *openfgaserver.Server
|
||||
licensing licensing.Licensing
|
||||
store roletypes.Store
|
||||
registry []authz.RegisterTypeable
|
||||
}
|
||||
|
||||
func NewProviderFactory(sqlstore sqlstore.SQLStore, openfgaSchema []openfgapkgtransformer.ModuleFile) factory.ProviderFactory[authz.AuthZ, authz.Config] {
|
||||
func NewProviderFactory(sqlstore sqlstore.SQLStore, openfgaSchema []openfgapkgtransformer.ModuleFile, licensing licensing.Licensing, registry ...authz.RegisterTypeable) factory.ProviderFactory[authz.AuthZ, authz.Config] {
|
||||
return factory.NewProviderFactory(factory.MustNewName("openfga"), func(ctx context.Context, ps factory.ProviderSettings, config authz.Config) (authz.AuthZ, error) {
|
||||
return newOpenfgaProvider(ctx, ps, config, sqlstore, openfgaSchema)
|
||||
return newOpenfgaProvider(ctx, ps, config, sqlstore, openfgaSchema, licensing, registry)
|
||||
})
|
||||
}
|
||||
|
||||
func newOpenfgaProvider(ctx context.Context, settings factory.ProviderSettings, config authz.Config, sqlstore sqlstore.SQLStore, openfgaSchema []openfgapkgtransformer.ModuleFile) (authz.AuthZ, error) {
|
||||
func newOpenfgaProvider(ctx context.Context, settings factory.ProviderSettings, config authz.Config, sqlstore sqlstore.SQLStore, openfgaSchema []openfgapkgtransformer.ModuleFile, licensing licensing.Licensing, registry []authz.RegisterTypeable) (authz.AuthZ, error) {
|
||||
pkgOpenfgaAuthzProvider := pkgopenfgaauthz.NewProviderFactory(sqlstore, openfgaSchema)
|
||||
pkgAuthzService, err := pkgOpenfgaAuthzProvider.New(ctx, settings, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
openfgaServer, err := openfgaserver.NewOpenfgaServer(ctx, pkgAuthzService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &provider{
|
||||
pkgAuthzService: pkgAuthzService,
|
||||
openfgaServer: openfgaServer,
|
||||
licensing: licensing,
|
||||
store: sqlauthzstore.NewSqlAuthzStore(sqlstore),
|
||||
registry: registry,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (provider *provider) Start(ctx context.Context) error {
|
||||
return provider.pkgAuthzService.Start(ctx)
|
||||
return provider.openfgaServer.Start(ctx)
|
||||
}
|
||||
|
||||
func (provider *provider) Stop(ctx context.Context) error {
|
||||
return provider.pkgAuthzService.Stop(ctx)
|
||||
return provider.openfgaServer.Stop(ctx)
|
||||
}
|
||||
|
||||
func (provider *provider) Check(ctx context.Context, tuple *openfgav1.TupleKey) error {
|
||||
return provider.pkgAuthzService.Check(ctx, tuple)
|
||||
return provider.openfgaServer.Check(ctx, tuple)
|
||||
}
|
||||
|
||||
func (provider *provider) CheckWithTupleCreation(ctx context.Context, claims authtypes.Claims, orgID valuer.UUID, relation authtypes.Relation, _ authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector) error {
|
||||
subject, err := authtypes.NewSubject(authtypes.TypeableUser, claims.UserID, orgID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tuples, err := typeable.Tuples(subject, relation, selectors, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = provider.BatchCheck(ctx, tuples)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
func (provider *provider) CheckWithTupleCreation(ctx context.Context, claims authtypes.Claims, orgID valuer.UUID, relation authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector, roleSelectors []authtypes.Selector) error {
|
||||
return provider.openfgaServer.CheckWithTupleCreation(ctx, claims, orgID, relation, typeable, selectors, roleSelectors)
|
||||
}
|
||||
|
||||
func (provider *provider) CheckWithTupleCreationWithoutClaims(ctx context.Context, orgID valuer.UUID, relation authtypes.Relation, _ authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector) error {
|
||||
subject, err := authtypes.NewSubject(authtypes.TypeableAnonymous, authtypes.AnonymousUser.String(), orgID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tuples, err := typeable.Tuples(subject, relation, selectors, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = provider.BatchCheck(ctx, tuples)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
func (provider *provider) CheckWithTupleCreationWithoutClaims(ctx context.Context, orgID valuer.UUID, relation authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector, roleSelectors []authtypes.Selector) error {
|
||||
return provider.openfgaServer.CheckWithTupleCreationWithoutClaims(ctx, orgID, relation, typeable, selectors, roleSelectors)
|
||||
}
|
||||
|
||||
func (provider *provider) BatchCheck(ctx context.Context, tuples []*openfgav1.TupleKey) error {
|
||||
return provider.pkgAuthzService.BatchCheck(ctx, tuples)
|
||||
return provider.openfgaServer.BatchCheck(ctx, tuples)
|
||||
}
|
||||
|
||||
func (provider *provider) ListObjects(ctx context.Context, subject string, relation authtypes.Relation, typeable authtypes.Typeable) ([]*authtypes.Object, error) {
|
||||
return provider.pkgAuthzService.ListObjects(ctx, subject, relation, typeable)
|
||||
return provider.openfgaServer.ListObjects(ctx, subject, relation, typeable)
|
||||
}
|
||||
|
||||
func (provider *provider) Write(ctx context.Context, additions []*openfgav1.TupleKey, deletions []*openfgav1.TupleKey) error {
|
||||
return provider.pkgAuthzService.Write(ctx, additions, deletions)
|
||||
return provider.openfgaServer.Write(ctx, additions, deletions)
|
||||
}
|
||||
|
||||
func (provider *provider) Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*roletypes.Role, error) {
|
||||
return provider.pkgAuthzService.Get(ctx, orgID, id)
|
||||
}
|
||||
|
||||
func (provider *provider) GetByOrgIDAndName(ctx context.Context, orgID valuer.UUID, name string) (*roletypes.Role, error) {
|
||||
return provider.pkgAuthzService.GetByOrgIDAndName(ctx, orgID, name)
|
||||
}
|
||||
|
||||
func (provider *provider) List(ctx context.Context, orgID valuer.UUID) ([]*roletypes.Role, error) {
|
||||
return provider.pkgAuthzService.List(ctx, orgID)
|
||||
}
|
||||
|
||||
func (provider *provider) ListByOrgIDAndNames(ctx context.Context, orgID valuer.UUID, names []string) ([]*roletypes.Role, error) {
|
||||
return provider.pkgAuthzService.ListByOrgIDAndNames(ctx, orgID, names)
|
||||
}
|
||||
|
||||
func (provider *provider) Grant(ctx context.Context, orgID valuer.UUID, name string, subject string) error {
|
||||
return provider.pkgAuthzService.Grant(ctx, orgID, name, subject)
|
||||
}
|
||||
|
||||
func (provider *provider) ModifyGrant(ctx context.Context, orgID valuer.UUID, existingRoleName string, updatedRoleName string, subject string) error {
|
||||
return provider.pkgAuthzService.ModifyGrant(ctx, orgID, existingRoleName, updatedRoleName, subject)
|
||||
}
|
||||
|
||||
func (provider *provider) Revoke(ctx context.Context, orgID valuer.UUID, name string, subject string) error {
|
||||
return provider.pkgAuthzService.Revoke(ctx, orgID, name, subject)
|
||||
}
|
||||
|
||||
func (provider *provider) CreateManagedRoles(ctx context.Context, orgID valuer.UUID, managedRoles []*roletypes.Role) error {
|
||||
return provider.pkgAuthzService.CreateManagedRoles(ctx, orgID, managedRoles)
|
||||
}
|
||||
|
||||
func (provider *provider) CreateManagedUserRoleTransactions(ctx context.Context, orgID valuer.UUID, userID valuer.UUID) error {
|
||||
tuples := make([]*openfgav1.TupleKey, 0)
|
||||
|
||||
grantTuples, err := provider.getManagedRoleGrantTuples(orgID, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tuples = append(tuples, grantTuples...)
|
||||
|
||||
managedRoleTuples, err := provider.getManagedRoleTransactionTuples(orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tuples = append(tuples, managedRoleTuples...)
|
||||
|
||||
return provider.Write(ctx, tuples, nil)
|
||||
}
|
||||
|
||||
func (provider *provider) Create(ctx context.Context, orgID valuer.UUID, role *roletypes.Role) error {
|
||||
_, err := provider.licensing.GetActive(ctx, orgID)
|
||||
if err != nil {
|
||||
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
|
||||
}
|
||||
|
||||
return provider.store.Create(ctx, roletypes.NewStorableRoleFromRole(role))
|
||||
}
|
||||
|
||||
func (provider *provider) GetOrCreate(ctx context.Context, orgID valuer.UUID, role *roletypes.Role) (*roletypes.Role, error) {
|
||||
_, err := provider.licensing.GetActive(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
|
||||
}
|
||||
|
||||
existingRole, err := provider.store.GetByOrgIDAndName(ctx, role.OrgID, role.Name)
|
||||
if err != nil {
|
||||
if !errors.Ast(err, errors.TypeNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if existingRole != nil {
|
||||
return roletypes.NewRoleFromStorableRole(existingRole), nil
|
||||
}
|
||||
|
||||
err = provider.store.Create(ctx, roletypes.NewStorableRoleFromRole(role))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return role, nil
|
||||
}
|
||||
|
||||
func (provider *provider) GetResources(_ context.Context) []*authtypes.Resource {
|
||||
typeables := make([]authtypes.Typeable, 0)
|
||||
for _, register := range provider.registry {
|
||||
typeables = append(typeables, register.MustGetTypeables()...)
|
||||
}
|
||||
// role module cannot self register itself!
|
||||
typeables = append(typeables, provider.MustGetTypeables()...)
|
||||
|
||||
resources := make([]*authtypes.Resource, 0)
|
||||
for _, typeable := range typeables {
|
||||
resources = append(resources, &authtypes.Resource{Name: typeable.Name(), Type: typeable.Type()})
|
||||
}
|
||||
|
||||
return resources
|
||||
}
|
||||
|
||||
func (provider *provider) GetObjects(ctx context.Context, orgID valuer.UUID, id valuer.UUID, relation authtypes.Relation) ([]*authtypes.Object, error) {
|
||||
storableRole, err := provider.store.Get(ctx, orgID, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
objects := make([]*authtypes.Object, 0)
|
||||
for _, resource := range provider.GetResources(ctx) {
|
||||
if slices.Contains(authtypes.TypeableRelations[resource.Type], relation) {
|
||||
resourceObjects, err := provider.
|
||||
ListObjects(
|
||||
ctx,
|
||||
authtypes.MustNewSubject(authtypes.TypeableRole, storableRole.ID.String(), orgID, &authtypes.RelationAssignee),
|
||||
relation,
|
||||
authtypes.MustNewTypeableFromType(resource.Type, resource.Name),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
objects = append(objects, resourceObjects...)
|
||||
}
|
||||
}
|
||||
|
||||
return objects, nil
|
||||
}
|
||||
|
||||
func (provider *provider) Patch(ctx context.Context, orgID valuer.UUID, role *roletypes.Role) error {
|
||||
_, err := provider.licensing.GetActive(ctx, orgID)
|
||||
if err != nil {
|
||||
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
|
||||
}
|
||||
|
||||
return provider.store.Update(ctx, orgID, roletypes.NewStorableRoleFromRole(role))
|
||||
}
|
||||
|
||||
func (provider *provider) PatchObjects(ctx context.Context, orgID valuer.UUID, name string, relation authtypes.Relation, additions, deletions []*authtypes.Object) error {
|
||||
_, err := provider.licensing.GetActive(ctx, orgID)
|
||||
if err != nil {
|
||||
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
|
||||
}
|
||||
|
||||
additionTuples, err := roletypes.GetAdditionTuples(name, orgID, relation, additions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deletionTuples, err := roletypes.GetDeletionTuples(name, orgID, relation, deletions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = provider.Write(ctx, additionTuples, deletionTuples)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (provider *provider) Delete(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error {
|
||||
_, err := provider.licensing.GetActive(ctx, orgID)
|
||||
if err != nil {
|
||||
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
|
||||
}
|
||||
|
||||
storableRole, err := provider.store.Get(ctx, orgID, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
role := roletypes.NewRoleFromStorableRole(storableRole)
|
||||
err = role.CanEditDelete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return provider.store.Delete(ctx, orgID, id)
|
||||
}
|
||||
|
||||
func (provider *provider) MustGetTypeables() []authtypes.Typeable {
|
||||
return []authtypes.Typeable{authtypes.TypeableRole, roletypes.TypeableResourcesRoles}
|
||||
}
|
||||
|
||||
func (provider *provider) getManagedRoleGrantTuples(orgID valuer.UUID, userID valuer.UUID) ([]*openfgav1.TupleKey, error) {
|
||||
tuples := []*openfgav1.TupleKey{}
|
||||
|
||||
// Grant the admin role to the user
|
||||
adminSubject := authtypes.MustNewSubject(authtypes.TypeableUser, userID.String(), orgID, nil)
|
||||
adminTuple, err := authtypes.TypeableRole.Tuples(
|
||||
adminSubject,
|
||||
authtypes.RelationAssignee,
|
||||
[]authtypes.Selector{
|
||||
authtypes.MustNewSelector(authtypes.TypeRole, roletypes.SigNozAdminRoleName),
|
||||
},
|
||||
orgID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tuples = append(tuples, adminTuple...)
|
||||
|
||||
// Grant the admin role to the anonymous user
|
||||
anonymousSubject := authtypes.MustNewSubject(authtypes.TypeableAnonymous, authtypes.AnonymousUser.String(), orgID, nil)
|
||||
anonymousTuple, err := authtypes.TypeableRole.Tuples(
|
||||
anonymousSubject,
|
||||
authtypes.RelationAssignee,
|
||||
[]authtypes.Selector{
|
||||
authtypes.MustNewSelector(authtypes.TypeRole, roletypes.SigNozAnonymousRoleName),
|
||||
},
|
||||
orgID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tuples = append(tuples, anonymousTuple...)
|
||||
|
||||
return tuples, nil
|
||||
}
|
||||
|
||||
func (provider *provider) getManagedRoleTransactionTuples(orgID valuer.UUID) ([]*openfgav1.TupleKey, error) {
|
||||
transactionsByRole := make(map[string][]*authtypes.Transaction)
|
||||
for _, register := range provider.registry {
|
||||
for roleName, txns := range register.MustGetManagedRoleTransactions() {
|
||||
transactionsByRole[roleName] = append(transactionsByRole[roleName], txns...)
|
||||
}
|
||||
}
|
||||
|
||||
tuples := make([]*openfgav1.TupleKey, 0)
|
||||
for roleName, transactions := range transactionsByRole {
|
||||
for _, txn := range transactions {
|
||||
typeable := authtypes.MustNewTypeableFromType(txn.Object.Resource.Type, txn.Object.Resource.Name)
|
||||
txnTuples, err := typeable.Tuples(
|
||||
authtypes.MustNewSubject(
|
||||
authtypes.TypeableRole,
|
||||
roleName,
|
||||
orgID,
|
||||
&authtypes.RelationAssignee,
|
||||
),
|
||||
txn.Relation,
|
||||
[]authtypes.Selector{txn.Object.Selector},
|
||||
orgID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tuples = append(tuples, txnTuples...)
|
||||
}
|
||||
}
|
||||
|
||||
return tuples, nil
|
||||
}
|
||||
|
||||
83
ee/authz/openfgaserver/server.go
Normal file
83
ee/authz/openfgaserver/server.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package openfgaserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/authz"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
openfgav1 "github.com/openfga/api/proto/openfga/v1"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
pkgAuthzService authz.AuthZ
|
||||
}
|
||||
|
||||
func NewOpenfgaServer(ctx context.Context, pkgAuthzService authz.AuthZ) (*Server, error) {
|
||||
|
||||
return &Server{
|
||||
pkgAuthzService: pkgAuthzService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (server *Server) Start(ctx context.Context) error {
|
||||
return server.pkgAuthzService.Start(ctx)
|
||||
}
|
||||
|
||||
func (server *Server) Stop(ctx context.Context) error {
|
||||
return server.pkgAuthzService.Stop(ctx)
|
||||
}
|
||||
|
||||
func (server *Server) Check(ctx context.Context, tuple *openfgav1.TupleKey) error {
|
||||
return server.pkgAuthzService.Check(ctx, tuple)
|
||||
}
|
||||
|
||||
func (server *Server) CheckWithTupleCreation(ctx context.Context, claims authtypes.Claims, orgID valuer.UUID, relation authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector, _ []authtypes.Selector) error {
|
||||
subject, err := authtypes.NewSubject(authtypes.TypeableUser, claims.UserID, orgID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tuples, err := typeable.Tuples(subject, relation, selectors, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = server.BatchCheck(ctx, tuples)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *Server) CheckWithTupleCreationWithoutClaims(ctx context.Context, orgID valuer.UUID, relation authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector, _ []authtypes.Selector) error {
|
||||
subject, err := authtypes.NewSubject(authtypes.TypeableAnonymous, authtypes.AnonymousUser.String(), orgID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tuples, err := typeable.Tuples(subject, relation, selectors, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = server.BatchCheck(ctx, tuples)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *Server) BatchCheck(ctx context.Context, tuples []*openfgav1.TupleKey) error {
|
||||
return server.pkgAuthzService.BatchCheck(ctx, tuples)
|
||||
}
|
||||
|
||||
func (server *Server) ListObjects(ctx context.Context, subject string, relation authtypes.Relation, typeable authtypes.Typeable) ([]*authtypes.Object, error) {
|
||||
return server.pkgAuthzService.ListObjects(ctx, subject, relation, typeable)
|
||||
}
|
||||
|
||||
func (server *Server) Write(ctx context.Context, additions []*openfgav1.TupleKey, deletions []*openfgav1.TupleKey) error {
|
||||
return server.pkgAuthzService.Write(ctx, additions, deletions)
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/modules/dashboard"
|
||||
pkgimpldashboard "github.com/SigNoz/signoz/pkg/modules/dashboard/impldashboard"
|
||||
"github.com/SigNoz/signoz/pkg/modules/organization"
|
||||
"github.com/SigNoz/signoz/pkg/modules/role"
|
||||
"github.com/SigNoz/signoz/pkg/querier"
|
||||
"github.com/SigNoz/signoz/pkg/queryparser"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
@@ -26,12 +25,11 @@ type module struct {
|
||||
pkgDashboardModule dashboard.Module
|
||||
store dashboardtypes.Store
|
||||
settings factory.ScopedProviderSettings
|
||||
role role.Module
|
||||
querier querier.Querier
|
||||
licensing licensing.Licensing
|
||||
}
|
||||
|
||||
func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, role role.Module, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing) dashboard.Module {
|
||||
func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing) dashboard.Module {
|
||||
scopedProviderSettings := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/ee/modules/dashboard/impldashboard")
|
||||
pkgDashboardModule := pkgimpldashboard.NewModule(store, settings, analytics, orgGetter, queryParser)
|
||||
|
||||
@@ -39,7 +37,6 @@ func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, an
|
||||
pkgDashboardModule: pkgDashboardModule,
|
||||
store: store,
|
||||
settings: scopedProviderSettings,
|
||||
role: role,
|
||||
querier: querier,
|
||||
licensing: licensing,
|
||||
}
|
||||
@@ -59,29 +56,6 @@ func (module *module) CreatePublic(ctx context.Context, orgID valuer.UUID, publi
|
||||
return errors.Newf(errors.TypeAlreadyExists, dashboardtypes.ErrCodePublicDashboardAlreadyExists, "dashboard with id %s is already public", storablePublicDashboard.DashboardID)
|
||||
}
|
||||
|
||||
role, err := module.role.GetOrCreate(ctx, roletypes.NewRole(roletypes.AnonymousUserRoleName, roletypes.AnonymousUserRoleDescription, roletypes.RoleTypeManaged.StringValue(), orgID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = module.role.Assign(ctx, role.ID, orgID, authtypes.MustNewSubject(authtypes.TypeableAnonymous, authtypes.AnonymousUser.StringValue(), orgID, nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
additionObject := authtypes.MustNewObject(
|
||||
authtypes.Resource{
|
||||
Name: dashboardtypes.TypeableMetaResourcePublicDashboard.Name(),
|
||||
Type: authtypes.TypeMetaResource,
|
||||
},
|
||||
authtypes.MustNewSelector(authtypes.TypeMetaResource, publicDashboard.ID.String()),
|
||||
)
|
||||
|
||||
err = module.role.PatchObjects(ctx, orgID, role.ID, authtypes.RelationRead, []*authtypes.Object{additionObject}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = module.store.CreatePublic(ctx, dashboardtypes.NewStorablePublicDashboardFromPublicDashboard(publicDashboard))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -126,6 +100,7 @@ func (module *module) GetPublicDashboardSelectorsAndOrg(ctx context.Context, id
|
||||
|
||||
return []authtypes.Selector{
|
||||
authtypes.MustNewSelector(authtypes.TypeMetaResource, id.StringValue()),
|
||||
authtypes.MustNewSelector(authtypes.TypeMetaResource, authtypes.WildCardSelectorString),
|
||||
}, storableDashboard.OrgID, nil
|
||||
}
|
||||
|
||||
@@ -188,29 +163,6 @@ func (module *module) DeletePublic(ctx context.Context, orgID valuer.UUID, dashb
|
||||
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
|
||||
}
|
||||
|
||||
publicDashboard, err := module.GetPublic(ctx, orgID, dashboardID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
role, err := module.role.GetOrCreate(ctx, roletypes.NewRole(roletypes.AnonymousUserRoleName, roletypes.AnonymousUserRoleDescription, roletypes.RoleTypeManaged.StringValue(), orgID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deletionObject := authtypes.MustNewObject(
|
||||
authtypes.Resource{
|
||||
Name: dashboardtypes.TypeableMetaResourcePublicDashboard.Name(),
|
||||
Type: authtypes.TypeMetaResource,
|
||||
},
|
||||
authtypes.MustNewSelector(authtypes.TypeMetaResource, publicDashboard.ID.String()),
|
||||
)
|
||||
|
||||
err = module.role.PatchObjects(ctx, orgID, role.ID, authtypes.RelationRead, nil, []*authtypes.Object{deletionObject})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = module.store.DeletePublic(ctx, dashboardID.StringValue())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -248,10 +200,6 @@ func (module *module) GetByMetricNames(ctx context.Context, orgID valuer.UUID, m
|
||||
return module.pkgDashboardModule.GetByMetricNames(ctx, orgID, metricNames)
|
||||
}
|
||||
|
||||
func (module *module) MustGetTypeables() []authtypes.Typeable {
|
||||
return module.pkgDashboardModule.MustGetTypeables()
|
||||
}
|
||||
|
||||
func (module *module) List(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error) {
|
||||
return module.pkgDashboardModule.List(ctx, orgID)
|
||||
}
|
||||
@@ -264,34 +212,27 @@ func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valu
|
||||
return module.pkgDashboardModule.LockUnlock(ctx, orgID, id, updatedBy, role, lock)
|
||||
}
|
||||
|
||||
func (module *module) deletePublic(ctx context.Context, orgID valuer.UUID, dashboardID valuer.UUID) error {
|
||||
publicDashboard, err := module.store.GetPublic(ctx, dashboardID.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
role, err := module.role.GetOrCreate(ctx, roletypes.NewRole(roletypes.AnonymousUserRoleName, roletypes.AnonymousUserRoleDescription, roletypes.RoleTypeManaged.StringValue(), orgID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deletionObject := authtypes.MustNewObject(
|
||||
authtypes.Resource{
|
||||
Name: dashboardtypes.TypeableMetaResourcePublicDashboard.Name(),
|
||||
Type: authtypes.TypeMetaResource,
|
||||
},
|
||||
authtypes.MustNewSelector(authtypes.TypeMetaResource, publicDashboard.ID.String()),
|
||||
)
|
||||
|
||||
err = module.role.PatchObjects(ctx, orgID, role.ID, authtypes.RelationRead, nil, []*authtypes.Object{deletionObject})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = module.store.DeletePublic(ctx, dashboardID.StringValue())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
func (module *module) MustGetTypeables() []authtypes.Typeable {
|
||||
return module.pkgDashboardModule.MustGetTypeables()
|
||||
}
|
||||
|
||||
func (module *module) MustGetManagedRoleTransactions() map[string][]*authtypes.Transaction {
|
||||
return map[string][]*authtypes.Transaction{
|
||||
roletypes.SigNozAnonymousRoleName: {
|
||||
{
|
||||
Relation: authtypes.RelationRead,
|
||||
Object: *authtypes.MustNewObject(
|
||||
authtypes.Resource{
|
||||
Type: authtypes.TypeMetaResource,
|
||||
Name: dashboardtypes.TypeableMetaResourcePublicDashboard.Name(),
|
||||
},
|
||||
authtypes.MustNewSelector(authtypes.TypeMetaResource, "*"),
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (module *module) deletePublic(ctx context.Context, _ valuer.UUID, dashboardID valuer.UUID) error {
|
||||
return module.store.DeletePublic(ctx, dashboardID.StringValue())
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ type GetAnomaliesResponse struct {
|
||||
//
|
||||
// ^ ^
|
||||
// | |
|
||||
// (rounded value for past peiod) + (seasonal growth)
|
||||
// (rounded value for past period) + (seasonal growth)
|
||||
//
|
||||
// score = abs(value - prediction) / stddev (current_season_query)
|
||||
type anomalyQueryParams struct {
|
||||
@@ -74,12 +74,12 @@ type anomalyQueryParams struct {
|
||||
// : For daily seasonality, this is the query range params for the (now-2d-5m, now-1d)
|
||||
// : For hourly seasonality, this is the query range params for the (now-2h-5m, now-1h)
|
||||
PastSeasonQuery *v3.QueryRangeParamsV3
|
||||
// Past2SeasonQuery is the query range params for past 2 seasonal period to the current season
|
||||
// Past2SeasonQuery is the query range params for past 2 seasonal periods to the current season
|
||||
// Example: For weekly seasonality, this is the query range params for the (now-3w-5m, now-2w)
|
||||
// : For daily seasonality, this is the query range params for the (now-3d-5m, now-2d)
|
||||
// : For hourly seasonality, this is the query range params for the (now-3h-5m, now-2h)
|
||||
Past2SeasonQuery *v3.QueryRangeParamsV3
|
||||
// Past3SeasonQuery is the query range params for past 3 seasonal period to the current season
|
||||
// Past3SeasonQuery is the query range params for past 3 seasonal periods to the current season
|
||||
// Example: For weekly seasonality, this is the query range params for the (now-4w-5m, now-3w)
|
||||
// : For daily seasonality, this is the query range params for the (now-4d-5m, now-3d)
|
||||
// : For hourly seasonality, this is the query range params for the (now-4h-5m, now-3h)
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/SigNoz/signoz/ee/query-service/integrations/gateway"
|
||||
"github.com/SigNoz/signoz/ee/query-service/usage"
|
||||
"github.com/SigNoz/signoz/pkg/alertmanager"
|
||||
"github.com/SigNoz/signoz/pkg/apis/fields"
|
||||
"github.com/SigNoz/signoz/pkg/global"
|
||||
"github.com/SigNoz/signoz/pkg/http/middleware"
|
||||
querierAPI "github.com/SigNoz/signoz/pkg/querier"
|
||||
@@ -56,7 +55,6 @@ func NewAPIHandler(opts APIHandlerOptions, signoz *signoz.SigNoz) (*APIHandler,
|
||||
FluxInterval: opts.FluxInterval,
|
||||
AlertmanagerAPI: alertmanager.NewAPI(signoz.Alertmanager),
|
||||
LicensingAPI: httplicensing.NewLicensingAPI(signoz.Licensing),
|
||||
FieldsAPI: fields.NewAPI(signoz.Instrumentation.ToProviderSettings(), signoz.TelemetryStore),
|
||||
Signoz: signoz,
|
||||
QuerierAPI: querierAPI.NewAPI(signoz.Instrumentation.ToProviderSettings(), signoz.Querier, signoz.Analytics),
|
||||
QueryParserAPI: queryparser.NewAPI(signoz.Instrumentation.ToProviderSettings(), signoz.QueryParser),
|
||||
|
||||
@@ -237,7 +237,6 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler, web web.Web) (*h
|
||||
apiHandler.RegisterLogsRoutes(r, am)
|
||||
apiHandler.RegisterIntegrationRoutes(r, am)
|
||||
apiHandler.RegisterCloudIntegrationsRoutes(r, am)
|
||||
apiHandler.RegisterFieldsRoutes(r, am)
|
||||
apiHandler.RegisterQueryRangeV3Routes(r, am)
|
||||
apiHandler.RegisterInfraMetricsRoutes(r, am)
|
||||
apiHandler.RegisterQueryRangeV4Routes(r, am)
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/query-service/common"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
"github.com/SigNoz/signoz/pkg/transition"
|
||||
ruletypes "github.com/SigNoz/signoz/pkg/types/ruletypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/ruletypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
|
||||
querierV2 "github.com/SigNoz/signoz/pkg/query-service/app/querier/v2"
|
||||
@@ -63,6 +63,8 @@ type AnomalyRule struct {
|
||||
seasonality anomaly.Seasonality
|
||||
}
|
||||
|
||||
var _ baserules.Rule = (*AnomalyRule)(nil)
|
||||
|
||||
func NewAnomalyRule(
|
||||
id string,
|
||||
orgID valuer.UUID,
|
||||
@@ -234,6 +236,11 @@ func (r *AnomalyRule) buildAndRunQuery(ctx context.Context, orgID valuer.UUID, t
|
||||
}
|
||||
}
|
||||
|
||||
hasData := len(queryResult.AnomalyScores) > 0
|
||||
if missingDataAlert := r.HandleMissingDataAlert(ctx, ts, hasData); missingDataAlert != nil {
|
||||
return ruletypes.Vector{*missingDataAlert}, nil
|
||||
}
|
||||
|
||||
var resultVector ruletypes.Vector
|
||||
|
||||
scoresJSON, _ := json.Marshal(queryResult.AnomalyScores)
|
||||
@@ -285,6 +292,11 @@ func (r *AnomalyRule) buildAndRunQueryV5(ctx context.Context, orgID valuer.UUID,
|
||||
|
||||
queryResult := transition.ConvertV5TimeSeriesDataToV4Result(qbResult)
|
||||
|
||||
hasData := len(queryResult.AnomalyScores) > 0
|
||||
if missingDataAlert := r.HandleMissingDataAlert(ctx, ts, hasData); missingDataAlert != nil {
|
||||
return ruletypes.Vector{*missingDataAlert}, nil
|
||||
}
|
||||
|
||||
var resultVector ruletypes.Vector
|
||||
|
||||
scoresJSON, _ := json.Marshal(queryResult.AnomalyScores)
|
||||
@@ -480,7 +492,7 @@ func (r *AnomalyRule) Eval(ctx context.Context, ts time.Time) (int, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
if a.State == model.StatePending && ts.Sub(a.ActiveAt) >= r.HoldDuration() {
|
||||
if a.State == model.StatePending && ts.Sub(a.ActiveAt) >= r.HoldDuration().Duration() {
|
||||
a.State = model.StateFiring
|
||||
a.FiredAt = ts
|
||||
state := model.StateFiring
|
||||
@@ -543,7 +555,7 @@ func (r *AnomalyRule) String() string {
|
||||
ar := ruletypes.PostableRule{
|
||||
AlertName: r.Name(),
|
||||
RuleCondition: r.Condition(),
|
||||
EvalWindow: ruletypes.Duration(r.EvalWindow()),
|
||||
EvalWindow: r.EvalWindow(),
|
||||
Labels: r.Labels().Map(),
|
||||
Annotations: r.Annotations().Map(),
|
||||
PreferredChannels: r.PreferredChannels(),
|
||||
|
||||
268
ee/query-service/rules/anomaly_test.go
Normal file
268
ee/query-service/rules/anomaly_test.go
Normal file
@@ -0,0 +1,268 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/query-service/anomaly"
|
||||
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/app/clickhouseReader"
|
||||
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrystore"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrystore/telemetrystoretest"
|
||||
"github.com/SigNoz/signoz/pkg/types/ruletypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
)
|
||||
|
||||
// mockAnomalyProvider is a mock implementation of anomaly.Provider for testing.
|
||||
// We need this because the anomaly provider makes 6 different queries for various
|
||||
// time periods (current, past period, current season, past season, past 2 seasons,
|
||||
// past 3 seasons), making it cumbersome to create mock data.
|
||||
type mockAnomalyProvider struct {
|
||||
responses []*anomaly.GetAnomaliesResponse
|
||||
callCount int
|
||||
}
|
||||
|
||||
func (m *mockAnomalyProvider) GetAnomalies(ctx context.Context, orgID valuer.UUID, req *anomaly.GetAnomaliesRequest) (*anomaly.GetAnomaliesResponse, error) {
|
||||
if m.callCount >= len(m.responses) {
|
||||
return &anomaly.GetAnomaliesResponse{Results: []*v3.Result{}}, nil
|
||||
}
|
||||
resp := m.responses[m.callCount]
|
||||
m.callCount++
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func TestAnomalyRule_NoData_AlertOnAbsent(t *testing.T) {
|
||||
// Test basic AlertOnAbsent functionality (without AbsentFor grace period)
|
||||
|
||||
baseTime := time.Unix(1700000000, 0)
|
||||
evalWindow := valuer.MustParseTextDuration("5m")
|
||||
evalTime := baseTime.Add(5 * time.Minute)
|
||||
|
||||
target := 500.0
|
||||
|
||||
postableRule := ruletypes.PostableRule{
|
||||
AlertName: "Test anomaly no data",
|
||||
AlertType: ruletypes.AlertTypeMetric,
|
||||
RuleType: RuleTypeAnomaly,
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
|
||||
EvalWindow: evalWindow,
|
||||
Frequency: valuer.MustParseTextDuration("1m"),
|
||||
}},
|
||||
RuleCondition: &ruletypes.RuleCondition{
|
||||
CompareOp: ruletypes.ValueIsAbove,
|
||||
MatchType: ruletypes.AtleastOnce,
|
||||
Target: &target,
|
||||
CompositeQuery: &v3.CompositeQuery{
|
||||
QueryType: v3.QueryTypeBuilder,
|
||||
BuilderQueries: map[string]*v3.BuilderQuery{
|
||||
"A": {
|
||||
QueryName: "A",
|
||||
Expression: "A",
|
||||
DataSource: v3.DataSourceMetrics,
|
||||
Temporality: v3.Unspecified,
|
||||
},
|
||||
},
|
||||
},
|
||||
SelectedQuery: "A",
|
||||
Seasonality: "daily",
|
||||
Thresholds: &ruletypes.RuleThresholdData{
|
||||
Kind: ruletypes.BasicThresholdKind,
|
||||
Spec: ruletypes.BasicRuleThresholds{{
|
||||
Name: "Test anomaly no data",
|
||||
TargetValue: &target,
|
||||
MatchType: ruletypes.AtleastOnce,
|
||||
CompareOp: ruletypes.ValueIsAbove,
|
||||
}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
responseNoData := &anomaly.GetAnomaliesResponse{
|
||||
Results: []*v3.Result{
|
||||
{
|
||||
QueryName: "A",
|
||||
AnomalyScores: []*v3.Series{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
description string
|
||||
alertOnAbsent bool
|
||||
expectAlerts int
|
||||
}{
|
||||
{
|
||||
description: "AlertOnAbsent=false",
|
||||
alertOnAbsent: false,
|
||||
expectAlerts: 0,
|
||||
},
|
||||
{
|
||||
description: "AlertOnAbsent=true",
|
||||
alertOnAbsent: true,
|
||||
expectAlerts: 1,
|
||||
},
|
||||
}
|
||||
|
||||
logger := instrumentationtest.New().Logger()
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.description, func(t *testing.T) {
|
||||
postableRule.RuleCondition.AlertOnAbsent = c.alertOnAbsent
|
||||
|
||||
telemetryStore := telemetrystoretest.New(telemetrystore.Config{}, nil)
|
||||
options := clickhouseReader.NewOptions("primaryNamespace")
|
||||
reader := clickhouseReader.NewReader(nil, telemetryStore, nil, "", time.Second, nil, nil, options)
|
||||
|
||||
rule, err := NewAnomalyRule(
|
||||
"test-anomaly-rule",
|
||||
valuer.GenerateUUID(),
|
||||
&postableRule,
|
||||
reader,
|
||||
nil,
|
||||
logger,
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
rule.provider = &mockAnomalyProvider{
|
||||
responses: []*anomaly.GetAnomaliesResponse{responseNoData},
|
||||
}
|
||||
|
||||
alertsFound, err := rule.Eval(context.Background(), evalTime)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, c.expectAlerts, alertsFound)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnomalyRule_NoData_AbsentFor(t *testing.T) {
|
||||
// Test missing data alert with AbsentFor grace period
|
||||
// 1. Call Eval with data at time t1, to populate lastTimestampWithDatapoints
|
||||
// 2. Call Eval without data at time t2
|
||||
// 3. Alert fires only if t2 - t1 > AbsentFor
|
||||
|
||||
baseTime := time.Unix(1700000000, 0)
|
||||
evalWindow := valuer.MustParseTextDuration("5m")
|
||||
|
||||
// Set target higher than test data so regular threshold alerts don't fire
|
||||
target := 500.0
|
||||
|
||||
postableRule := ruletypes.PostableRule{
|
||||
AlertName: "Test anomaly no data with AbsentFor",
|
||||
AlertType: ruletypes.AlertTypeMetric,
|
||||
RuleType: RuleTypeAnomaly,
|
||||
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
|
||||
EvalWindow: evalWindow,
|
||||
Frequency: valuer.MustParseTextDuration("1m"),
|
||||
}},
|
||||
RuleCondition: &ruletypes.RuleCondition{
|
||||
CompareOp: ruletypes.ValueIsAbove,
|
||||
MatchType: ruletypes.AtleastOnce,
|
||||
AlertOnAbsent: true,
|
||||
Target: &target,
|
||||
CompositeQuery: &v3.CompositeQuery{
|
||||
QueryType: v3.QueryTypeBuilder,
|
||||
BuilderQueries: map[string]*v3.BuilderQuery{
|
||||
"A": {
|
||||
QueryName: "A",
|
||||
Expression: "A",
|
||||
DataSource: v3.DataSourceMetrics,
|
||||
Temporality: v3.Unspecified,
|
||||
},
|
||||
},
|
||||
},
|
||||
SelectedQuery: "A",
|
||||
Seasonality: "daily",
|
||||
Thresholds: &ruletypes.RuleThresholdData{
|
||||
Kind: ruletypes.BasicThresholdKind,
|
||||
Spec: ruletypes.BasicRuleThresholds{{
|
||||
Name: "Test anomaly no data with AbsentFor",
|
||||
TargetValue: &target,
|
||||
MatchType: ruletypes.AtleastOnce,
|
||||
CompareOp: ruletypes.ValueIsAbove,
|
||||
}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
responseNoData := &anomaly.GetAnomaliesResponse{
|
||||
Results: []*v3.Result{
|
||||
{
|
||||
QueryName: "A",
|
||||
AnomalyScores: []*v3.Series{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
description string
|
||||
absentFor uint64
|
||||
timeBetweenEvals time.Duration
|
||||
expectAlertOnEval2 int
|
||||
}{
|
||||
{
|
||||
description: "WithinGracePeriod",
|
||||
absentFor: 5,
|
||||
timeBetweenEvals: 4 * time.Minute,
|
||||
expectAlertOnEval2: 0,
|
||||
},
|
||||
{
|
||||
description: "AfterGracePeriod",
|
||||
absentFor: 5,
|
||||
timeBetweenEvals: 6 * time.Minute,
|
||||
expectAlertOnEval2: 1,
|
||||
},
|
||||
}
|
||||
|
||||
logger := instrumentationtest.New().Logger()
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.description, func(t *testing.T) {
|
||||
postableRule.RuleCondition.AbsentFor = c.absentFor
|
||||
|
||||
t1 := baseTime.Add(5 * time.Minute)
|
||||
t2 := t1.Add(c.timeBetweenEvals)
|
||||
|
||||
responseWithData := &anomaly.GetAnomaliesResponse{
|
||||
Results: []*v3.Result{
|
||||
{
|
||||
QueryName: "A",
|
||||
AnomalyScores: []*v3.Series{
|
||||
{
|
||||
Labels: map[string]string{"test": "label"},
|
||||
Points: []v3.Point{
|
||||
{Timestamp: baseTime.UnixMilli(), Value: 1.0},
|
||||
{Timestamp: baseTime.Add(time.Minute).UnixMilli(), Value: 1.5},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
telemetryStore := telemetrystoretest.New(telemetrystore.Config{}, nil)
|
||||
options := clickhouseReader.NewOptions("primaryNamespace")
|
||||
reader := clickhouseReader.NewReader(nil, telemetryStore, nil, "", time.Second, nil, nil, options)
|
||||
|
||||
rule, err := NewAnomalyRule("test-anomaly-rule", valuer.GenerateUUID(), &postableRule, reader, nil, logger, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
rule.provider = &mockAnomalyProvider{
|
||||
responses: []*anomaly.GetAnomaliesResponse{responseWithData, responseNoData},
|
||||
}
|
||||
|
||||
alertsFound1, err := rule.Eval(context.Background(), t1)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, alertsFound1, "First eval with data should not alert")
|
||||
|
||||
alertsFound2, err := rule.Eval(context.Background(), t2)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, c.expectAlertOnEval2, alertsFound2)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
rules = append(rules, tr)
|
||||
|
||||
// create ch rule task for evaluation
|
||||
task = newTask(baserules.TaskTypeCh, opts.TaskName, time.Duration(evaluation.GetFrequency()), rules, opts.ManagerOpts, opts.NotifyFunc, opts.MaintenanceStore, opts.OrgID)
|
||||
task = newTask(baserules.TaskTypeCh, opts.TaskName, evaluation.GetFrequency().Duration(), rules, opts.ManagerOpts, opts.NotifyFunc, opts.MaintenanceStore, opts.OrgID)
|
||||
|
||||
} else if opts.Rule.RuleType == ruletypes.RuleTypeProm {
|
||||
|
||||
@@ -72,7 +72,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
rules = append(rules, pr)
|
||||
|
||||
// create promql rule task for evaluation
|
||||
task = newTask(baserules.TaskTypeProm, opts.TaskName, time.Duration(evaluation.GetFrequency()), rules, opts.ManagerOpts, opts.NotifyFunc, opts.MaintenanceStore, opts.OrgID)
|
||||
task = newTask(baserules.TaskTypeProm, opts.TaskName, evaluation.GetFrequency().Duration(), rules, opts.ManagerOpts, opts.NotifyFunc, opts.MaintenanceStore, opts.OrgID)
|
||||
|
||||
} else if opts.Rule.RuleType == ruletypes.RuleTypeAnomaly {
|
||||
// create anomaly rule
|
||||
@@ -96,7 +96,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
rules = append(rules, ar)
|
||||
|
||||
// create anomaly rule task for evaluation
|
||||
task = newTask(baserules.TaskTypeCh, opts.TaskName, time.Duration(evaluation.GetFrequency()), rules, opts.ManagerOpts, opts.NotifyFunc, opts.MaintenanceStore, opts.OrgID)
|
||||
task = newTask(baserules.TaskTypeCh, opts.TaskName, evaluation.GetFrequency().Duration(), rules, opts.ManagerOpts, opts.NotifyFunc, opts.MaintenanceStore, opts.OrgID)
|
||||
|
||||
} else {
|
||||
return nil, fmt.Errorf("unsupported rule type %s. Supported types: %s, %s", opts.Rule.RuleType, ruletypes.RuleTypeProm, ruletypes.RuleTypeThreshold)
|
||||
@@ -213,8 +213,7 @@ func TestNotification(opts baserules.PrepareTestRuleOptions) (int, *basemodel.Ap
|
||||
return alertsFound, nil
|
||||
}
|
||||
|
||||
// newTask returns an appropriate group for
|
||||
// rule type
|
||||
// newTask returns an appropriate group for the rule type
|
||||
func newTask(taskType baserules.TaskType, name string, frequency time.Duration, rules []baserules.Rule, opts *baserules.ManagerOptions, notify baserules.NotifyFunc, maintenanceStore ruletypes.MaintenanceStore, orgID valuer.UUID) baserules.Task {
|
||||
if taskType == baserules.TaskTypeCh {
|
||||
return baserules.NewRuleTask(name, "", frequency, rules, opts, notify, maintenanceStore, orgID)
|
||||
|
||||
@@ -61,10 +61,19 @@ module.exports = {
|
||||
curly: 'error', // Requires curly braces for all control statements
|
||||
eqeqeq: ['error', 'always', { null: 'ignore' }], // Enforces === and !== (allows == null for null/undefined check)
|
||||
'no-console': ['error', { allow: ['warn', 'error'] }], // Warns on console.log, allows console.warn/error
|
||||
// TODO: Change this to error in May 2026
|
||||
'max-params': ['warn', 3], // a function can have max 3 params after which it should become an object
|
||||
|
||||
// TypeScript rules
|
||||
'@typescript-eslint/explicit-function-return-type': 'error', // Requires explicit return types on functions
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
// Disallows unused variables/args
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^_', // Allows unused args prefixed with _ (e.g., _unusedParam)
|
||||
varsIgnorePattern: '^_', // Allows unused vars prefixed with _ (e.g., _unusedVar)
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/no-explicit-any': 'warn', // Warns when using 'any' type (consider upgrading to error)
|
||||
// TODO: Change to 'error' after fixing ~80 empty function placeholders in providers/contexts
|
||||
'@typescript-eslint/no-empty-function': 'off', // Disallows empty function bodies
|
||||
@@ -109,23 +118,22 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
'import/no-extraneous-dependencies': ['error', { devDependencies: true }], // Prevents importing packages not in package.json
|
||||
// 'import/no-cycle': 'warn', // TODO: Enable later to detect circular dependencies
|
||||
'import/no-cycle': 'warn', // Warns about circular dependencies
|
||||
|
||||
// TODO: Enable in separate PR with auto fixes
|
||||
// // Import sorting rules
|
||||
// 'simple-import-sort/imports': [
|
||||
// 'error',
|
||||
// {
|
||||
// groups: [
|
||||
// ['^react', '^@?\\w'], // React first, then external packages
|
||||
// ['^@/'], // Absolute imports with @ alias
|
||||
// ['^\\u0000'], // Side effect imports (import './file')
|
||||
// ['^\\.'], // Relative imports
|
||||
// ['^.+\\.s?css$'], // Style imports
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// 'simple-import-sort/exports': 'error', // Auto-sorts exports
|
||||
// Import sorting rules
|
||||
'simple-import-sort/imports': [
|
||||
'error',
|
||||
{
|
||||
groups: [
|
||||
['^react', '^@?\\w'], // React first, then external packages
|
||||
['^@/'], // Absolute imports with @ alias
|
||||
['^\\u0000'], // Side effect imports (import './file')
|
||||
['^\\.'], // Relative imports
|
||||
['^.+\\.s?css$'], // Style imports
|
||||
],
|
||||
},
|
||||
],
|
||||
'simple-import-sort/exports': 'error', // Auto-sorts exports
|
||||
|
||||
// Prettier - code formatting
|
||||
'prettier/prettier': [
|
||||
@@ -140,6 +148,19 @@ module.exports = {
|
||||
'sonarjs/no-duplicate-string': 'off', // Disabled - can be noisy (enable periodically to check)
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
'**/*.test.{js,jsx,ts,tsx}',
|
||||
'**/*.spec.{js,jsx,ts,tsx}',
|
||||
'**/__tests__/**/*.{js,jsx,ts,tsx}',
|
||||
],
|
||||
rules: {
|
||||
// Tests often have intentional duplication and complexity - disable SonarJS rules
|
||||
'sonarjs/cognitive-complexity': 'off', // Tests can be complex
|
||||
'sonarjs/no-identical-functions': 'off', // Similar test patterns are OK
|
||||
'sonarjs/no-small-switch': 'off', // Small switches are OK in tests
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['src/api/generated/**/*.ts'],
|
||||
rules: {
|
||||
@@ -147,7 +168,6 @@ module.exports = {
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'no-nested-ternary': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'warn',
|
||||
'sonarjs/no-duplicate-string': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
Embrace the spirit of collaboration and contribute to the success of our open-source project by adhering to these frontend development guidelines with precision and passion.
|
||||
|
||||
### Export Style
|
||||
|
||||
- **React components** (`src/components/`, `src/container/`, `src/pages/`): Prefer **default exports** for the main component in each file
|
||||
- **Utilities, hooks, APIs, types, constants** (`src/utils/`, `src/hooks/`, `src/api/`, `src/lib/`, `src/types/`, `src/constants/`): Prefer **named exports** for better tree-shaking and explicit imports
|
||||
|
||||
### React and Components
|
||||
|
||||
- Strive to create small and modular components, ensuring they are divided into individual pieces for improved maintainability and reusability.
|
||||
|
||||
@@ -12,6 +12,8 @@ export interface MockUPlotInstance {
|
||||
export interface MockUPlotPaths {
|
||||
spline: jest.Mock;
|
||||
bars: jest.Mock;
|
||||
linear: jest.Mock;
|
||||
stepped: jest.Mock;
|
||||
}
|
||||
|
||||
// Create mock instance methods
|
||||
@@ -23,10 +25,23 @@ const createMockUPlotInstance = (): MockUPlotInstance => ({
|
||||
setSeries: jest.fn(),
|
||||
});
|
||||
|
||||
// Create mock paths
|
||||
const mockPaths: MockUPlotPaths = {
|
||||
spline: jest.fn(),
|
||||
bars: jest.fn(),
|
||||
// Path builder: (self, seriesIdx, idx0, idx1) => paths or null
|
||||
const createMockPathBuilder = (name: string): jest.Mock =>
|
||||
jest.fn(() => ({
|
||||
name, // To test if the correct pathBuilder is used
|
||||
stroke: jest.fn(),
|
||||
fill: jest.fn(),
|
||||
clip: jest.fn(),
|
||||
}));
|
||||
|
||||
// Create mock paths - linear, spline, stepped needed by UPlotSeriesBuilder.getPathBuilder
|
||||
const mockPaths = {
|
||||
spline: jest.fn(() => createMockPathBuilder('spline')),
|
||||
bars: jest.fn(() => createMockPathBuilder('bars')),
|
||||
linear: jest.fn(() => createMockPathBuilder('linear')),
|
||||
stepped: jest.fn((opts?: { align?: number }) =>
|
||||
createMockPathBuilder(`stepped-(${opts?.align ?? 0})`),
|
||||
),
|
||||
};
|
||||
|
||||
// Mock static methods
|
||||
|
||||
@@ -17,6 +17,8 @@ const config: Config.InitialOptions = {
|
||||
'^hooks/useSafeNavigate$': USE_SAFE_NAVIGATE_MOCK_PATH,
|
||||
'^src/hooks/useSafeNavigate$': USE_SAFE_NAVIGATE_MOCK_PATH,
|
||||
'^.*/useSafeNavigate$': USE_SAFE_NAVIGATE_MOCK_PATH,
|
||||
'^@signozhq/icons$':
|
||||
'<rootDir>/node_modules/@signozhq/icons/dist/index.esm.js',
|
||||
},
|
||||
globals: {
|
||||
extensionsToTreatAsEsm: ['.ts'],
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"commitlint": "commitlint --edit $1",
|
||||
"test": "jest",
|
||||
"test:changedsince": "jest --changedSince=main --coverage --silent",
|
||||
"generate:api": "orval --config ./orval.config.ts && sh scripts/post-types-generation.sh && prettier --write src/api/generated && (eslint --fix src/api/generated || true)"
|
||||
"generate:api": "orval --config ./orval.config.ts && sh scripts/post-types-generation.sh"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.15.0"
|
||||
@@ -51,7 +51,8 @@
|
||||
"@signozhq/checkbox": "0.0.2",
|
||||
"@signozhq/combobox": "0.0.2",
|
||||
"@signozhq/command": "0.0.0",
|
||||
"@signozhq/design-tokens": "1.1.4",
|
||||
"@signozhq/design-tokens": "2.1.1",
|
||||
"@signozhq/icons": "0.1.0",
|
||||
"@signozhq/input": "0.0.2",
|
||||
"@signozhq/popover": "0.0.0",
|
||||
"@signozhq/resizable": "0.0.0",
|
||||
@@ -105,6 +106,7 @@
|
||||
"i18next": "^21.6.12",
|
||||
"i18next-browser-languagedetector": "^6.1.3",
|
||||
"i18next-http-backend": "^1.3.2",
|
||||
"immer": "11.1.3",
|
||||
"jest": "^27.5.1",
|
||||
"js-base64": "^3.7.2",
|
||||
"less": "^4.1.2",
|
||||
|
||||
1
frontend/public/Logos/convex-logo.svg
Normal file
1
frontend/public/Logos/convex-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="184" height="188" fill="none" viewBox="0 0 184 188"><path fill="#f3b01c" d="M108.092 130.021c18.166-2.018 35.293-11.698 44.723-27.854-4.466 39.961-48.162 65.218-83.83 49.711-3.286-1.425-6.115-3.796-8.056-6.844-8.016-12.586-10.65-28.601-6.865-43.135 10.817 18.668 32.81 30.111 54.028 28.122"/><path fill="#8d2676" d="M53.401 90.174c-7.364 17.017-7.682 36.94 1.345 53.336-31.77-23.902-31.423-75.052-.388-98.715 2.87-2.187 6.282-3.485 9.86-3.683 14.713-.776 29.662 4.91 40.146 15.507-21.3.212-42.046 13.857-50.963 33.555"/><path fill="#ee342f" d="M114.637 61.855C103.89 46.87 87.069 36.668 68.639 36.358c35.625-16.17 79.446 10.047 84.217 48.807.444 3.598-.139 7.267-1.734 10.512-6.656 13.518-18.998 24.002-33.42 27.882 10.567-19.599 9.263-43.544-3.065-61.704"/></svg>
|
||||
|
After Width: | Height: | Size: 811 B |
3
frontend/public/Logos/google-adk.svg
Normal file
3
frontend/public/Logos/google-adk.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 11 KiB |
1
frontend/public/Logos/groq.svg
Normal file
1
frontend/public/Logos/groq.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Groq</title><path d="M12.036 2c-3.853-.035-7 3-7.036 6.781-.035 3.782 3.055 6.872 6.908 6.907h2.42v-2.566h-2.292c-2.407.028-4.38-1.866-4.408-4.23-.029-2.362 1.901-4.298 4.308-4.326h.1c2.407 0 4.358 1.915 4.365 4.278v6.305c0 2.342-1.944 4.25-4.323 4.279a4.375 4.375 0 01-3.033-1.252l-1.851 1.818A7 7 0 0012.029 22h.092c3.803-.056 6.858-3.083 6.879-6.816v-6.5C18.907 4.963 15.817 2 12.036 2z"></path></svg>
|
||||
|
After Width: | Height: | Size: 568 B |
3
frontend/public/Logos/langtrace.svg
Normal file
3
frontend/public/Logos/langtrace.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet">
|
||||
<image width="200" height="200" href="data:image/webp;base64,UklGRuINAABXRUJQVlA4WAoAAAAQAAAAxwAAxwAAQUxQSEMFAAABoLz+/6M4+7ogM2lSYJ6SJrj4L3h1+x5SBO+Snph+38I8vfiU9N6jsEdTPG16Ipue7Jree0QYnirID2f5HmxTfr/v7xoREwBc9nwVjaf0/bnzd599NiqVaaxUyqVnty/l9uupeFQDGqs9wzkDbTbO6P0qaQKDQ2NTJjrULGZHBgMkCS47Y6Lj2ZllGi3U2PeFKrq0WvghplAhvMtAlxvbIgSYuy5fQw7W8hvmii1yzERuskxYWEpyvIpcZfmkIqKQ/h45/DndKRptG0NOs21+kcxP/40cL6dDoujYWEHO/73VK4T+Igpwspd/czIoyIyfb8qaVyjMF2sUfnmWPEahPkl4eHUYhbubT91TKOCHvRxKmChkM84b3+8MBc3SPq7Mvo4Cv65ypPcjCr00wI1FDAXPFnFi1ETx6zzwnkASZr2uU68hES+pLvOfQzKeC7pKe4OEfKO5SJtAUk5orgm+QWK+8btEPYfkPKe6wnsJCXrN64YskvS4C3Qk6qjjFiFVzUUOG2BkQdbjKLWEhP0420G+60ja6z7npJG4vzsmzqjDEg7pMZG8ZrczHiKBp5zg2Y0kPuyxL4FEXmyb8pRKjxW7ViOZV9vkf0GnV3PsySChM7b0Iqn7bPBO0qrYYd1WJPZGy0J/U6sy36o0kvtXi/xlev2lWbMNCb7Nkk5GMRayIo0k1y1QPtPsvdJeEomebC9PtfG2woxq1Ug7GST7sTbmMrqZc1vbgIRf11qecvmWIjXK1cKtbEPS72pBMWhnqM1iSPxYsx+o912zAvUKTbQq9arBRsuQ/Msanabf6QYBRj8zUDeIEjhYNywDQ3VZGRirK8rAJACopgyYKkAfSmEPgC4HwwCn5SAHYMiB4dFQEr+KykI0LgvxlCykdFnQ98nC/pws5C7JwvnbsnD3mSw8K8nCp7IsGBVZqMgDyuL0tCxgRRYq8mDIQvmTLJSeycKzu7Jw+7wsXMrJQm6/LOzTZUFPyUIqLgvxqCxEv5IFzWPIgQGQk4PTAMNyoAP0yEEfgGrKgKkCwKQMFAEAxmQgWzckA8N1gzIwWBcw6ccCdXCafnlouIx+yxoFq9Srao2gQL0CNP2Oej80i1Ev1kw1aGcozWAX7bZBi+Ea5WqRViBPuTy0vI5yG1qba9KNzW0NjtEtA21GqlRj4XZgnGp5aDtJtWR7ynuafVbaA51mabAwxCjGOq2AbRTbBpZqf9Gr7LcGfqVXGiyeX6HW3yGrYCO1toLlHUVaTXqtgz5a9YKdGUplwNY5r+j0wm8PrKbTarBZeUylp4pdsJhKCbDdc5hGuz32AUxR6CE4stukj9njDEgw6rA4OPV36qTBsb7rtLnucw7M/kiZkgpO7mF0YQPg7EUmWRaB00epooPzj9MkCy70XqPIJa8bQD1Hj3MquNP/hhpvguBWbYIWExq4V3tDiTcauDl4jg7n/OBu9RIVrqngdm+WBie8wEGdAOYo8HEREx1bBLwcKIntYy/wU70usuuzgae+NBMV+90HnI2bYjITwN/ehyKa6gYu7xbPYeC0J/FELI+XeHgFoKx5IY5XaxTguj8jiswc4H7vpAiK/SBC79a/eVfZ2AGCDKXLPPs7PR8E6t/GeMW2aSDYzvRnHr3XQyBgJZlnfKmOJxUQdTjD+GEei4DQ527I13hQy6+bC+KPbDPcZuwKAxGV2A+Fqluqhe9jKpBSW5ZnzjPPLAsCRQODI9mi6RRzamxoMACUVfv1M4ZdRm64RwUaa9F4St+fu3T7WalcqeB0pWJ8fnb3fG6/nopHv/IAlwEAVlA4IHgIAACwOACdASrIAMgAPm0yk0YkIyGhL7cowIANiWlu4ME0Z2dc36Rf1TwF/nn82/JL256O/rLnEfsT+C/sHnB3g+7b+q9QL8a/on6Tb4Tj/+M9ALu//uu6A9B/rT/mfcA/Tv/W+g/8e8Ab6l/afYA/iX9A/6n+T9RP/H/vvnE/Mv7r/0P8N8CP8e/m3/O/s/an9Bz9JzCMO+Myw4dZdESvjaIP6nMyViAm4nbqrdpXzuF+/VTRlZPwI47fmfvDl5hbzvvZesvGUKjN7ws4T3LThWfoRQ4AoAA8e9lYL1nVnC85qq4mvj9Iph8YxivL/rrIH+nx3GNtE7c2oXhy5gEx47Z8sNva+odGL0UOFre7a/8pcCVRR+VAqOA+CSTUwrA/FB3RytCzvsm/UJ3htyMkuiFBPkIQkgeyZRBek+/i/YVS2uzhmupStTtUD66oGcS5+EVAH8fWxWkDLcyezIzzEhXFpHDKBmiU8U3CGZPeURs5O40NHmZ1yuL/LSebx3inBTn4fScXY5NtGQmTuvJRgK1ZkPKfur71V57K9aGxoHcFJWEWoT+wdJqn/+CEXgxOXAsN7CY9yIhMXtIKmxfysDoOvJcu/r+kfQ+KAF12SAAA/tznX6ah3T+0kRzuFzn2fQ8fFQ3Jwhf+PAnqgJuUaDbeHheuyuveOy2cK7s60D6dQJ/6PJXvNmeGbDhD3I1NjZn9oc4JUzlHaJP8whuvwQH/+01Q425kRC4hJihTqmiFP5nRhpc7iojBlxQWo4EVUGzU3wuFln27vn07cdcSf8WjpT+zeWz4PVcN8pkVGsiKq7cBNzA3mqWriMtC2CSTtTYTdjMvF7Ijau6AcNe7AIgk6dia7G1bv5y7LBzTXH6/6CeEBeH+MU/ERnSMlwi7VF5hFXzLzRHBV/v1swHdmHAOmY60klxbO1sY26jVQdRXsf4BTv4aJ1LVbXI3ZFDBhVXuY/q0r3zY1ve75gXWrzLOdUpmWVI+ohESBQUZ+rU+U6osFlcstDVHqCNBEOiT1jawA4oQoqrxGTonFFIGpeu2Xj8UTnLeFE2Md3o2FwYCri8tnQ5YN/XViP9pfXkt2qOy/yEtKZZNhoBmIHfHbQrYCz5Kh2bdgqFw5O1uy/Hou6pfwPWz3f2JocCmu2hqd32lMlF7X6xR+B7KcNvMTXv9GkELd8Xu/Kfpoax7QPHsq9RNLcdLDme5+5J8r5I31b/bsb2Dr3veZ5TYKOfV6S+zqm3Pm3su3t6C2kn7SOtPaXrXGBgTZapBKzj5rvfobSFdc/F15bMv/SRizlLib5FfiLOiZ6k/j6LGHT37iY4b1+TQFbOGGn+tY5WRq6SisawiHhcRzE9LURYQtib7q0jxkwQBuBCXPTBOJAkaAG7Vp5dU+qxrV88x9ASUpuVyMu1qzoKu7SKuhpoqbqdcdNWiBV+lVb41JHBEJ7oeHuTt/PyKeXXDdZ5ohET/Y75lxzxI6uzQ5r4IGRvLWul1kvJbP1nnNsAoQhO0tt0L60Pp7S5cTCavKf2FyYs/nxKXq6DKJtk8uRIycOOtWfyvZHYkjulFNNFR/IjND9uujdq66p3qRvf1Nm8SZOIwpni9IrNC9uOzRXnq9BhaDPbRNwLK2DHcYuH1nwzm4cUSUBu7gk5JC5UGE1CfP0TLXwWWr+6JUra/cyPfLM1oeynDbzAToAPUuWA2L9545vaFlmshP8Nj7r96uNDW6ngAyjF0RPM4pH5pGHzui7GI9KmamJujUcZHQLh3/w1hSn4IJdpYUoZMQHC3iKNFeOvi94ZueafCvFyASXifsLgpzzwNt9z5juYKX+CJES84eVuQ5+BncnQF6BZqo2ezHyrmL/ctjxvWpRnj33RIWMu1kccgXDdGBgevRfNIHxouiYJs6eE/Gt593jZcGq/L55a1l9OO/jzhuDz4lDbhFfmbpK/sEfDFeY3XHjDMj+TkeVBLAbJ5EVVKCYeWVurm5iroOfGnBuUSzeP2mKC2ENA3HaMy2jTzGV7FMun64t97WY1zOM8R5FG7QyAeZuNQos1KH15jO1Dymt2/DO6bHgFWloeRbpv+sovdYJSx2/gjgvYHEO2VwRFao5Bny2/MA31GzjN4eTyWvA16rhRu0NMu477gNZEaCRgHvcTVDchTfVckI4Cx4gd4YhUAgjKD5wvCFwX8upRTi2Rdy3FeXDhmw3xEntdU9rGdmncE7jFw+s+vAR2v+V2PjV7jAf9YvwKTdX8v/49RppBE21OCxhVheNMphMDyhtGRopafi54pihoCFgfyYzNzbyFH5voOmGEIIE+cSgHxkMFNbiR3/7BbwcP5SBwy6u/vmP02xcKsRdFj1UW7ZLxdk8dzs8oZEioxMnOR2rxrQ+N9z5nc6U7u40DDVEdwbJuyyQHU/LiE4wmO1N3bxC33X10I8gHmjukAh/Axq6s/eRqK1hwiHkR98coaA6CjFu3hAWv3mwnvK2Y+j/MzAuzOaxEiEMKOJp8JB+dsF7YyNwRM9+pFGSmF95KwrPdEM+/ZUBRDawKe5Kh0NkfZPSesQvMnn3ZgX+3P8ebe1SHo/4p00CyCfNiZ+efcxFg/mw1jqPsN7MOOv+lOglbWG3QEqlDs3OqCKIzANydcibObrwLNDGusfzk42/iksBPVgCgkil6O65u7r5O+q6NhFJRIaVVtGEYSUXNrHnsnBz30tuyBsc1bP9wF3KI7iNCPcDEV+4lT5OMJp5vKeg6p4BGfY76Aap/wY5Pdu/JHo3yI47AqoWq3Z5/P+O6mBnP3a6N/BdS62DLwp0WWwLAn/k1aiJr2oMje765btFUIiGn0MJ3o4nk4ANHxLRR9HrZndMvIAcAOBq5offJZ+HpBeAQ5WEqiPOd5kpWNg0wkdJCMpHwJ4AAAAA==" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
3
frontend/public/Logos/openlit.svg
Normal file
3
frontend/public/Logos/openlit.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 14 KiB |
3
frontend/public/Logos/traceloop.svg
Normal file
3
frontend/public/Logos/traceloop.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256" preserveAspectRatio="xMidYMid meet">
|
||||
<image width="256" height="256" href="data:image/webp;base64,UklGRjoOAABXRUJQVlA4WAoAAAAQAAAA/wAA/wAAQUxQSLsGAAAB8IZtE+q22baNJFsOrKIpqC01lLw1jOWayszMTGFmZo6s0nWVmQzXFeb4KoUjwwVO1BguV3HBDIL5YZqZNda/bIqICYCw/8P+DxvYmulyt2AX/ce+2UkyIm5/v8iHWra4XZnWDt1ciF178NP+Au7/H2pbeHN7did2/dV3cfX4HDV22tuw52AoGHicp8c+1DnH3sqJoaH/OpavUWsnANyEoeKvPRmeQL1vAmthyIBT6ezlihVaMzB0rLCRPYKap2eFEHg12beqZblDiclkv6nmbg4l3qEyUPVmDCW/pOqnGwZDifepLtAt6AklFlBBnWqer0OJu8j2qPb1UyFEw7lkk1V7yqgKHf4G5PGNilUZMClkaEygg+WKTQKI/DlUmACMRrFaP0cCQL/S0OADCwdcekap0n7QekBRKOC0AW+KR6WiAdC2scHf1VU+COwXvK+Pf4MBHUxaW9qFBX58tTtITMmqVKV0bRJ01nHDXV3z7aPOBbkJaXdpeYMDwv4/C6GR+uJYLV/OPF+MdeCjY8W/ekusnJQHxtK/mGp0JiPXh5oGdtxlkeBY5UVz5j8aISFmYSny+nIzOtJnM+p7IJnNNr0RzXtsMN9LNShwc592RnhR49oMph7/RFM3PcBk/whleke0MbAadW66jiVyG5o8cBeL5TOUWj0QAIwS1Pq3OI7laPraJI7xKLfEAFiOen/IMNBvPtzG0L9BEC6H6AbFgol0X6GGY+g2ouSG6NdQ80VkF/pUeJfM/qcofC1PtYNkD6CKZWTXouy8MtVaIqgW64AxVG8KK0Pd46neV2Iw1VJh2juoPtJtjbR63XpQOZVIppohrP6gauVA/YYOTRFUDwo7uEa1T8kG6bAbqHsJWzNKtTvJoEiFF8hgj6xRkK/Yf6x0L2pwpjvdnaLyAUYE9LoF6COOKPAMMG4XFBgBANPU2gCcl1ab7gvg7OuVMw1ab1LqcxsLpNabbEd3Fhh6RsomaHuCT6HgQhswDykxlcsOzJccF+GbAO1fnq3O7pHA32P+X6b5MRX47ZOq+LIvhw4nTMx2e7Qsypt5Ocjs+dDffjzlkV68dd4wkBl1tyv/pIfcnT0xAcL+P9twwsRst4f8ZL7rnighQ+duLvaI//FvjxhCLpuZW+TR0p09MaFjl2cje9Vku4AbfkSz/rWop4DhO1Hb7Ms7MMGHEo9fwmXfiGY+NYzLuiCI+vomtLMJhf4+nCdqG5q7IZXH9gnqvKmNaSjW24/lUzR7bQrLWtR6GgCMCMjBnRxPovmPRzDciGoHRgDko+S76Lr/XwF8ic5aqBfmwygUfYDuOdTwv3S3o+aj1sjCvmTbVcBhZB+ptuagsIepbI06jCX7VbWD9cLmUF2EOrqouqPq9Sh8LdVgJT6n6qOb+JVUVyjxAVW0cmXCxlFdqMQyKmuzamV5wq6ngtM6PEQFP6uW95qs6iiyt1TwxZLNU+216AZRm4B8pArfAHmCX7GGaFguqdFBB/9QIDCIDv6m2HIAo0TQRGBMrDXfCmCMrVSrxACAgdVivrRwwB0Bs+2I5IBrGpSqHgitR3iFfGoH3vuazLWlB/CmV6vkHQFt99ksoeY1C3APPmKipuk24E48oNDmPtDBjFwfU9nCWBBoe/iASbxrHCDQctf2gCq+3AzopJH64lj6B1MsIDX2llfHin9soBWknpfx8lgtX0w1IOz/sxA6briL/LbhhhzrxZl3aXltX0GxV90l/gZHp5LWliKrf++zdhGj3/8DNT251CEiZnYBmrJ0bVJHjA1+5D91M1+fb1HdlsVRbLZJdWha/wajnQFFKHO+hWmMFzU+GMd07lY0ddGANvqVotQVPCMbUOeiGJYe/0KTl/YDgMifUe6jHLEVqPU2C8ff0fQ/RwJMQsF/RDN8gHo/zZCJCk4Co0oSLqG7LKjY6Qi6nzSoMp5C0ZU2spWo+a1kQ1DFp76WhaPJilVzkc3U4WuPsNepzkHVD5J9r4MnKGw5VYpulWSHdQii8LVUg3X7i+y4DtgsbAFVsm6nyX7Wodkt7EmqSL9qu8k+1sGdJSyJCvJVW0D2kg5ZGbKOAfk41QaT9Q6okG4tFPUU3fm1iu0B+s81KLTCTZKORdDBJL2CoxgSGhW4CQCcchquAEbbHrUWAOcL5nMCANhzpLTcCqzRJ5T6yMICS82WY28FdqeMymuB+fzNKi22APM4n6mcdmj35kK+lndjgN3yfIU6B68B/kF7zFN4M3TUmulytzB4t0/pCyLtD3z8X78ajUc2XAMyhy8/WCevxe3KtELY/2H/hw0OAFZQOCBYBwAAcDIAnQEqAAEAAT5tMpJFpCOhmApkyEAGxLE3cLO/I/8A/AD9APeogBDf+wH8n/gH4AfoB/D8D/bUGJv3b8rvGLBD2z8kv6L+13LBGO/UZ+8+1n5jf2T+j+wDzCP0i/03UP8wn6r/83/Ye+Z/jv7B7I/13/ID5AP6p/eP/Z7WHqRft57AH8g/2XpTfsZ/3fkf/a/9xvgd/XX/4ewB6AHVf9AP4B+AH6V0/6X/37XCnfIaNJCv3UeIbyMN5GG7FGGXSbcdew8aH+Bc8jPujAWD5wlI0vGluc15OXPagLZ8UxFfBAlngGwyAgncED6mebGS9plnBjVRDpz0QjHI7NbLJCxCvFKIDQxTIXTAX5W3acocmvQ/OXAfnjdGNjAFiZXJq+/TbBzGEHdg+muQ+hFFPR2JnvUSNpSYiGR57j5nlFet8+EyOPVmbGlR6r47DqM+38DTtDHOHz36jaDYexg9qHpxk3+59nQC1SOzy4m4u34GLkKXdKCpMehdu53FcSHUZwi37E2m0zNsuu+Q0aSFfuo8Q3kYbyMN5GG6AAD8hoAAAAAAAtSatOsx3/xQJLZJVNwvp3oF/sWdRuskPj8s391kh8d5sIy+9WFVihdPhMB/7oNptL8qeszrOKuQiABZ2qtQOEHxZqWJnio26h/5Vo4krKGOO0sEz6Hv5rWo4fY5j+Zkip4N2flcerdMsQa4aobjtm8EeilMPd1RKe3T2L0a/Cv9h3t065fg6SjwXyBvg2hYN5RVMz/+NTMiir38FhGGkGCU+n7zH7a6z+ZsKOKACwNxEF24gJYE5Z8YDT/LDnQYzNPs7fnw0DWqqrx34u1n8kIsG90iig+vnPhkaVDzEnlMOItgwAov/p/WcPmzTS/ESKniY3/MPn06vQ7wic6l2jPoEyPrpPntLEOo7YMH2DlbEeYrf53exjRiZcoP/Ct0vnxkiHQpZk7RAgR6cllYgknBYToYbOnOoJ31iIPn+tjP9Wi1AD4rjN8FcbwzXiiXhq7Gpi/P39FnE7kEHxM3vJ6IfeN8kET6YhP9+bS4Ndq9z76kggowPI6pCeXTbktqMjiZBKP512NVTKWySMPWK2cDgYHLavMlfOsRt+ejI3anQJ8WOB5Sj4jg+PmmRO0YbrVrKJlMyW9DQhQxUYSb68hxwsa0pT95muv26wX/UbDfNNZqiY+FY3E3IrOLBfx/PvkZag+Z1tU15DmS4oWxI1MZPiItkOO5brQrLJ4gEX/aqDZVYH5qQqEYAdzEawMyn+D8EIsnVFuZBNbvILVTzHSwk5p+TPibb4Bij8La/IJ3+b8zP3KyRwEs7cd4bm+Kk65mOeRHpY//wUWtOhkyo+qCpkP9B+BZwjtgg93EV8KAePfDCEvQd6szMwcXg364KeljltsktN3CEwdKtH5sTvqV4jy9/ySVzVng2aUX/rOq5NjhT5vpK5nuKGWPdhY6RWG/JJfzsRE9JFNVJDLuZWWPyOhtK52DWPq8KkvizSdW1HXse/jEbnWBMMY4QwuO7eYDSR462HFk4zWyEZKugT+Uop5KD4KF+4xpfPgWfPcD4doS/+fEI2HjOrl8ctTT0EKp255SHoe3jdEi6QVMzZoAJS4j6vntijLltNjzgznBcSIrdKAgCdZjX9+VDrtqECJvxN3Z0S2oEoVZf2tji5V6DXamlubRVYpvsgB0DK/ACFIRFc4ggMNRpcbv9wYeN/ch3k6B5RkfzyDTkXb+RkS8ZLdbq1+tq/I8eK9g1/wuAZNhQkc5QmjUYgl3QAo86JmxC4zO0au6U/fSE11r16YB3WkeheQcJUKCbRTGS8OOs30DN7fpcxuuyEU3yM8HEqoyjd1rdQAi9K6LdRvQyLh3A9JmvA1EAjN8i2uLOeZi81BhiwAsZle61AOM78/l7yxuHy40ECHE9YostmdueER4HTWcMMGg0X8eJcujrbN1S4qyGxITPLghrKViISKTyPZ5qSo6EwnWhwA+XrAtKvtNVyS5f2iWAFmfHlQxfB+NXNwhxPwQ2akkMg3wgSifNE4lDRelowqblVu+ByzHBWsJkemp5mw2u/1Wl+RmpkyV7U5cIjxTkKyprg12fSsb7L3rIIHxd4ZgDArHDgESQGwDGC+iMlFrZKAfhcSUxuvPko5fkWdmQ/+oI2RMP4/d0h4/foef6PFHier1x+nRlT+0ZjBnE6Z32aVtbLbEPc+Z/EgAGsRF1RpteYADfJzufleSz65a2AZGpwwvDlrHbL9WdGx4Ww776VnxhYV27x6KH0biDB/mTxsIwv4zQQiKkDjcibMmzgp2PvZ3foNNj+SEDx11+lqzPpayPGMBRlQgr9yVhV93j2rzdy+mYvCoHNBVmA6kubmaB2ilYOI/AMpq6CFrzpkL8UJoedOwyLxtwJIWPjP+a++KkMbgYxBuo7dViu8XMjZ9jD1lMMABEIMT5fvOnzyyoKUFfnseMxeoFZjuySXC9vxk95ivyfGaZgXSPDdaiQAGYrj9aBUAAAAAAAA=" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.9 KiB |
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"SIGN_UP": "SigNoz | Sign Up",
|
||||
"LOGIN": "SigNoz | Login",
|
||||
"FORGOT_PASSWORD": "SigNoz | Forgot Password",
|
||||
"HOME": "SigNoz | Home",
|
||||
"SERVICE_METRICS": "SigNoz | Service Metrics",
|
||||
"SERVICE_MAP": "SigNoz | Service Map",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "\n\n---\nRenamed tag files to index.ts...\n"
|
||||
# Rename tag files to index.ts in services directories
|
||||
# tags-split creates: services/tagName/tagName.ts -> rename to services/tagName/index.ts
|
||||
find src/api/generated/services -mindepth 1 -maxdepth 1 -type d | while read -r dir; do
|
||||
@@ -11,4 +12,33 @@ find src/api/generated/services -mindepth 1 -maxdepth 1 -type d | while read -r
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Tag files renamed to index.ts"
|
||||
echo "\n✅ Tag files renamed to index.ts"
|
||||
|
||||
# Format generated files
|
||||
echo "\n\n---\nRunning prettier...\n"
|
||||
if ! prettier --write src/api/generated; then
|
||||
echo "Prettier formatting failed!"
|
||||
exit 1
|
||||
fi
|
||||
echo "\n✅ Prettier formatting successful"
|
||||
|
||||
|
||||
# Fix linting issues
|
||||
echo "\n\n---\nRunning eslint...\n"
|
||||
if ! yarn lint --fix --quiet src/api/generated; then
|
||||
echo "ESLint check failed! Please fix linting errors before proceeding."
|
||||
exit 1
|
||||
fi
|
||||
echo "\n✅ ESLint check successful"
|
||||
|
||||
|
||||
# Check for type errors
|
||||
echo "\n\n---\nChecking for type errors...\n"
|
||||
if ! tsc --noEmit; then
|
||||
echo "Type check failed! Please fix type errors before proceeding."
|
||||
exit 1
|
||||
fi
|
||||
echo "\n✅ Type check successful"
|
||||
|
||||
|
||||
echo "\n\n---\n ✅✅✅ API generation complete!"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { ReactChild, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useQuery } from 'react-query';
|
||||
import { matchPath, useLocation } from 'react-router-dom';
|
||||
import getLocalStorageApi from 'api/browser/localstorage/get';
|
||||
import setLocalStorageApi from 'api/browser/localstorage/set';
|
||||
import getAll from 'api/v1/user/get';
|
||||
@@ -9,9 +12,6 @@ import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
||||
import history from 'lib/history';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
import { ReactChild, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useQuery } from 'react-query';
|
||||
import { matchPath, useLocation } from 'react-router-dom';
|
||||
import { SuccessResponseV2 } from 'types/api';
|
||||
import APIError from 'types/api/error';
|
||||
import { LicensePlatform, LicenseState } from 'types/api/licensesV3/getActive';
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { Suspense, useCallback, useEffect, useState } from 'react';
|
||||
import { Route, Router, Switch } from 'react-router-dom';
|
||||
import { CompatRouter } from 'react-router-dom-v5-compat';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import getLocalStorageApi from 'api/browser/localstorage/get';
|
||||
@@ -30,9 +33,6 @@ import { DashboardProvider } from 'providers/Dashboard/Dashboard';
|
||||
import { ErrorModalProvider } from 'providers/ErrorModalProvider';
|
||||
import { PreferenceContextProvider } from 'providers/preferences/context/PreferenceContextProvider';
|
||||
import { QueryBuilderProvider } from 'providers/QueryBuilder';
|
||||
import { Suspense, useCallback, useEffect, useState } from 'react';
|
||||
import { Route, Router, Switch } from 'react-router-dom';
|
||||
import { CompatRouter } from 'react-router-dom-v5-compat';
|
||||
import { LicenseStatus } from 'types/api/licensesV3/getActive';
|
||||
import { extractDomain } from 'utils/app';
|
||||
|
||||
|
||||
@@ -194,6 +194,10 @@ export const Login = Loadable(
|
||||
() => import(/* webpackChunkName: "Login" */ 'pages/Login'),
|
||||
);
|
||||
|
||||
export const ForgotPassword = Loadable(
|
||||
() => import(/* webpackChunkName: "ForgotPassword" */ 'pages/ForgotPassword'),
|
||||
);
|
||||
|
||||
export const UnAuthorized = Loadable(
|
||||
() => import(/* webpackChunkName: "UnAuthorized" */ 'pages/UnAuthorized'),
|
||||
);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { RouteProps } from 'react-router-dom';
|
||||
import ROUTES from 'constants/routes';
|
||||
import AlertTypeSelectionPage from 'pages/AlertTypeSelection';
|
||||
import MessagingQueues from 'pages/MessagingQueues';
|
||||
import MeterExplorer from 'pages/MeterExplorer';
|
||||
import { RouteProps } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
AlertHistory,
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
DashboardWidget,
|
||||
EditRulesPage,
|
||||
ErrorDetails,
|
||||
ForgotPassword,
|
||||
Home,
|
||||
InfrastructureMonitoring,
|
||||
InstalledIntegrations,
|
||||
@@ -339,6 +340,13 @@ const routes: AppRoutes[] = [
|
||||
isPrivate: false,
|
||||
key: 'LOGIN',
|
||||
},
|
||||
{
|
||||
path: ROUTES.FORGOT_PASSWORD,
|
||||
exact: true,
|
||||
component: ForgotPassword,
|
||||
isPrivate: false,
|
||||
key: 'FORGOT_PASSWORD',
|
||||
},
|
||||
{
|
||||
path: ROUTES.UN_AUTHORIZED,
|
||||
exact: true,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
import i18n from 'i18next';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
import Backend from 'i18next-http-backend';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
|
||||
import cacheBursting from '../../i18n-translations-hash.json';
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
|
||||
const dashboardVariablesQuery = async (
|
||||
props: Props,
|
||||
signal?: AbortSignal,
|
||||
): Promise<SuccessResponse<VariableResponseProps> | ErrorResponse> => {
|
||||
try {
|
||||
const { globalTime } = store.getState();
|
||||
@@ -32,7 +33,7 @@ const dashboardVariablesQuery = async (
|
||||
|
||||
payload.variables = { ...payload.variables, ...timeVariables };
|
||||
|
||||
const response = await axios.post(`/variables/query`, payload);
|
||||
const response = await axios.post(`/variables/query`, payload, { signal });
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
|
||||
@@ -19,6 +19,7 @@ export const getFieldValues = async (
|
||||
startUnixMilli?: number,
|
||||
endUnixMilli?: number,
|
||||
existingQuery?: string,
|
||||
abortSignal?: AbortSignal,
|
||||
): Promise<SuccessResponseV2<FieldValueResponse>> => {
|
||||
const params: Record<string, string> = {};
|
||||
|
||||
@@ -47,7 +48,10 @@ export const getFieldValues = async (
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.get('/fields/values', { params });
|
||||
const response = await axios.get('/fields/values', {
|
||||
params,
|
||||
signal: abortSignal,
|
||||
});
|
||||
|
||||
// Normalize values from different types (stringValues, boolValues, etc.)
|
||||
if (response.data?.data?.values) {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
@@ -16,7 +15,9 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
AuthtypesPostableAuthDomainDTO,
|
||||
AuthtypesUpdateableAuthDomainDTO,
|
||||
@@ -27,8 +28,6 @@ import type {
|
||||
UpdateAuthDomainPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
@@ -16,7 +15,9 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
CreatePublicDashboard201,
|
||||
CreatePublicDashboardPathParameters,
|
||||
@@ -33,14 +34,12 @@ import type {
|
||||
UpdatePublicDashboardPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoints deletes the public sharing config and disables the public sharing of a dashboard
|
||||
* This endpoint deletes the public sharing config and disables the public sharing of a dashboard
|
||||
* @summary Delete public dashboard
|
||||
*/
|
||||
export const deletePublicDashboard = ({
|
||||
@@ -119,7 +118,7 @@ export const useDeletePublicDashboard = <
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* This endpoints returns public sharing config for a dashboard
|
||||
* This endpoint returns public sharing config for a dashboard
|
||||
* @summary Get public dashboard
|
||||
*/
|
||||
export const getPublicDashboard = (
|
||||
@@ -223,7 +222,7 @@ export const invalidateGetPublicDashboard = async (
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoints creates public sharing config and enables public sharing of the dashboard
|
||||
* This endpoint creates public sharing config and enables public sharing of the dashboard
|
||||
* @summary Create public dashboard
|
||||
*/
|
||||
export const createPublicDashboard = (
|
||||
@@ -322,7 +321,7 @@ export const useCreatePublicDashboard = <
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* This endpoints updates the public sharing config for a dashboard
|
||||
* This endpoint updates the public sharing config for a dashboard
|
||||
* @summary Update public dashboard
|
||||
*/
|
||||
export const updatePublicDashboard = (
|
||||
@@ -419,7 +418,7 @@ export const useUpdatePublicDashboard = <
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* This endpoints returns the sanitized dashboard data for public access
|
||||
* This endpoint returns the sanitized dashboard data for public access
|
||||
* @summary Get public dashboard data
|
||||
*/
|
||||
export const getPublicDashboardData = (
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
QueryClient,
|
||||
@@ -13,10 +12,10 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
|
||||
import type { GetFeatures200, RenderErrorResponseDTO } from '../sigNoz.schemas';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type { GetFeatures200, RenderErrorResponseDTO } from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
|
||||
222
frontend/src/api/generated/services/fields/index.ts
Normal file
222
frontend/src/api/generated/services/fields/index.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* ! Do not edit manually
|
||||
* * The file has been auto-generated using Orval for SigNoz
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
GetFieldsKeys200,
|
||||
GetFieldsKeysParams,
|
||||
GetFieldsValues200,
|
||||
GetFieldsValuesParams,
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint returns field keys
|
||||
* @summary Get field keys
|
||||
*/
|
||||
export const getFieldsKeys = (
|
||||
params?: GetFieldsKeysParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetFieldsKeys200>({
|
||||
url: `/api/v1/fields/keys`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetFieldsKeysQueryKey = (params?: GetFieldsKeysParams) => {
|
||||
return ['getFieldsKeys', ...(params ? [params] : [])] as const;
|
||||
};
|
||||
|
||||
export const getGetFieldsKeysQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getFieldsKeys>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetFieldsKeysParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getFieldsKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetFieldsKeysQueryKey(params);
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getFieldsKeys>>> = ({
|
||||
signal,
|
||||
}) => getFieldsKeys(params, signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getFieldsKeys>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetFieldsKeysQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getFieldsKeys>>
|
||||
>;
|
||||
export type GetFieldsKeysQueryError = RenderErrorResponseDTO;
|
||||
|
||||
/**
|
||||
* @summary Get field keys
|
||||
*/
|
||||
|
||||
export function useGetFieldsKeys<
|
||||
TData = Awaited<ReturnType<typeof getFieldsKeys>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetFieldsKeysParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getFieldsKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetFieldsKeysQueryOptions(params, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get field keys
|
||||
*/
|
||||
export const invalidateGetFieldsKeys = async (
|
||||
queryClient: QueryClient,
|
||||
params?: GetFieldsKeysParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetFieldsKeysQueryKey(params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint returns field values
|
||||
* @summary Get field values
|
||||
*/
|
||||
export const getFieldsValues = (
|
||||
params?: GetFieldsValuesParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetFieldsValues200>({
|
||||
url: `/api/v1/fields/values`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetFieldsValuesQueryKey = (params?: GetFieldsValuesParams) => {
|
||||
return ['getFieldsValues', ...(params ? [params] : [])] as const;
|
||||
};
|
||||
|
||||
export const getGetFieldsValuesQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getFieldsValues>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetFieldsValuesParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getFieldsValues>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetFieldsValuesQueryKey(params);
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getFieldsValues>>> = ({
|
||||
signal,
|
||||
}) => getFieldsValues(params, signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getFieldsValues>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetFieldsValuesQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getFieldsValues>>
|
||||
>;
|
||||
export type GetFieldsValuesQueryError = RenderErrorResponseDTO;
|
||||
|
||||
/**
|
||||
* @summary Get field values
|
||||
*/
|
||||
|
||||
export function useGetFieldsValues<
|
||||
TData = Awaited<ReturnType<typeof getFieldsValues>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetFieldsValuesParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getFieldsValues>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetFieldsValuesQueryOptions(params, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get field values
|
||||
*/
|
||||
export const invalidateGetFieldsValues = async (
|
||||
queryClient: QueryClient,
|
||||
params?: GetFieldsValuesParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetFieldsValuesQueryKey(params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
@@ -16,7 +15,9 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
CreateIngestionKey200,
|
||||
CreateIngestionKeyLimit201,
|
||||
@@ -27,14 +28,14 @@ import type {
|
||||
GatewaytypesPostableIngestionKeyLimitDTO,
|
||||
GatewaytypesUpdatableIngestionKeyLimitDTO,
|
||||
GetIngestionKeys200,
|
||||
GetIngestionKeysParams,
|
||||
RenderErrorResponseDTO,
|
||||
SearchIngestionKeys200,
|
||||
SearchIngestionKeysParams,
|
||||
UpdateIngestionKeyLimitPathParameters,
|
||||
UpdateIngestionKeyPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
@@ -43,35 +44,44 @@ type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
* This endpoint returns the ingestion keys for a workspace
|
||||
* @summary Get ingestion keys for workspace
|
||||
*/
|
||||
export const getIngestionKeys = (signal?: AbortSignal) => {
|
||||
export const getIngestionKeys = (
|
||||
params?: GetIngestionKeysParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetIngestionKeys200>({
|
||||
url: `/api/v2/gateway/ingestion_keys`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetIngestionKeysQueryKey = () => {
|
||||
return ['getIngestionKeys'] as const;
|
||||
export const getGetIngestionKeysQueryKey = (
|
||||
params?: GetIngestionKeysParams,
|
||||
) => {
|
||||
return ['getIngestionKeys', ...(params ? [params] : [])] as const;
|
||||
};
|
||||
|
||||
export const getGetIngestionKeysQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getIngestionKeys>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}) => {
|
||||
>(
|
||||
params?: GetIngestionKeysParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetIngestionKeysQueryKey();
|
||||
const queryKey = queryOptions?.queryKey ?? getGetIngestionKeysQueryKey(params);
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getIngestionKeys>>> = ({
|
||||
signal,
|
||||
}) => getIngestionKeys(signal);
|
||||
}) => getIngestionKeys(params, signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKeys>>,
|
||||
@@ -92,14 +102,17 @@ export type GetIngestionKeysQueryError = RenderErrorResponseDTO;
|
||||
export function useGetIngestionKeys<
|
||||
TData = Awaited<ReturnType<typeof getIngestionKeys>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetIngestionKeysQueryOptions(options);
|
||||
>(
|
||||
params?: GetIngestionKeysParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetIngestionKeysQueryOptions(params, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
@@ -115,10 +128,11 @@ export function useGetIngestionKeys<
|
||||
*/
|
||||
export const invalidateGetIngestionKeys = async (
|
||||
queryClient: QueryClient,
|
||||
params?: GetIngestionKeysParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetIngestionKeysQueryKey() },
|
||||
{ queryKey: getGetIngestionKeysQueryKey(params) },
|
||||
options,
|
||||
);
|
||||
|
||||
@@ -663,35 +677,45 @@ export const useUpdateIngestionKeyLimit = <
|
||||
* This endpoint returns the ingestion keys for a workspace
|
||||
* @summary Search ingestion keys for workspace
|
||||
*/
|
||||
export const searchIngestionKeys = (signal?: AbortSignal) => {
|
||||
export const searchIngestionKeys = (
|
||||
params?: SearchIngestionKeysParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<SearchIngestionKeys200>({
|
||||
url: `/api/v2/gateway/ingestion_keys/search`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getSearchIngestionKeysQueryKey = () => {
|
||||
return ['searchIngestionKeys'] as const;
|
||||
export const getSearchIngestionKeysQueryKey = (
|
||||
params?: SearchIngestionKeysParams,
|
||||
) => {
|
||||
return ['searchIngestionKeys', ...(params ? [params] : [])] as const;
|
||||
};
|
||||
|
||||
export const getSearchIngestionKeysQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof searchIngestionKeys>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof searchIngestionKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}) => {
|
||||
>(
|
||||
params?: SearchIngestionKeysParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof searchIngestionKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getSearchIngestionKeysQueryKey();
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getSearchIngestionKeysQueryKey(params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof searchIngestionKeys>>
|
||||
> = ({ signal }) => searchIngestionKeys(signal);
|
||||
> = ({ signal }) => searchIngestionKeys(params, signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof searchIngestionKeys>>,
|
||||
@@ -712,14 +736,17 @@ export type SearchIngestionKeysQueryError = RenderErrorResponseDTO;
|
||||
export function useSearchIngestionKeys<
|
||||
TData = Awaited<ReturnType<typeof searchIngestionKeys>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof searchIngestionKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getSearchIngestionKeysQueryOptions(options);
|
||||
>(
|
||||
params?: SearchIngestionKeysParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof searchIngestionKeys>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getSearchIngestionKeysQueryOptions(params, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
@@ -735,10 +762,11 @@ export function useSearchIngestionKeys<
|
||||
*/
|
||||
export const invalidateSearchIngestionKeys = async (
|
||||
queryClient: QueryClient,
|
||||
params?: SearchIngestionKeysParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getSearchIngestionKeysQueryKey() },
|
||||
{ queryKey: getSearchIngestionKeysQueryKey(params) },
|
||||
options,
|
||||
);
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
QueryClient,
|
||||
@@ -13,20 +12,20 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
GetGlobalConfig200,
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoints returns global config
|
||||
* This endpoint returns global config
|
||||
* @summary Get global config
|
||||
*/
|
||||
export const getGlobalConfig = (signal?: AbortSignal) => {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
@@ -16,15 +15,15 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
ListPromotedAndIndexedPaths200,
|
||||
PromotetypesPromotePathDTO,
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
@@ -16,7 +15,9 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
GetMetricAlerts200,
|
||||
GetMetricAlertsParams,
|
||||
@@ -37,8 +38,6 @@ import type {
|
||||
UpdateMetricMetadataPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
@@ -48,7 +47,7 @@ type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
* @summary Get metric alerts
|
||||
*/
|
||||
export const getMetricAlerts = (
|
||||
params?: GetMetricAlertsParams,
|
||||
params: GetMetricAlertsParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetMetricAlerts200>({
|
||||
@@ -67,7 +66,7 @@ export const getGetMetricAlertsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getMetricAlerts>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetMetricAlertsParams,
|
||||
params: GetMetricAlertsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMetricAlerts>>,
|
||||
@@ -104,7 +103,7 @@ export function useGetMetricAlerts<
|
||||
TData = Awaited<ReturnType<typeof getMetricAlerts>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetMetricAlertsParams,
|
||||
params: GetMetricAlertsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMetricAlerts>>,
|
||||
@@ -129,7 +128,7 @@ export function useGetMetricAlerts<
|
||||
*/
|
||||
export const invalidateGetMetricAlerts = async (
|
||||
queryClient: QueryClient,
|
||||
params?: GetMetricAlertsParams,
|
||||
params: GetMetricAlertsParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
@@ -145,7 +144,7 @@ export const invalidateGetMetricAlerts = async (
|
||||
* @summary Get metric dashboards
|
||||
*/
|
||||
export const getMetricDashboards = (
|
||||
params?: GetMetricDashboardsParams,
|
||||
params: GetMetricDashboardsParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetMetricDashboards200>({
|
||||
@@ -166,7 +165,7 @@ export const getGetMetricDashboardsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getMetricDashboards>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetMetricDashboardsParams,
|
||||
params: GetMetricDashboardsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMetricDashboards>>,
|
||||
@@ -204,7 +203,7 @@ export function useGetMetricDashboards<
|
||||
TData = Awaited<ReturnType<typeof getMetricDashboards>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetMetricDashboardsParams,
|
||||
params: GetMetricDashboardsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMetricDashboards>>,
|
||||
@@ -229,7 +228,7 @@ export function useGetMetricDashboards<
|
||||
*/
|
||||
export const invalidateGetMetricDashboards = async (
|
||||
queryClient: QueryClient,
|
||||
params?: GetMetricDashboardsParams,
|
||||
params: GetMetricDashboardsParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
@@ -245,7 +244,7 @@ export const invalidateGetMetricDashboards = async (
|
||||
* @summary Get metric highlights
|
||||
*/
|
||||
export const getMetricHighlights = (
|
||||
params?: GetMetricHighlightsParams,
|
||||
params: GetMetricHighlightsParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetMetricHighlights200>({
|
||||
@@ -266,7 +265,7 @@ export const getGetMetricHighlightsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getMetricHighlights>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetMetricHighlightsParams,
|
||||
params: GetMetricHighlightsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMetricHighlights>>,
|
||||
@@ -304,7 +303,7 @@ export function useGetMetricHighlights<
|
||||
TData = Awaited<ReturnType<typeof getMetricHighlights>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetMetricHighlightsParams,
|
||||
params: GetMetricHighlightsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMetricHighlights>>,
|
||||
@@ -329,7 +328,7 @@ export function useGetMetricHighlights<
|
||||
*/
|
||||
export const invalidateGetMetricHighlights = async (
|
||||
queryClient: QueryClient,
|
||||
params?: GetMetricHighlightsParams,
|
||||
params: GetMetricHighlightsParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
@@ -527,7 +526,7 @@ export const useGetMetricAttributes = <
|
||||
* @summary Get metric metadata
|
||||
*/
|
||||
export const getMetricMetadata = (
|
||||
params?: GetMetricMetadataParams,
|
||||
params: GetMetricMetadataParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetMetricMetadata200>({
|
||||
@@ -548,7 +547,7 @@ export const getGetMetricMetadataQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getMetricMetadata>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetMetricMetadataParams,
|
||||
params: GetMetricMetadataParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMetricMetadata>>,
|
||||
@@ -586,7 +585,7 @@ export function useGetMetricMetadata<
|
||||
TData = Awaited<ReturnType<typeof getMetricMetadata>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
params?: GetMetricMetadataParams,
|
||||
params: GetMetricMetadataParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMetricMetadata>>,
|
||||
@@ -611,7 +610,7 @@ export function useGetMetricMetadata<
|
||||
*/
|
||||
export const invalidateGetMetricMetadata = async (
|
||||
queryClient: QueryClient,
|
||||
params?: GetMetricMetadataParams,
|
||||
params: GetMetricMetadataParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
@@ -16,15 +15,15 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
GetMyOrganization200,
|
||||
RenderErrorResponseDTO,
|
||||
TypesOrganizationDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
@@ -16,7 +15,9 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
GetOrgPreference200,
|
||||
GetOrgPreferencePathParameters,
|
||||
@@ -30,8 +31,6 @@ import type {
|
||||
UpdateUserPreferencePathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
433
frontend/src/api/generated/services/role/index.ts
Normal file
433
frontend/src/api/generated/services/role/index.ts
Normal file
@@ -0,0 +1,433 @@
|
||||
/**
|
||||
* ! Do not edit manually
|
||||
* * The file has been auto-generated using Orval for SigNoz
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
CreateRole201,
|
||||
DeleteRolePathParameters,
|
||||
GetRole200,
|
||||
GetRolePathParameters,
|
||||
ListRoles200,
|
||||
PatchRolePathParameters,
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint lists all roles
|
||||
* @summary List roles
|
||||
*/
|
||||
export const listRoles = (signal?: AbortSignal) => {
|
||||
return GeneratedAPIInstance<ListRoles200>({
|
||||
url: `/api/v1/roles`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getListRolesQueryKey = () => {
|
||||
return ['listRoles'] as const;
|
||||
};
|
||||
|
||||
export const getListRolesQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listRoles>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<Awaited<ReturnType<typeof listRoles>>, TError, TData>;
|
||||
}) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getListRolesQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listRoles>>> = ({
|
||||
signal,
|
||||
}) => listRoles(signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listRoles>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type ListRolesQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listRoles>>
|
||||
>;
|
||||
export type ListRolesQueryError = RenderErrorResponseDTO;
|
||||
|
||||
/**
|
||||
* @summary List roles
|
||||
*/
|
||||
|
||||
export function useListRoles<
|
||||
TData = Awaited<ReturnType<typeof listRoles>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<Awaited<ReturnType<typeof listRoles>>, TError, TData>;
|
||||
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getListRolesQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary List roles
|
||||
*/
|
||||
export const invalidateListRoles = async (
|
||||
queryClient: QueryClient,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getListRolesQueryKey() },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint creates a role
|
||||
* @summary Create role
|
||||
*/
|
||||
export const createRole = (signal?: AbortSignal) => {
|
||||
return GeneratedAPIInstance<CreateRole201>({
|
||||
url: `/api/v1/roles`,
|
||||
method: 'POST',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getCreateRoleMutationOptions = <
|
||||
TError = RenderErrorResponseDTO,
|
||||
TContext = unknown
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createRole>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createRole>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['createRole'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof createRole>>,
|
||||
void
|
||||
> = () => {
|
||||
return createRole();
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type CreateRoleMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createRole>>
|
||||
>;
|
||||
|
||||
export type CreateRoleMutationError = RenderErrorResponseDTO;
|
||||
|
||||
/**
|
||||
* @summary Create role
|
||||
*/
|
||||
export const useCreateRole = <
|
||||
TError = RenderErrorResponseDTO,
|
||||
TContext = unknown
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createRole>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createRole>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getCreateRoleMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* This endpoint deletes a role
|
||||
* @summary Delete role
|
||||
*/
|
||||
export const deleteRole = ({ id }: DeleteRolePathParameters) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
url: `/api/v1/roles/${id}`,
|
||||
method: 'DELETE',
|
||||
});
|
||||
};
|
||||
|
||||
export const getDeleteRoleMutationOptions = <
|
||||
TError = RenderErrorResponseDTO,
|
||||
TContext = unknown
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteRole>>,
|
||||
TError,
|
||||
{ pathParams: DeleteRolePathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteRole>>,
|
||||
TError,
|
||||
{ pathParams: DeleteRolePathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['deleteRole'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof deleteRole>>,
|
||||
{ pathParams: DeleteRolePathParameters }
|
||||
> = (props) => {
|
||||
const { pathParams } = props ?? {};
|
||||
|
||||
return deleteRole(pathParams);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type DeleteRoleMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof deleteRole>>
|
||||
>;
|
||||
|
||||
export type DeleteRoleMutationError = RenderErrorResponseDTO;
|
||||
|
||||
/**
|
||||
* @summary Delete role
|
||||
*/
|
||||
export const useDeleteRole = <
|
||||
TError = RenderErrorResponseDTO,
|
||||
TContext = unknown
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteRole>>,
|
||||
TError,
|
||||
{ pathParams: DeleteRolePathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteRole>>,
|
||||
TError,
|
||||
{ pathParams: DeleteRolePathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getDeleteRoleMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* This endpoint gets a role
|
||||
* @summary Get role
|
||||
*/
|
||||
export const getRole = (
|
||||
{ id }: GetRolePathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetRole200>({
|
||||
url: `/api/v1/roles/${id}`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetRoleQueryKey = ({ id }: GetRolePathParameters) => {
|
||||
return ['getRole'] as const;
|
||||
};
|
||||
|
||||
export const getGetRoleQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getRole>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
{ id }: GetRolePathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<Awaited<ReturnType<typeof getRole>>, TError, TData>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetRoleQueryKey({ id });
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getRole>>> = ({
|
||||
signal,
|
||||
}) => getRole({ id }, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!id,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<Awaited<ReturnType<typeof getRole>>, TError, TData> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
};
|
||||
|
||||
export type GetRoleQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getRole>>
|
||||
>;
|
||||
export type GetRoleQueryError = RenderErrorResponseDTO;
|
||||
|
||||
/**
|
||||
* @summary Get role
|
||||
*/
|
||||
|
||||
export function useGetRole<
|
||||
TData = Awaited<ReturnType<typeof getRole>>,
|
||||
TError = RenderErrorResponseDTO
|
||||
>(
|
||||
{ id }: GetRolePathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<Awaited<ReturnType<typeof getRole>>, TError, TData>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetRoleQueryOptions({ id }, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get role
|
||||
*/
|
||||
export const invalidateGetRole = async (
|
||||
queryClient: QueryClient,
|
||||
{ id }: GetRolePathParameters,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetRoleQueryKey({ id }) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint patches a role
|
||||
* @summary Patch role
|
||||
*/
|
||||
export const patchRole = ({ id }: PatchRolePathParameters) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
url: `/api/v1/roles/${id}`,
|
||||
method: 'PATCH',
|
||||
});
|
||||
};
|
||||
|
||||
export const getPatchRoleMutationOptions = <
|
||||
TError = RenderErrorResponseDTO,
|
||||
TContext = unknown
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof patchRole>>,
|
||||
TError,
|
||||
{ pathParams: PatchRolePathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof patchRole>>,
|
||||
TError,
|
||||
{ pathParams: PatchRolePathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['patchRole'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof patchRole>>,
|
||||
{ pathParams: PatchRolePathParameters }
|
||||
> = (props) => {
|
||||
const { pathParams } = props ?? {};
|
||||
|
||||
return patchRole(pathParams);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type PatchRoleMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof patchRole>>
|
||||
>;
|
||||
|
||||
export type PatchRoleMutationError = RenderErrorResponseDTO;
|
||||
|
||||
/**
|
||||
* @summary Patch role
|
||||
*/
|
||||
export const usePatchRole = <
|
||||
TError = RenderErrorResponseDTO,
|
||||
TContext = unknown
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof patchRole>>,
|
||||
TError,
|
||||
{ pathParams: PatchRolePathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof patchRole>>,
|
||||
TError,
|
||||
{ pathParams: PatchRolePathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getPatchRoleMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
@@ -16,7 +15,9 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
AuthtypesPostableEmailPasswordSessionDTO,
|
||||
AuthtypesPostableRotateTokenDTO,
|
||||
@@ -31,8 +32,6 @@ import type {
|
||||
RotateSession200,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
@@ -650,11 +650,11 @@ export interface MetricsexplorertypesMetricAlertDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
alertId?: string;
|
||||
alertId: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
alertName?: string;
|
||||
alertName: string;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesMetricAlertsResponseDTO {
|
||||
@@ -662,24 +662,24 @@ export interface MetricsexplorertypesMetricAlertsResponseDTO {
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
alerts?: MetricsexplorertypesMetricAlertDTO[] | null;
|
||||
alerts: MetricsexplorertypesMetricAlertDTO[] | null;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesMetricAttributeDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
key?: string;
|
||||
key: string;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
valueCount?: number;
|
||||
valueCount: number;
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
values?: string[] | null;
|
||||
values: string[] | null;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesMetricAttributesRequestDTO {
|
||||
@@ -691,7 +691,7 @@ export interface MetricsexplorertypesMetricAttributesRequestDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
metricName?: string;
|
||||
metricName: string;
|
||||
/**
|
||||
* @type integer
|
||||
* @nullable true
|
||||
@@ -704,31 +704,31 @@ export interface MetricsexplorertypesMetricAttributesResponseDTO {
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
attributes?: MetricsexplorertypesMetricAttributeDTO[] | null;
|
||||
attributes: MetricsexplorertypesMetricAttributeDTO[] | null;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
totalKeys?: number;
|
||||
totalKeys: number;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesMetricDashboardDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
dashboardId?: string;
|
||||
dashboardId: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
dashboardName?: string;
|
||||
dashboardName: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
widgetId?: string;
|
||||
widgetId: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
widgetName?: string;
|
||||
widgetName: string;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesMetricDashboardsResponseDTO {
|
||||
@@ -736,7 +736,7 @@ export interface MetricsexplorertypesMetricDashboardsResponseDTO {
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
dashboards?: MetricsexplorertypesMetricDashboardDTO[] | null;
|
||||
dashboards: MetricsexplorertypesMetricDashboardDTO[] | null;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesMetricHighlightsResponseDTO {
|
||||
@@ -744,74 +744,65 @@ export interface MetricsexplorertypesMetricHighlightsResponseDTO {
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
activeTimeSeries?: number;
|
||||
activeTimeSeries: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
dataPoints?: number;
|
||||
dataPoints: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
lastReceived?: number;
|
||||
lastReceived: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
totalTimeSeries?: number;
|
||||
totalTimeSeries: number;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesMetricMetadataDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
description: string;
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
isMonotonic?: boolean;
|
||||
isMonotonic: boolean;
|
||||
temporality: MetrictypesTemporalityDTO;
|
||||
type: MetrictypesTypeDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
temporality?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
unit?: string;
|
||||
unit: string;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesStatDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
description: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
metricName?: string;
|
||||
metricName: string;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
samples?: number;
|
||||
samples: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
timeseries?: number;
|
||||
timeseries: number;
|
||||
type: MetrictypesTypeDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
unit?: string;
|
||||
unit: string;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesStatsRequestDTO {
|
||||
@@ -819,12 +810,12 @@ export interface MetricsexplorertypesStatsRequestDTO {
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
end?: number;
|
||||
end: number;
|
||||
filter?: Querybuildertypesv5FilterDTO;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
limit?: number;
|
||||
limit: number;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
@@ -834,7 +825,7 @@ export interface MetricsexplorertypesStatsRequestDTO {
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
start?: number;
|
||||
start: number;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesStatsResponseDTO {
|
||||
@@ -842,51 +833,52 @@ export interface MetricsexplorertypesStatsResponseDTO {
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
metrics?: MetricsexplorertypesStatDTO[] | null;
|
||||
metrics: MetricsexplorertypesStatDTO[] | null;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
total?: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesTreemapEntryDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
metricName?: string;
|
||||
metricName: string;
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
percentage?: number;
|
||||
percentage: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
totalValue?: number;
|
||||
totalValue: number;
|
||||
}
|
||||
|
||||
export enum MetricsexplorertypesTreemapModeDTO {
|
||||
timeseries = 'timeseries',
|
||||
samples = 'samples',
|
||||
}
|
||||
export interface MetricsexplorertypesTreemapRequestDTO {
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
end?: number;
|
||||
end: number;
|
||||
filter?: Querybuildertypesv5FilterDTO;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
mode?: string;
|
||||
limit: number;
|
||||
mode: MetricsexplorertypesTreemapModeDTO;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
start?: number;
|
||||
start: number;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesTreemapResponseDTO {
|
||||
@@ -894,41 +886,47 @@ export interface MetricsexplorertypesTreemapResponseDTO {
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
samples?: MetricsexplorertypesTreemapEntryDTO[] | null;
|
||||
samples: MetricsexplorertypesTreemapEntryDTO[] | null;
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
timeseries?: MetricsexplorertypesTreemapEntryDTO[] | null;
|
||||
timeseries: MetricsexplorertypesTreemapEntryDTO[] | null;
|
||||
}
|
||||
|
||||
export interface MetricsexplorertypesUpdateMetricMetadataRequestDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
description: string;
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
isMonotonic?: boolean;
|
||||
isMonotonic: boolean;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
metricName?: string;
|
||||
metricName: string;
|
||||
temporality: MetrictypesTemporalityDTO;
|
||||
type: MetrictypesTypeDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
temporality?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
unit?: string;
|
||||
unit: string;
|
||||
}
|
||||
|
||||
export enum MetrictypesTemporalityDTO {
|
||||
delta = 'delta',
|
||||
cumulative = 'cumulative',
|
||||
unspecified = 'unspecified',
|
||||
}
|
||||
export enum MetrictypesTypeDTO {
|
||||
gauge = 'gauge',
|
||||
sum = 'sum',
|
||||
histogram = 'histogram',
|
||||
summary = 'summary',
|
||||
exponentialhistogram = 'exponentialhistogram',
|
||||
}
|
||||
export interface PreferencetypesPreferenceDTO {
|
||||
/**
|
||||
* @type array
|
||||
@@ -1051,7 +1049,7 @@ export interface Querybuildertypesv5OrderByKeyDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name?: string;
|
||||
name: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
@@ -1110,6 +1108,112 @@ export interface RenderErrorResponseDTO {
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export interface RoletypesRoleDTO {
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
createdAt?: Date;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
orgId?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
updatedAt?: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @nullable
|
||||
*/
|
||||
export type TelemetrytypesGettableFieldKeysDTOKeys = {
|
||||
[key: string]: TelemetrytypesTelemetryFieldKeyDTO[];
|
||||
} | null;
|
||||
|
||||
export interface TelemetrytypesGettableFieldKeysDTO {
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
complete: boolean;
|
||||
/**
|
||||
* @type object
|
||||
* @nullable true
|
||||
*/
|
||||
keys: TelemetrytypesGettableFieldKeysDTOKeys;
|
||||
}
|
||||
|
||||
export interface TelemetrytypesGettableFieldValuesDTO {
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
complete: boolean;
|
||||
values: TelemetrytypesTelemetryFieldValuesDTO;
|
||||
}
|
||||
|
||||
export interface TelemetrytypesTelemetryFieldKeyDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
fieldContext?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
fieldDataType?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
signal?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
unit?: string;
|
||||
}
|
||||
|
||||
export interface TelemetrytypesTelemetryFieldValuesDTO {
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
boolValues?: boolean[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
numberValues?: number[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
relatedValues?: string[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
stringValues?: string[];
|
||||
}
|
||||
|
||||
export interface TypesChangePasswordRequestDTO {
|
||||
/**
|
||||
* @type string
|
||||
@@ -1310,6 +1414,21 @@ export interface TypesPostableAcceptInviteDTO {
|
||||
token?: string;
|
||||
}
|
||||
|
||||
export interface TypesPostableForgotPasswordDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
email: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
frontendBaseURL?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
orgId: string;
|
||||
}
|
||||
|
||||
export interface TypesPostableInviteDTO {
|
||||
/**
|
||||
* @type string
|
||||
@@ -1341,6 +1460,11 @@ export interface TypesPostableResetPasswordDTO {
|
||||
}
|
||||
|
||||
export interface TypesResetPasswordTokenDTO {
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
expiresAt?: Date;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
@@ -1537,6 +1661,132 @@ export type DeleteAuthDomainPathParameters = {
|
||||
export type UpdateAuthDomainPathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetFieldsKeysParams = {
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
signal?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
source?: string;
|
||||
/**
|
||||
* @type integer
|
||||
* @description undefined
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
startUnixMilli?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
endUnixMilli?: number;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
fieldContext?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
fieldDataType?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
metricName?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
searchText?: string;
|
||||
};
|
||||
|
||||
export type GetFieldsKeys200 = {
|
||||
data?: TelemetrytypesGettableFieldKeysDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status?: string;
|
||||
};
|
||||
|
||||
export type GetFieldsValuesParams = {
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
signal?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
source?: string;
|
||||
/**
|
||||
* @type integer
|
||||
* @description undefined
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
startUnixMilli?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
* @description undefined
|
||||
*/
|
||||
endUnixMilli?: number;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
fieldContext?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
fieldDataType?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
metricName?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
searchText?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
existingQuery?: string;
|
||||
};
|
||||
|
||||
export type GetFieldsValues200 = {
|
||||
data?: TelemetrytypesGettableFieldValuesDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status?: string;
|
||||
};
|
||||
|
||||
export type GetResetPasswordTokenPathParameters = {
|
||||
id: string;
|
||||
};
|
||||
@@ -1682,6 +1932,42 @@ export type GetPublicDashboardWidgetQueryRange200 = {
|
||||
status?: string;
|
||||
};
|
||||
|
||||
export type ListRoles200 = {
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
data?: RoletypesRoleDTO[];
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status?: string;
|
||||
};
|
||||
|
||||
export type CreateRole201 = {
|
||||
data?: TypesIdentifiableDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status?: string;
|
||||
};
|
||||
|
||||
export type DeleteRolePathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetRolePathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetRole200 = {
|
||||
data?: RoletypesRoleDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status?: string;
|
||||
};
|
||||
|
||||
export type PatchRolePathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type ListUsers200 = {
|
||||
/**
|
||||
* @type array
|
||||
@@ -1762,6 +2048,19 @@ export type GetFeatures200 = {
|
||||
status?: string;
|
||||
};
|
||||
|
||||
export type GetIngestionKeysParams = {
|
||||
/**
|
||||
* @type integer
|
||||
* @description undefined
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @description undefined
|
||||
*/
|
||||
per_page?: number;
|
||||
};
|
||||
|
||||
export type GetIngestionKeys200 = {
|
||||
data?: GatewaytypesGettableIngestionKeysDTO;
|
||||
/**
|
||||
@@ -1801,6 +2100,24 @@ export type DeleteIngestionKeyLimitPathParameters = {
|
||||
export type UpdateIngestionKeyLimitPathParameters = {
|
||||
limitId: string;
|
||||
};
|
||||
export type SearchIngestionKeysParams = {
|
||||
/**
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* @type integer
|
||||
* @description undefined
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @description undefined
|
||||
*/
|
||||
per_page?: number;
|
||||
};
|
||||
|
||||
export type SearchIngestionKeys200 = {
|
||||
data?: GatewaytypesGettableIngestionKeysDTO;
|
||||
/**
|
||||
@@ -1814,7 +2131,7 @@ export type GetMetricAlertsParams = {
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
metricName?: string;
|
||||
metricName: string;
|
||||
};
|
||||
|
||||
export type GetMetricAlerts200 = {
|
||||
@@ -1830,7 +2147,7 @@ export type GetMetricDashboardsParams = {
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
metricName?: string;
|
||||
metricName: string;
|
||||
};
|
||||
|
||||
export type GetMetricDashboards200 = {
|
||||
@@ -1846,7 +2163,7 @@ export type GetMetricHighlightsParams = {
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
metricName?: string;
|
||||
metricName: string;
|
||||
};
|
||||
|
||||
export type GetMetricHighlights200 = {
|
||||
@@ -1873,7 +2190,7 @@ export type GetMetricMetadataParams = {
|
||||
* @type string
|
||||
* @description undefined
|
||||
*/
|
||||
metricName?: string;
|
||||
metricName: string;
|
||||
};
|
||||
|
||||
export type GetMetricMetadata200 = {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
@@ -16,7 +15,9 @@ import type {
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
import type {
|
||||
AcceptInvite201,
|
||||
ChangePasswordPathParameters,
|
||||
@@ -37,8 +38,9 @@ import type {
|
||||
RenderErrorResponseDTO,
|
||||
RevokeAPIKeyPathParameters,
|
||||
TypesChangePasswordRequestDTO,
|
||||
TypesPostableAPIKeyDTO,
|
||||
TypesPostableAcceptInviteDTO,
|
||||
TypesPostableAPIKeyDTO,
|
||||
TypesPostableForgotPasswordDTO,
|
||||
TypesPostableInviteDTO,
|
||||
TypesPostableResetPasswordDTO,
|
||||
TypesStorableAPIKeyDTO,
|
||||
@@ -48,8 +50,6 @@ import type {
|
||||
UpdateUserPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../index';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
@@ -1568,3 +1568,87 @@ export const invalidateGetMyUser = async (
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint initiates the forgot password flow by sending a reset password email
|
||||
* @summary Forgot password
|
||||
*/
|
||||
export const forgotPassword = (
|
||||
typesPostableForgotPasswordDTO: TypesPostableForgotPasswordDTO,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v2/factor_password/forgot`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: typesPostableForgotPasswordDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getForgotPasswordMutationOptions = <
|
||||
TError = RenderErrorResponseDTO,
|
||||
TContext = unknown
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof forgotPassword>>,
|
||||
TError,
|
||||
{ data: TypesPostableForgotPasswordDTO },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof forgotPassword>>,
|
||||
TError,
|
||||
{ data: TypesPostableForgotPasswordDTO },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['forgotPassword'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof forgotPassword>>,
|
||||
{ data: TypesPostableForgotPasswordDTO }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return forgotPassword(data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type ForgotPasswordMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof forgotPassword>>
|
||||
>;
|
||||
export type ForgotPasswordMutationBody = TypesPostableForgotPasswordDTO;
|
||||
export type ForgotPasswordMutationError = RenderErrorResponseDTO;
|
||||
|
||||
/**
|
||||
* @summary Forgot password
|
||||
*/
|
||||
export const useForgotPassword = <
|
||||
TError = RenderErrorResponseDTO,
|
||||
TContext = unknown
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof forgotPassword>>,
|
||||
TError,
|
||||
{ data: TypesPostableForgotPasswordDTO },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof forgotPassword>>,
|
||||
TError,
|
||||
{ data: TypesPostableForgotPasswordDTO },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getForgotPasswordMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable sonarjs/cognitive-complexity */
|
||||
/* eslint-disable no-param-reassign */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { QueryClient } from 'react-query';
|
||||
import getLocalStorageApi from 'api/browser/localstorage/get';
|
||||
import post from 'api/v2/sessions/rotate/post';
|
||||
import afterLogin from 'AppRoutes/utils';
|
||||
@@ -12,7 +13,6 @@ import axios, {
|
||||
import { ENVIRONMENT } from 'constants/env';
|
||||
import { Events } from 'constants/events';
|
||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||
import { QueryClient } from 'react-query';
|
||||
import { eventEmitter } from 'utils/getEventEmitter';
|
||||
|
||||
import apiV1, {
|
||||
|
||||
@@ -41,7 +41,7 @@ export const getConsumerLagDetails = async (
|
||||
> => {
|
||||
const { detailType, ...restProps } = props;
|
||||
const response = await axios.post(
|
||||
`/messaging-queues/kafka/consumer-lag/${props.detailType}`,
|
||||
`/messaging-queues/kafka/consumer-lag/${detailType}`,
|
||||
{
|
||||
...restProps,
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import axios from 'api';
|
||||
import { useMutation, UseMutationResult } from 'react-query';
|
||||
import axios from 'api';
|
||||
|
||||
export interface DeleteDowntimeScheduleProps {
|
||||
id?: number;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useQuery, UseQueryResult } from 'react-query';
|
||||
import axios from 'api';
|
||||
import { AxiosError, AxiosResponse } from 'axios';
|
||||
import { Option } from 'container/PlannedDowntime/PlannedDowntimeutils';
|
||||
import { useQuery, UseQueryResult } from 'react-query';
|
||||
|
||||
export type Recurrence = {
|
||||
startTime?: string | null;
|
||||
|
||||
1
frontend/src/auto-import-registry.d.ts
vendored
1
frontend/src/auto-import-registry.d.ts
vendored
@@ -18,6 +18,7 @@ import '@signozhq/checkbox';
|
||||
import '@signozhq/combobox';
|
||||
import '@signozhq/command';
|
||||
import '@signozhq/design-tokens';
|
||||
import '@signozhq/icons';
|
||||
import '@signozhq/input';
|
||||
import '@signozhq/popover';
|
||||
import '@signozhq/resizable';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import './Filters.styles.scss';
|
||||
|
||||
import DateTimeSelector from 'container/TopNav/DateTimeSelectionV2';
|
||||
|
||||
import './Filters.styles.scss';
|
||||
|
||||
export function Filters(): JSX.Element {
|
||||
return (
|
||||
<div className="filters">
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import './AppLoading.styles.scss';
|
||||
|
||||
import { Typography } from 'antd';
|
||||
import get from 'api/browser/localstorage/get';
|
||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||
import { THEME_MODE } from 'hooks/useDarkMode/constant';
|
||||
|
||||
import './AppLoading.styles.scss';
|
||||
|
||||
function AppLoading(): JSX.Element {
|
||||
// Get theme from localStorage directly to avoid context dependency
|
||||
const getThemeFromStorage = (): boolean => {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import './AuthError.styles.scss';
|
||||
|
||||
import ErrorContent from 'components/ErrorModal/components/ErrorContent';
|
||||
import { CircleAlert } from 'lucide-react';
|
||||
import APIError from 'types/api/error';
|
||||
|
||||
import './AuthError.styles.scss';
|
||||
|
||||
interface AuthErrorProps {
|
||||
error: APIError;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
padding: 12px;
|
||||
background: var(--bg-ink-400, #121317);
|
||||
border: 1px solid var(--bg-ink-200, #23262e);
|
||||
background: var(--bg-ink-400);
|
||||
border: 1px solid var(--bg-ink-200);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
color: var(--text-neutral-dark-100, #adb4c2);
|
||||
color: var(--text-neutral-dark-100);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
.auth-footer-link-icon {
|
||||
flex-shrink: 0;
|
||||
color: var(--text-neutral-dark-50, #eceef2);
|
||||
color: var(--text-neutral-dark-50);
|
||||
}
|
||||
|
||||
.auth-footer-link-status {
|
||||
@@ -84,14 +84,14 @@
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-ink-200, #23262e);
|
||||
background: var(--bg-ink-200);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.auth-footer-content {
|
||||
background: var(--bg-base-white, #ffffff);
|
||||
border-color: var(--bg-vanilla-300, #e9e9e9);
|
||||
background: var(--bg-base-white);
|
||||
border-color: var(--bg-vanilla-300);
|
||||
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
@@ -102,14 +102,14 @@
|
||||
}
|
||||
|
||||
.auth-footer-text {
|
||||
color: var(--text-neutral-light-200, #80828d);
|
||||
color: var(--text-neutral-light-200);
|
||||
}
|
||||
|
||||
.auth-footer-link-icon {
|
||||
color: var(--text-neutral-light-100, #62636c);
|
||||
color: var(--text-neutral-light-100);
|
||||
}
|
||||
|
||||
.auth-footer-separator {
|
||||
background: var(--bg-vanilla-300, #e9e9e9);
|
||||
background: var(--bg-vanilla-300);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import './AuthFooter.styles.scss';
|
||||
|
||||
import { ArrowUpRight } from 'lucide-react';
|
||||
import React from 'react';
|
||||
import { ArrowUpRight } from 'lucide-react';
|
||||
|
||||
import './AuthFooter.styles.scss';
|
||||
|
||||
interface FooterItem {
|
||||
icon?: string;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
font-size: 15.4px;
|
||||
font-weight: 500;
|
||||
line-height: 17.5px;
|
||||
color: var(--text-neutral-dark-50, #eceef2);
|
||||
color: var(--text-neutral-dark-50);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
gap: 8px;
|
||||
height: 32px;
|
||||
padding: 10px 16px;
|
||||
background: var(--bg-ink-400, #121317);
|
||||
background: var(--bg-ink-400);
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
@@ -52,13 +52,13 @@
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
color: var(--text-neutral-dark-100, #adb4c2);
|
||||
color: var(--text-neutral-dark-100);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
svg {
|
||||
flex-shrink: 0;
|
||||
color: var(--text-neutral-dark-100, #adb4c2);
|
||||
color: var(--text-neutral-dark-100);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -68,15 +68,15 @@
|
||||
|
||||
.lightMode {
|
||||
.auth-header-logo-text {
|
||||
color: var(--text-neutral-light-100, #62636c);
|
||||
color: var(--text-neutral-light-100);
|
||||
}
|
||||
|
||||
.auth-header-help-button {
|
||||
background: var(--bg-vanilla-200, #f5f5f5);
|
||||
background: var(--bg-vanilla-200);
|
||||
|
||||
span,
|
||||
svg {
|
||||
color: var(--text-neutral-light-200, #80828d);
|
||||
color: var(--text-neutral-light-200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import './AuthHeader.styles.scss';
|
||||
|
||||
import { useCallback } from 'react';
|
||||
import { Button } from '@signozhq/button';
|
||||
import { LifeBuoy } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import './AuthHeader.styles.scss';
|
||||
|
||||
function AuthHeader(): JSX.Element {
|
||||
const handleGetHelp = useCallback((): void => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
background: var(--bg-neutral-dark-1000, #0a0c10);
|
||||
background: var(--bg-neutral-dark-1000);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
.bg-dot-pattern {
|
||||
background: radial-gradient(
|
||||
circle,
|
||||
var(--bg-neutral-dark-50, #eceef2) 1px,
|
||||
var(--bg-neutral-dark-50) 1px,
|
||||
transparent 1px
|
||||
);
|
||||
background-size: 12px 12px;
|
||||
@@ -85,8 +85,8 @@
|
||||
height: 100%;
|
||||
background-image: repeating-linear-gradient(
|
||||
to bottom,
|
||||
var(--bg-ink-200, #23262e) 0px,
|
||||
var(--bg-ink-200, #23262e) 4px,
|
||||
var(--bg-ink-200) 0px,
|
||||
var(--bg-ink-200) 4px,
|
||||
transparent 4px,
|
||||
transparent 8px
|
||||
);
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
.lightMode {
|
||||
.auth-page-wrapper {
|
||||
background: var(--bg-base-white, #ffffff);
|
||||
background: var(--bg-base-white);
|
||||
}
|
||||
|
||||
.bg-dot-pattern {
|
||||
@@ -172,8 +172,8 @@
|
||||
.auth-page-line-right {
|
||||
background-image: repeating-linear-gradient(
|
||||
to bottom,
|
||||
var(--bg-vanilla-300, #e9e9e9) 0px,
|
||||
var(--bg-vanilla-300, #e9e9e9) 4px,
|
||||
var(--bg-vanilla-300) 0px,
|
||||
var(--bg-vanilla-300) 4px,
|
||||
transparent 4px,
|
||||
transparent 8px
|
||||
);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import './AuthPageContainer.styles.scss';
|
||||
|
||||
import { PropsWithChildren } from 'react';
|
||||
|
||||
import AuthFooter from './AuthFooter';
|
||||
import AuthHeader from './AuthHeader';
|
||||
|
||||
import './AuthPageContainer.styles.scss';
|
||||
|
||||
type AuthPageContainerProps = PropsWithChildren<{
|
||||
isOnboarding?: boolean;
|
||||
}>;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import './CeleryOverviewConfigOptions.styles.scss';
|
||||
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { Row, Select, Spin } from 'antd';
|
||||
import {
|
||||
getValuesFromQueryParams,
|
||||
@@ -9,8 +9,8 @@ import { useCeleryFilterOptions } from 'components/CeleryTask/useCeleryFilterOpt
|
||||
import { SelectMaxTagPlaceholder } from 'components/MessagingQueues/MQCommon/MQCommon';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
|
||||
import './CeleryOverviewConfigOptions.styles.scss';
|
||||
|
||||
export interface SelectOptionConfig {
|
||||
placeholder: string;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import './CeleryOverviewTable.styles.scss';
|
||||
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { LoadingOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import {
|
||||
@@ -27,13 +28,12 @@ import useDragColumns from 'hooks/useDragColumns';
|
||||
import { getDraggedColumns } from 'hooks/useDragColumns/utils';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
import { formatNumericValue } from 'utils/numericUtils';
|
||||
|
||||
import './CeleryOverviewTable.styles.scss';
|
||||
|
||||
const INITIAL_PAGE_SIZE = 20;
|
||||
|
||||
const showPaginationItem = (total: number, range: number[]): JSX.Element => (
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import './CeleryTaskConfigOptions.styles.scss';
|
||||
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { Select, Spin, Typography } from 'antd';
|
||||
import { SelectMaxTagPlaceholder } from 'components/MessagingQueues/MQCommon/MQCommon';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
getValuesFromQueryParams,
|
||||
@@ -12,6 +10,8 @@ import {
|
||||
} from '../CeleryUtils';
|
||||
import { useCeleryFilterOptions } from '../useCeleryFilterOptions';
|
||||
|
||||
import './CeleryTaskConfigOptions.styles.scss';
|
||||
|
||||
function CeleryTaskConfigOptions(): JSX.Element {
|
||||
const { handleSearch, isFetching, options } = useCeleryFilterOptions(
|
||||
'celery.task_name',
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { useQuery } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import { getAttributesValues } from 'api/queryBuilder/getAttributesValues';
|
||||
import { DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY } from 'constants/queryBuilder';
|
||||
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
||||
import { useQuery } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import './CeleryTaskDetail.style.scss';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Color, Spacing } from '@signozhq/design-tokens';
|
||||
import { Divider, Drawer, Typography } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
@@ -7,7 +6,6 @@ import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import dayjs from 'dayjs';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { X } from 'lucide-react';
|
||||
import { useState } from 'react';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
@@ -16,6 +14,8 @@ import CeleryTaskGraph from '../CeleryTaskGraph/CeleryTaskGraph';
|
||||
import { createFiltersFromData } from '../CeleryUtils';
|
||||
import { useNavigateToExplorer } from '../useNavigateToExplorer';
|
||||
|
||||
import './CeleryTaskDetail.style.scss';
|
||||
|
||||
export type CeleryTaskData = {
|
||||
entity: string;
|
||||
value: string | number;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import './CeleryTaskGraph.style.scss';
|
||||
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
@@ -10,9 +11,6 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { UpdateTimeInterval } from 'store/actions';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
@@ -39,6 +37,8 @@ import {
|
||||
CeleryTaskStateGraphConfig,
|
||||
} from './CeleryTaskStateGraphConfig';
|
||||
|
||||
import './CeleryTaskGraph.style.scss';
|
||||
|
||||
function CeleryTaskBar({
|
||||
onClick,
|
||||
queryEnabled,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { ENTITY_VERSION_V4 } from 'constants/app';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
@@ -8,9 +11,6 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { UpdateTimeInterval } from 'store/actions';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import './CeleryTaskGraph.style.scss';
|
||||
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Card, Typography } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { CardContainer } from 'container/GridCardLayout/styles';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
@@ -24,6 +22,8 @@ import {
|
||||
} from './CeleryTaskGraphUtils';
|
||||
import CeleryTaskLatencyGraph from './CeleryTaskLatencyGraph';
|
||||
|
||||
import './CeleryTaskGraph.style.scss';
|
||||
|
||||
export default function CeleryTaskGraphGrid({
|
||||
onClick,
|
||||
queryEnabled,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import './CeleryTaskGraph.style.scss';
|
||||
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { Col, Row } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { QueryParams } from 'constants/query';
|
||||
@@ -13,9 +14,6 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
||||
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { UpdateTimeInterval } from 'store/actions';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
@@ -29,6 +27,8 @@ import {
|
||||
import { useNavigateToExplorer } from '../useNavigateToExplorer';
|
||||
import { celeryTaskLatencyWidgetData } from './CeleryTaskGraphUtils';
|
||||
|
||||
import './CeleryTaskGraph.style.scss';
|
||||
|
||||
interface TabData {
|
||||
label: string;
|
||||
key: string;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/* eslint-disable no-nested-ternary */
|
||||
import './CeleryTaskGraph.style.scss';
|
||||
|
||||
import { Dispatch, SetStateAction, useMemo } from 'react';
|
||||
import { Col, Row } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { Dispatch, SetStateAction, useMemo } from 'react';
|
||||
|
||||
import {
|
||||
applyCeleryFilterOnWidgetData,
|
||||
@@ -19,6 +17,8 @@ import {
|
||||
} from './CeleryTaskGraphUtils';
|
||||
import { useGetValueFromWidget } from './useGetValueFromWidget';
|
||||
|
||||
import './CeleryTaskGraph.style.scss';
|
||||
|
||||
interface TabData {
|
||||
label: string;
|
||||
key: string;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useQueries } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { ENTITY_VERSION_V4 } from 'constants/app';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
|
||||
import { getQueryPayloadFromWidgetsData } from 'pages/Celery/CeleryOverview/CeleryOverviewUtils';
|
||||
import { useCallback } from 'react';
|
||||
import { useQueries } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { SuccessResponse } from 'types/api';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import useDebouncedFn from 'hooks/useDebouncedFunction';
|
||||
import { useState } from 'react';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import ROUTES from 'constants/routes';
|
||||
@@ -5,8 +7,6 @@ import useUpdatedQuery from 'container/GridCardLayout/useResolveQuery';
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||
import { useCallback } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource, MetricAggregateOperator } from 'types/common/queryBuilder';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import './ChangePercentagePill.styles.scss';
|
||||
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import cx from 'classnames';
|
||||
import { ArrowDown, ArrowUp } from 'lucide-react';
|
||||
|
||||
import './ChangePercentagePill.styles.scss';
|
||||
|
||||
interface ChangePercentagePillProps {
|
||||
percentage: number;
|
||||
direction: number;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import './ChangelogModal.styles.scss';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
|
||||
import { Button, Modal } from 'antd';
|
||||
import updateUserPreference from 'api/v1/user/preferences/name/update';
|
||||
@@ -9,13 +9,13 @@ import dayjs from 'dayjs';
|
||||
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
|
||||
import { ChevronsDown, ScrollText } from 'lucide-react';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
import { ChangelogSchema } from 'types/api/changelog/getChangelogByVersion';
|
||||
import { UserPreference } from 'types/api/preferences/preference';
|
||||
|
||||
import ChangelogRenderer from './components/ChangelogRenderer';
|
||||
|
||||
import './ChangelogModal.styles.scss';
|
||||
|
||||
interface Props {
|
||||
changelog: ChangelogSchema;
|
||||
onClose: () => void;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import './ChangelogRenderer.styles.scss';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
ChangelogSchema,
|
||||
Media,
|
||||
@@ -9,6 +7,8 @@ import {
|
||||
SupportedVideoTypes,
|
||||
} from 'types/api/changelog/getChangelogByVersion';
|
||||
|
||||
import './ChangelogRenderer.styles.scss';
|
||||
|
||||
interface Props {
|
||||
changelog: ChangelogSchema;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { Button, Modal, Typography } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import updateCreditCardApi from 'api/v1/checkout/create';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
import { CreditCard, MessageSquareText, X } from 'lucide-react';
|
||||
import { useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { SuccessResponseV2 } from 'types/api';
|
||||
import { CheckoutSuccessPayloadProps } from 'types/api/billing/checkout';
|
||||
import APIError from 'types/api/error';
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
/* eslint-disable sonarjs/cognitive-complexity */
|
||||
|
||||
import './ClientSideQBSearch.styles.scss';
|
||||
|
||||
import {
|
||||
KeyboardEvent,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Select, Tag, Tooltip } from 'antd';
|
||||
import {
|
||||
@@ -33,14 +39,6 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { isArray, isEmpty, isEqual, isObject } from 'lodash-es';
|
||||
import { ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import type { BaseSelectRef } from 'rc-select';
|
||||
import {
|
||||
KeyboardEvent,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
@@ -52,6 +50,8 @@ import {
|
||||
import { popupContainer } from 'utils/selectPopupContainer';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import './ClientSideQBSearch.styles.scss';
|
||||
|
||||
export interface AttributeKey {
|
||||
key: string;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user