mirror of
https://github.com/SigNoz/signoz.git
synced 2026-02-08 02:39:55 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1224222d5b | ||
|
|
c8e7abaa85 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -83,4 +83,3 @@ queries.active
|
||||
|
||||
# .devenv tmp files
|
||||
.devenv/**/tmp/**
|
||||
.qodo
|
||||
|
||||
4
Makefile
4
Makefile
@@ -74,10 +74,6 @@ go-run-enterprise: ## Runs the enterprise go backend server
|
||||
--use-logs-new-schema true \
|
||||
--use-trace-new-schema true
|
||||
|
||||
.PHONY: go-test
|
||||
go-test: ## Runs go unit tests
|
||||
@go test -race ./...
|
||||
|
||||
.PHONY: go-run-community
|
||||
go-run-community: ## Runs the community go backend server
|
||||
@SIGNOZ_INSTRUMENTATION_LOGS_LEVEL=debug \
|
||||
|
||||
@@ -72,6 +72,7 @@ sqlstore:
|
||||
# The path to the SQLite database file.
|
||||
path: /var/lib/signoz/signoz.db
|
||||
|
||||
|
||||
##################### APIServer #####################
|
||||
apiserver:
|
||||
timeout:
|
||||
@@ -90,29 +91,20 @@ apiserver:
|
||||
- /api/v1/version
|
||||
- /
|
||||
|
||||
|
||||
##################### TelemetryStore #####################
|
||||
telemetrystore:
|
||||
# Specifies the telemetrystore provider to use.
|
||||
provider: clickhouse
|
||||
# Maximum number of idle connections in the connection pool.
|
||||
max_idle_conns: 50
|
||||
# Maximum number of open connections to the database.
|
||||
max_open_conns: 100
|
||||
# Maximum time to wait for a connection to be established.
|
||||
dial_timeout: 5s
|
||||
# Specifies the telemetrystore provider to use.
|
||||
provider: clickhouse
|
||||
clickhouse:
|
||||
# The DSN to use for clickhouse.
|
||||
dsn: tcp://localhost:9000
|
||||
|
||||
##################### Prometheus #####################
|
||||
prometheus:
|
||||
active_query_tracker:
|
||||
# Whether to enable the active query tracker.
|
||||
enabled: true
|
||||
# The path to use for the active query tracker.
|
||||
path: ""
|
||||
# The maximum number of concurrent queries.
|
||||
max_concurrent: 20
|
||||
# The DSN to use for ClickHouse.
|
||||
dsn: http://localhost:9000
|
||||
|
||||
##################### Alertmanager #####################
|
||||
alertmanager:
|
||||
@@ -125,7 +117,7 @@ alertmanager:
|
||||
# The poll interval for periodically syncing the alertmanager with the config in the store.
|
||||
poll_interval: 1m
|
||||
# The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy). Used for generating relative and absolute links back to Alertmanager itself.
|
||||
external_url: http://localhost:8080
|
||||
external_url: http://localhost:9093
|
||||
# The global configuration for the alertmanager. All the exahustive fields can be found in the upstream: https://github.com/prometheus/alertmanager/blob/efa05feffd644ba4accb526e98a8c6545d26a783/config/config.go#L833
|
||||
global:
|
||||
# ResolveTimeout is the time after which an alert is declared resolved if it has not been updated.
|
||||
|
||||
@@ -174,7 +174,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:v0.77.0
|
||||
image: signoz/signoz:v0.76.2
|
||||
command:
|
||||
- --config=/root/config/prometheus.yml
|
||||
- --use-logs-new-schema=true
|
||||
@@ -208,7 +208,7 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:v0.111.37
|
||||
image: signoz/signoz-otel-collector:v0.111.34
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
- --manager-config=/etc/manager-config.yaml
|
||||
@@ -232,7 +232,7 @@ services:
|
||||
- signoz
|
||||
schema-migrator:
|
||||
!!merge <<: *common
|
||||
image: signoz/signoz-schema-migrator:v0.111.37
|
||||
image: signoz/signoz-schema-migrator:v0.111.34
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
||||
@@ -110,7 +110,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:v0.77.0
|
||||
image: signoz/signoz:v0.76.2
|
||||
command:
|
||||
- --config=/root/config/prometheus.yml
|
||||
- --use-logs-new-schema=true
|
||||
@@ -143,7 +143,7 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:v0.111.37
|
||||
image: signoz/signoz-otel-collector:v0.111.34
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
- --manager-config=/etc/manager-config.yaml
|
||||
@@ -167,7 +167,7 @@ services:
|
||||
- signoz
|
||||
schema-migrator:
|
||||
!!merge <<: *common
|
||||
image: signoz/signoz-schema-migrator:v0.111.37
|
||||
image: signoz/signoz-schema-migrator:v0.111.34
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
||||
@@ -177,7 +177,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:${VERSION:-v0.77.0}
|
||||
image: signoz/signoz:${VERSION:-v0.76.2}
|
||||
container_name: signoz
|
||||
command:
|
||||
- --config=/root/config/prometheus.yml
|
||||
@@ -212,7 +212,7 @@ services:
|
||||
# TODO: support otel-collector multiple replicas. Nginx/Traefik for loadbalancing?
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.111.37}
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.111.34}
|
||||
container_name: signoz-otel-collector
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
@@ -238,7 +238,7 @@ services:
|
||||
condition: service_healthy
|
||||
schema-migrator-sync:
|
||||
!!merge <<: *common
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.37}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.34}
|
||||
container_name: schema-migrator-sync
|
||||
command:
|
||||
- sync
|
||||
@@ -249,7 +249,7 @@ services:
|
||||
condition: service_healthy
|
||||
schema-migrator-async:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.37}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.34}
|
||||
container_name: schema-migrator-async
|
||||
command:
|
||||
- async
|
||||
|
||||
@@ -110,7 +110,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:${VERSION:-v0.77.0}
|
||||
image: signoz/signoz:${VERSION:-v0.76.2}
|
||||
container_name: signoz
|
||||
command:
|
||||
- --config=/root/config/prometheus.yml
|
||||
@@ -146,7 +146,7 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.111.37}
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.111.34}
|
||||
container_name: signoz-otel-collector
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
@@ -168,7 +168,7 @@ services:
|
||||
condition: service_healthy
|
||||
schema-migrator-sync:
|
||||
!!merge <<: *common
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.37}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.34}
|
||||
container_name: schema-migrator-sync
|
||||
command:
|
||||
- sync
|
||||
@@ -180,7 +180,7 @@ services:
|
||||
restart: on-failure
|
||||
schema-migrator-async:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.37}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.34}
|
||||
container_name: schema-migrator-async
|
||||
command:
|
||||
- async
|
||||
|
||||
@@ -110,7 +110,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:${VERSION:-v0.77.0}
|
||||
image: signoz/signoz:${VERSION:-v0.76.2}
|
||||
container_name: signoz
|
||||
command:
|
||||
- --config=/root/config/prometheus.yml
|
||||
@@ -144,7 +144,7 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.111.37}
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.111.34}
|
||||
container_name: signoz-otel-collector
|
||||
command:
|
||||
- --config=/etc/otel-collector-config.yaml
|
||||
@@ -166,7 +166,7 @@ services:
|
||||
condition: service_healthy
|
||||
schema-migrator-sync:
|
||||
!!merge <<: *common
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.37}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.34}
|
||||
container_name: schema-migrator-sync
|
||||
command:
|
||||
- sync
|
||||
@@ -178,7 +178,7 @@ services:
|
||||
restart: on-failure
|
||||
schema-migrator-async:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.37}
|
||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.111.34}
|
||||
container_name: schema-migrator-async
|
||||
command:
|
||||
- async
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
eeTypes "github.com/SigNoz/signoz/ee/types"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
@@ -25,7 +24,7 @@ func (p *Pat) Wrap(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var values []string
|
||||
var patToken string
|
||||
var pat eeTypes.StorablePersonalAccessToken
|
||||
var pat types.StorablePersonalAccessToken
|
||||
|
||||
for _, header := range p.headers {
|
||||
values = append(values, r.Header.Get(header))
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package licensingserver
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/licensing"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
PollingConfig PollingConfig `mapstructure:"polling"`
|
||||
}
|
||||
|
||||
type PollingConfig struct {
|
||||
Interval time.Duration `mapstructure:"interval"`
|
||||
}
|
||||
|
||||
func NewConfig() Config {
|
||||
return Config{
|
||||
PollingConfig: PollingConfig{
|
||||
Interval: 24 * time.Hour,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewConfigFromLicensingConfig(config licensing.Config) Config {
|
||||
return Config{
|
||||
PollingConfig: PollingConfig{
|
||||
Interval: config.PollingConfig.Interval,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package licensingserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"sync"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/licensetypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
logger *slog.Logger
|
||||
|
||||
cfg Config
|
||||
|
||||
orgID valuer.UUID
|
||||
|
||||
zeus zeus.Zeus
|
||||
|
||||
store licensetypes.Store
|
||||
|
||||
license licensetypes.License
|
||||
|
||||
mtx sync.RWMutex
|
||||
}
|
||||
|
||||
func NewServer(logger *slog.Logger, config Config, orgID valuer.UUID, zeus zeus.Zeus, store licensetypes.Store) *Server {
|
||||
return &Server{
|
||||
logger: logger,
|
||||
cfg: config,
|
||||
orgID: orgID,
|
||||
zeus: zeus,
|
||||
store: store,
|
||||
license: licensetypes.NewNoop(),
|
||||
}
|
||||
}
|
||||
|
||||
func (server *Server) Fetch(ctx context.Context) error {
|
||||
license, err := server.store.GetLatest(ctx, server.orgID)
|
||||
if err != nil {
|
||||
if errors.Ast(err, errors.TypeNotFound) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
fetchedLicense, err := server.zeus.GetLicense(ctx, license.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return server.SetLicense(ctx, fetchedLicense)
|
||||
}
|
||||
|
||||
func (server *Server) SetLicense(ctx context.Context, license licensetypes.License) error {
|
||||
server.mtx.Lock()
|
||||
defer server.mtx.Unlock()
|
||||
|
||||
server.license = license
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *Server) GetLicense(ctx context.Context) licensetypes.License {
|
||||
server.mtx.RLock()
|
||||
defer server.mtx.RUnlock()
|
||||
|
||||
return server.license
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package sqllicensingstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/types/licensetypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
)
|
||||
|
||||
type store struct {
|
||||
sqlstore sqlstore.SQLStore
|
||||
}
|
||||
|
||||
func NewStore(sqlstore sqlstore.SQLStore) licensetypes.Store {
|
||||
return &store{
|
||||
sqlstore: sqlstore,
|
||||
}
|
||||
}
|
||||
|
||||
func (store *store) Set(ctx context.Context, license licensetypes.License) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *store) Get(ctx context.Context, orgID valuer.UUID) ([]licensetypes.License, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (store *store) GetLatest(ctx context.Context, orgID valuer.UUID) (licensetypes.License, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (store *store) ListOrgs(ctx context.Context) ([]valuer.UUID, error) {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
package pollinglicensing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/licensing/licensingstore/sqllicensingstore"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/licensing"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/types/licensetypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
)
|
||||
|
||||
type provider struct {
|
||||
config licensing.Config
|
||||
settings factory.ScopedProviderSettings
|
||||
zeus zeus.Zeus
|
||||
service *Service
|
||||
store licensetypes.Store
|
||||
stopC chan struct{}
|
||||
}
|
||||
|
||||
func NewFactory(zeus zeus.Zeus, sqlstore sqlstore.SQLStore) factory.ProviderFactory[licensing.Licensing, licensing.Config] {
|
||||
return factory.NewProviderFactory(factory.MustNewName("sql"), func(ctx context.Context, providerSettings factory.ProviderSettings, config licensing.Config) (licensing.Licensing, error) {
|
||||
return New(ctx, providerSettings, config, zeus, sqlstore)
|
||||
})
|
||||
}
|
||||
|
||||
func New(ctx context.Context, providerSettings factory.ProviderSettings, config licensing.Config, zeus zeus.Zeus, sqlstore sqlstore.SQLStore) (licensing.Licensing, error) {
|
||||
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/ee/licensing/pollinglicensing")
|
||||
store := sqllicensingstore.NewStore(sqlstore)
|
||||
|
||||
return &provider{
|
||||
config: config,
|
||||
settings: settings,
|
||||
zeus: zeus,
|
||||
service: NewService(ctx, settings, config, store, zeus),
|
||||
stopC: make(chan struct{}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (provider *provider) Start(ctx context.Context) error {
|
||||
if err := provider.service.SyncServers(ctx); err != nil {
|
||||
provider.settings.Logger().ErrorContext(ctx, "failed to sync licensing servers", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(provider.config.PollingConfig.Interval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-provider.stopC:
|
||||
return nil
|
||||
case <-ticker.C:
|
||||
if err := provider.service.SyncServers(ctx); err != nil {
|
||||
provider.settings.Logger().ErrorContext(ctx, "failed to sync licensing servers", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (provider *provider) GetLatestLicense(ctx context.Context, orgID valuer.UUID) (licensetypes.License, error) {
|
||||
server, err := provider.service.getServer(orgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return server.GetLicense(ctx), nil
|
||||
}
|
||||
|
||||
func (provider *provider) GetLicenses(ctx context.Context, orgID valuer.UUID, params licensetypes.GettableLicenseParams) (licensetypes.GettableLicenses, error) {
|
||||
if params.Active != nil {
|
||||
if *params.Active {
|
||||
license, err := provider.GetLatestLicense(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return licensetypes.GettableLicenses{license}, nil
|
||||
}
|
||||
}
|
||||
|
||||
licenses, err := provider.store.Get(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return licenses, nil
|
||||
}
|
||||
|
||||
func (provider *provider) SetLicense(ctx context.Context, orgID valuer.UUID, key string) error {
|
||||
license, err := provider.zeus.GetLicense(ctx, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := provider.store.Set(ctx, license); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return provider.service.SyncOrgServer(ctx, orgID)
|
||||
}
|
||||
|
||||
func (provider *provider) Stop(ctx context.Context) error {
|
||||
close(provider.stopC)
|
||||
return nil
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package pollinglicensing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/licensing/licensingserver"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/licensing"
|
||||
"github.com/SigNoz/signoz/pkg/types/licensetypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
// config is the config for the licensing service
|
||||
config licensing.Config
|
||||
|
||||
// store is the store for the licensing service
|
||||
store licensetypes.Store
|
||||
|
||||
// zeus
|
||||
zeus zeus.Zeus
|
||||
|
||||
// settings is the settings for the licensing service
|
||||
settings factory.ScopedProviderSettings
|
||||
|
||||
// Map of organization id to alertmanager server
|
||||
servers map[valuer.UUID]*licensingserver.Server
|
||||
|
||||
// Mutex to protect the servers map
|
||||
serversMtx sync.RWMutex
|
||||
}
|
||||
|
||||
func NewService(ctx context.Context, settings factory.ScopedProviderSettings, config licensing.Config, store licensetypes.Store, zeus zeus.Zeus) *Service {
|
||||
service := &Service{
|
||||
config: config,
|
||||
store: store,
|
||||
zeus: zeus,
|
||||
settings: settings,
|
||||
servers: make(map[valuer.UUID]*licensingserver.Server),
|
||||
serversMtx: sync.RWMutex{},
|
||||
}
|
||||
|
||||
return service
|
||||
}
|
||||
|
||||
func (service *Service) SyncServers(ctx context.Context) error {
|
||||
orgIDs, err := service.store.ListOrgs(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
service.serversMtx.Lock()
|
||||
for _, orgID := range orgIDs {
|
||||
// If the server is not present, create it and sync the config
|
||||
if _, ok := service.servers[orgID]; !ok {
|
||||
server := licensingserver.NewServer(service.settings.Logger(), licensingserver.NewConfigFromLicensingConfig(service.config), orgID, service.zeus, service.store)
|
||||
service.servers[orgID] = server
|
||||
}
|
||||
|
||||
err = service.servers[orgID].Fetch(ctx)
|
||||
if err != nil {
|
||||
service.settings.Logger().Error("failed to fetch license for licensing server", "orgID", orgID, "error", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
service.serversMtx.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service *Service) SyncOrgServer(ctx context.Context, orgID valuer.UUID) error {
|
||||
service.serversMtx.Lock()
|
||||
defer service.serversMtx.Unlock()
|
||||
|
||||
_, ok := service.servers[orgID]
|
||||
if !ok {
|
||||
server := licensingserver.NewServer(service.settings.Logger(), licensingserver.NewConfigFromLicensingConfig(service.config), orgID, service.zeus, service.store)
|
||||
service.servers[orgID] = server
|
||||
}
|
||||
|
||||
err := service.servers[orgID].Fetch(ctx)
|
||||
if err != nil {
|
||||
service.settings.Logger().Error("failed to fetch license for licensing server", "orgID", orgID, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service *Service) getServer(orgID valuer.UUID) (*licensingserver.Server, error) {
|
||||
service.serversMtx.RLock()
|
||||
defer service.serversMtx.RUnlock()
|
||||
|
||||
server, ok := service.servers[orgID]
|
||||
if !ok {
|
||||
return nil, errors.Newf(errors.TypeNotFound, licensing.ErrCodeLicensingServerNotFound, "server not found for %s", orgID.StringValue())
|
||||
}
|
||||
|
||||
return server, nil
|
||||
}
|
||||
@@ -28,10 +28,11 @@ func NewDailyProvider(opts ...GenericProviderOption[*DailyProvider]) *DailyProvi
|
||||
}
|
||||
|
||||
dp.querierV2 = querierV2.NewQuerier(querierV2.QuerierOptions{
|
||||
Reader: dp.reader,
|
||||
Cache: dp.cache,
|
||||
KeyGenerator: queryBuilder.NewKeyGenerator(),
|
||||
FluxInterval: dp.fluxInterval,
|
||||
Reader: dp.reader,
|
||||
Cache: dp.cache,
|
||||
KeyGenerator: queryBuilder.NewKeyGenerator(),
|
||||
FluxInterval: dp.fluxInterval,
|
||||
FeatureLookup: dp.ff,
|
||||
})
|
||||
|
||||
return dp
|
||||
|
||||
@@ -28,10 +28,11 @@ func NewHourlyProvider(opts ...GenericProviderOption[*HourlyProvider]) *HourlyPr
|
||||
}
|
||||
|
||||
hp.querierV2 = querierV2.NewQuerier(querierV2.QuerierOptions{
|
||||
Reader: hp.reader,
|
||||
Cache: hp.cache,
|
||||
KeyGenerator: queryBuilder.NewKeyGenerator(),
|
||||
FluxInterval: hp.fluxInterval,
|
||||
Reader: hp.reader,
|
||||
Cache: hp.cache,
|
||||
KeyGenerator: queryBuilder.NewKeyGenerator(),
|
||||
FluxInterval: hp.fluxInterval,
|
||||
FeatureLookup: hp.ff,
|
||||
})
|
||||
|
||||
return hp
|
||||
|
||||
@@ -38,6 +38,12 @@ func WithKeyGenerator[T BaseProvider](keyGenerator cache.KeyGenerator) GenericPr
|
||||
}
|
||||
}
|
||||
|
||||
func WithFeatureLookup[T BaseProvider](ff interfaces.FeatureLookup) GenericProviderOption[T] {
|
||||
return func(p T) {
|
||||
p.GetBaseSeasonalProvider().ff = ff
|
||||
}
|
||||
}
|
||||
|
||||
func WithReader[T BaseProvider](reader interfaces.Reader) GenericProviderOption[T] {
|
||||
return func(p T) {
|
||||
p.GetBaseSeasonalProvider().reader = reader
|
||||
@@ -50,6 +56,7 @@ type BaseSeasonalProvider struct {
|
||||
fluxInterval time.Duration
|
||||
cache cache.Cache
|
||||
keyGenerator cache.KeyGenerator
|
||||
ff interfaces.FeatureLookup
|
||||
}
|
||||
|
||||
func (p *BaseSeasonalProvider) getQueryParams(req *GetAnomaliesRequest) *anomalyQueryParams {
|
||||
|
||||
@@ -27,10 +27,11 @@ func NewWeeklyProvider(opts ...GenericProviderOption[*WeeklyProvider]) *WeeklyPr
|
||||
}
|
||||
|
||||
wp.querierV2 = querierV2.NewQuerier(querierV2.QuerierOptions{
|
||||
Reader: wp.reader,
|
||||
Cache: wp.cache,
|
||||
KeyGenerator: queryBuilder.NewKeyGenerator(),
|
||||
FluxInterval: wp.fluxInterval,
|
||||
Reader: wp.reader,
|
||||
Cache: wp.cache,
|
||||
KeyGenerator: queryBuilder.NewKeyGenerator(),
|
||||
FluxInterval: wp.fluxInterval,
|
||||
FeatureLookup: wp.ff,
|
||||
})
|
||||
|
||||
return wp
|
||||
|
||||
@@ -7,11 +7,10 @@ import (
|
||||
|
||||
"github.com/SigNoz/signoz/ee/query-service/dao"
|
||||
"github.com/SigNoz/signoz/ee/query-service/integrations/gateway"
|
||||
"github.com/SigNoz/signoz/ee/query-service/interfaces"
|
||||
"github.com/SigNoz/signoz/ee/query-service/license"
|
||||
"github.com/SigNoz/signoz/ee/query-service/usage"
|
||||
"github.com/SigNoz/signoz/pkg/alertmanager"
|
||||
"github.com/SigNoz/signoz/pkg/modules/preference"
|
||||
preferencecore "github.com/SigNoz/signoz/pkg/modules/preference/core"
|
||||
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/app/integrations"
|
||||
@@ -22,13 +21,12 @@ import (
|
||||
rules "github.com/SigNoz/signoz/pkg/query-service/rules"
|
||||
"github.com/SigNoz/signoz/pkg/signoz"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
|
||||
"github.com/SigNoz/signoz/pkg/version"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type APIHandlerOptions struct {
|
||||
DataConnector baseint.Reader
|
||||
DataConnector interfaces.DataConnector
|
||||
SkipConfig *basemodel.SkipConfig
|
||||
PreferSpanMetrics bool
|
||||
AppDao dao.ModelDao
|
||||
@@ -56,7 +54,6 @@ type APIHandler struct {
|
||||
|
||||
// NewAPIHandler returns an APIHandler
|
||||
func NewAPIHandler(opts APIHandlerOptions, signoz *signoz.SigNoz) (*APIHandler, error) {
|
||||
preference := preference.NewAPI(preferencecore.NewPreference(preferencecore.NewStore(signoz.SQLStore), preferencetypes.NewDefaultPreferenceMap()))
|
||||
|
||||
baseHandler, err := baseapp.NewAPIHandler(baseapp.APIHandlerOpts{
|
||||
Reader: opts.DataConnector,
|
||||
@@ -74,7 +71,6 @@ func NewAPIHandler(opts APIHandlerOptions, signoz *signoz.SigNoz) (*APIHandler,
|
||||
UseTraceNewSchema: opts.UseTraceNewSchema,
|
||||
AlertmanagerAPI: alertmanager.NewAPI(signoz.Alertmanager),
|
||||
Signoz: signoz,
|
||||
Preference: preference,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -161,6 +157,7 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *baseapp.AuthMiddlew
|
||||
router.HandleFunc("/api/v1/invite/{token}", am.OpenAccess(ah.getInvite)).Methods(http.MethodGet)
|
||||
router.HandleFunc("/api/v1/register", am.OpenAccess(ah.registerUser)).Methods(http.MethodPost)
|
||||
router.HandleFunc("/api/v1/login", am.OpenAccess(ah.loginUser)).Methods(http.MethodPost)
|
||||
router.HandleFunc("/api/v1/traces/{traceId}", am.ViewAccess(ah.searchTraces)).Methods(http.MethodGet)
|
||||
|
||||
// PAT APIs
|
||||
router.HandleFunc("/api/v1/pats", am.AdminAccess(ah.createPAT)).Methods(http.MethodPost)
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/query-service/constants"
|
||||
eeTypes "github.com/SigNoz/signoz/ee/types"
|
||||
"github.com/SigNoz/signoz/ee/query-service/model"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/auth"
|
||||
baseconstants "github.com/SigNoz/signoz/pkg/query-service/constants"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/dao"
|
||||
@@ -135,12 +135,19 @@ func (ah *APIHandler) getOrCreateCloudIntegrationPAT(ctx context.Context, orgId
|
||||
zap.String("cloudProvider", cloudProvider),
|
||||
)
|
||||
|
||||
newPAT := eeTypes.NewGettablePAT(
|
||||
integrationPATName,
|
||||
baseconstants.ViewerGroup,
|
||||
integrationUser.ID,
|
||||
0,
|
||||
)
|
||||
newPAT := model.PAT{
|
||||
StorablePersonalAccessToken: types.StorablePersonalAccessToken{
|
||||
Token: generatePATToken(),
|
||||
UserID: integrationUser.ID,
|
||||
Name: integrationPATName,
|
||||
Role: baseconstants.ViewerGroup,
|
||||
ExpiresAt: 0,
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
integrationPAT, err := ah.AppDao().CreatePAT(ctx, orgId, newPAT)
|
||||
if err != nil {
|
||||
return "", basemodel.InternalError(fmt.Errorf(
|
||||
|
||||
@@ -2,24 +2,31 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/query-service/model"
|
||||
"github.com/SigNoz/signoz/ee/types"
|
||||
eeTypes "github.com/SigNoz/signoz/ee/types"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/http/render"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/auth"
|
||||
baseconstants "github.com/SigNoz/signoz/pkg/query-service/constants"
|
||||
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func generatePATToken() string {
|
||||
// Generate a 32-byte random token.
|
||||
token := make([]byte, 32)
|
||||
rand.Read(token)
|
||||
// Encode the token in base64.
|
||||
encodedToken := base64.StdEncoding.EncodeToString(token)
|
||||
return encodedToken
|
||||
}
|
||||
|
||||
func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.Background()
|
||||
|
||||
@@ -36,18 +43,31 @@ func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
|
||||
}, nil)
|
||||
return
|
||||
}
|
||||
pat := eeTypes.NewGettablePAT(
|
||||
req.Name,
|
||||
req.Role,
|
||||
user.ID,
|
||||
req.ExpiresInDays,
|
||||
)
|
||||
pat := model.PAT{
|
||||
StorablePersonalAccessToken: types.StorablePersonalAccessToken{
|
||||
Name: req.Name,
|
||||
Role: req.Role,
|
||||
ExpiresAt: req.ExpiresInDays,
|
||||
},
|
||||
}
|
||||
err = validatePATRequest(pat)
|
||||
if err != nil {
|
||||
RespondError(w, model.BadRequest(err), nil)
|
||||
return
|
||||
}
|
||||
|
||||
// All the PATs are associated with the user creating the PAT.
|
||||
pat.UserID = user.ID
|
||||
pat.CreatedAt = time.Now()
|
||||
pat.UpdatedAt = time.Now()
|
||||
pat.LastUsed = 0
|
||||
pat.Token = generatePATToken()
|
||||
|
||||
if pat.ExpiresAt != 0 {
|
||||
// convert expiresAt to unix timestamp from days
|
||||
pat.ExpiresAt = time.Now().Unix() + (pat.ExpiresAt * 24 * 60 * 60)
|
||||
}
|
||||
|
||||
zap.L().Info("Got Create PAT request", zap.Any("pat", pat))
|
||||
var apierr basemodel.BaseApiError
|
||||
if pat, apierr = ah.AppDao().CreatePAT(ctx, user.OrgID, pat); apierr != nil {
|
||||
@@ -58,7 +78,7 @@ func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
|
||||
ah.Respond(w, &pat)
|
||||
}
|
||||
|
||||
func validatePATRequest(req types.GettablePAT) error {
|
||||
func validatePATRequest(req model.PAT) error {
|
||||
if req.Role == "" || (req.Role != baseconstants.ViewerGroup && req.Role != baseconstants.EditorGroup && req.Role != baseconstants.AdminGroup) {
|
||||
return fmt.Errorf("valid role is required")
|
||||
}
|
||||
@@ -74,7 +94,7 @@ func validatePATRequest(req types.GettablePAT) error {
|
||||
func (ah *APIHandler) updatePAT(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.Background()
|
||||
|
||||
req := types.GettablePAT{}
|
||||
req := model.PAT{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
RespondError(w, model.BadRequest(err), nil)
|
||||
return
|
||||
@@ -96,12 +116,7 @@ func (ah *APIHandler) updatePAT(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
req.UpdatedByUserID = user.ID
|
||||
idStr := mux.Vars(r)["id"]
|
||||
id, err := valuer.NewUUID(idStr)
|
||||
if err != nil {
|
||||
render.Error(w, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is not a valid uuid-v7"))
|
||||
return
|
||||
}
|
||||
id := mux.Vars(r)["id"]
|
||||
req.UpdatedAt = time.Now()
|
||||
zap.L().Info("Got Update PAT request", zap.Any("pat", req))
|
||||
var apierr basemodel.BaseApiError
|
||||
@@ -134,12 +149,7 @@ func (ah *APIHandler) getPATs(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (ah *APIHandler) revokePAT(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.Background()
|
||||
idStr := mux.Vars(r)["id"]
|
||||
id, err := valuer.NewUUID(idStr)
|
||||
if err != nil {
|
||||
render.Error(w, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is not a valid uuid-v7"))
|
||||
return
|
||||
}
|
||||
id := mux.Vars(r)["id"]
|
||||
user, err := auth.GetUserFromReqContext(r.Context())
|
||||
if err != nil {
|
||||
RespondError(w, &model.ApiError{
|
||||
@@ -149,7 +159,7 @@ func (ah *APIHandler) revokePAT(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
zap.L().Info("Revoke PAT with id", zap.String("id", id.StringValue()))
|
||||
zap.L().Info("Revoke PAT with id", zap.String("id", id))
|
||||
if apierr := ah.AppDao().RevokePAT(ctx, user.OrgID, id, user.ID); apierr != nil {
|
||||
RespondError(w, apierr, nil)
|
||||
return
|
||||
|
||||
@@ -88,24 +88,28 @@ func (aH *APIHandler) queryRangeV4(w http.ResponseWriter, r *http.Request) {
|
||||
anomaly.WithCache[*anomaly.WeeklyProvider](aH.opts.Cache),
|
||||
anomaly.WithKeyGenerator[*anomaly.WeeklyProvider](queryBuilder.NewKeyGenerator()),
|
||||
anomaly.WithReader[*anomaly.WeeklyProvider](aH.opts.DataConnector),
|
||||
anomaly.WithFeatureLookup[*anomaly.WeeklyProvider](aH.opts.FeatureFlags),
|
||||
)
|
||||
case anomaly.SeasonalityDaily:
|
||||
provider = anomaly.NewDailyProvider(
|
||||
anomaly.WithCache[*anomaly.DailyProvider](aH.opts.Cache),
|
||||
anomaly.WithKeyGenerator[*anomaly.DailyProvider](queryBuilder.NewKeyGenerator()),
|
||||
anomaly.WithReader[*anomaly.DailyProvider](aH.opts.DataConnector),
|
||||
anomaly.WithFeatureLookup[*anomaly.DailyProvider](aH.opts.FeatureFlags),
|
||||
)
|
||||
case anomaly.SeasonalityHourly:
|
||||
provider = anomaly.NewHourlyProvider(
|
||||
anomaly.WithCache[*anomaly.HourlyProvider](aH.opts.Cache),
|
||||
anomaly.WithKeyGenerator[*anomaly.HourlyProvider](queryBuilder.NewKeyGenerator()),
|
||||
anomaly.WithReader[*anomaly.HourlyProvider](aH.opts.DataConnector),
|
||||
anomaly.WithFeatureLookup[*anomaly.HourlyProvider](aH.opts.FeatureFlags),
|
||||
)
|
||||
default:
|
||||
provider = anomaly.NewDailyProvider(
|
||||
anomaly.WithCache[*anomaly.DailyProvider](aH.opts.Cache),
|
||||
anomaly.WithKeyGenerator[*anomaly.DailyProvider](queryBuilder.NewKeyGenerator()),
|
||||
anomaly.WithReader[*anomaly.DailyProvider](aH.opts.DataConnector),
|
||||
anomaly.WithFeatureLookup[*anomaly.DailyProvider](aH.opts.FeatureFlags),
|
||||
)
|
||||
}
|
||||
anomalies, err := provider.GetAnomalies(r.Context(), &anomaly.GetAnomaliesRequest{Params: queryRangeParams})
|
||||
|
||||
33
ee/query-service/app/api/traces.go
Normal file
33
ee/query-service/app/api/traces.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/query-service/app/db"
|
||||
"github.com/SigNoz/signoz/ee/query-service/model"
|
||||
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
|
||||
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func (ah *APIHandler) searchTraces(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if !ah.CheckFeature(basemodel.SmartTraceDetail) {
|
||||
zap.L().Info("SmartTraceDetail feature is not enabled in this plan")
|
||||
ah.APIHandler.SearchTraces(w, r)
|
||||
return
|
||||
}
|
||||
searchTracesParams, err := baseapp.ParseSearchTracesParams(r)
|
||||
if err != nil {
|
||||
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, "Error reading params")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := ah.opts.DataConnector.SearchTraces(r.Context(), searchTracesParams, db.SmartTraceAlgorithm)
|
||||
if ah.HandleError(w, err, http.StatusBadRequest) {
|
||||
return
|
||||
}
|
||||
|
||||
ah.WriteJSON(w, r, result)
|
||||
|
||||
}
|
||||
@@ -5,33 +5,38 @@ import (
|
||||
|
||||
"github.com/ClickHouse/clickhouse-go/v2"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/cache"
|
||||
"github.com/SigNoz/signoz/pkg/prometheus"
|
||||
basechr "github.com/SigNoz/signoz/pkg/query-service/app/clickhouseReader"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrystore"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/interfaces"
|
||||
)
|
||||
|
||||
type ClickhouseReader struct {
|
||||
conn clickhouse.Conn
|
||||
appdb sqlstore.SQLStore
|
||||
appdb *sqlx.DB
|
||||
*basechr.ClickHouseReader
|
||||
}
|
||||
|
||||
func NewDataConnector(
|
||||
sqlDB sqlstore.SQLStore,
|
||||
telemetryStore telemetrystore.TelemetryStore,
|
||||
prometheus prometheus.Prometheus,
|
||||
localDB *sqlx.DB,
|
||||
ch clickhouse.Conn,
|
||||
promConfigPath string,
|
||||
lm interfaces.FeatureLookup,
|
||||
cluster string,
|
||||
useLogsNewSchema bool,
|
||||
useTraceNewSchema bool,
|
||||
fluxIntervalForTraceDetail time.Duration,
|
||||
cache cache.Cache,
|
||||
) *ClickhouseReader {
|
||||
chReader := basechr.NewReader(sqlDB, telemetryStore, prometheus, cluster, useLogsNewSchema, useTraceNewSchema, fluxIntervalForTraceDetail, cache)
|
||||
chReader := basechr.NewReader(localDB, ch, promConfigPath, lm, cluster, useLogsNewSchema, useTraceNewSchema, fluxIntervalForTraceDetail, cache)
|
||||
return &ClickhouseReader{
|
||||
conn: telemetryStore.ClickhouseDB(),
|
||||
appdb: sqlDB,
|
||||
conn: ch,
|
||||
appdb: localDB,
|
||||
ClickHouseReader: chReader,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ClickhouseReader) Start(readerReady chan bool) {
|
||||
r.ClickHouseReader.Start(readerReady)
|
||||
}
|
||||
|
||||
@@ -18,14 +18,13 @@ import (
|
||||
"github.com/SigNoz/signoz/ee/query-service/constants"
|
||||
"github.com/SigNoz/signoz/ee/query-service/dao"
|
||||
"github.com/SigNoz/signoz/ee/query-service/integrations/gateway"
|
||||
"github.com/SigNoz/signoz/ee/query-service/interfaces"
|
||||
"github.com/SigNoz/signoz/ee/query-service/rules"
|
||||
"github.com/SigNoz/signoz/pkg/alertmanager"
|
||||
"github.com/SigNoz/signoz/pkg/http/middleware"
|
||||
"github.com/SigNoz/signoz/pkg/prometheus"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/auth"
|
||||
"github.com/SigNoz/signoz/pkg/signoz"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrystore"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/web"
|
||||
@@ -44,11 +43,13 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/query-service/app/logparsingpipeline"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/app/opamp"
|
||||
opAmpModel "github.com/SigNoz/signoz/pkg/query-service/app/opamp/model"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/app/preferences"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/cache"
|
||||
baseconst "github.com/SigNoz/signoz/pkg/query-service/constants"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/healthcheck"
|
||||
baseint "github.com/SigNoz/signoz/pkg/query-service/interfaces"
|
||||
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
pqle "github.com/SigNoz/signoz/pkg/query-service/pqlEngine"
|
||||
baserules "github.com/SigNoz/signoz/pkg/query-service/rules"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/telemetry"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/utils"
|
||||
@@ -115,6 +116,10 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := preferences.InitDB(serverOptions.SigNoz.SQLStore.SQLxDB()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := dashboards.InitDB(serverOptions.SigNoz.SQLStore); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -132,22 +137,27 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
||||
|
||||
// set license manager as feature flag provider in dao
|
||||
modelDao.SetFlagProvider(lm)
|
||||
readerReady := make(chan bool)
|
||||
|
||||
fluxIntervalForTraceDetail, err := time.ParseDuration(serverOptions.FluxIntervalForTraceDetail)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reader := db.NewDataConnector(
|
||||
serverOptions.SigNoz.SQLStore,
|
||||
serverOptions.SigNoz.TelemetryStore,
|
||||
serverOptions.SigNoz.Prometheus,
|
||||
var reader interfaces.DataConnector
|
||||
qb := db.NewDataConnector(
|
||||
serverOptions.SigNoz.SQLStore.SQLxDB(),
|
||||
serverOptions.SigNoz.TelemetryStore.ClickHouseDB(),
|
||||
serverOptions.PromConfigPath,
|
||||
lm,
|
||||
serverOptions.Cluster,
|
||||
serverOptions.UseLogsNewSchema,
|
||||
serverOptions.UseTraceNewSchema,
|
||||
fluxIntervalForTraceDetail,
|
||||
serverOptions.SigNoz.Cache,
|
||||
)
|
||||
go qb.Start(readerReady)
|
||||
reader = qb
|
||||
|
||||
skipConfig := &basemodel.SkipConfig{}
|
||||
if serverOptions.SkipTopLvlOpsPath != "" {
|
||||
@@ -166,18 +176,19 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
||||
c = cache.NewCache(cacheOpts)
|
||||
}
|
||||
|
||||
<-readerReady
|
||||
rm, err := makeRulesManager(
|
||||
serverOptions.PromConfigPath,
|
||||
serverOptions.RuleRepoURL,
|
||||
serverOptions.SigNoz.SQLStore.SQLxDB(),
|
||||
reader,
|
||||
c,
|
||||
serverOptions.DisableRules,
|
||||
lm,
|
||||
serverOptions.UseLogsNewSchema,
|
||||
serverOptions.UseTraceNewSchema,
|
||||
serverOptions.SigNoz.Alertmanager,
|
||||
serverOptions.SigNoz.SQLStore,
|
||||
serverOptions.SigNoz.TelemetryStore,
|
||||
serverOptions.SigNoz.Prometheus,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -222,7 +233,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
||||
}
|
||||
|
||||
// start the usagemanager
|
||||
usageManager, err := usage.New(lm.GetRepo(), serverOptions.SigNoz.TelemetryStore, serverOptions.SigNoz.Zeus)
|
||||
usageManager, err := usage.New(modelDao, lm.GetRepo(), serverOptions.SigNoz.TelemetryStore.ClickHouseDB(), serverOptions.Config.TelemetryStore.ClickHouse.DSN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -293,7 +304,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
||||
&opAmpModel.AllAgents, agentConfMgr,
|
||||
)
|
||||
|
||||
errorList := reader.PreloadMetricsMetadata(context.Background())
|
||||
errorList := qb.PreloadMetricsMetadata(context.Background())
|
||||
for _, er := range errorList {
|
||||
zap.L().Error("failed to preload metrics metadata", zap.Error(er))
|
||||
}
|
||||
@@ -526,27 +537,33 @@ func (s *Server) Stop() error {
|
||||
}
|
||||
|
||||
func makeRulesManager(
|
||||
promConfigPath,
|
||||
ruleRepoURL string,
|
||||
db *sqlx.DB,
|
||||
ch baseint.Reader,
|
||||
cache cache.Cache,
|
||||
disableRules bool,
|
||||
fm baseint.FeatureLookup,
|
||||
useLogsNewSchema bool,
|
||||
useTraceNewSchema bool,
|
||||
alertmanager alertmanager.Alertmanager,
|
||||
sqlstore sqlstore.SQLStore,
|
||||
telemetryStore telemetrystore.TelemetryStore,
|
||||
prometheus prometheus.Prometheus,
|
||||
) (*baserules.Manager, error) {
|
||||
// create engine
|
||||
pqle, err := pqle.FromConfigPath(promConfigPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create pql engine : %v", err)
|
||||
}
|
||||
|
||||
// create manager opts
|
||||
managerOpts := &baserules.ManagerOptions{
|
||||
TelemetryStore: telemetryStore,
|
||||
Prometheus: prometheus,
|
||||
PqlEngine: pqle,
|
||||
RepoURL: ruleRepoURL,
|
||||
DBConn: db,
|
||||
Context: context.Background(),
|
||||
Logger: zap.L(),
|
||||
DisableRules: disableRules,
|
||||
FeatureFlags: fm,
|
||||
Reader: ch,
|
||||
Cache: cache,
|
||||
EvalDelay: baseconst.GetEvalDelay(),
|
||||
|
||||
@@ -4,13 +4,13 @@ import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/query-service/model"
|
||||
"github.com/SigNoz/signoz/ee/types"
|
||||
basedao "github.com/SigNoz/signoz/pkg/query-service/dao"
|
||||
baseint "github.com/SigNoz/signoz/pkg/query-service/interfaces"
|
||||
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
ossTypes "github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/google/uuid"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
@@ -36,11 +36,11 @@ type ModelDao interface {
|
||||
DeleteDomain(ctx context.Context, id uuid.UUID) basemodel.BaseApiError
|
||||
GetDomainByEmail(ctx context.Context, email string) (*types.GettableOrgDomain, basemodel.BaseApiError)
|
||||
|
||||
CreatePAT(ctx context.Context, orgID string, p types.GettablePAT) (types.GettablePAT, basemodel.BaseApiError)
|
||||
UpdatePAT(ctx context.Context, orgID string, p types.GettablePAT, id valuer.UUID) basemodel.BaseApiError
|
||||
GetPAT(ctx context.Context, pat string) (*types.GettablePAT, basemodel.BaseApiError)
|
||||
GetPATByID(ctx context.Context, orgID string, id valuer.UUID) (*types.GettablePAT, basemodel.BaseApiError)
|
||||
CreatePAT(ctx context.Context, orgID string, p model.PAT) (model.PAT, basemodel.BaseApiError)
|
||||
UpdatePAT(ctx context.Context, orgID string, p model.PAT, id string) basemodel.BaseApiError
|
||||
GetPAT(ctx context.Context, pat string) (*model.PAT, basemodel.BaseApiError)
|
||||
GetPATByID(ctx context.Context, orgID string, id string) (*model.PAT, basemodel.BaseApiError)
|
||||
GetUserByPAT(ctx context.Context, orgID string, token string) (*ossTypes.GettableUser, basemodel.BaseApiError)
|
||||
ListPATs(ctx context.Context, orgID string) ([]types.GettablePAT, basemodel.BaseApiError)
|
||||
RevokePAT(ctx context.Context, orgID string, id valuer.UUID, userID string) basemodel.BaseApiError
|
||||
ListPATs(ctx context.Context, orgID string) ([]model.PAT, basemodel.BaseApiError)
|
||||
RevokePAT(ctx context.Context, orgID string, id string, userID string) basemodel.BaseApiError
|
||||
}
|
||||
|
||||
@@ -6,53 +6,45 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/query-service/model"
|
||||
"github.com/SigNoz/signoz/ee/types"
|
||||
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
ossTypes "github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func (m *modelDao) CreatePAT(ctx context.Context, orgID string, p types.GettablePAT) (types.GettablePAT, basemodel.BaseApiError) {
|
||||
func (m *modelDao) CreatePAT(ctx context.Context, orgID string, p model.PAT) (model.PAT, basemodel.BaseApiError) {
|
||||
p.StorablePersonalAccessToken.OrgID = orgID
|
||||
p.StorablePersonalAccessToken.ID = valuer.GenerateUUID()
|
||||
_, err := m.DB().NewInsert().
|
||||
Model(&p.StorablePersonalAccessToken).
|
||||
Returning("id").
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
zap.L().Error("Failed to insert PAT in db, err: %v", zap.Error(err))
|
||||
return types.GettablePAT{}, model.InternalError(fmt.Errorf("PAT insertion failed"))
|
||||
return model.PAT{}, model.InternalError(fmt.Errorf("PAT insertion failed"))
|
||||
}
|
||||
|
||||
createdByUser, _ := m.GetUser(ctx, p.UserID)
|
||||
if createdByUser == nil {
|
||||
p.CreatedByUser = types.PatUser{
|
||||
p.CreatedByUser = model.User{
|
||||
NotFound: true,
|
||||
}
|
||||
} else {
|
||||
p.CreatedByUser = types.PatUser{
|
||||
User: ossTypes.User{
|
||||
ID: createdByUser.ID,
|
||||
Name: createdByUser.Name,
|
||||
Email: createdByUser.Email,
|
||||
TimeAuditable: ossTypes.TimeAuditable{
|
||||
CreatedAt: createdByUser.CreatedAt,
|
||||
UpdatedAt: createdByUser.UpdatedAt,
|
||||
},
|
||||
ProfilePictureURL: createdByUser.ProfilePictureURL,
|
||||
},
|
||||
NotFound: false,
|
||||
p.CreatedByUser = model.User{
|
||||
Id: createdByUser.ID,
|
||||
Name: createdByUser.Name,
|
||||
Email: createdByUser.Email,
|
||||
CreatedAt: createdByUser.CreatedAt.Unix(),
|
||||
ProfilePictureURL: createdByUser.ProfilePictureURL,
|
||||
NotFound: false,
|
||||
}
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (m *modelDao) UpdatePAT(ctx context.Context, orgID string, p types.GettablePAT, id valuer.UUID) basemodel.BaseApiError {
|
||||
func (m *modelDao) UpdatePAT(ctx context.Context, orgID string, p model.PAT, id string) basemodel.BaseApiError {
|
||||
_, err := m.DB().NewUpdate().
|
||||
Model(&p.StorablePersonalAccessToken).
|
||||
Column("role", "name", "updated_at", "updated_by_user_id").
|
||||
Where("id = ?", id.StringValue()).
|
||||
Where("id = ?", id).
|
||||
Where("org_id = ?", orgID).
|
||||
Where("revoked = false").
|
||||
Exec(ctx)
|
||||
@@ -63,7 +55,7 @@ func (m *modelDao) UpdatePAT(ctx context.Context, orgID string, p types.Gettable
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *modelDao) ListPATs(ctx context.Context, orgID string) ([]types.GettablePAT, basemodel.BaseApiError) {
|
||||
func (m *modelDao) ListPATs(ctx context.Context, orgID string) ([]model.PAT, basemodel.BaseApiError) {
|
||||
pats := []types.StorablePersonalAccessToken{}
|
||||
|
||||
if err := m.DB().NewSelect().
|
||||
@@ -76,51 +68,41 @@ func (m *modelDao) ListPATs(ctx context.Context, orgID string) ([]types.Gettable
|
||||
return nil, model.InternalError(fmt.Errorf("failed to fetch PATs"))
|
||||
}
|
||||
|
||||
patsWithUsers := []types.GettablePAT{}
|
||||
patsWithUsers := []model.PAT{}
|
||||
for i := range pats {
|
||||
patWithUser := types.GettablePAT{
|
||||
patWithUser := model.PAT{
|
||||
StorablePersonalAccessToken: pats[i],
|
||||
}
|
||||
|
||||
createdByUser, _ := m.GetUser(ctx, pats[i].UserID)
|
||||
if createdByUser == nil {
|
||||
patWithUser.CreatedByUser = types.PatUser{
|
||||
patWithUser.CreatedByUser = model.User{
|
||||
NotFound: true,
|
||||
}
|
||||
} else {
|
||||
patWithUser.CreatedByUser = types.PatUser{
|
||||
User: ossTypes.User{
|
||||
ID: createdByUser.ID,
|
||||
Name: createdByUser.Name,
|
||||
Email: createdByUser.Email,
|
||||
TimeAuditable: ossTypes.TimeAuditable{
|
||||
CreatedAt: createdByUser.CreatedAt,
|
||||
UpdatedAt: createdByUser.UpdatedAt,
|
||||
},
|
||||
ProfilePictureURL: createdByUser.ProfilePictureURL,
|
||||
},
|
||||
NotFound: false,
|
||||
patWithUser.CreatedByUser = model.User{
|
||||
Id: createdByUser.ID,
|
||||
Name: createdByUser.Name,
|
||||
Email: createdByUser.Email,
|
||||
CreatedAt: createdByUser.CreatedAt.Unix(),
|
||||
ProfilePictureURL: createdByUser.ProfilePictureURL,
|
||||
NotFound: false,
|
||||
}
|
||||
}
|
||||
|
||||
updatedByUser, _ := m.GetUser(ctx, pats[i].UpdatedByUserID)
|
||||
if updatedByUser == nil {
|
||||
patWithUser.UpdatedByUser = types.PatUser{
|
||||
patWithUser.UpdatedByUser = model.User{
|
||||
NotFound: true,
|
||||
}
|
||||
} else {
|
||||
patWithUser.UpdatedByUser = types.PatUser{
|
||||
User: ossTypes.User{
|
||||
ID: updatedByUser.ID,
|
||||
Name: updatedByUser.Name,
|
||||
Email: updatedByUser.Email,
|
||||
TimeAuditable: ossTypes.TimeAuditable{
|
||||
CreatedAt: updatedByUser.CreatedAt,
|
||||
UpdatedAt: updatedByUser.UpdatedAt,
|
||||
},
|
||||
ProfilePictureURL: updatedByUser.ProfilePictureURL,
|
||||
},
|
||||
NotFound: false,
|
||||
patWithUser.UpdatedByUser = model.User{
|
||||
Id: updatedByUser.ID,
|
||||
Name: updatedByUser.Name,
|
||||
Email: updatedByUser.Email,
|
||||
CreatedAt: updatedByUser.CreatedAt.Unix(),
|
||||
ProfilePictureURL: updatedByUser.ProfilePictureURL,
|
||||
NotFound: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,14 +111,14 @@ func (m *modelDao) ListPATs(ctx context.Context, orgID string) ([]types.Gettable
|
||||
return patsWithUsers, nil
|
||||
}
|
||||
|
||||
func (m *modelDao) RevokePAT(ctx context.Context, orgID string, id valuer.UUID, userID string) basemodel.BaseApiError {
|
||||
func (m *modelDao) RevokePAT(ctx context.Context, orgID string, id string, userID string) basemodel.BaseApiError {
|
||||
updatedAt := time.Now().Unix()
|
||||
_, err := m.DB().NewUpdate().
|
||||
Model(&types.StorablePersonalAccessToken{}).
|
||||
Set("revoked = ?", true).
|
||||
Set("updated_by_user_id = ?", userID).
|
||||
Set("updated_at = ?", updatedAt).
|
||||
Where("id = ?", id.StringValue()).
|
||||
Where("id = ?", id).
|
||||
Where("org_id = ?", orgID).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
@@ -146,7 +128,7 @@ func (m *modelDao) RevokePAT(ctx context.Context, orgID string, id valuer.UUID,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *modelDao) GetPAT(ctx context.Context, token string) (*types.GettablePAT, basemodel.BaseApiError) {
|
||||
func (m *modelDao) GetPAT(ctx context.Context, token string) (*model.PAT, basemodel.BaseApiError) {
|
||||
pats := []types.StorablePersonalAccessToken{}
|
||||
|
||||
if err := m.DB().NewSelect().
|
||||
@@ -164,19 +146,19 @@ func (m *modelDao) GetPAT(ctx context.Context, token string) (*types.GettablePAT
|
||||
}
|
||||
}
|
||||
|
||||
patWithUser := types.GettablePAT{
|
||||
patWithUser := model.PAT{
|
||||
StorablePersonalAccessToken: pats[0],
|
||||
}
|
||||
|
||||
return &patWithUser, nil
|
||||
}
|
||||
|
||||
func (m *modelDao) GetPATByID(ctx context.Context, orgID string, id valuer.UUID) (*types.GettablePAT, basemodel.BaseApiError) {
|
||||
func (m *modelDao) GetPATByID(ctx context.Context, orgID string, id string) (*model.PAT, basemodel.BaseApiError) {
|
||||
pats := []types.StorablePersonalAccessToken{}
|
||||
|
||||
if err := m.DB().NewSelect().
|
||||
Model(&pats).
|
||||
Where("id = ?", id.StringValue()).
|
||||
Where("id = ?", id).
|
||||
Where("org_id = ?", orgID).
|
||||
Where("revoked = false").
|
||||
Scan(ctx); err != nil {
|
||||
@@ -190,7 +172,7 @@ func (m *modelDao) GetPATByID(ctx context.Context, orgID string, id valuer.UUID)
|
||||
}
|
||||
}
|
||||
|
||||
patWithUser := types.GettablePAT{
|
||||
patWithUser := model.PAT{
|
||||
StorablePersonalAccessToken: pats[0],
|
||||
}
|
||||
|
||||
@@ -198,8 +180,8 @@ func (m *modelDao) GetPATByID(ctx context.Context, orgID string, id valuer.UUID)
|
||||
}
|
||||
|
||||
// deprecated
|
||||
func (m *modelDao) GetUserByPAT(ctx context.Context, orgID string, token string) (*ossTypes.GettableUser, basemodel.BaseApiError) {
|
||||
users := []ossTypes.GettableUser{}
|
||||
func (m *modelDao) GetUserByPAT(ctx context.Context, orgID string, token string) (*types.GettableUser, basemodel.BaseApiError) {
|
||||
users := []types.GettableUser{}
|
||||
|
||||
if err := m.DB().NewSelect().
|
||||
Model(&users).
|
||||
|
||||
12
ee/query-service/interfaces/connector.go
Normal file
12
ee/query-service/interfaces/connector.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package interfaces
|
||||
|
||||
import (
|
||||
baseint "github.com/SigNoz/signoz/pkg/query-service/interfaces"
|
||||
)
|
||||
|
||||
// Connector defines methods for interaction
|
||||
// with o11y data. for example - clickhouse
|
||||
type DataConnector interface {
|
||||
Start(readerReady chan bool)
|
||||
baseint.Reader
|
||||
}
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
|
||||
validate "github.com/SigNoz/signoz/ee/query-service/integrations/signozio"
|
||||
"github.com/SigNoz/signoz/ee/query-service/model"
|
||||
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/telemetry"
|
||||
@@ -29,7 +29,6 @@ var validationFrequency = 24 * 60 * time.Minute
|
||||
|
||||
type Manager struct {
|
||||
repo *Repo
|
||||
zeus zeus.Zeus
|
||||
mutex sync.Mutex
|
||||
validatorRunning bool
|
||||
// end the license validation, this is important to gracefully
|
||||
@@ -46,7 +45,7 @@ type Manager struct {
|
||||
activeFeatures basemodel.FeatureSet
|
||||
}
|
||||
|
||||
func StartManager(db *sqlx.DB, store sqlstore.SQLStore, zeus zeus.Zeus, features ...basemodel.Feature) (*Manager, error) {
|
||||
func StartManager(db *sqlx.DB, store sqlstore.SQLStore, features ...basemodel.Feature) (*Manager, error) {
|
||||
if LM != nil {
|
||||
return LM, nil
|
||||
}
|
||||
@@ -54,7 +53,6 @@ func StartManager(db *sqlx.DB, store sqlstore.SQLStore, zeus zeus.Zeus, features
|
||||
repo := NewLicenseRepo(db, store)
|
||||
m := &Manager{
|
||||
repo: &repo,
|
||||
zeus: zeus,
|
||||
}
|
||||
if err := m.start(features...); err != nil {
|
||||
return m, err
|
||||
@@ -175,12 +173,14 @@ func (lm *Manager) ValidatorV3(ctx context.Context) {
|
||||
}
|
||||
|
||||
func (lm *Manager) RefreshLicense(ctx context.Context) *model.ApiError {
|
||||
license, err := lm.zeus.GetLicense(ctx, lm.activeLicenseV3.Key)
|
||||
if err != nil {
|
||||
return model.BadRequest(errors.Wrap(err, "failed to get license"))
|
||||
|
||||
license, apiError := validate.ValidateLicenseV3(lm.activeLicenseV3.Key)
|
||||
if apiError != nil {
|
||||
zap.L().Error("failed to validate license", zap.Error(apiError.Err))
|
||||
return apiError
|
||||
}
|
||||
|
||||
err = lm.repo.UpdateLicenseV3(ctx, license)
|
||||
err := lm.repo.UpdateLicenseV3(ctx, license)
|
||||
if err != nil {
|
||||
return model.BadRequest(errors.Wrap(err, "failed to update the new license"))
|
||||
}
|
||||
@@ -247,9 +247,10 @@ func (lm *Manager) ActivateV3(ctx context.Context, licenseKey string) (licenseRe
|
||||
}
|
||||
}()
|
||||
|
||||
license, errv2 := lm.zeus.GetLicense(ctx, lm.activeLicenseV3.Key)
|
||||
if errv2 != nil {
|
||||
return nil, model.BadRequest(errors.Wrap(errv2, "failed to get license"))
|
||||
license, apiError := validate.ValidateLicenseV3(licenseKey)
|
||||
if apiError != nil {
|
||||
zap.L().Error("failed to get the license", zap.Error(apiError.Err))
|
||||
return nil, apiError
|
||||
}
|
||||
|
||||
// insert the new license to the sqlite db
|
||||
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/version"
|
||||
|
||||
prommodel "github.com/prometheus/common/model"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
@@ -30,6 +32,10 @@ func initZapLog() *zap.Logger {
|
||||
return logger
|
||||
}
|
||||
|
||||
func init() {
|
||||
prommodel.NameValidationScheme = prommodel.UTF8Validation
|
||||
}
|
||||
|
||||
func main() {
|
||||
var promConfigPath, skipTopLvlOpsPath string
|
||||
|
||||
@@ -83,7 +89,6 @@ func main() {
|
||||
MaxIdleConns: maxIdleConns,
|
||||
MaxOpenConns: maxOpenConns,
|
||||
DialTimeout: dialTimeout,
|
||||
Config: promConfigPath,
|
||||
})
|
||||
if err != nil {
|
||||
zap.L().Fatal("Failed to create config", zap.Error(err))
|
||||
@@ -105,7 +110,7 @@ func main() {
|
||||
signoz.NewTelemetryStoreProviderFactories(),
|
||||
)
|
||||
if err != nil {
|
||||
zap.L().Fatal("Failed to create signoz", zap.Error(err))
|
||||
zap.L().Fatal("Failed to create signoz struct", zap.Error(err))
|
||||
}
|
||||
|
||||
jwtSecret := os.Getenv("SIGNOZ_JWT_SECRET")
|
||||
|
||||
246
ee/query-service/model/license.go
Normal file
246
ee/query-service/model/license.go
Normal file
@@ -0,0 +1,246 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type License struct {
|
||||
Key string `json:"key" db:"key"`
|
||||
ActivationId string `json:"activationId" db:"activationId"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
|
||||
// PlanDetails contains the encrypted plan info
|
||||
PlanDetails string `json:"planDetails" db:"planDetails"`
|
||||
|
||||
// stores parsed license details
|
||||
LicensePlan
|
||||
|
||||
FeatureSet basemodel.FeatureSet
|
||||
|
||||
// populated in case license has any errors
|
||||
ValidationMessage string `db:"validationMessage"`
|
||||
|
||||
// used only for sending details to front-end
|
||||
IsCurrent bool `json:"isCurrent"`
|
||||
}
|
||||
|
||||
func (l *License) MarshalJSON() ([]byte, error) {
|
||||
|
||||
return json.Marshal(&struct {
|
||||
Key string `json:"key" db:"key"`
|
||||
ActivationId string `json:"activationId" db:"activationId"`
|
||||
ValidationMessage string `db:"validationMessage"`
|
||||
IsCurrent bool `json:"isCurrent"`
|
||||
PlanKey string `json:"planKey"`
|
||||
ValidFrom time.Time `json:"ValidFrom"`
|
||||
ValidUntil time.Time `json:"ValidUntil"`
|
||||
Status string `json:"status"`
|
||||
}{
|
||||
Key: l.Key,
|
||||
ActivationId: l.ActivationId,
|
||||
IsCurrent: l.IsCurrent,
|
||||
PlanKey: l.PlanKey,
|
||||
ValidFrom: time.Unix(l.ValidFrom, 0),
|
||||
ValidUntil: time.Unix(l.ValidUntil, 0),
|
||||
Status: l.Status,
|
||||
ValidationMessage: l.ValidationMessage,
|
||||
})
|
||||
}
|
||||
|
||||
type LicensePlan struct {
|
||||
PlanKey string `json:"planKey"`
|
||||
ValidFrom int64 `json:"validFrom"`
|
||||
ValidUntil int64 `json:"validUntil"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type Licenses struct {
|
||||
TrialStart int64 `json:"trialStart"`
|
||||
TrialEnd int64 `json:"trialEnd"`
|
||||
OnTrial bool `json:"onTrial"`
|
||||
WorkSpaceBlock bool `json:"workSpaceBlock"`
|
||||
TrialConvertedToSubscription bool `json:"trialConvertedToSubscription"`
|
||||
GracePeriodEnd int64 `json:"gracePeriodEnd"`
|
||||
Licenses []License `json:"licenses"`
|
||||
}
|
||||
|
||||
type SubscriptionServerResp struct {
|
||||
Status string `json:"status"`
|
||||
Data Licenses `json:"data"`
|
||||
}
|
||||
|
||||
type Plan struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type LicenseDB struct {
|
||||
ID string `json:"id"`
|
||||
Key string `json:"key"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
type LicenseV3 struct {
|
||||
ID string
|
||||
Key string
|
||||
Data map[string]interface{}
|
||||
PlanName string
|
||||
Features basemodel.FeatureSet
|
||||
Status string
|
||||
IsCurrent bool
|
||||
ValidFrom int64
|
||||
ValidUntil int64
|
||||
}
|
||||
|
||||
func extractKeyFromMapStringInterface[T any](data map[string]interface{}, key string) (T, error) {
|
||||
var zeroValue T
|
||||
if val, ok := data[key]; ok {
|
||||
if value, ok := val.(T); ok {
|
||||
return value, nil
|
||||
}
|
||||
return zeroValue, fmt.Errorf("%s key is not a valid %s", key, reflect.TypeOf(zeroValue))
|
||||
}
|
||||
return zeroValue, fmt.Errorf("%s key is missing", key)
|
||||
}
|
||||
|
||||
func NewLicenseV3(data map[string]interface{}) (*LicenseV3, error) {
|
||||
var features basemodel.FeatureSet
|
||||
|
||||
// extract id from data
|
||||
licenseID, err := extractKeyFromMapStringInterface[string](data, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delete(data, "id")
|
||||
|
||||
// extract key from data
|
||||
licenseKey, err := extractKeyFromMapStringInterface[string](data, "key")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delete(data, "key")
|
||||
|
||||
// extract status from data
|
||||
status, err := extractKeyFromMapStringInterface[string](data, "status")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
planMap, err := extractKeyFromMapStringInterface[map[string]any](data, "plan")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
planName, err := extractKeyFromMapStringInterface[string](planMap, "name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// if license status is invalid then default it to basic
|
||||
if status == LicenseStatusInvalid {
|
||||
planName = PlanNameBasic
|
||||
}
|
||||
|
||||
featuresFromZeus := basemodel.FeatureSet{}
|
||||
if _features, ok := data["features"]; ok {
|
||||
featuresData, err := json.Marshal(_features)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal features data")
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(featuresData, &featuresFromZeus); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal features data")
|
||||
}
|
||||
}
|
||||
|
||||
switch planName {
|
||||
case PlanNameTeams:
|
||||
features = append(features, ProPlan...)
|
||||
case PlanNameEnterprise:
|
||||
features = append(features, EnterprisePlan...)
|
||||
case PlanNameBasic:
|
||||
features = append(features, BasicPlan...)
|
||||
default:
|
||||
features = append(features, BasicPlan...)
|
||||
}
|
||||
|
||||
if len(featuresFromZeus) > 0 {
|
||||
for _, feature := range featuresFromZeus {
|
||||
exists := false
|
||||
for i, existingFeature := range features {
|
||||
if existingFeature.Name == feature.Name {
|
||||
features[i] = feature // Replace existing feature
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
features = append(features, feature) // Append if it doesn't exist
|
||||
}
|
||||
}
|
||||
}
|
||||
data["features"] = features
|
||||
|
||||
_validFrom, err := extractKeyFromMapStringInterface[float64](data, "valid_from")
|
||||
if err != nil {
|
||||
_validFrom = 0
|
||||
}
|
||||
validFrom := int64(_validFrom)
|
||||
|
||||
_validUntil, err := extractKeyFromMapStringInterface[float64](data, "valid_until")
|
||||
if err != nil {
|
||||
_validUntil = 0
|
||||
}
|
||||
validUntil := int64(_validUntil)
|
||||
|
||||
return &LicenseV3{
|
||||
ID: licenseID,
|
||||
Key: licenseKey,
|
||||
Data: data,
|
||||
PlanName: planName,
|
||||
Features: features,
|
||||
ValidFrom: validFrom,
|
||||
ValidUntil: validUntil,
|
||||
Status: status,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func NewLicenseV3WithIDAndKey(id string, key string, data map[string]interface{}) (*LicenseV3, error) {
|
||||
licenseDataWithIdAndKey := data
|
||||
licenseDataWithIdAndKey["id"] = id
|
||||
licenseDataWithIdAndKey["key"] = key
|
||||
return NewLicenseV3(licenseDataWithIdAndKey)
|
||||
}
|
||||
|
||||
func ConvertLicenseV3ToLicenseV2(l *LicenseV3) *License {
|
||||
planKeyFromPlanName, ok := MapOldPlanKeyToNewPlanName[l.PlanName]
|
||||
if !ok {
|
||||
planKeyFromPlanName = Basic
|
||||
}
|
||||
return &License{
|
||||
Key: l.Key,
|
||||
ActivationId: "",
|
||||
PlanDetails: "",
|
||||
FeatureSet: l.Features,
|
||||
ValidationMessage: "",
|
||||
IsCurrent: l.IsCurrent,
|
||||
LicensePlan: LicensePlan{
|
||||
PlanKey: planKeyFromPlanName,
|
||||
ValidFrom: l.ValidFrom,
|
||||
ValidUntil: l.ValidUntil,
|
||||
Status: l.Status},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type CheckoutRequest struct {
|
||||
SuccessURL string `json:"url"`
|
||||
}
|
||||
|
||||
type PortalRequest struct {
|
||||
SuccessURL string `json:"url"`
|
||||
}
|
||||
170
ee/query-service/model/license_test.go
Normal file
170
ee/query-service/model/license_test.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewLicenseV3(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
data []byte
|
||||
pass bool
|
||||
expected *LicenseV3
|
||||
error error
|
||||
}{
|
||||
{
|
||||
name: "Error for missing license id",
|
||||
data: []byte(`{}`),
|
||||
pass: false,
|
||||
error: errors.New("id key is missing"),
|
||||
},
|
||||
{
|
||||
name: "Error for license id not being a valid string",
|
||||
data: []byte(`{"id": 10}`),
|
||||
pass: false,
|
||||
error: errors.New("id key is not a valid string"),
|
||||
},
|
||||
{
|
||||
name: "Error for missing license key",
|
||||
data: []byte(`{"id":"does-not-matter"}`),
|
||||
pass: false,
|
||||
error: errors.New("key key is missing"),
|
||||
},
|
||||
{
|
||||
name: "Error for invalid string license key",
|
||||
data: []byte(`{"id":"does-not-matter","key":10}`),
|
||||
pass: false,
|
||||
error: errors.New("key key is not a valid string"),
|
||||
},
|
||||
{
|
||||
name: "Error for missing license status",
|
||||
data: []byte(`{"id":"does-not-matter", "key": "does-not-matter","category":"FREE"}`),
|
||||
pass: false,
|
||||
error: errors.New("status key is missing"),
|
||||
},
|
||||
{
|
||||
name: "Error for invalid string license status",
|
||||
data: []byte(`{"id":"does-not-matter","key": "does-not-matter", "category":"FREE", "status":10}`),
|
||||
pass: false,
|
||||
error: errors.New("status key is not a valid string"),
|
||||
},
|
||||
{
|
||||
name: "Error for missing license plan",
|
||||
data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE"}`),
|
||||
pass: false,
|
||||
error: errors.New("plan key is missing"),
|
||||
},
|
||||
{
|
||||
name: "Error for invalid json license plan",
|
||||
data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE","plan":10}`),
|
||||
pass: false,
|
||||
error: errors.New("plan key is not a valid map[string]interface {}"),
|
||||
},
|
||||
{
|
||||
name: "Error for invalid license plan",
|
||||
data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE","plan":{}}`),
|
||||
pass: false,
|
||||
error: errors.New("name key is missing"),
|
||||
},
|
||||
{
|
||||
name: "Parse the entire license properly",
|
||||
data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE","plan":{"name":"TEAMS"},"valid_from": 1730899309,"valid_until": -1}`),
|
||||
pass: true,
|
||||
expected: &LicenseV3{
|
||||
ID: "does-not-matter",
|
||||
Key: "does-not-matter-key",
|
||||
Data: map[string]interface{}{
|
||||
"plan": map[string]interface{}{
|
||||
"name": "TEAMS",
|
||||
},
|
||||
"category": "FREE",
|
||||
"status": "ACTIVE",
|
||||
"valid_from": float64(1730899309),
|
||||
"valid_until": float64(-1),
|
||||
},
|
||||
PlanName: PlanNameTeams,
|
||||
ValidFrom: 1730899309,
|
||||
ValidUntil: -1,
|
||||
Status: "ACTIVE",
|
||||
IsCurrent: false,
|
||||
Features: model.FeatureSet{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Fallback to basic plan if license status is invalid",
|
||||
data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"INVALID","plan":{"name":"TEAMS"},"valid_from": 1730899309,"valid_until": -1}`),
|
||||
pass: true,
|
||||
expected: &LicenseV3{
|
||||
ID: "does-not-matter",
|
||||
Key: "does-not-matter-key",
|
||||
Data: map[string]interface{}{
|
||||
"plan": map[string]interface{}{
|
||||
"name": "TEAMS",
|
||||
},
|
||||
"category": "FREE",
|
||||
"status": "INVALID",
|
||||
"valid_from": float64(1730899309),
|
||||
"valid_until": float64(-1),
|
||||
},
|
||||
PlanName: PlanNameBasic,
|
||||
ValidFrom: 1730899309,
|
||||
ValidUntil: -1,
|
||||
Status: "INVALID",
|
||||
IsCurrent: false,
|
||||
Features: model.FeatureSet{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "fallback states for validFrom and validUntil",
|
||||
data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE","plan":{"name":"TEAMS"},"valid_from":1234.456,"valid_until":5678.567}`),
|
||||
pass: true,
|
||||
expected: &LicenseV3{
|
||||
ID: "does-not-matter",
|
||||
Key: "does-not-matter-key",
|
||||
Data: map[string]interface{}{
|
||||
"plan": map[string]interface{}{
|
||||
"name": "TEAMS",
|
||||
},
|
||||
"valid_from": 1234.456,
|
||||
"valid_until": 5678.567,
|
||||
"category": "FREE",
|
||||
"status": "ACTIVE",
|
||||
},
|
||||
PlanName: PlanNameTeams,
|
||||
ValidFrom: 1234,
|
||||
ValidUntil: 5678,
|
||||
Status: "ACTIVE",
|
||||
IsCurrent: false,
|
||||
Features: model.FeatureSet{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
var licensePayload map[string]interface{}
|
||||
err := json.Unmarshal(tc.data, &licensePayload)
|
||||
require.NoError(t, err)
|
||||
license, err := NewLicenseV3(licensePayload)
|
||||
if license != nil {
|
||||
license.Features = make(model.FeatureSet, 0)
|
||||
delete(license.Data, "features")
|
||||
}
|
||||
|
||||
if tc.pass {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, license)
|
||||
assert.Equal(t, tc.expected, license)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
assert.EqualError(t, err, tc.error.Error())
|
||||
require.Nil(t, license)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,25 @@
|
||||
package model
|
||||
|
||||
import "github.com/SigNoz/signoz/pkg/types"
|
||||
|
||||
type User struct {
|
||||
Id string `json:"id" db:"id"`
|
||||
Name string `json:"name" db:"name"`
|
||||
Email string `json:"email" db:"email"`
|
||||
CreatedAt int64 `json:"createdAt" db:"created_at"`
|
||||
ProfilePictureURL string `json:"profilePictureURL" db:"profile_picture_url"`
|
||||
NotFound bool `json:"notFound"`
|
||||
}
|
||||
|
||||
type CreatePATRequestBody struct {
|
||||
Name string `json:"name"`
|
||||
Role string `json:"role"`
|
||||
ExpiresInDays int64 `json:"expiresInDays"`
|
||||
}
|
||||
|
||||
type PAT struct {
|
||||
CreatedByUser User `json:"createdByUser"`
|
||||
UpdatedByUser User `json:"updatedByUser"`
|
||||
|
||||
types.StorablePersonalAccessToken
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/SigNoz/signoz/pkg/query-service/constants"
|
||||
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
|
||||
)
|
||||
|
||||
@@ -23,6 +24,7 @@ var (
|
||||
LicenseStatusInvalid = "INVALID"
|
||||
)
|
||||
|
||||
const DisableUpsell = "DISABLE_UPSELL"
|
||||
const Onboarding = "ONBOARDING"
|
||||
const ChatSupport = "CHAT_SUPPORT"
|
||||
const Gateway = "GATEWAY"
|
||||
@@ -36,6 +38,90 @@ var BasicPlan = basemodel.FeatureSet{
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.OSS,
|
||||
Active: false,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: DisableUpsell,
|
||||
Active: false,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.SmartTraceDetail,
|
||||
Active: false,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.CustomMetricsFunction,
|
||||
Active: false,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.QueryBuilderPanels,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.QueryBuilderAlerts,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelSlack,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelWebhook,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelPagerduty,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelOpsgenie,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelEmail,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelMsTeams,
|
||||
Active: false,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.UseSpanMetrics,
|
||||
Active: false,
|
||||
@@ -64,6 +150,142 @@ var BasicPlan = basemodel.FeatureSet{
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.HostsInfraMonitoring,
|
||||
Active: constants.EnableHostsInfraMonitoring(),
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.TraceFunnels,
|
||||
Active: false,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
}
|
||||
|
||||
var ProPlan = basemodel.FeatureSet{
|
||||
basemodel.Feature{
|
||||
Name: SSO,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.OSS,
|
||||
Active: false,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.SmartTraceDetail,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.CustomMetricsFunction,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.QueryBuilderPanels,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.QueryBuilderAlerts,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelSlack,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelWebhook,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelPagerduty,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelOpsgenie,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelEmail,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelMsTeams,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.UseSpanMetrics,
|
||||
Active: false,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: Gateway,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: PremiumSupport,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AnomalyDetection,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.HostsInfraMonitoring,
|
||||
Active: constants.EnableHostsInfraMonitoring(),
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.TraceFunnels,
|
||||
Active: false,
|
||||
@@ -81,6 +303,83 @@ var EnterprisePlan = basemodel.FeatureSet{
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.OSS,
|
||||
Active: false,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.SmartTraceDetail,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.CustomMetricsFunction,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.QueryBuilderPanels,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.QueryBuilderAlerts,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelSlack,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelWebhook,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelPagerduty,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelOpsgenie,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelEmail,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.AlertChannelMsTeams,
|
||||
Active: true,
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.UseSpanMetrics,
|
||||
Active: false,
|
||||
@@ -123,6 +422,13 @@ var EnterprisePlan = basemodel.FeatureSet{
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.HostsInfraMonitoring,
|
||||
Active: constants.EnableHostsInfraMonitoring(),
|
||||
Usage: 0,
|
||||
UsageLimit: -1,
|
||||
Route: "",
|
||||
},
|
||||
basemodel.Feature{
|
||||
Name: basemodel.TraceFunnels,
|
||||
Active: false,
|
||||
|
||||
@@ -53,6 +53,7 @@ type AnomalyRule struct {
|
||||
func NewAnomalyRule(
|
||||
id string,
|
||||
p *baserules.PostableRule,
|
||||
featureFlags interfaces.FeatureLookup,
|
||||
reader interfaces.Reader,
|
||||
cache cache.Cache,
|
||||
opts ...baserules.RuleOption,
|
||||
@@ -88,9 +89,10 @@ func NewAnomalyRule(
|
||||
zap.L().Info("using seasonality", zap.String("seasonality", t.seasonality.String()))
|
||||
|
||||
querierOptsV2 := querierV2.QuerierOptions{
|
||||
Reader: reader,
|
||||
Cache: cache,
|
||||
KeyGenerator: queryBuilder.NewKeyGenerator(),
|
||||
Reader: reader,
|
||||
Cache: cache,
|
||||
KeyGenerator: queryBuilder.NewKeyGenerator(),
|
||||
FeatureLookup: featureFlags,
|
||||
}
|
||||
|
||||
t.querierV2 = querierV2.NewQuerier(querierOptsV2)
|
||||
@@ -100,18 +102,21 @@ func NewAnomalyRule(
|
||||
anomaly.WithCache[*anomaly.HourlyProvider](cache),
|
||||
anomaly.WithKeyGenerator[*anomaly.HourlyProvider](queryBuilder.NewKeyGenerator()),
|
||||
anomaly.WithReader[*anomaly.HourlyProvider](reader),
|
||||
anomaly.WithFeatureLookup[*anomaly.HourlyProvider](featureFlags),
|
||||
)
|
||||
} else if t.seasonality == anomaly.SeasonalityDaily {
|
||||
t.provider = anomaly.NewDailyProvider(
|
||||
anomaly.WithCache[*anomaly.DailyProvider](cache),
|
||||
anomaly.WithKeyGenerator[*anomaly.DailyProvider](queryBuilder.NewKeyGenerator()),
|
||||
anomaly.WithReader[*anomaly.DailyProvider](reader),
|
||||
anomaly.WithFeatureLookup[*anomaly.DailyProvider](featureFlags),
|
||||
)
|
||||
} else if t.seasonality == anomaly.SeasonalityWeekly {
|
||||
t.provider = anomaly.NewWeeklyProvider(
|
||||
anomaly.WithCache[*anomaly.WeeklyProvider](cache),
|
||||
anomaly.WithKeyGenerator[*anomaly.WeeklyProvider](queryBuilder.NewKeyGenerator()),
|
||||
anomaly.WithReader[*anomaly.WeeklyProvider](reader),
|
||||
anomaly.WithFeatureLookup[*anomaly.WeeklyProvider](featureFlags),
|
||||
)
|
||||
}
|
||||
return &t, nil
|
||||
|
||||
@@ -23,6 +23,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
tr, err := baserules.NewThresholdRule(
|
||||
ruleId,
|
||||
opts.Rule,
|
||||
opts.FF,
|
||||
opts.Reader,
|
||||
opts.UseLogsNewSchema,
|
||||
opts.UseTraceNewSchema,
|
||||
@@ -47,7 +48,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
opts.Rule,
|
||||
opts.Logger,
|
||||
opts.Reader,
|
||||
opts.ManagerOpts.Prometheus,
|
||||
opts.ManagerOpts.PqlEngine,
|
||||
baserules.WithSQLStore(opts.SQLStore),
|
||||
)
|
||||
|
||||
@@ -65,6 +66,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
||||
ar, err := NewAnomalyRule(
|
||||
ruleId,
|
||||
opts.Rule,
|
||||
opts.FF,
|
||||
opts.Reader,
|
||||
opts.Cache,
|
||||
baserules.WithEvalDelay(opts.ManagerOpts.EvalDelay),
|
||||
@@ -121,6 +123,7 @@ func TestNotification(opts baserules.PrepareTestRuleOptions) (int, *basemodel.Ap
|
||||
rule, err = baserules.NewThresholdRule(
|
||||
alertname,
|
||||
parsedRule,
|
||||
opts.FF,
|
||||
opts.Reader,
|
||||
opts.UseLogsNewSchema,
|
||||
opts.UseTraceNewSchema,
|
||||
@@ -142,7 +145,7 @@ func TestNotification(opts baserules.PrepareTestRuleOptions) (int, *basemodel.Ap
|
||||
parsedRule,
|
||||
opts.Logger,
|
||||
opts.Reader,
|
||||
opts.ManagerOpts.Prometheus,
|
||||
opts.ManagerOpts.PqlEngine,
|
||||
baserules.WithSendAlways(),
|
||||
baserules.WithSendUnmatched(),
|
||||
baserules.WithSQLStore(opts.SQLStore),
|
||||
@@ -157,6 +160,7 @@ func TestNotification(opts baserules.PrepareTestRuleOptions) (int, *basemodel.Ap
|
||||
rule, err = NewAnomalyRule(
|
||||
alertname,
|
||||
parsedRule,
|
||||
opts.FF,
|
||||
opts.Reader,
|
||||
opts.Cache,
|
||||
baserules.WithSendAlways(),
|
||||
|
||||
@@ -4,21 +4,22 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/ClickHouse/clickhouse-go/v2"
|
||||
"github.com/go-co-op/gocron"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/query-service/dao"
|
||||
licenseserver "github.com/SigNoz/signoz/ee/query-service/integrations/signozio"
|
||||
"github.com/SigNoz/signoz/ee/query-service/license"
|
||||
"github.com/SigNoz/signoz/ee/query-service/model"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/utils/encryption"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrystore"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -33,20 +34,35 @@ var (
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
telemetryStore telemetrystore.TelemetryStore
|
||||
licenseRepo *license.Repo
|
||||
scheduler *gocron.Scheduler
|
||||
zeus zeus.Zeus
|
||||
clickhouseConn clickhouse.Conn
|
||||
|
||||
licenseRepo *license.Repo
|
||||
|
||||
scheduler *gocron.Scheduler
|
||||
|
||||
modelDao dao.ModelDao
|
||||
|
||||
tenantID string
|
||||
}
|
||||
|
||||
func New(licenseRepo *license.Repo, telemetryStore telemetrystore.TelemetryStore, zeus zeus.Zeus) (*Manager, error) {
|
||||
m := &Manager{
|
||||
licenseRepo: licenseRepo,
|
||||
telemetryStore: telemetryStore,
|
||||
zeus: zeus,
|
||||
scheduler: gocron.NewScheduler(time.UTC).Every(1).Day().At("00:00"), // send usage every at 00:00 UTC
|
||||
func New(modelDao dao.ModelDao, licenseRepo *license.Repo, clickhouseConn clickhouse.Conn, chUrl string) (*Manager, error) {
|
||||
hostNameRegex := regexp.MustCompile(`tcp://(?P<hostname>.*):`)
|
||||
hostNameRegexMatches := hostNameRegex.FindStringSubmatch(chUrl)
|
||||
|
||||
tenantID := ""
|
||||
if len(hostNameRegexMatches) == 2 {
|
||||
tenantID = hostNameRegexMatches[1]
|
||||
tenantID = strings.TrimSuffix(tenantID, "-clickhouse")
|
||||
}
|
||||
|
||||
m := &Manager{
|
||||
// repository: repo,
|
||||
clickhouseConn: clickhouseConn,
|
||||
licenseRepo: licenseRepo,
|
||||
scheduler: gocron.NewScheduler(time.UTC).Every(1).Day().At("00:00"), // send usage every at 00:00 UTC
|
||||
modelDao: modelDao,
|
||||
tenantID: tenantID,
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@@ -104,7 +120,7 @@ func (lm *Manager) UploadUsage() {
|
||||
|
||||
for _, db := range dbs {
|
||||
dbusages := []model.UsageDB{}
|
||||
err := lm.telemetryStore.ClickhouseDB().Select(ctx, &dbusages, fmt.Sprintf(query, db, db), time.Now().Add(-(24 * time.Hour)))
|
||||
err := lm.clickhouseConn.Select(ctx, &dbusages, fmt.Sprintf(query, db, db), time.Now().Add(-(24 * time.Hour)))
|
||||
if err != nil && !strings.Contains(err.Error(), "doesn't exist") {
|
||||
zap.L().Error("failed to get usage from clickhouse: %v", zap.Error(err))
|
||||
return
|
||||
@@ -120,6 +136,17 @@ func (lm *Manager) UploadUsage() {
|
||||
return
|
||||
}
|
||||
|
||||
zap.L().Info("uploading usage data")
|
||||
|
||||
orgName := ""
|
||||
orgNames, orgError := lm.modelDao.GetOrgs(ctx)
|
||||
if orgError != nil {
|
||||
zap.L().Error("failed to get org data: %v", zap.Error(orgError))
|
||||
}
|
||||
if len(orgNames) == 1 {
|
||||
orgName = orgNames[0].Name
|
||||
}
|
||||
|
||||
usagesPayload := []model.Usage{}
|
||||
for _, usage := range usages {
|
||||
usageDataBytes, err := encryption.Decrypt([]byte(usage.ExporterID[:32]), []byte(usage.Data))
|
||||
@@ -139,8 +166,8 @@ func (lm *Manager) UploadUsage() {
|
||||
usageData.ExporterID = usage.ExporterID
|
||||
usageData.Type = usage.Type
|
||||
usageData.Tenant = "default"
|
||||
usageData.OrgName = "default"
|
||||
usageData.TenantId = "default"
|
||||
usageData.OrgName = orgName
|
||||
usageData.TenantId = lm.tenantID
|
||||
usagesPayload = append(usagesPayload, usageData)
|
||||
}
|
||||
|
||||
@@ -149,7 +176,6 @@ func (lm *Manager) UploadUsage() {
|
||||
LicenseKey: key,
|
||||
Usage: usagesPayload,
|
||||
}
|
||||
|
||||
lm.UploadUsageWithExponentalBackOff(ctx, payload)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,30 +2,11 @@ package postgressqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
var (
|
||||
Identity = "id"
|
||||
Integer = "bigint"
|
||||
Text = "text"
|
||||
)
|
||||
|
||||
var (
|
||||
Org = "org"
|
||||
User = "user"
|
||||
)
|
||||
|
||||
var (
|
||||
OrgReference = `("org_id") REFERENCES "organizations" ("id")`
|
||||
UserReference = `("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE`
|
||||
)
|
||||
|
||||
type dialect struct {
|
||||
}
|
||||
|
||||
@@ -193,10 +174,7 @@ func (dialect *dialect) TableExists(ctx context.Context, bun bun.IDB, table inte
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (dialect *dialect) RenameTableAndModifyModel(ctx context.Context, bun bun.IDB, oldModel interface{}, newModel interface{}, references []string, cb func(context.Context) error) error {
|
||||
if len(references) == 0 {
|
||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot run migration without reference")
|
||||
}
|
||||
func (dialect *dialect) RenameTableAndModifyModel(ctx context.Context, bun bun.IDB, oldModel interface{}, newModel interface{}, cb func(context.Context) error) error {
|
||||
exists, err := dialect.TableExists(ctx, bun, newModel)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -205,81 +183,10 @@ func (dialect *dialect) RenameTableAndModifyModel(ctx context.Context, bun bun.I
|
||||
return nil
|
||||
}
|
||||
|
||||
var fkReferences []string
|
||||
for _, reference := range references {
|
||||
if reference == Org && !slices.Contains(fkReferences, OrgReference) {
|
||||
fkReferences = append(fkReferences, OrgReference)
|
||||
} else if reference == User && !slices.Contains(fkReferences, UserReference) {
|
||||
fkReferences = append(fkReferences, UserReference)
|
||||
}
|
||||
}
|
||||
|
||||
createTable := bun.
|
||||
NewCreateTable().
|
||||
IfNotExists().
|
||||
Model(newModel)
|
||||
|
||||
for _, fk := range fkReferences {
|
||||
createTable = createTable.ForeignKey(fk)
|
||||
}
|
||||
|
||||
_, err = createTable.Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cb(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = bun.
|
||||
NewDropTable().
|
||||
IfExists().
|
||||
Model(oldModel).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dialect *dialect) AddNotNullDefaultToColumn(ctx context.Context, bun bun.IDB, table string, column, columnType, defaultValue string) error {
|
||||
query := fmt.Sprintf("ALTER TABLE %s ALTER COLUMN %s SET DEFAULT %s, ALTER COLUMN %s SET NOT NULL", table, column, defaultValue, column)
|
||||
if _, err := bun.ExecContext(ctx, query); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dialect *dialect) UpdatePrimaryKey(ctx context.Context, bun bun.IDB, oldModel interface{}, newModel interface{}, reference string, cb func(context.Context) error) error {
|
||||
if reference == "" {
|
||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot run migration without reference")
|
||||
}
|
||||
oldTableName := bun.Dialect().Tables().Get(reflect.TypeOf(oldModel)).Name
|
||||
newTableName := bun.Dialect().Tables().Get(reflect.TypeOf(newModel)).Name
|
||||
|
||||
columnType, err := dialect.GetColumnType(ctx, bun, oldTableName, Identity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if columnType == Text {
|
||||
return nil
|
||||
}
|
||||
|
||||
fkReference := ""
|
||||
if reference == Org {
|
||||
fkReference = OrgReference
|
||||
} else if reference == User {
|
||||
fkReference = UserReference
|
||||
}
|
||||
|
||||
_, err = bun.
|
||||
NewCreateTable().
|
||||
IfNotExists().
|
||||
Model(newModel).
|
||||
ForeignKey(fkReference).
|
||||
Exec(ctx)
|
||||
|
||||
if err != nil {
|
||||
@@ -300,67 +207,5 @@ func (dialect *dialect) UpdatePrimaryKey(ctx context.Context, bun bun.IDB, oldMo
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = bun.
|
||||
ExecContext(ctx, fmt.Sprintf("ALTER TABLE %s RENAME TO %s", newTableName, oldTableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dialect *dialect) AddPrimaryKey(ctx context.Context, bun bun.IDB, oldModel interface{}, newModel interface{}, reference string, cb func(context.Context) error) error {
|
||||
if reference == "" {
|
||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot run migration without reference")
|
||||
}
|
||||
oldTableName := bun.Dialect().Tables().Get(reflect.TypeOf(oldModel)).Name
|
||||
newTableName := bun.Dialect().Tables().Get(reflect.TypeOf(newModel)).Name
|
||||
|
||||
identityExists, err := dialect.ColumnExists(ctx, bun, oldTableName, Identity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if identityExists {
|
||||
return nil
|
||||
}
|
||||
|
||||
fkReference := ""
|
||||
if reference == Org {
|
||||
fkReference = OrgReference
|
||||
} else if reference == User {
|
||||
fkReference = UserReference
|
||||
}
|
||||
|
||||
_, err = bun.
|
||||
NewCreateTable().
|
||||
IfNotExists().
|
||||
Model(newModel).
|
||||
ForeignKey(fkReference).
|
||||
Exec(ctx)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cb(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = bun.
|
||||
NewDropTable().
|
||||
IfExists().
|
||||
Model(oldModel).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = bun.
|
||||
ExecContext(ctx, fmt.Sprintf("ALTER TABLE %s RENAME TO %s", newTableName, oldTableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package featuretypes
|
||||
|
||||
import "github.com/SigNoz/signoz/pkg/types/featuretypes"
|
||||
|
||||
var (
|
||||
SingleSignOn = featuretypes.MustNewName("SingleSignOn")
|
||||
)
|
||||
|
||||
func NewEnterpriseRegistry() (featuretypes.Registry, error) {
|
||||
enterpriseRegistry, err := featuretypes.NewRegistry(
|
||||
&featuretypes.Feature{
|
||||
Name: SingleSignOn,
|
||||
Kind: featuretypes.KindBoolean,
|
||||
Description: "Enable single sign on.",
|
||||
Stage: featuretypes.StageStable,
|
||||
Default: true,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return enterpriseRegistry.MergeOrOverride(featuretypes.MustNewCommunityRegistry()), nil
|
||||
}
|
||||
|
||||
func MustNewEnterpriseRegistry() featuretypes.Registry {
|
||||
enterpriseRegistry, err := NewEnterpriseRegistry()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return enterpriseRegistry
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package licensetypes
|
||||
@@ -1,245 +0,0 @@
|
||||
package licensetypes
|
||||
|
||||
import "github.com/SigNoz/signoz/pkg/types/featuretypes"
|
||||
|
||||
type License struct {
|
||||
ID string
|
||||
Key string
|
||||
Contents map[string]any
|
||||
OrgFeatures []*featuretypes.StorableOrgFeature
|
||||
}
|
||||
|
||||
// type License struct {
|
||||
// Key string `json:"key" db:"key"`
|
||||
// ActivationId string `json:"activationId" db:"activationId"`
|
||||
// CreatedAt time.Time `db:"created_at"`
|
||||
|
||||
// // PlanDetails contains the encrypted plan info
|
||||
// PlanDetails string `json:"planDetails" db:"planDetails"`
|
||||
|
||||
// // stores parsed license details
|
||||
// LicensePlan
|
||||
|
||||
// FeatureSet basemodel.FeatureSet
|
||||
|
||||
// // populated in case license has any errors
|
||||
// ValidationMessage string `db:"validationMessage"`
|
||||
|
||||
// // used only for sending details to front-end
|
||||
// IsCurrent bool `json:"isCurrent"`
|
||||
// }
|
||||
|
||||
// func (l *License) MarshalJSON() ([]byte, error) {
|
||||
|
||||
// return json.Marshal(&struct {
|
||||
// Key string `json:"key" db:"key"`
|
||||
// ActivationId string `json:"activationId" db:"activationId"`
|
||||
// ValidationMessage string `db:"validationMessage"`
|
||||
// IsCurrent bool `json:"isCurrent"`
|
||||
// PlanKey string `json:"planKey"`
|
||||
// ValidFrom time.Time `json:"ValidFrom"`
|
||||
// ValidUntil time.Time `json:"ValidUntil"`
|
||||
// Status string `json:"status"`
|
||||
// }{
|
||||
// Key: l.Key,
|
||||
// ActivationId: l.ActivationId,
|
||||
// IsCurrent: l.IsCurrent,
|
||||
// PlanKey: l.PlanKey,
|
||||
// ValidFrom: time.Unix(l.ValidFrom, 0),
|
||||
// ValidUntil: time.Unix(l.ValidUntil, 0),
|
||||
// Status: l.Status,
|
||||
// ValidationMessage: l.ValidationMessage,
|
||||
// })
|
||||
// }
|
||||
|
||||
// type LicensePlan struct {
|
||||
// PlanKey string `json:"planKey"`
|
||||
// ValidFrom int64 `json:"validFrom"`
|
||||
// ValidUntil int64 `json:"validUntil"`
|
||||
// Status string `json:"status"`
|
||||
// }
|
||||
|
||||
// type Licenses struct {
|
||||
// TrialStart int64 `json:"trialStart"`
|
||||
// TrialEnd int64 `json:"trialEnd"`
|
||||
// OnTrial bool `json:"onTrial"`
|
||||
// WorkSpaceBlock bool `json:"workSpaceBlock"`
|
||||
// TrialConvertedToSubscription bool `json:"trialConvertedToSubscription"`
|
||||
// GracePeriodEnd int64 `json:"gracePeriodEnd"`
|
||||
// Licenses []License `json:"licenses"`
|
||||
// }
|
||||
|
||||
// type SubscriptionServerResp struct {
|
||||
// Status string `json:"status"`
|
||||
// Data Licenses `json:"data"`
|
||||
// }
|
||||
|
||||
// type Plan struct {
|
||||
// Name string `json:"name"`
|
||||
// }
|
||||
|
||||
// type LicenseDB struct {
|
||||
// ID string `json:"id"`
|
||||
// Key string `json:"key"`
|
||||
// Data string `json:"data"`
|
||||
// }
|
||||
// type LicenseV3 struct {
|
||||
// ID string
|
||||
// Key string
|
||||
// Data map[string]interface{}
|
||||
// PlanName string
|
||||
// Features basemodel.FeatureSet
|
||||
// Status string
|
||||
// IsCurrent bool
|
||||
// ValidFrom int64
|
||||
// ValidUntil int64
|
||||
// }
|
||||
|
||||
// func extractKeyFromMapStringInterface[T any](data map[string]interface{}, key string) (T, error) {
|
||||
// var zeroValue T
|
||||
// if val, ok := data[key]; ok {
|
||||
// if value, ok := val.(T); ok {
|
||||
// return value, nil
|
||||
// }
|
||||
// return zeroValue, fmt.Errorf("%s key is not a valid %s", key, reflect.TypeOf(zeroValue))
|
||||
// }
|
||||
// return zeroValue, fmt.Errorf("%s key is missing", key)
|
||||
// }
|
||||
|
||||
// func NewLicenseV3(data map[string]interface{}) (*LicenseV3, error) {
|
||||
// var features basemodel.FeatureSet
|
||||
|
||||
// // extract id from data
|
||||
// licenseID, err := extractKeyFromMapStringInterface[string](data, "id")
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// delete(data, "id")
|
||||
|
||||
// // extract key from data
|
||||
// licenseKey, err := extractKeyFromMapStringInterface[string](data, "key")
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// delete(data, "key")
|
||||
|
||||
// // extract status from data
|
||||
// status, err := extractKeyFromMapStringInterface[string](data, "status")
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// planMap, err := extractKeyFromMapStringInterface[map[string]any](data, "plan")
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// planName, err := extractKeyFromMapStringInterface[string](planMap, "name")
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// // if license status is invalid then default it to basic
|
||||
// if status == LicenseStatusInvalid {
|
||||
// planName = PlanNameBasic
|
||||
// }
|
||||
|
||||
// featuresFromZeus := basemodel.FeatureSet{}
|
||||
// if _features, ok := data["features"]; ok {
|
||||
// featuresData, err := json.Marshal(_features)
|
||||
// if err != nil {
|
||||
// return nil, errors.Wrap(err, "failed to marshal features data")
|
||||
// }
|
||||
|
||||
// if err := json.Unmarshal(featuresData, &featuresFromZeus); err != nil {
|
||||
// return nil, errors.Wrap(err, "failed to unmarshal features data")
|
||||
// }
|
||||
// }
|
||||
|
||||
// switch planName {
|
||||
// case PlanNameTeams:
|
||||
// features = append(features, ProPlan...)
|
||||
// case PlanNameEnterprise:
|
||||
// features = append(features, EnterprisePlan...)
|
||||
// case PlanNameBasic:
|
||||
// features = append(features, BasicPlan...)
|
||||
// default:
|
||||
// features = append(features, BasicPlan...)
|
||||
// }
|
||||
|
||||
// if len(featuresFromZeus) > 0 {
|
||||
// for _, feature := range featuresFromZeus {
|
||||
// exists := false
|
||||
// for i, existingFeature := range features {
|
||||
// if existingFeature.Name == feature.Name {
|
||||
// features[i] = feature // Replace existing feature
|
||||
// exists = true
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// if !exists {
|
||||
// features = append(features, feature) // Append if it doesn't exist
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// data["features"] = features
|
||||
|
||||
// _validFrom, err := extractKeyFromMapStringInterface[float64](data, "valid_from")
|
||||
// if err != nil {
|
||||
// _validFrom = 0
|
||||
// }
|
||||
// validFrom := int64(_validFrom)
|
||||
|
||||
// _validUntil, err := extractKeyFromMapStringInterface[float64](data, "valid_until")
|
||||
// if err != nil {
|
||||
// _validUntil = 0
|
||||
// }
|
||||
// validUntil := int64(_validUntil)
|
||||
|
||||
// return &LicenseV3{
|
||||
// ID: licenseID,
|
||||
// Key: licenseKey,
|
||||
// Data: data,
|
||||
// PlanName: planName,
|
||||
// Features: features,
|
||||
// ValidFrom: validFrom,
|
||||
// ValidUntil: validUntil,
|
||||
// Status: status,
|
||||
// }, nil
|
||||
|
||||
// }
|
||||
|
||||
// func NewLicenseV3WithIDAndKey(id string, key string, data map[string]interface{}) (*LicenseV3, error) {
|
||||
// licenseDataWithIdAndKey := data
|
||||
// licenseDataWithIdAndKey["id"] = id
|
||||
// licenseDataWithIdAndKey["key"] = key
|
||||
// return NewLicenseV3(licenseDataWithIdAndKey)
|
||||
// }
|
||||
|
||||
// func ConvertLicenseV3ToLicenseV2(l *LicenseV3) *License {
|
||||
// planKeyFromPlanName, ok := MapOldPlanKeyToNewPlanName[l.PlanName]
|
||||
// if !ok {
|
||||
// planKeyFromPlanName = Basic
|
||||
// }
|
||||
// return &License{
|
||||
// Key: l.Key,
|
||||
// ActivationId: "",
|
||||
// PlanDetails: "",
|
||||
// FeatureSet: l.Features,
|
||||
// ValidationMessage: "",
|
||||
// IsCurrent: l.IsCurrent,
|
||||
// LicensePlan: LicensePlan{
|
||||
// PlanKey: planKeyFromPlanName,
|
||||
// ValidFrom: l.ValidFrom,
|
||||
// ValidUntil: l.ValidUntil,
|
||||
// Status: l.Status},
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// type CheckoutRequest struct {
|
||||
// SuccessURL string `json:"url"`
|
||||
// }
|
||||
|
||||
// type PortalRequest struct {
|
||||
// SuccessURL string `json:"url"`
|
||||
// }
|
||||
@@ -1,160 +0,0 @@
|
||||
package licensetypes
|
||||
|
||||
// func TestNewLicenseV3(t *testing.T) {
|
||||
// testCases := []struct {
|
||||
// name string
|
||||
// data []byte
|
||||
// pass bool
|
||||
// expected *LicenseV3
|
||||
// error error
|
||||
// }{
|
||||
// {
|
||||
// name: "Error for missing license id",
|
||||
// data: []byte(`{}`),
|
||||
// pass: false,
|
||||
// error: errors.New("id key is missing"),
|
||||
// },
|
||||
// {
|
||||
// name: "Error for license id not being a valid string",
|
||||
// data: []byte(`{"id": 10}`),
|
||||
// pass: false,
|
||||
// error: errors.New("id key is not a valid string"),
|
||||
// },
|
||||
// {
|
||||
// name: "Error for missing license key",
|
||||
// data: []byte(`{"id":"does-not-matter"}`),
|
||||
// pass: false,
|
||||
// error: errors.New("key key is missing"),
|
||||
// },
|
||||
// {
|
||||
// name: "Error for invalid string license key",
|
||||
// data: []byte(`{"id":"does-not-matter","key":10}`),
|
||||
// pass: false,
|
||||
// error: errors.New("key key is not a valid string"),
|
||||
// },
|
||||
// {
|
||||
// name: "Error for missing license status",
|
||||
// data: []byte(`{"id":"does-not-matter", "key": "does-not-matter","category":"FREE"}`),
|
||||
// pass: false,
|
||||
// error: errors.New("status key is missing"),
|
||||
// },
|
||||
// {
|
||||
// name: "Error for invalid string license status",
|
||||
// data: []byte(`{"id":"does-not-matter","key": "does-not-matter", "category":"FREE", "status":10}`),
|
||||
// pass: false,
|
||||
// error: errors.New("status key is not a valid string"),
|
||||
// },
|
||||
// {
|
||||
// name: "Error for missing license plan",
|
||||
// data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE"}`),
|
||||
// pass: false,
|
||||
// error: errors.New("plan key is missing"),
|
||||
// },
|
||||
// {
|
||||
// name: "Error for invalid json license plan",
|
||||
// data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE","plan":10}`),
|
||||
// pass: false,
|
||||
// error: errors.New("plan key is not a valid map[string]interface {}"),
|
||||
// },
|
||||
// {
|
||||
// name: "Error for invalid license plan",
|
||||
// data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE","plan":{}}`),
|
||||
// pass: false,
|
||||
// error: errors.New("name key is missing"),
|
||||
// },
|
||||
// {
|
||||
// name: "Parse the entire license properly",
|
||||
// data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE","plan":{"name":"TEAMS"},"valid_from": 1730899309,"valid_until": -1}`),
|
||||
// pass: true,
|
||||
// expected: &LicenseV3{
|
||||
// ID: "does-not-matter",
|
||||
// Key: "does-not-matter-key",
|
||||
// Data: map[string]interface{}{
|
||||
// "plan": map[string]interface{}{
|
||||
// "name": "TEAMS",
|
||||
// },
|
||||
// "category": "FREE",
|
||||
// "status": "ACTIVE",
|
||||
// "valid_from": float64(1730899309),
|
||||
// "valid_until": float64(-1),
|
||||
// },
|
||||
// PlanName: PlanNameTeams,
|
||||
// ValidFrom: 1730899309,
|
||||
// ValidUntil: -1,
|
||||
// Status: "ACTIVE",
|
||||
// IsCurrent: false,
|
||||
// Features: model.FeatureSet{},
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "Fallback to basic plan if license status is invalid",
|
||||
// data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"INVALID","plan":{"name":"TEAMS"},"valid_from": 1730899309,"valid_until": -1}`),
|
||||
// pass: true,
|
||||
// expected: &LicenseV3{
|
||||
// ID: "does-not-matter",
|
||||
// Key: "does-not-matter-key",
|
||||
// Data: map[string]interface{}{
|
||||
// "plan": map[string]interface{}{
|
||||
// "name": "TEAMS",
|
||||
// },
|
||||
// "category": "FREE",
|
||||
// "status": "INVALID",
|
||||
// "valid_from": float64(1730899309),
|
||||
// "valid_until": float64(-1),
|
||||
// },
|
||||
// PlanName: PlanNameBasic,
|
||||
// ValidFrom: 1730899309,
|
||||
// ValidUntil: -1,
|
||||
// Status: "INVALID",
|
||||
// IsCurrent: false,
|
||||
// Features: model.FeatureSet{},
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "fallback states for validFrom and validUntil",
|
||||
// data: []byte(`{"id":"does-not-matter","key":"does-not-matter-key","category":"FREE","status":"ACTIVE","plan":{"name":"TEAMS"},"valid_from":1234.456,"valid_until":5678.567}`),
|
||||
// pass: true,
|
||||
// expected: &LicenseV3{
|
||||
// ID: "does-not-matter",
|
||||
// Key: "does-not-matter-key",
|
||||
// Data: map[string]interface{}{
|
||||
// "plan": map[string]interface{}{
|
||||
// "name": "TEAMS",
|
||||
// },
|
||||
// "valid_from": 1234.456,
|
||||
// "valid_until": 5678.567,
|
||||
// "category": "FREE",
|
||||
// "status": "ACTIVE",
|
||||
// },
|
||||
// PlanName: PlanNameTeams,
|
||||
// ValidFrom: 1234,
|
||||
// ValidUntil: 5678,
|
||||
// Status: "ACTIVE",
|
||||
// IsCurrent: false,
|
||||
// Features: model.FeatureSet{},
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
|
||||
// for _, tc := range testCases {
|
||||
// var licensePayload map[string]interface{}
|
||||
// err := json.Unmarshal(tc.data, &licensePayload)
|
||||
// require.NoError(t, err)
|
||||
// license, err := NewLicenseV3(licensePayload)
|
||||
// if license != nil {
|
||||
// license.Features = make(model.FeatureSet, 0)
|
||||
// delete(license.Data, "features")
|
||||
// }
|
||||
|
||||
// if tc.pass {
|
||||
// require.NoError(t, err)
|
||||
// require.NotNil(t, license)
|
||||
// assert.Equal(t, tc.expected, license)
|
||||
// } else {
|
||||
// require.Error(t, err)
|
||||
// assert.EqualError(t, err, tc.error.Error())
|
||||
// require.Nil(t, license)
|
||||
// }
|
||||
|
||||
// }
|
||||
// }
|
||||
@@ -1,76 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
type GettablePAT struct {
|
||||
CreatedByUser PatUser `json:"createdByUser"`
|
||||
UpdatedByUser PatUser `json:"updatedByUser"`
|
||||
|
||||
StorablePersonalAccessToken
|
||||
}
|
||||
|
||||
type PatUser struct {
|
||||
types.User
|
||||
NotFound bool `json:"notFound"`
|
||||
}
|
||||
|
||||
func NewGettablePAT(name, role, userID string, expiresAt int64) GettablePAT {
|
||||
return GettablePAT{
|
||||
StorablePersonalAccessToken: NewStorablePersonalAccessToken(name, role, userID, expiresAt),
|
||||
}
|
||||
}
|
||||
|
||||
type StorablePersonalAccessToken struct {
|
||||
bun.BaseModel `bun:"table:personal_access_token"`
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
OrgID string `json:"orgId" bun:"org_id,type:text,notnull"`
|
||||
Role string `json:"role" bun:"role,type:text,notnull,default:'ADMIN'"`
|
||||
UserID string `json:"userId" bun:"user_id,type:text,notnull"`
|
||||
Token string `json:"token" bun:"token,type:text,notnull,unique"`
|
||||
Name string `json:"name" bun:"name,type:text,notnull"`
|
||||
ExpiresAt int64 `json:"expiresAt" bun:"expires_at,notnull,default:0"`
|
||||
LastUsed int64 `json:"lastUsed" bun:"last_used,notnull,default:0"`
|
||||
Revoked bool `json:"revoked" bun:"revoked,notnull,default:false"`
|
||||
UpdatedByUserID string `json:"updatedByUserId" bun:"updated_by_user_id,type:text,notnull,default:''"`
|
||||
}
|
||||
|
||||
func NewStorablePersonalAccessToken(name, role, userID string, expiresAt int64) StorablePersonalAccessToken {
|
||||
now := time.Now()
|
||||
if expiresAt != 0 {
|
||||
// convert expiresAt to unix timestamp from days
|
||||
expiresAt = now.Unix() + (expiresAt * 24 * 60 * 60)
|
||||
}
|
||||
|
||||
// Generate a 32-byte random token.
|
||||
token := make([]byte, 32)
|
||||
rand.Read(token)
|
||||
// Encode the token in base64.
|
||||
encodedToken := base64.StdEncoding.EncodeToString(token)
|
||||
|
||||
return StorablePersonalAccessToken{
|
||||
Token: encodedToken,
|
||||
Name: name,
|
||||
Role: role,
|
||||
UserID: userID,
|
||||
ExpiresAt: expiresAt,
|
||||
LastUsed: 0,
|
||||
Revoked: false,
|
||||
UpdatedByUserID: "",
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
},
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package zeus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
neturl "net/url"
|
||||
"sync"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
)
|
||||
|
||||
// This will be set via ldflags at build time.
|
||||
var (
|
||||
url string = "<unset>"
|
||||
once sync.Once
|
||||
GlobalConfig zeus.Config
|
||||
)
|
||||
|
||||
// init initializes and validates the Zeus configuration
|
||||
func init() {
|
||||
once.Do(func() {
|
||||
parsedURL, err := neturl.Parse(url)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("invalid zeus URL: %w", err))
|
||||
}
|
||||
|
||||
GlobalConfig = zeus.Config{URL: parsedURL}
|
||||
if err := GlobalConfig.Validate(); err != nil {
|
||||
panic(fmt.Errorf("invalid zeus config: %w", err))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package implzeus
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/http/client"
|
||||
"github.com/SigNoz/signoz/pkg/types/licensetypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/metertypes"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
)
|
||||
|
||||
type Provider struct {
|
||||
settings factory.ScopedProviderSettings
|
||||
config zeus.Config
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func NewProviderFactory() factory.ProviderFactory[zeus.Zeus, zeus.Config] {
|
||||
return factory.NewProviderFactory(factory.MustNewName("impl"), func(ctx context.Context, providerSettings factory.ProviderSettings, config zeus.Config) (zeus.Zeus, error) {
|
||||
return New(ctx, providerSettings, config)
|
||||
})
|
||||
}
|
||||
|
||||
func New(ctx context.Context, providerSettings factory.ProviderSettings, config zeus.Config) (zeus.Zeus, error) {
|
||||
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/ee/zeus/implzeus")
|
||||
|
||||
httpClient := client.New(
|
||||
settings.Logger(),
|
||||
providerSettings.TracerProvider,
|
||||
providerSettings.MeterProvider,
|
||||
client.WithRequestResponseLog(true),
|
||||
client.WithRetryCount(3),
|
||||
)
|
||||
|
||||
return &Provider{
|
||||
settings: settings,
|
||||
config: config,
|
||||
client: httpClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) GetLicense(ctx context.Context, key string) (*licensetypes.License, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) GetCheckoutURL(ctx context.Context, key string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (provider *Provider) GetPortalURL(ctx context.Context, key string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (provider *Provider) GetDeployment(ctx context.Context, key string) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) PutMeters(ctx context.Context, key string, meters metertypes.Meters) error {
|
||||
return nil
|
||||
}
|
||||
@@ -18,13 +18,6 @@
|
||||
"field_send_resolved": "Send resolved alerts",
|
||||
"field_channel_type": "Type",
|
||||
"field_webhook_url": "Webhook URL",
|
||||
"tooltip_webhook_url": "The URL of the webhook to send alerts to. Learn more about webhook integration in the docs [here](https://signoz.io/docs/alerts-management/notification-channel/webhook/). Integrates with [Incident.io](https://signoz.io/docs/alerts-management/notification-channel/incident-io/), [Rootly](https://signoz.io/docs/alerts-management/notification-channel/rootly/), [Zenduty](https://signoz.io/docs/alerts-management/notification-channel/zenduty/) and [more](https://signoz.io/docs/alerts-management/notification-channel/webhook/#my-incident-management-tool-is-not-listed-can-i-still-integrate).",
|
||||
"tooltip_slack_url": "The URL of the slack [incoming webhook](https://docs.slack.dev/messaging/sending-messages-using-incoming-webhooks/) to send alerts to. Learn more about slack integration in the docs [here](https://signoz.io/docs/alerts-management/notification-channel/slack/).",
|
||||
"tooltip_pager_routing_key": "Learn how to obtain the routing key from your PagerDuty account [here](https://signoz.io/docs/alerts-management/notification-channel/pagerduty/#obtaining-integration-or-routing-key).",
|
||||
"tooltip_opsgenie_api_key": "Learn how to obtain the API key from your OpsGenie account [here](https://support.atlassian.com/opsgenie/docs/integrate-opsgenie-with-prometheus/).",
|
||||
"tooltip_email_to": "Enter email addresses separated by commas.",
|
||||
"tooltip_ms_teams_url": "The URL of the Microsoft Teams [webhook](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498) to send alerts to. Learn more about Microsoft Teams integration in the docs [here](https://signoz.io/docs/alerts-management/notification-channel/ms-teams/).",
|
||||
|
||||
"field_slack_recipient": "Recipient",
|
||||
"field_slack_title": "Title",
|
||||
"field_slack_description": "Description",
|
||||
|
||||
@@ -18,12 +18,6 @@
|
||||
"field_send_resolved": "Send resolved alerts",
|
||||
"field_channel_type": "Type",
|
||||
"field_webhook_url": "Webhook URL",
|
||||
"tooltip_webhook_url": "The URL of the webhook to send alerts to. Learn more about webhook integration in the docs [here](https://signoz.io/docs/alerts-management/notification-channel/webhook/). Integrates with [Incident.io](https://signoz.io/docs/alerts-management/notification-channel/incident-io/), [Rootly](https://signoz.io/docs/alerts-management/notification-channel/rootly/), [Zenduty](https://signoz.io/docs/alerts-management/notification-channel/zenduty/) and [more](https://signoz.io/docs/alerts-management/notification-channel/webhook/#my-incident-management-tool-is-not-listed-can-i-still-integrate).",
|
||||
"tooltip_slack_url": "The URL of the slack [incoming webhook](https://docs.slack.dev/messaging/sending-messages-using-incoming-webhooks/) to send alerts to. Learn more about slack integration in the docs [here](https://signoz.io/docs/alerts-management/notification-channel/slack/).",
|
||||
"tooltip_pager_routing_key": "Learn how to obtain the routing key from your PagerDuty account [here](https://signoz.io/docs/alerts-management/notification-channel/pagerduty/#obtaining-integration-or-routing-key).",
|
||||
"tooltip_opsgenie_api_key": "Learn how to obtain the API key from your OpsGenie account [here](https://support.atlassian.com/opsgenie/docs/integrate-opsgenie-with-prometheus/).",
|
||||
"tooltip_email_to": "Enter email addresses separated by commas.",
|
||||
"tooltip_ms_teams_url": "The URL of the Microsoft Teams [webhook](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498) to send alerts to. Learn more about Microsoft Teams integration in the docs [here](https://signoz.io/docs/alerts-management/notification-channel/ms-teams/).",
|
||||
"field_slack_recipient": "Recipient",
|
||||
"field_slack_title": "Title",
|
||||
"field_slack_description": "Description",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import getLocalStorageApi from 'api/browser/localstorage/get';
|
||||
import setLocalStorageApi from 'api/browser/localstorage/set';
|
||||
@@ -16,7 +15,6 @@ import { LICENSE_PLAN_KEY } from 'hooks/useLicense';
|
||||
import { NotificationProvider } from 'hooks/useNotifications';
|
||||
import { ResourceProvider } from 'hooks/useResourceAttribute';
|
||||
import history from 'lib/history';
|
||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||
import posthog from 'posthog-js';
|
||||
import AlertRuleProvider from 'providers/Alert';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
@@ -28,7 +26,6 @@ import { Route, Router, Switch } from 'react-router-dom';
|
||||
import { CompatRouter } from 'react-router-dom-v5-compat';
|
||||
import { extractDomain } from 'utils/app';
|
||||
|
||||
import { Home } from './pageComponents';
|
||||
import PrivateRoute from './Private';
|
||||
import defaultRoutes, {
|
||||
AppRoutes,
|
||||
@@ -48,6 +45,7 @@ function App(): JSX.Element {
|
||||
activeLicenseV3,
|
||||
isFetchingActiveLicenseV3,
|
||||
userFetchError,
|
||||
licensesFetchError,
|
||||
featureFlagsFetchError,
|
||||
isLoggedIn: isLoggedInState,
|
||||
featureFlags,
|
||||
@@ -57,7 +55,10 @@ function App(): JSX.Element {
|
||||
|
||||
const { hostname, pathname } = window.location;
|
||||
|
||||
const { isCloudUser, isEnterpriseSelfHostedUser } = useGetTenantLicense();
|
||||
const {
|
||||
isCloudUser: isCloudUserVal,
|
||||
isEECloudUser: isEECloudUserVal,
|
||||
} = useGetTenantLicense();
|
||||
|
||||
const enableAnalytics = useCallback(
|
||||
(user: IUser): void => {
|
||||
@@ -167,7 +168,7 @@ function App(): JSX.Element {
|
||||
|
||||
let updatedRoutes = defaultRoutes;
|
||||
// if the user is a cloud user
|
||||
if (isCloudUser || isEnterpriseSelfHostedUser) {
|
||||
if (isCloudUserVal || isEECloudUserVal) {
|
||||
// if the user is on basic plan then remove billing
|
||||
if (isOnBasicPlan) {
|
||||
updatedRoutes = updatedRoutes.filter(
|
||||
@@ -189,10 +190,10 @@ function App(): JSX.Element {
|
||||
isLoggedInState,
|
||||
user,
|
||||
licenses,
|
||||
isCloudUser,
|
||||
isEnterpriseSelfHostedUser,
|
||||
isCloudUserVal,
|
||||
isFetchingLicenses,
|
||||
isFetchingUser,
|
||||
isEECloudUserVal,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -207,7 +208,6 @@ function App(): JSX.Element {
|
||||
}
|
||||
}, [pathname]);
|
||||
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
useEffect(() => {
|
||||
// feature flag shouldn't be loading and featureFlags or fetchError any one of this should be true indicating that req is complete
|
||||
// licenses should also be present. there is no check for licenses for loading and error as that is mandatory if not present then routing
|
||||
@@ -233,12 +233,7 @@ function App(): JSX.Element {
|
||||
const showAddCreditCardModal =
|
||||
!isPremiumSupportEnabled && !trialInfo?.trialConvertedToSubscription;
|
||||
|
||||
if (
|
||||
isLoggedInState &&
|
||||
isChatSupportEnabled &&
|
||||
!showAddCreditCardModal &&
|
||||
(isCloudUser || isEnterpriseSelfHostedUser)
|
||||
) {
|
||||
if (isLoggedInState && isChatSupportEnabled && !showAddCreditCardModal) {
|
||||
window.Intercom('boot', {
|
||||
app_id: process.env.INTERCOM_APP_ID,
|
||||
email: user?.email || '',
|
||||
@@ -257,53 +252,13 @@ function App(): JSX.Element {
|
||||
licenses,
|
||||
activeLicenseV3,
|
||||
trialInfo,
|
||||
isCloudUser,
|
||||
isEnterpriseSelfHostedUser,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isFetchingUser && isCloudUser && user && user.email) {
|
||||
if (!isFetchingUser && isCloudUserVal && user && user.email) {
|
||||
enableAnalytics(user);
|
||||
}
|
||||
}, [user, isFetchingUser, isCloudUser, enableAnalytics]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isCloudUser || isEnterpriseSelfHostedUser) {
|
||||
if (process.env.POSTHOG_KEY) {
|
||||
posthog.init(process.env.POSTHOG_KEY, {
|
||||
api_host: 'https://us.i.posthog.com',
|
||||
person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well
|
||||
});
|
||||
}
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN,
|
||||
tunnel: process.env.TUNNEL_URL,
|
||||
environment: 'production',
|
||||
integrations: [
|
||||
Sentry.browserTracingIntegration(),
|
||||
Sentry.replayIntegration({
|
||||
maskAllText: false,
|
||||
blockAllMedia: false,
|
||||
}),
|
||||
],
|
||||
// Performance Monitoring
|
||||
tracesSampleRate: 1.0, // Capture 100% of the transactions
|
||||
// Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
|
||||
tracePropagationTargets: [],
|
||||
// Session Replay
|
||||
replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
|
||||
replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
|
||||
});
|
||||
} else {
|
||||
posthog.reset();
|
||||
Sentry.close();
|
||||
|
||||
if (window.cioanalytics && typeof window.cioanalytics.reset === 'function') {
|
||||
window.cioanalytics.reset();
|
||||
}
|
||||
}
|
||||
}, [isCloudUser, isEnterpriseSelfHostedUser]);
|
||||
}, [user, isFetchingUser, isCloudUserVal, enableAnalytics]);
|
||||
|
||||
// if the user is in logged in state
|
||||
if (isLoggedInState) {
|
||||
@@ -315,55 +270,60 @@ function App(): JSX.Element {
|
||||
// if the required calls fails then return a something went wrong error
|
||||
// this needs to be on top of data missing error because if there is an error, data will never be loaded and it will
|
||||
// move to indefinitive loading
|
||||
if (userFetchError && pathname !== ROUTES.SOMETHING_WENT_WRONG) {
|
||||
if (
|
||||
(userFetchError || licensesFetchError) &&
|
||||
pathname !== ROUTES.SOMETHING_WENT_WRONG
|
||||
) {
|
||||
history.replace(ROUTES.SOMETHING_WENT_WRONG);
|
||||
}
|
||||
|
||||
// if all of the data is not set then return a spinner, this is required because there is some gap between loading states and data setting
|
||||
if ((!licenses || !user.email || !featureFlags) && !userFetchError) {
|
||||
if (
|
||||
(!licenses || !user.email || !featureFlags) &&
|
||||
!userFetchError &&
|
||||
!licensesFetchError
|
||||
) {
|
||||
return <Spinner tip="Loading..." />;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||
<ConfigProvider theme={themeConfig}>
|
||||
<Router history={history}>
|
||||
<CompatRouter>
|
||||
<NotificationProvider>
|
||||
<PrivateRoute>
|
||||
<ResourceProvider>
|
||||
<QueryBuilderProvider>
|
||||
<DashboardProvider>
|
||||
<KeyboardHotkeysProvider>
|
||||
<AlertRuleProvider>
|
||||
<AppLayout>
|
||||
<Suspense fallback={<Spinner size="large" tip="Loading..." />}>
|
||||
<Switch>
|
||||
{routes.map(({ path, component, exact }) => (
|
||||
<Route
|
||||
key={`${path}`}
|
||||
exact={exact}
|
||||
path={path}
|
||||
component={component}
|
||||
/>
|
||||
))}
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route path="*" component={NotFound} />
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</AppLayout>
|
||||
</AlertRuleProvider>
|
||||
</KeyboardHotkeysProvider>
|
||||
</DashboardProvider>
|
||||
</QueryBuilderProvider>
|
||||
</ResourceProvider>
|
||||
</PrivateRoute>
|
||||
</NotificationProvider>
|
||||
</CompatRouter>
|
||||
</Router>
|
||||
</ConfigProvider>
|
||||
</Sentry.ErrorBoundary>
|
||||
<ConfigProvider theme={themeConfig}>
|
||||
<Router history={history}>
|
||||
<CompatRouter>
|
||||
<NotificationProvider>
|
||||
<PrivateRoute>
|
||||
<ResourceProvider>
|
||||
<QueryBuilderProvider>
|
||||
<DashboardProvider>
|
||||
<KeyboardHotkeysProvider>
|
||||
<AlertRuleProvider>
|
||||
<AppLayout>
|
||||
<Suspense fallback={<Spinner size="large" tip="Loading..." />}>
|
||||
<Switch>
|
||||
{routes.map(({ path, component, exact }) => (
|
||||
<Route
|
||||
key={`${path}`}
|
||||
exact={exact}
|
||||
path={path}
|
||||
component={component}
|
||||
/>
|
||||
))}
|
||||
|
||||
<Route path="*" component={NotFound} />
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</AppLayout>
|
||||
</AlertRuleProvider>
|
||||
</KeyboardHotkeysProvider>
|
||||
</DashboardProvider>
|
||||
</QueryBuilderProvider>
|
||||
</ResourceProvider>
|
||||
</PrivateRoute>
|
||||
</NotificationProvider>
|
||||
</CompatRouter>
|
||||
</Router>
|
||||
</ConfigProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
// keep this consistent with backend constants.go
|
||||
export enum FeatureKeys {
|
||||
SSO = 'SSO',
|
||||
ENTERPRISE_PLAN = 'ENTERPRISE_PLAN',
|
||||
BASIC_PLAN = 'BASIC_PLAN',
|
||||
ALERT_CHANNEL_SLACK = 'ALERT_CHANNEL_SLACK',
|
||||
ALERT_CHANNEL_WEBHOOK = 'ALERT_CHANNEL_WEBHOOK',
|
||||
ALERT_CHANNEL_PAGERDUTY = 'ALERT_CHANNEL_PAGERDUTY',
|
||||
ALERT_CHANNEL_OPSGENIE = 'ALERT_CHANNEL_OPSGENIE',
|
||||
ALERT_CHANNEL_MSTEAMS = 'ALERT_CHANNEL_MSTEAMS',
|
||||
DurationSort = 'DurationSort',
|
||||
TimestampSort = 'TimestampSort',
|
||||
SMART_TRACE_DETAIL = 'SMART_TRACE_DETAIL',
|
||||
CUSTOM_METRICS_FUNCTION = 'CUSTOM_METRICS_FUNCTION',
|
||||
QUERY_BUILDER_PANELS = 'QUERY_BUILDER_PANELS',
|
||||
QUERY_BUILDER_ALERTS = 'QUERY_BUILDER_ALERTS',
|
||||
DISABLE_UPSELL = 'DISABLE_UPSELL',
|
||||
USE_SPAN_METRICS = 'USE_SPAN_METRICS',
|
||||
OSS = 'OSS',
|
||||
ONBOARDING = 'ONBOARDING',
|
||||
CHAT_SUPPORT = 'CHAT_SUPPORT',
|
||||
GATEWAY = 'GATEWAY',
|
||||
PREMIUM_SUPPORT = 'PREMIUM_SUPPORT',
|
||||
QUERY_BUILDER_SEARCH_V2 = 'QUERY_BUILDER_SEARCH_V2',
|
||||
ANOMALY_DETECTION = 'ANOMALY_DETECTION',
|
||||
AWS_INTEGRATION = 'AWS_INTEGRATION',
|
||||
ONBOARDING_V3 = 'ONBOARDING_V3',
|
||||
THIRD_PARTY_API = 'THIRD_PARTY_API',
|
||||
TRACE_FUNNELS = 'TRACE_FUNNELS',
|
||||
|
||||
@@ -31,10 +31,6 @@ jest.mock('hooks/useNotifications', () => ({
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('components/MarkdownRenderer/MarkdownRenderer', () => ({
|
||||
MarkdownRenderer: jest.fn(() => <div>Mocked MarkdownRenderer</div>),
|
||||
}));
|
||||
|
||||
describe('Create Alert Channel', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
@@ -18,10 +18,6 @@ import { render, screen } from 'tests/test-utils';
|
||||
|
||||
import { testLabelInputAndHelpValue } from './testUtils';
|
||||
|
||||
jest.mock('components/MarkdownRenderer/MarkdownRenderer', () => ({
|
||||
MarkdownRenderer: jest.fn(() => <div>Mocked MarkdownRenderer</div>),
|
||||
}));
|
||||
|
||||
describe('Create Alert Channel (Normal User)', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
@@ -20,10 +20,6 @@ jest.mock('hooks/useNotifications', () => ({
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('components/MarkdownRenderer/MarkdownRenderer', () => ({
|
||||
MarkdownRenderer: jest.fn(() => <div>Mocked MarkdownRenderer</div>),
|
||||
}));
|
||||
|
||||
describe('Should check if the edit alert channel is properly displayed ', () => {
|
||||
beforeEach(() => {
|
||||
render(<EditAlertChannels initialValue={editAlertChannelInitialValue} />);
|
||||
|
||||
@@ -61,7 +61,7 @@ export default function CustomDomainSettings(): JSX.Element {
|
||||
isLoading: isLoadingDeploymentsData,
|
||||
isFetching: isFetchingDeploymentsData,
|
||||
refetch: refetchDeploymentsData,
|
||||
} = useGetDeploymentsData(true);
|
||||
} = useGetDeploymentsData();
|
||||
|
||||
const {
|
||||
mutate: updateSubDomain,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Form, Input } from 'antd';
|
||||
import { MarkdownRenderer } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -10,20 +9,7 @@ function MsTeams({ setSelectedConfig }: MsTeamsProps): JSX.Element {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name="webhook_url"
|
||||
label={t('field_webhook_url')}
|
||||
tooltip={{
|
||||
title: (
|
||||
<MarkdownRenderer
|
||||
markdownContent={t('tooltip_ms_teams_url')}
|
||||
variables={{}}
|
||||
/>
|
||||
),
|
||||
overlayInnerStyle: { maxWidth: 400 },
|
||||
placement: 'right',
|
||||
}}
|
||||
>
|
||||
<Form.Item name="webhook_url" label={t('field_webhook_url')}>
|
||||
<Input
|
||||
onChange={(event): void => {
|
||||
setSelectedConfig((value) => ({
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Form, Input } from 'antd';
|
||||
import { MarkdownRenderer } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { OpsgenieChannel } from '../../CreateAlertChannels/config';
|
||||
@@ -20,21 +19,7 @@ function OpsgenieForm({ setSelectedConfig }: OpsgenieFormProps): JSX.Element {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name="api_key"
|
||||
label={t('field_opsgenie_api_key')}
|
||||
tooltip={{
|
||||
title: (
|
||||
<MarkdownRenderer
|
||||
markdownContent={t('tooltip_opsgenie_api_key')}
|
||||
variables={{}}
|
||||
/>
|
||||
),
|
||||
overlayInnerStyle: { maxWidth: 400 },
|
||||
placement: 'right',
|
||||
}}
|
||||
required
|
||||
>
|
||||
<Form.Item name="api_key" label={t('field_opsgenie_api_key')} required>
|
||||
<Input
|
||||
onChange={handleInputChange('api_key')}
|
||||
data-testid="opsgenie-api-key-textbox"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Form, Input } from 'antd';
|
||||
import { MarkdownRenderer } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -11,20 +10,7 @@ function PagerForm({ setSelectedConfig }: PagerFormProps): JSX.Element {
|
||||
const { t } = useTranslation('channels');
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name="routing_key"
|
||||
label={t('field_pager_routing_key')}
|
||||
tooltip={{
|
||||
title: (
|
||||
<MarkdownRenderer
|
||||
markdownContent={t('tooltip_pager_routing_key')}
|
||||
variables={{}}
|
||||
/>
|
||||
),
|
||||
overlayInnerStyle: { maxWidth: 400 },
|
||||
placement: 'right',
|
||||
}}
|
||||
>
|
||||
<Form.Item name="routing_key" label={t('field_pager_routing_key')} required>
|
||||
<Input
|
||||
onChange={(event): void => {
|
||||
setSelectedConfig((value) => ({
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Form, Input } from 'antd';
|
||||
import { MarkdownRenderer } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -12,20 +11,7 @@ function Slack({ setSelectedConfig }: SlackProps): JSX.Element {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name="api_url"
|
||||
label={t('field_webhook_url')}
|
||||
tooltip={{
|
||||
title: (
|
||||
<MarkdownRenderer
|
||||
markdownContent={t('tooltip_slack_url')}
|
||||
variables={{}}
|
||||
/>
|
||||
),
|
||||
overlayInnerStyle: { maxWidth: 400 },
|
||||
placement: 'right',
|
||||
}}
|
||||
>
|
||||
<Form.Item name="api_url" label={t('field_webhook_url')}>
|
||||
<Input
|
||||
onChange={(event): void => {
|
||||
setSelectedConfig((value) => ({
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Form, Input } from 'antd';
|
||||
import { MarkdownRenderer } from 'components/MarkdownRenderer/MarkdownRenderer';
|
||||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -10,20 +9,7 @@ function WebhookSettings({ setSelectedConfig }: WebhookProps): JSX.Element {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name="api_url"
|
||||
label={t('field_webhook_url')}
|
||||
tooltip={{
|
||||
title: (
|
||||
<MarkdownRenderer
|
||||
markdownContent={t('tooltip_webhook_url')}
|
||||
variables={{}}
|
||||
/>
|
||||
),
|
||||
overlayInnerStyle: { maxWidth: 400 },
|
||||
placement: 'right',
|
||||
}}
|
||||
>
|
||||
<Form.Item name="api_url" label={t('field_webhook_url')}>
|
||||
<Input
|
||||
onChange={(event): void => {
|
||||
setSelectedConfig((value) => ({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Form, FormInstance, Input, Select, Switch, Typography } from 'antd';
|
||||
import { Store } from 'antd/lib/form/interface';
|
||||
import { FeatureKeys } from 'constants/features';
|
||||
import ROUTES from 'constants/routes';
|
||||
import {
|
||||
ChannelType,
|
||||
@@ -10,8 +11,11 @@ import {
|
||||
WebhookChannel,
|
||||
} from 'container/CreateAlertChannels/config';
|
||||
import history from 'lib/history';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
import { Dispatch, ReactElement, SetStateAction } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FeatureFlagProps } from 'types/api/features/getFeaturesFlags';
|
||||
import { isFeatureKeys } from 'utils/app';
|
||||
|
||||
import EmailSettings from './Settings/Email';
|
||||
import MsTeamsSettings from './Settings/MsTeams';
|
||||
@@ -35,6 +39,17 @@ function FormAlertChannels({
|
||||
editing = false,
|
||||
}: FormAlertChannelsProps): JSX.Element {
|
||||
const { t } = useTranslation('channels');
|
||||
const { featureFlags } = useAppContext();
|
||||
|
||||
const feature = `ALERT_CHANNEL_${type.toUpperCase()}`;
|
||||
|
||||
const featureKey = isFeatureKeys(feature)
|
||||
? feature
|
||||
: FeatureKeys.ALERT_CHANNEL_SLACK;
|
||||
|
||||
const hasFeature = featureFlags?.find(
|
||||
(flag: FeatureFlagProps) => flag.name === featureKey,
|
||||
);
|
||||
|
||||
const renderSettings = (): ReactElement | null => {
|
||||
switch (type) {
|
||||
@@ -131,7 +146,7 @@ function FormAlertChannels({
|
||||
|
||||
<Form.Item>
|
||||
<Button
|
||||
disabled={savingState}
|
||||
disabled={savingState || !hasFeature}
|
||||
loading={savingState}
|
||||
type="primary"
|
||||
onClick={(): void => onSaveHandler(type)}
|
||||
@@ -139,7 +154,7 @@ function FormAlertChannels({
|
||||
{t('button_save_channel')}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={testingState}
|
||||
disabled={testingState || !hasFeature}
|
||||
loading={testingState}
|
||||
onClick={(): void => onTestHandler(type)}
|
||||
>
|
||||
|
||||
@@ -467,6 +467,10 @@ function FormAlertRules({
|
||||
panelType,
|
||||
]);
|
||||
|
||||
const isAlertAvailable =
|
||||
!featureFlags?.find((flag) => flag.name === FeatureKeys.QUERY_BUILDER_ALERTS)
|
||||
?.active || false;
|
||||
|
||||
const saveRule = useCallback(async () => {
|
||||
if (!isFormValid()) {
|
||||
return;
|
||||
@@ -685,6 +689,7 @@ function FormAlertRules({
|
||||
const isAlertNameMissing = !formInstance.getFieldValue('alert');
|
||||
|
||||
const isAlertAvailableToSave =
|
||||
isAlertAvailable &&
|
||||
currentQuery.queryType === EQueryType.QUERY_BUILDER &&
|
||||
alertType !== AlertTypes.METRICS_BASED_ALERT;
|
||||
|
||||
|
||||
@@ -23,13 +23,10 @@ function DataSourceInfo({
|
||||
|
||||
const notSendingData = !dataSentToSigNoz;
|
||||
|
||||
const isEnabled =
|
||||
activeLicenseV3 && activeLicenseV3.platform === LicensePlatform.CLOUD;
|
||||
|
||||
const {
|
||||
data: deploymentsData,
|
||||
isError: isErrorDeploymentsData,
|
||||
} = useGetDeploymentsData(isEnabled || false);
|
||||
} = useGetDeploymentsData();
|
||||
|
||||
const [region, setRegion] = useState<string>('');
|
||||
const [url, setUrl] = useState<string>('');
|
||||
|
||||
@@ -293,7 +293,7 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
isLoading: isLoadingDeploymentsData,
|
||||
isFetching: isFetchingDeploymentsData,
|
||||
isError: isErrorDeploymentsData,
|
||||
} = useGetDeploymentsData(true);
|
||||
} = useGetDeploymentsData();
|
||||
|
||||
const {
|
||||
mutate: createIngestionKey,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQue
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import useDebouncedFn from 'hooks/useDebouncedFunction';
|
||||
import { useEventSourceEvent } from 'hooks/useEventSourceEvent';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
import { prepareQueryRangePayload } from 'lib/dashboard/prepareQueryRangePayload';
|
||||
import { useEventSource } from 'providers/EventSource';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
@@ -37,6 +38,8 @@ function LiveLogsContainer(): JSX.Element {
|
||||
|
||||
const batchedEventsRef = useRef<ILog[]>([]);
|
||||
|
||||
const { notifications } = useNotifications();
|
||||
|
||||
const { selectedTime: globalSelectedTime } = useSelector<
|
||||
AppState,
|
||||
GlobalReducer
|
||||
@@ -47,8 +50,6 @@ function LiveLogsContainer(): JSX.Element {
|
||||
handleCloseConnection,
|
||||
initialLoading,
|
||||
isConnectionLoading,
|
||||
isConnectionError,
|
||||
reconnectDueToError,
|
||||
} = useEventSource();
|
||||
|
||||
const compositeQuery = useGetCompositeQueryParam();
|
||||
@@ -85,8 +86,8 @@ function LiveLogsContainer(): JSX.Element {
|
||||
);
|
||||
|
||||
const handleError = useCallback(() => {
|
||||
console.error('Sorry, something went wrong');
|
||||
}, []);
|
||||
notifications.error({ message: 'Sorry, something went wrong' });
|
||||
}, [notifications]);
|
||||
|
||||
useEventSourceEvent('message', handleGetLiveLogs);
|
||||
useEventSourceEvent('error', handleError);
|
||||
@@ -152,23 +153,6 @@ function LiveLogsContainer(): JSX.Element {
|
||||
handleStartNewConnection,
|
||||
]);
|
||||
|
||||
useEffect((): (() => void) | undefined => {
|
||||
if (isConnectionError && reconnectDueToError && compositeQuery) {
|
||||
// Small delay to prevent immediate reconnection attempts
|
||||
const reconnectTimer = setTimeout(() => {
|
||||
handleStartNewConnection(compositeQuery);
|
||||
}, 1000);
|
||||
|
||||
return (): void => clearTimeout(reconnectTimer);
|
||||
}
|
||||
return undefined;
|
||||
}, [
|
||||
isConnectionError,
|
||||
reconnectDueToError,
|
||||
compositeQuery,
|
||||
handleStartNewConnection,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const prefetchedList = queryLocationState?.listQueryPayload[0]?.list;
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
.inspect-metrics-modal {
|
||||
.inspect-metrics-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 6px;
|
||||
|
||||
.inspect-metrics-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: default;
|
||||
color: var(--text-vanilla-500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import './Inspect.styles.scss';
|
||||
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Button, Drawer, Typography } from 'antd';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { Compass } from 'lucide-react';
|
||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||
|
||||
import { InspectProps } from './types';
|
||||
|
||||
function Inspect({ metricName, isOpen, onClose }: InspectProps): JSX.Element {
|
||||
const isDarkMode = useIsDarkMode();
|
||||
|
||||
return (
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||
<Drawer
|
||||
width="100%"
|
||||
title={
|
||||
<div className="inspect-metrics-title">
|
||||
<Typography.Text>Metrics Explorer —</Typography.Text>
|
||||
<Button
|
||||
className="inspect-metrics-button"
|
||||
size="small"
|
||||
icon={<Compass size={14} />}
|
||||
disabled
|
||||
>
|
||||
Inspect Metric
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
open={isOpen}
|
||||
onClose={onClose}
|
||||
style={{
|
||||
overscrollBehavior: 'contain',
|
||||
background: isDarkMode ? Color.BG_INK_400 : Color.BG_VANILLA_100,
|
||||
}}
|
||||
className="inspect-metrics-modal"
|
||||
destroyOnClose
|
||||
>
|
||||
<div>Inspect</div>
|
||||
<div>{metricName}</div>
|
||||
</Drawer>
|
||||
</Sentry.ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
export default Inspect;
|
||||
@@ -1 +0,0 @@
|
||||
export const INSPECT_FEATURE_FLAG_KEY = 'metrics-explorer-inspect-feature-flag';
|
||||
@@ -1,3 +0,0 @@
|
||||
import Inspect from './Inspect';
|
||||
|
||||
export default Inspect;
|
||||
@@ -1,5 +0,0 @@
|
||||
export type InspectProps = {
|
||||
metricName: string | null;
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
import { INSPECT_FEATURE_FLAG_KEY } from './constants';
|
||||
|
||||
/**
|
||||
* Check if the inspect feature flag is enabled
|
||||
* returns true if the feature flag is enabled, false otherwise
|
||||
* Show the inspect button in metrics explorer if the feature flag is enabled
|
||||
*/
|
||||
export function isInspectEnabled(): boolean {
|
||||
const featureFlag = localStorage.getItem(INSPECT_FEATURE_FLAG_KEY);
|
||||
return featureFlag === 'true';
|
||||
}
|
||||
@@ -20,12 +20,6 @@
|
||||
gap: 4px;
|
||||
background-color: var(--bg-slate-300);
|
||||
}
|
||||
|
||||
.inspect-metrics-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.metric-details-content {
|
||||
|
||||
@@ -2,21 +2,12 @@ import './MetricDetails.styles.scss';
|
||||
import '../Summary/Summary.styles.scss';
|
||||
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
Drawer,
|
||||
Empty,
|
||||
Skeleton,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { Divider, Drawer, Empty, Skeleton, Tooltip, Typography } from 'antd';
|
||||
import { useGetMetricDetails } from 'hooks/metricsExplorer/useGetMetricDetails';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { Compass, X } from 'lucide-react';
|
||||
import { X } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { isInspectEnabled } from '../Inspect/utils';
|
||||
import { formatNumberIntoHumanReadableFormat } from '../Summary/utils';
|
||||
import AllAttributes from './AllAttributes';
|
||||
import DashboardsAndAlertsPopover from './DashboardsAndAlertsPopover';
|
||||
@@ -31,7 +22,6 @@ function MetricDetails({
|
||||
onClose,
|
||||
isOpen,
|
||||
metricName,
|
||||
openInspectModal,
|
||||
}: MetricDetailsProps): JSX.Element {
|
||||
const isDarkMode = useIsDarkMode();
|
||||
// const { safeNavigate } = useSafeNavigate();
|
||||
@@ -53,8 +43,6 @@ function MetricDetails({
|
||||
return formatTimestampToReadableDate(metric.lastReceived);
|
||||
}, [metric]);
|
||||
|
||||
const showInspectFeature = useMemo(() => isInspectEnabled(), []);
|
||||
|
||||
const isMetricDetailsLoading = isLoading || isFetching;
|
||||
|
||||
const timeSeries = useMemo(() => {
|
||||
@@ -104,19 +92,6 @@ function MetricDetails({
|
||||
>
|
||||
Open in Explorer
|
||||
</Button> */}
|
||||
{/* Show the based on the feature flag. Will remove before releasing the feature */}
|
||||
{showInspectFeature && (
|
||||
<Button
|
||||
className="inspect-metrics-button"
|
||||
aria-label="Inspect Metric"
|
||||
icon={<Compass size={18} />}
|
||||
onClick={(): void => {
|
||||
if (metric?.name) {
|
||||
openInspectModal(metric.name);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
placement="right"
|
||||
|
||||
@@ -10,7 +10,6 @@ export interface MetricDetailsProps {
|
||||
isOpen: boolean;
|
||||
metricName: string | null;
|
||||
isModalTimeSelection: boolean;
|
||||
openInspectModal: (metricName: string) => void;
|
||||
}
|
||||
|
||||
export interface DashboardsAndAlertsPopoverProps {
|
||||
|
||||
@@ -13,7 +13,6 @@ import { AppState } from 'store/reducers';
|
||||
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
|
||||
import InspectModal from '../Inspect';
|
||||
import MetricDetails from '../MetricDetails';
|
||||
import MetricsSearch from './MetricsSearch';
|
||||
import MetricsTable from './MetricsTable';
|
||||
@@ -36,7 +35,6 @@ function Summary(): JSX.Element {
|
||||
TreemapViewType.TIMESERIES,
|
||||
);
|
||||
const [isMetricDetailsOpen, setIsMetricDetailsOpen] = useState(false);
|
||||
const [isInspectModalOpen, setIsInspectModalOpen] = useState(false);
|
||||
const [selectedMetricName, setSelectedMetricName] = useState<string | null>(
|
||||
null,
|
||||
);
|
||||
@@ -152,17 +150,6 @@ function Summary(): JSX.Element {
|
||||
setIsMetricDetailsOpen(false);
|
||||
};
|
||||
|
||||
const openInspectModal = (metricName: string): void => {
|
||||
setSelectedMetricName(metricName);
|
||||
setIsInspectModalOpen(true);
|
||||
setIsMetricDetailsOpen(false);
|
||||
};
|
||||
|
||||
const closeInspectModal = (): void => {
|
||||
setIsInspectModalOpen(false);
|
||||
setSelectedMetricName(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||
<div className="metrics-explorer-summary-tab">
|
||||
@@ -197,14 +184,6 @@ function Summary(): JSX.Element {
|
||||
onClose={closeMetricDetails}
|
||||
metricName={selectedMetricName}
|
||||
isModalTimeSelection={false}
|
||||
openInspectModal={openInspectModal}
|
||||
/>
|
||||
)}
|
||||
{isInspectModalOpen && (
|
||||
<InspectModal
|
||||
isOpen={isInspectModalOpen}
|
||||
onClose={closeInspectModal}
|
||||
metricName={selectedMetricName}
|
||||
/>
|
||||
)}
|
||||
</Sentry.ErrorBoundary>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { WarningOutlined } from '@ant-design/icons';
|
||||
import { Button, Flex, Modal, Space, Typography } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||
import { FeatureKeys } from 'constants/features';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import {
|
||||
initialQueriesMap,
|
||||
@@ -26,6 +27,7 @@ import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults';
|
||||
import { cloneDeep, defaultTo, isEmpty, isUndefined } from 'lodash-es';
|
||||
import { Check, X } from 'lucide-react';
|
||||
import { DashboardWidgetPageParams } from 'pages/DashboardWidget';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||
import {
|
||||
getNextWidgets,
|
||||
@@ -77,6 +79,8 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
|
||||
const { t } = useTranslation(['dashboard']);
|
||||
|
||||
const { featureFlags } = useAppContext();
|
||||
|
||||
const { registerShortcut, deregisterShortcut } = useKeyboardHotkeys();
|
||||
|
||||
const {
|
||||
@@ -562,7 +566,12 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const isQueryBuilderActive =
|
||||
!featureFlags?.find((flag) => flag.name === FeatureKeys.QUERY_BUILDER_PANELS)
|
||||
?.active || false;
|
||||
|
||||
const isNewTraceLogsAvailable =
|
||||
isQueryBuilderActive &&
|
||||
currentQuery.queryType === EQueryType.QUERY_BUILDER &&
|
||||
currentQuery.builder.queryData.find(
|
||||
(query) => query.dataSource !== DataSource.METRICS,
|
||||
|
||||
@@ -15,12 +15,11 @@ import {
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
|
||||
import ROUTES from 'constants/routes';
|
||||
import useDebouncedFn from 'hooks/useDebouncedFunction';
|
||||
import history from 'lib/history';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { CheckIcon, Goal, UserPlus, X } from 'lucide-react';
|
||||
import { ArrowRight, X } from 'lucide-react';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import OnboardingIngestionDetails from '../IngestionDetails/IngestionDetails';
|
||||
import InviteTeamMembers from '../InviteTeamMembers/InviteTeamMembers';
|
||||
@@ -69,7 +68,6 @@ interface Entity {
|
||||
};
|
||||
};
|
||||
tags: string[];
|
||||
relatedSearchKeywords?: string[];
|
||||
link?: string;
|
||||
}
|
||||
|
||||
@@ -101,11 +99,8 @@ const ONBOARDING_V3_ANALYTICS_EVENTS_MAP = {
|
||||
GET_EXPERT_ASSISTANCE_BUTTON_CLICKED: 'Get expert assistance clicked',
|
||||
INVITE_TEAM_MEMBER_BUTTON_CLICKED: 'Invite team member clicked',
|
||||
CLOSE_ONBOARDING_CLICKED: 'Close onboarding clicked',
|
||||
DATA_SOURCE_REQUESTED: 'Datasource requested',
|
||||
DATA_SOURCE_SEARCHED: 'Searched',
|
||||
};
|
||||
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
function OnboardingAddDataSource(): JSX.Element {
|
||||
const [groupedDataSources, setGroupedDataSources] = useState<{
|
||||
[tag: string]: Entity[];
|
||||
@@ -115,8 +110,6 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
|
||||
const [setupStepItems, setSetupStepItems] = useState(setupStepItemsBase);
|
||||
|
||||
const [searchQuery, setSearchQuery] = useState<string>('');
|
||||
|
||||
const question2Ref = useRef<HTMLDivElement | null>(null);
|
||||
const question3Ref = useRef<HTMLDivElement | null>(null);
|
||||
const configureProdRef = useRef<HTMLDivElement | null>(null);
|
||||
@@ -127,15 +120,8 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
|
||||
const [currentStep, setCurrentStep] = useState(1);
|
||||
|
||||
const [dataSourceRequest, setDataSourceRequest] = useState<string>('');
|
||||
|
||||
const [hasMoreQuestions, setHasMoreQuestions] = useState<boolean>(true);
|
||||
|
||||
const [
|
||||
showRequestDataSourceModal,
|
||||
setShowRequestDataSourceModal,
|
||||
] = useState<boolean>(false);
|
||||
|
||||
const [
|
||||
showInviteTeamMembersModal,
|
||||
setShowInviteTeamMembersModal,
|
||||
@@ -159,11 +145,6 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>('All');
|
||||
|
||||
const [
|
||||
dataSourceRequestSubmitted,
|
||||
setDataSourceRequestSubmitted,
|
||||
] = useState<boolean>(false);
|
||||
|
||||
const handleScrollToStep = (ref: React.RefObject<HTMLDivElement>): void => {
|
||||
setTimeout(() => {
|
||||
ref.current?.scrollIntoView({
|
||||
@@ -305,10 +286,8 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
setGroupedDataSources(groupedDataSources);
|
||||
}, []);
|
||||
|
||||
const debouncedUpdate = useDebouncedFn((query) => {
|
||||
setSearchQuery(query as string);
|
||||
|
||||
setDataSourceRequestSubmitted(false);
|
||||
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
const query = e.target.value.toLowerCase();
|
||||
|
||||
if (query === '') {
|
||||
setGroupedDataSources(
|
||||
@@ -319,35 +298,15 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
|
||||
const filteredDataSources = onboardingConfigWithLinks.filter(
|
||||
(dataSource) =>
|
||||
dataSource.label.toLowerCase().includes(query as string) ||
|
||||
dataSource.tags.some((tag) =>
|
||||
tag.toLowerCase().includes(query as string),
|
||||
) ||
|
||||
dataSource.relatedSearchKeywords?.some((keyword) =>
|
||||
keyword?.toLowerCase().includes(query as string),
|
||||
),
|
||||
dataSource.label.toLowerCase().includes(query) ||
|
||||
dataSource.tags.some((tag) => tag.toLowerCase().includes(query)),
|
||||
);
|
||||
|
||||
setGroupedDataSources(
|
||||
groupDataSourcesByTags(filteredDataSources as Entity[]),
|
||||
);
|
||||
};
|
||||
|
||||
logEvent(
|
||||
`${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.DATA_SOURCE_SEARCHED}`,
|
||||
{
|
||||
searchedDataSource: query,
|
||||
},
|
||||
);
|
||||
}, 300);
|
||||
|
||||
const handleSearch = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
const query = e.target.value.trim().toLowerCase();
|
||||
|
||||
debouncedUpdate(query || '');
|
||||
},
|
||||
[debouncedUpdate],
|
||||
);
|
||||
const handleFilterByCategory = (category: string): void => {
|
||||
setSelectedDataSource(null);
|
||||
setSelectedFramework(null);
|
||||
@@ -450,129 +409,6 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
setShowInviteTeamMembersModal(true);
|
||||
};
|
||||
|
||||
const handleSubmitDataSourceRequest = (): void => {
|
||||
logEvent(
|
||||
`${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.DATA_SOURCE_REQUESTED}`,
|
||||
{
|
||||
requestedDataSource: dataSourceRequest,
|
||||
},
|
||||
);
|
||||
setShowRequestDataSourceModal(false);
|
||||
setDataSourceRequestSubmitted(true);
|
||||
};
|
||||
|
||||
const handleRequestDataSource = (): void => {
|
||||
setShowRequestDataSourceModal(true);
|
||||
};
|
||||
|
||||
const handleRaiseRequest = (): void => {
|
||||
logEvent(
|
||||
`${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.DATA_SOURCE_REQUESTED}`,
|
||||
{
|
||||
requestedDataSource: searchQuery,
|
||||
},
|
||||
);
|
||||
|
||||
setDataSourceRequestSubmitted(true);
|
||||
};
|
||||
|
||||
const renderRequestDataSource = (): JSX.Element => {
|
||||
const isSearchQueryEmpty = searchQuery.length === 0;
|
||||
const isNoResultsFound = Object.keys(groupedDataSources).length === 0;
|
||||
|
||||
return (
|
||||
<div className="request-data-source-container">
|
||||
{!isNoResultsFound && (
|
||||
<>
|
||||
<Typography.Text>Can’t find what you’re looking for?</Typography.Text>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="279"
|
||||
height="2"
|
||||
viewBox="0 0 279 2"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M0 1L279 1"
|
||||
stroke="#7190F9"
|
||||
strokeOpacity="0.2"
|
||||
strokeDasharray="4 4"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{!dataSourceRequestSubmitted && (
|
||||
<Button
|
||||
type="default"
|
||||
className="periscope-btn request-data-source-btn secondary"
|
||||
icon={<Goal size={16} />}
|
||||
onClick={handleRequestDataSource}
|
||||
>
|
||||
Request Data Source
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{dataSourceRequestSubmitted && (
|
||||
<Button
|
||||
type="default"
|
||||
className="periscope-btn request-data-source-btn success"
|
||||
icon={<CheckIcon size={16} />}
|
||||
>
|
||||
Request raised
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{isNoResultsFound && !isSearchQueryEmpty && (
|
||||
<>
|
||||
<Typography.Text>
|
||||
Our team can help add{' '}
|
||||
<span className="request-data-source-search-query">{searchQuery}</span>{' '}
|
||||
support for you
|
||||
</Typography.Text>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="279"
|
||||
height="2"
|
||||
viewBox="0 0 279 2"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M0 1L279 1"
|
||||
stroke="#7190F9"
|
||||
strokeOpacity="0.2"
|
||||
strokeDasharray="4 4"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{!dataSourceRequestSubmitted && (
|
||||
<Button
|
||||
type="default"
|
||||
className="periscope-btn request-data-source-btn secondary"
|
||||
icon={<Goal size={16} />}
|
||||
onClick={handleRaiseRequest}
|
||||
>
|
||||
Raise request
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{dataSourceRequestSubmitted && (
|
||||
<Button
|
||||
type="default"
|
||||
className="periscope-btn request-data-source-btn success"
|
||||
icon={<CheckIcon size={16} />}
|
||||
>
|
||||
Request raised
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="onboarding-v2">
|
||||
<Layout>
|
||||
@@ -597,15 +433,6 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
</div>
|
||||
|
||||
<div className="header-right-section">
|
||||
<Button
|
||||
type="default"
|
||||
className="periscope-btn invite-teammate-btn outlined"
|
||||
onClick={handleShowInviteTeamMembersModal}
|
||||
icon={<UserPlus size={16} />}
|
||||
>
|
||||
Invite a teammate
|
||||
</Button>
|
||||
|
||||
<LaunchChatSupport
|
||||
attributes={{
|
||||
dataSource: selectedDataSource?.dataSource,
|
||||
@@ -615,7 +442,7 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
}}
|
||||
eventName={`${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.GET_HELP_BUTTON_CLICKED}`}
|
||||
message=""
|
||||
buttonText="Contact Support"
|
||||
buttonText="Get Help"
|
||||
className="periscope-btn get-help-btn outlined"
|
||||
/>
|
||||
</div>
|
||||
@@ -634,11 +461,7 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
</Header>
|
||||
|
||||
<div className="onboarding-product-setup-container">
|
||||
<div
|
||||
className={`onboarding-product-setup-container_left-section ${
|
||||
currentStep === 1 ? 'step-id-1' : 'step-id-2'
|
||||
}`}
|
||||
>
|
||||
<div className="onboarding-product-setup-container_left-section">
|
||||
<div className="perlian-bg" />
|
||||
|
||||
{currentStep === 1 && (
|
||||
@@ -668,7 +491,6 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
<div className="onboarding-data-source-search">
|
||||
<Input
|
||||
placeholder="Search"
|
||||
maxLength={20}
|
||||
onChange={handleSearch}
|
||||
addonAfter={<SearchOutlined />}
|
||||
/>
|
||||
@@ -703,14 +525,6 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{Object.keys(groupedDataSources).length === 0 && (
|
||||
<div className="no-results-found-container">
|
||||
<Typography.Text>No results for {searchQuery} :/</Typography.Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!selectedDataSource && renderRequestDataSource()}
|
||||
</div>
|
||||
|
||||
<div className="data-source-categories-filter-container">
|
||||
@@ -720,66 +534,33 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
Filters{' '}
|
||||
</Typography.Title>
|
||||
|
||||
<div
|
||||
key="all"
|
||||
className="onboarding-data-source-category-item"
|
||||
<Typography.Title
|
||||
level={5}
|
||||
className={`onboarding-filters-item-title ${
|
||||
selectedCategory === 'All' ? 'selected' : ''
|
||||
}`}
|
||||
onClick={(): void => handleFilterByCategory('All')}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyDown={(e): void => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
handleFilterByCategory('All');
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Typography.Title
|
||||
level={5}
|
||||
className={`onboarding-filters-item-title ${
|
||||
selectedCategory === 'All' ? 'selected' : ''
|
||||
}`}
|
||||
>
|
||||
All
|
||||
</Typography.Title>
|
||||
|
||||
<div className="line-divider" />
|
||||
|
||||
<Typography.Text className="onboarding-filters-item-count">
|
||||
{onboardingConfigWithLinks.length}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
All ({onboardingConfigWithLinks.length})
|
||||
</Typography.Title>
|
||||
|
||||
{Object.keys(groupedDataSources).map((tag) => (
|
||||
<div
|
||||
key={tag}
|
||||
className="onboarding-data-source-category-item"
|
||||
onClick={(): void => handleFilterByCategory(tag)}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyDown={(e): void => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
handleFilterByCategory(tag);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div key={tag} className="onboarding-data-source-category-item">
|
||||
<Typography.Title
|
||||
level={5}
|
||||
className={`onboarding-filters-item-title ${
|
||||
selectedCategory === tag ? 'selected' : ''
|
||||
}`}
|
||||
onClick={(): void => handleFilterByCategory(tag)}
|
||||
>
|
||||
{tag}
|
||||
{tag} ({groupedDataSources[tag].length})
|
||||
</Typography.Title>
|
||||
|
||||
<div className="line-divider" />
|
||||
|
||||
<Typography.Text className="onboarding-filters-item-count">
|
||||
{groupedDataSources[tag].length}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectedDataSource &&
|
||||
selectedDataSource?.question &&
|
||||
!isEmpty(selectedDataSource?.question) && (
|
||||
@@ -834,6 +615,7 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{selectedFramework &&
|
||||
selectedFramework?.question &&
|
||||
!isEmpty(selectedFramework?.question) && (
|
||||
@@ -877,6 +659,7 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!hasMoreQuestions && showConfigureProduct && (
|
||||
<div className="questionaire-footer" ref={configureProdRef}>
|
||||
<Button
|
||||
@@ -984,6 +767,39 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
</div>
|
||||
|
||||
<div className="onboarding-product-setup-container_right-section">
|
||||
{currentStep === 1 && (
|
||||
<div className="invite-user-section-content">
|
||||
<Button
|
||||
type="default"
|
||||
shape="round"
|
||||
className="invite-user-section-content-button"
|
||||
onClick={handleShowInviteTeamMembersModal}
|
||||
>
|
||||
Invite a team member to help with this step
|
||||
<ArrowRight size={14} />
|
||||
</Button>
|
||||
<div className="need-help-section-content-divider">Or</div>
|
||||
<div className="need-help-section-content">
|
||||
<Typography.Text>
|
||||
Need help with setup? Upgrade now and get expert assistance.
|
||||
</Typography.Text>
|
||||
|
||||
<LaunchChatSupport
|
||||
attributes={{
|
||||
dataSource: selectedDataSource?.dataSource,
|
||||
framework: selectedFramework?.label,
|
||||
environment: selectedEnvironment?.label,
|
||||
currentPage: setupStepItems[currentStep]?.title || '',
|
||||
}}
|
||||
eventName={`${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.GET_EXPERT_ASSISTANCE_BUTTON_CLICKED}`}
|
||||
message=""
|
||||
buttonText="Get Expert Assistance"
|
||||
className="periscope-btn get-help-btn rounded-btn outlined"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{currentStep === 2 && <OnboardingIngestionDetails />}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1008,46 +824,6 @@ function OnboardingAddDataSource(): JSX.Element {
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
className="request-data-source-modal"
|
||||
title={<span className="title">Request Data Source</span>}
|
||||
open={showRequestDataSourceModal}
|
||||
closable
|
||||
onCancel={(): void => setShowRequestDataSourceModal(false)}
|
||||
width="640px"
|
||||
footer={[
|
||||
<Button
|
||||
type="default"
|
||||
className="periscope-btn outlined"
|
||||
key="back"
|
||||
onClick={(): void => setShowRequestDataSourceModal(false)}
|
||||
icon={<X size={16} />}
|
||||
>
|
||||
Cancel
|
||||
</Button>,
|
||||
<Button
|
||||
key="submit"
|
||||
type="primary"
|
||||
className="periscope-btn primary"
|
||||
disabled={dataSourceRequest.length <= 0}
|
||||
onClick={handleSubmitDataSourceRequest}
|
||||
icon={<CheckIcon size={16} />}
|
||||
>
|
||||
Submit request
|
||||
</Button>,
|
||||
]}
|
||||
destroyOnClose
|
||||
>
|
||||
<div className="request-data-source-modal-content">
|
||||
<Typography.Text>Enter your request</Typography.Text>
|
||||
<Input
|
||||
placeholder="Eg: Kotlin"
|
||||
className="request-data-source-modal-input"
|
||||
onChange={(e): void => setDataSourceRequest(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
</Layout>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -63,7 +63,7 @@ export default function OnboardingIngestionDetails(): JSX.Element {
|
||||
isLoading: isLoadingDeploymentsData,
|
||||
isFetching: isFetchingDeploymentsData,
|
||||
isError: isDeploymentsDataError,
|
||||
} = useGetDeploymentsData(true);
|
||||
} = useGetDeploymentsData();
|
||||
|
||||
const handleCopyKey = (text: string): void => {
|
||||
handleCopyToClipboard(text);
|
||||
|
||||
@@ -4,15 +4,14 @@
|
||||
|
||||
&__header {
|
||||
background: rgba(11, 12, 14, 0.7);
|
||||
border-bottom: 1px solid var(--bg-slate-500);
|
||||
backdrop-filter: blur(20px);
|
||||
padding: 12px 0px;
|
||||
padding: 16px 0px 0px 0px;
|
||||
|
||||
&--sticky {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0px 1rem;
|
||||
margin-top: 12px;
|
||||
// margin-top: 16px;
|
||||
|
||||
background: rgba(11, 12, 14, 0.7);
|
||||
backdrop-filter: blur(20px);
|
||||
@@ -324,8 +323,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.get-help-btn,
|
||||
.invite-teammate-btn {
|
||||
.get-help-btn {
|
||||
font-size: 11px;
|
||||
padding: 6px 16px;
|
||||
border: 1px solid var(--bg-slate-400) !important;
|
||||
@@ -612,61 +610,15 @@
|
||||
display: flex;
|
||||
|
||||
.data-sources-container {
|
||||
flex: 0 0 80%;
|
||||
max-width: 80%;
|
||||
flex: 0 0 70%;
|
||||
max-width: 70%;
|
||||
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
.data-source-categories-filter-container {
|
||||
flex: 0 0 20%;
|
||||
max-width: 20%;
|
||||
|
||||
.onboarding-data-source-category {
|
||||
.onboarding-data-source-category-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
margin-bottom: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.onboarding-filters-item-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
|
||||
.line-divider {
|
||||
height: 1px;
|
||||
margin: 0 16px;
|
||||
flex-grow: 1;
|
||||
border-top: 2px dotted var(--bg-slate-400);
|
||||
}
|
||||
|
||||
.onboarding-filters-item-count {
|
||||
color: var(--text-vanilla-400);
|
||||
font-family: Inter;
|
||||
font-size: 10px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 18px; /* 150% */
|
||||
|
||||
background-color: var(--bg-ink-400);
|
||||
border-radius: 4px;
|
||||
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
flex: 0 0 30%;
|
||||
max-width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,14 +643,8 @@
|
||||
max-width: 70%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
|
||||
&.step-id-1 {
|
||||
flex: 0 0 90%;
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
// border-right: 1px solid var(--Greyscale-Slate-400, #1d212d);
|
||||
|
||||
.perlian-bg {
|
||||
@@ -732,7 +678,7 @@
|
||||
&_right-section {
|
||||
flex: 1;
|
||||
max-width: 30%;
|
||||
height: calc(100vh - 130px);
|
||||
height: calc(100vh - 120px);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -1026,52 +972,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.no-results-found-container {
|
||||
.ant-typography {
|
||||
color: rgba(192, 193, 195, 0.6);
|
||||
font-family: Inter;
|
||||
font-size: 11px;
|
||||
font-style: normal;
|
||||
line-height: 18px; /* 150% */
|
||||
letter-spacing: 0.48px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.request-data-source-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
|
||||
margin: 36px 0;
|
||||
|
||||
display: flex;
|
||||
|
||||
width: fit-content;
|
||||
gap: 24px;
|
||||
|
||||
padding: 12px 12px 12px 16px;
|
||||
border-radius: 6px;
|
||||
background: rgba(171, 189, 255, 0.06);
|
||||
|
||||
.request-data-source-search-query {
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgba(173, 127, 88, 0.1);
|
||||
background: rgba(173, 127, 88, 0.1);
|
||||
|
||||
color: var(--Sienna-400, #bd9979);
|
||||
font-size: 13px;
|
||||
padding: 2px;
|
||||
line-height: 20px; /* 142.857% */
|
||||
}
|
||||
|
||||
.request-data-source-btn {
|
||||
border-radius: 2px;
|
||||
border: 1px solid var(--Slate-200, #2c3140);
|
||||
background: var(--Ink-200, #23262e);
|
||||
}
|
||||
}
|
||||
|
||||
.onboarding-data-source-category-container {
|
||||
flex: 1;
|
||||
max-width: 30%;
|
||||
@@ -1096,7 +996,7 @@
|
||||
}
|
||||
|
||||
.onboarding-configure-container {
|
||||
height: calc(100vh - 130px);
|
||||
height: calc(100vh - 120px);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -1170,8 +1070,7 @@
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.invite-team-member-modal,
|
||||
.request-data-source-modal {
|
||||
.invite-team-member-modal {
|
||||
.ant-modal-content {
|
||||
background-color: var(--bg-ink-500);
|
||||
}
|
||||
@@ -1180,26 +1079,9 @@
|
||||
background-color: var(--bg-ink-500);
|
||||
}
|
||||
|
||||
.invite-team-member-modal-content,
|
||||
.request-data-source-modal-content {
|
||||
.invite-team-member-modal-content {
|
||||
background-color: var(--bg-ink-500);
|
||||
}
|
||||
|
||||
.request-data-source-modal-content {
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.request-data-source-modal-input {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.request-data-source-modal {
|
||||
.ant-modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.ingestion-setup-details-links {
|
||||
@@ -1380,8 +1262,7 @@
|
||||
}
|
||||
|
||||
.onboarding-v2 {
|
||||
.get-help-btn,
|
||||
.invite-teammate-btn {
|
||||
.get-help-btn {
|
||||
border: 1px solid var(--bg-vanilla-300) !important;
|
||||
color: var(--bg-ink-300) !important;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,11 @@ function OrganizationSettings(): JSX.Element {
|
||||
const isNotSSO =
|
||||
!featureFlags?.find((flag) => flag.name === FeatureKeys.SSO)?.active || false;
|
||||
|
||||
const isAuthDomain = !isNotSSO;
|
||||
const isNoUpSell =
|
||||
!featureFlags?.find((flag) => flag.name === FeatureKeys.DISABLE_UPSELL)
|
||||
?.active || false;
|
||||
|
||||
const isAuthDomain = !isNoUpSell || (isNoUpSell && !isNotSSO);
|
||||
|
||||
if (!org) {
|
||||
return <div />;
|
||||
|
||||
@@ -453,7 +453,7 @@ export const Query = memo(function Query({
|
||||
</Col>
|
||||
)}
|
||||
<Col flex="1" className="qb-search-container">
|
||||
{query.dataSource === DataSource.LOGS ? (
|
||||
{[DataSource.LOGS, DataSource.TRACES].includes(query.dataSource) ? (
|
||||
<QueryBuilderSearchV2
|
||||
query={query}
|
||||
onChange={handleChangeTagFilters}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import './QueryBuilderSearchV2.styles.scss';
|
||||
|
||||
import { Typography } from 'antd';
|
||||
import cx from 'classnames';
|
||||
import {
|
||||
ArrowDown,
|
||||
ArrowUp,
|
||||
@@ -25,6 +26,7 @@ interface ICustomDropdownProps {
|
||||
exampleQueries: TagFilter[];
|
||||
onChange: (value: TagFilter) => void;
|
||||
currentFilterItem?: ITag;
|
||||
isLogsDataSource: boolean;
|
||||
}
|
||||
|
||||
export default function QueryBuilderSearchDropdown(
|
||||
@@ -38,11 +40,14 @@ export default function QueryBuilderSearchDropdown(
|
||||
exampleQueries,
|
||||
options,
|
||||
onChange,
|
||||
isLogsDataSource,
|
||||
} = props;
|
||||
const userOs = getUserOperatingSystem();
|
||||
return (
|
||||
<>
|
||||
<div className="content">
|
||||
<div
|
||||
className={cx('content', { 'non-logs-data-source': !isLogsDataSource })}
|
||||
>
|
||||
{!currentFilterItem?.key ? (
|
||||
<div className="suggested-filters">Suggested Filters</div>
|
||||
) : !currentFilterItem?.op ? (
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
.rc-virtual-list-holder {
|
||||
height: 115px;
|
||||
}
|
||||
&.non-logs-data-source {
|
||||
.rc-virtual-list-holder {
|
||||
height: 256px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -689,12 +689,29 @@ function QueryBuilderSearchV2(
|
||||
})),
|
||||
);
|
||||
} else {
|
||||
setDropdownOptions(
|
||||
data?.payload?.attributeKeys?.map((key) => ({
|
||||
setDropdownOptions([
|
||||
// Add user typed option if it doesn't exist in the payload
|
||||
...(!isEmpty(tagKey) &&
|
||||
!data?.payload?.attributeKeys?.some((val) => isEqual(val.key, tagKey))
|
||||
? [
|
||||
{
|
||||
label: tagKey,
|
||||
value: {
|
||||
key: tagKey,
|
||||
dataType: DataTypes.EMPTY,
|
||||
type: '',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// Map existing attribute keys from payload
|
||||
...(data?.payload?.attributeKeys?.map((key) => ({
|
||||
label: key.key,
|
||||
value: key,
|
||||
})) || [],
|
||||
);
|
||||
})) || []),
|
||||
]);
|
||||
}
|
||||
}
|
||||
if (currentState === DropdownState.OPERATOR) {
|
||||
@@ -964,6 +981,7 @@ function QueryBuilderSearchV2(
|
||||
exampleQueries={suggestionsData?.payload?.example_queries || []}
|
||||
tags={tags}
|
||||
currentFilterItem={currentFilterItem}
|
||||
isLogsDataSource={isLogsDataSource}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -69,12 +69,6 @@
|
||||
opacity: 1;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
&.community-enterprise-user {
|
||||
color: var(--bg-sakura-500);
|
||||
background: rgba(255, 113, 113, 0.1);
|
||||
border: 1px solid var(--bg-sakura-500);
|
||||
}
|
||||
}
|
||||
|
||||
.dockBtn {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import './SideNav.styles.scss';
|
||||
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
import { Button } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import cx from 'classnames';
|
||||
import { FeatureKeys } from 'constants/features';
|
||||
@@ -75,7 +75,7 @@ function SideNav(): JSX.Element {
|
||||
|
||||
const [userManagementMenuItems, setUserManagementMenuItems] = useState<
|
||||
UserManagementMenuItems[]
|
||||
>([]);
|
||||
>([manageLicenseMenuItem]);
|
||||
|
||||
const onClickSlackHandler = (): void => {
|
||||
window.open('https://signoz.io/slack', '_blank');
|
||||
@@ -88,10 +88,8 @@ function SideNav(): JSX.Element {
|
||||
const { registerShortcut, deregisterShortcut } = useKeyboardHotkeys();
|
||||
|
||||
const {
|
||||
isCloudUser,
|
||||
isEnterpriseSelfHostedUser,
|
||||
isCommunityUser,
|
||||
isCommunityEnterpriseUser,
|
||||
isCloudUser: isCloudUserVal,
|
||||
isEECloudUser: isEECloudUserVal,
|
||||
} = useGetTenantLicense();
|
||||
|
||||
const { t } = useTranslation('');
|
||||
@@ -105,6 +103,11 @@ function SideNav(): JSX.Element {
|
||||
licenseStatus?.toLocaleLowerCase() ===
|
||||
LICENSE_PLAN_STATUS.VALID.toLocaleLowerCase();
|
||||
|
||||
const isEnterprise = licenses?.licenses?.some(
|
||||
(license: License) =>
|
||||
license.isCurrent && license.planKey === LICENSE_PLAN_KEY.ENTERPRISE_PLAN,
|
||||
);
|
||||
|
||||
const onClickSignozCloud = (): void => {
|
||||
window.open(
|
||||
'https://signoz.io/oss-to-cloud/?utm_source=product_navbar&utm_medium=frontend&utm_campaign=oss_users',
|
||||
@@ -198,21 +201,14 @@ function SideNav(): JSX.Element {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isCloudUser) {
|
||||
if (isCloudUserVal) {
|
||||
setLicenseTag('Cloud');
|
||||
} else if (isEnterpriseSelfHostedUser) {
|
||||
} else if (isEnterprise) {
|
||||
setLicenseTag('Enterprise');
|
||||
} else if (isCommunityEnterpriseUser) {
|
||||
setLicenseTag('Enterprise');
|
||||
} else if (isCommunityUser) {
|
||||
setLicenseTag('Community');
|
||||
} else {
|
||||
setLicenseTag('Free');
|
||||
}
|
||||
}, [
|
||||
isCloudUser,
|
||||
isEnterpriseSelfHostedUser,
|
||||
isCommunityEnterpriseUser,
|
||||
isCommunityUser,
|
||||
]);
|
||||
}, [isCloudUserVal, isEnterprise]);
|
||||
|
||||
const [isCurrentOrgSettings] = useComponentPermission(
|
||||
['current_org_settings'],
|
||||
@@ -294,7 +290,7 @@ function SideNav(): JSX.Element {
|
||||
);
|
||||
}
|
||||
|
||||
if (isCloudUser || isEnterpriseSelfHostedUser) {
|
||||
if (isCloudUserVal || isEECloudUserVal) {
|
||||
const isOnboardingEnabled =
|
||||
featureFlags?.find((feature) => feature.name === FeatureKeys.ONBOARDING)
|
||||
?.active || false;
|
||||
@@ -321,11 +317,6 @@ function SideNav(): JSX.Element {
|
||||
}
|
||||
|
||||
updatedUserManagementItems = [helpSupportMenuItem];
|
||||
|
||||
// Show manage license menu item for EE cloud users with a active license
|
||||
if (isEnterpriseSelfHostedUser) {
|
||||
updatedUserManagementItems.push(manageLicenseMenuItem);
|
||||
}
|
||||
} else {
|
||||
updatedMenuItems = updatedMenuItems.filter(
|
||||
(item) => item.key !== ROUTES.INTEGRATIONS && item.key !== ROUTES.BILLING,
|
||||
@@ -341,21 +332,20 @@ function SideNav(): JSX.Element {
|
||||
onClick: onClickVersionHandler,
|
||||
};
|
||||
|
||||
updatedUserManagementItems = [versionMenuItem, slackSupportMenuItem];
|
||||
|
||||
if (isCommunityEnterpriseUser) {
|
||||
updatedUserManagementItems.push(manageLicenseMenuItem);
|
||||
}
|
||||
updatedUserManagementItems = [
|
||||
versionMenuItem,
|
||||
slackSupportMenuItem,
|
||||
manageLicenseMenuItem,
|
||||
];
|
||||
}
|
||||
setMenuItems(updatedMenuItems);
|
||||
setUserManagementMenuItems(updatedUserManagementItems);
|
||||
}, [
|
||||
isCommunityEnterpriseUser,
|
||||
currentVersion,
|
||||
featureFlags,
|
||||
isCloudUser,
|
||||
isEnterpriseSelfHostedUser,
|
||||
isCloudUserVal,
|
||||
isCurrentVersionError,
|
||||
isEECloudUserVal,
|
||||
isLatestVersion,
|
||||
licenses?.licenses,
|
||||
onClickVersionHandler,
|
||||
@@ -382,31 +372,12 @@ function SideNav(): JSX.Element {
|
||||
</div>
|
||||
|
||||
{licenseTag && (
|
||||
<Tooltip
|
||||
title={
|
||||
// eslint-disable-next-line no-nested-ternary
|
||||
isCommunityUser
|
||||
? 'You are running the community version of SigNoz. You have to install the Enterprise edition in order enable Enterprise features.'
|
||||
: isCommunityEnterpriseUser
|
||||
? 'You do not have an active license present. Add an active license to enable Enterprise features.'
|
||||
: ''
|
||||
}
|
||||
placement="bottomRight"
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
'license tag nav-item-label',
|
||||
isCommunityEnterpriseUser && 'community-enterprise-user',
|
||||
)}
|
||||
>
|
||||
{licenseTag}
|
||||
</div>
|
||||
</Tooltip>
|
||||
<div className="license tag nav-item-label">{licenseTag}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isCloudUser && user?.role !== USER_ROLES.VIEWER && (
|
||||
{isCloudUserVal && user?.role !== USER_ROLES.VIEWER && (
|
||||
<div className="get-started-nav-items">
|
||||
<Button
|
||||
className="get-started-btn"
|
||||
@@ -425,7 +396,7 @@ function SideNav(): JSX.Element {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={cx(`nav-wrapper`, isCloudUser && 'nav-wrapper-cloud')}>
|
||||
<div className={cx(`nav-wrapper`, isCloudUserVal && 'nav-wrapper-cloud')}>
|
||||
<div className="primary-nav-items">
|
||||
{menuItems.map((item, index) => (
|
||||
<NavItem
|
||||
|
||||
@@ -112,6 +112,7 @@ const menuItems: SidebarItem[] = [
|
||||
key: ROUTES.INFRASTRUCTURE_MONITORING_HOSTS,
|
||||
label: 'Infra Monitoring',
|
||||
icon: <Boxes size={16} />,
|
||||
isNew: true,
|
||||
},
|
||||
{
|
||||
key: ROUTES.ALL_DASHBOARD,
|
||||
|
||||
@@ -3,11 +3,11 @@ import { AxiosError, AxiosResponse } from 'axios';
|
||||
import { useQuery, UseQueryResult } from 'react-query';
|
||||
import { DeploymentsDataProps } from 'types/api/customDomain/types';
|
||||
|
||||
export const useGetDeploymentsData = (
|
||||
isEnabled: boolean,
|
||||
): UseQueryResult<AxiosResponse<DeploymentsDataProps>, AxiosError> =>
|
||||
export const useGetDeploymentsData = (): UseQueryResult<
|
||||
AxiosResponse<DeploymentsDataProps>,
|
||||
AxiosError
|
||||
> =>
|
||||
useQuery<AxiosResponse<DeploymentsDataProps>, AxiosError>({
|
||||
queryKey: ['getDeploymentsData'],
|
||||
queryFn: () => getDeploymentsData(),
|
||||
enabled: isEnabled,
|
||||
});
|
||||
|
||||
@@ -170,11 +170,7 @@ export const useOptions = (
|
||||
(option, index, self) =>
|
||||
index ===
|
||||
self.findIndex(
|
||||
(o) =>
|
||||
// to remove duplicate & empty options from list
|
||||
o.label === option.label &&
|
||||
o.value === option.value &&
|
||||
o.dataType?.toLowerCase() === option.dataType?.toLowerCase(), // handle case sensitivity
|
||||
(o) => o.label === option.label && o.value === option.value, // to remove duplicate & empty options from list
|
||||
) && option.value !== '',
|
||||
) || []
|
||||
).map((option) => {
|
||||
|
||||
@@ -1,36 +1,15 @@
|
||||
import { AxiosError } from 'axios';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
import { LicensePlatform } from 'types/api/licensesV3/getActive';
|
||||
|
||||
export const useGetTenantLicense = (): {
|
||||
isCloudUser: boolean;
|
||||
isEnterpriseSelfHostedUser: boolean;
|
||||
isCommunityUser: boolean;
|
||||
isCommunityEnterpriseUser: boolean;
|
||||
isEECloudUser: boolean;
|
||||
} => {
|
||||
const { activeLicenseV3, activeLicenseV3FetchError } = useAppContext();
|
||||
const { activeLicenseV3 } = useAppContext();
|
||||
|
||||
const responsePayload = {
|
||||
return {
|
||||
isCloudUser: activeLicenseV3?.platform === LicensePlatform.CLOUD || false,
|
||||
isEnterpriseSelfHostedUser:
|
||||
isEECloudUser:
|
||||
activeLicenseV3?.platform === LicensePlatform.SELF_HOSTED || false,
|
||||
isCommunityUser: false,
|
||||
isCommunityEnterpriseUser: false,
|
||||
};
|
||||
|
||||
if (
|
||||
activeLicenseV3FetchError &&
|
||||
(activeLicenseV3FetchError as AxiosError)?.response?.status === 404
|
||||
) {
|
||||
responsePayload.isCommunityEnterpriseUser = true;
|
||||
}
|
||||
|
||||
if (
|
||||
activeLicenseV3FetchError &&
|
||||
(activeLicenseV3FetchError as AxiosError)?.response?.status === 501
|
||||
) {
|
||||
responsePayload.isCommunityUser = true;
|
||||
}
|
||||
|
||||
return responsePayload;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import './ReactI18';
|
||||
import 'styles.scss';
|
||||
|
||||
import * as Sentry from '@sentry/react';
|
||||
import AppRoutes from 'AppRoutes';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ThemeProvider } from 'hooks/useDarkMode';
|
||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||
import posthog from 'posthog-js';
|
||||
import { AppProvider } from 'providers/App/App';
|
||||
import TimezoneProvider from 'providers/Timezone';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
@@ -34,25 +37,54 @@ const queryClient = new QueryClient({
|
||||
|
||||
const container = document.getElementById('root');
|
||||
|
||||
if (process.env.POSTHOG_KEY) {
|
||||
posthog.init(process.env.POSTHOG_KEY, {
|
||||
api_host: 'https://us.i.posthog.com',
|
||||
person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well
|
||||
});
|
||||
}
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN,
|
||||
tunnel: process.env.TUNNEL_URL,
|
||||
environment: 'production',
|
||||
integrations: [
|
||||
Sentry.browserTracingIntegration(),
|
||||
Sentry.replayIntegration({
|
||||
maskAllText: false,
|
||||
blockAllMedia: false,
|
||||
}),
|
||||
],
|
||||
// Performance Monitoring
|
||||
tracesSampleRate: 1.0, // Capture 100% of the transactions
|
||||
// Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
|
||||
tracePropagationTargets: [],
|
||||
// Session Replay
|
||||
replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
|
||||
replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
|
||||
});
|
||||
|
||||
if (container) {
|
||||
const root = createRoot(container);
|
||||
|
||||
root.render(
|
||||
<HelmetProvider>
|
||||
<ThemeProvider>
|
||||
<TimezoneProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Provider store={store}>
|
||||
<AppProvider>
|
||||
<AppRoutes />
|
||||
</AppProvider>
|
||||
</Provider>
|
||||
{process.env.NODE_ENV === 'development' && (
|
||||
<ReactQueryDevtools initialIsOpen={false} />
|
||||
)}
|
||||
</QueryClientProvider>
|
||||
</TimezoneProvider>
|
||||
</ThemeProvider>
|
||||
</HelmetProvider>,
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||
<HelmetProvider>
|
||||
<ThemeProvider>
|
||||
<TimezoneProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Provider store={store}>
|
||||
<AppProvider>
|
||||
<AppRoutes />
|
||||
</AppProvider>
|
||||
</Provider>
|
||||
{process.env.NODE_ENV === 'development' && (
|
||||
<ReactQueryDevtools initialIsOpen={false} />
|
||||
)}
|
||||
</QueryClientProvider>
|
||||
</TimezoneProvider>
|
||||
</ThemeProvider>
|
||||
</HelmetProvider>
|
||||
</Sentry.ErrorBoundary>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,10 @@ import { getRoutes } from './utils';
|
||||
function SettingsPage(): JSX.Element {
|
||||
const { pathname } = useLocation();
|
||||
const { user, featureFlags, trialInfo } = useAppContext();
|
||||
const { isCloudUser, isEnterpriseSelfHostedUser } = useGetTenantLicense();
|
||||
const {
|
||||
isCloudUser: isCloudAccount,
|
||||
isEECloudUser: isEECloudAccount,
|
||||
} = useGetTenantLicense();
|
||||
|
||||
const isWorkspaceBlocked = trialInfo?.workSpaceBlock || false;
|
||||
|
||||
@@ -34,8 +37,8 @@ function SettingsPage(): JSX.Element {
|
||||
isCurrentOrgSettings,
|
||||
isGatewayEnabled,
|
||||
isWorkspaceBlocked,
|
||||
isCloudUser,
|
||||
isEnterpriseSelfHostedUser,
|
||||
isCloudAccount,
|
||||
isEECloudAccount,
|
||||
t,
|
||||
),
|
||||
[
|
||||
@@ -43,8 +46,8 @@ function SettingsPage(): JSX.Element {
|
||||
isCurrentOrgSettings,
|
||||
isGatewayEnabled,
|
||||
isWorkspaceBlocked,
|
||||
isCloudUser,
|
||||
isEnterpriseSelfHostedUser,
|
||||
isCloudAccount,
|
||||
isEECloudAccount,
|
||||
t,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -17,8 +17,8 @@ export const getRoutes = (
|
||||
isCurrentOrgSettings: boolean,
|
||||
isGatewayEnabled: boolean,
|
||||
isWorkspaceBlocked: boolean,
|
||||
isCloudUser: boolean,
|
||||
isEnterpriseSelfHostedUser: boolean,
|
||||
isCloudAccount: boolean,
|
||||
isEECloudAccount: boolean,
|
||||
t: TFunction,
|
||||
): RouteTabProps['routes'] => {
|
||||
const settings = [];
|
||||
@@ -42,17 +42,17 @@ export const getRoutes = (
|
||||
settings.push(...multiIngestionSettings(t));
|
||||
}
|
||||
|
||||
if (isCloudUser && !isGatewayEnabled) {
|
||||
if (isCloudAccount && !isGatewayEnabled) {
|
||||
settings.push(...ingestionSettings(t));
|
||||
}
|
||||
|
||||
settings.push(...alertChannels(t));
|
||||
|
||||
if ((isCloudUser || isEnterpriseSelfHostedUser) && isAdmin) {
|
||||
if ((isCloudAccount || isEECloudAccount) && isAdmin) {
|
||||
settings.push(...apiKeys(t));
|
||||
}
|
||||
|
||||
if (isCloudUser && isAdmin) {
|
||||
if (isCloudAccount && isAdmin) {
|
||||
settings.push(...customDomainSettings(t));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.traces-funnels-header {
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
.traces-funnels-header-title {
|
||||
&__title {
|
||||
color: var(--bg-vanilla-100);
|
||||
font-size: 18px;
|
||||
font-style: normal;
|
||||
@@ -13,7 +13,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.traces-funnels-header-subtitle {
|
||||
&__subtitle {
|
||||
color: var(--bg-vanilla-400);
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
@@ -21,13 +21,13 @@
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.traces-funnels-header {
|
||||
.traces-funnels-header-title {
|
||||
.header {
|
||||
&__title {
|
||||
color: var(--bg-ink-500);
|
||||
}
|
||||
|
||||
.traces-funnels-header-subtitle {
|
||||
&__subtitle {
|
||||
color: var(--bg-ink-400);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
function Header(): JSX.Element {
|
||||
return (
|
||||
<div className="traces-funnels-header">
|
||||
<div className="traces-funnels-header-title">Funnels</div>
|
||||
<div className="traces-funnels-header-subtitle">
|
||||
Create and manage tracing funnels.
|
||||
</div>
|
||||
<div className="header">
|
||||
<div className="header__title">Funnels</div>
|
||||
<div className="header__subtitle">Create and manage tracing funnels.</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -45,13 +45,6 @@
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
&.success {
|
||||
color: var(--bg-forest-400) !important;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgba(37, 225, 146, 0.1);
|
||||
background: rgba(37, 225, 146, 0.1) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.periscope-tab {
|
||||
|
||||
@@ -21,7 +21,6 @@ import { useQuery } from 'react-query';
|
||||
import { FeatureFlagProps as FeatureFlags } from 'types/api/features/getFeaturesFlags';
|
||||
import { PayloadProps as LicensesResModel } from 'types/api/licenses/getAll';
|
||||
import {
|
||||
LicensePlatform,
|
||||
LicenseState,
|
||||
LicenseV3ResModel,
|
||||
TrialInfo,
|
||||
@@ -146,8 +145,7 @@ export function AppProvider({ children }: PropsWithChildren): JSX.Element {
|
||||
).unix(),
|
||||
onTrial: isOnTrial,
|
||||
workSpaceBlock:
|
||||
activeLicenseV3Data.payload.state === LicenseState.EVALUATION_EXPIRED &&
|
||||
activeLicenseV3Data.payload.platform === LicensePlatform.CLOUD,
|
||||
activeLicenseV3Data.payload.state === LicenseState.EVALUATION_EXPIRED,
|
||||
trialConvertedToSubscription:
|
||||
activeLicenseV3Data.payload.state !== LicenseState.ISSUED &&
|
||||
activeLicenseV3Data.payload.state !== LicenseState.EVALUATING &&
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
import { apiV3 } from 'api/apiV1';
|
||||
import getLocalStorageApi from 'api/browser/localstorage/get';
|
||||
import loginApi from 'api/user/login';
|
||||
import { Logout } from 'api/utils';
|
||||
import afterLogin from 'AppRoutes/utils';
|
||||
import { ENVIRONMENT } from 'constants/env';
|
||||
import { LIVE_TAIL_HEARTBEAT_TIMEOUT } from 'constants/liveTail';
|
||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||
import { EventListener, EventSourcePolyfill } from 'event-source-polyfill';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
import {
|
||||
createContext,
|
||||
PropsWithChildren,
|
||||
@@ -19,13 +13,14 @@ import {
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import { useAppContext } from './App/App';
|
||||
|
||||
interface IEventSourceContext {
|
||||
eventSourceInstance: EventSourcePolyfill | null;
|
||||
isConnectionOpen: boolean;
|
||||
isConnectionLoading: boolean;
|
||||
isConnectionError: boolean;
|
||||
initialLoading: boolean;
|
||||
reconnectDueToError: boolean;
|
||||
handleStartOpenConnection: (urlProps: {
|
||||
url?: string;
|
||||
queryString: string;
|
||||
@@ -40,7 +35,6 @@ const EventSourceContext = createContext<IEventSourceContext>({
|
||||
isConnectionLoading: false,
|
||||
initialLoading: true,
|
||||
isConnectionError: false,
|
||||
reconnectDueToError: false,
|
||||
handleStartOpenConnection: () => {},
|
||||
handleCloseConnection: () => {},
|
||||
handleSetInitialLoading: () => {},
|
||||
@@ -53,13 +47,11 @@ export function EventSourceProvider({
|
||||
const [isConnectionLoading, setIsConnectionLoading] = useState<boolean>(false);
|
||||
const [isConnectionError, setIsConnectionError] = useState<boolean>(false);
|
||||
|
||||
const [reconnectDueToError, setReconnectDueToError] = useState<boolean>(false);
|
||||
|
||||
const [initialLoading, setInitialLoading] = useState<boolean>(true);
|
||||
|
||||
const eventSourceRef = useRef<EventSourcePolyfill | null>(null);
|
||||
const { user } = useAppContext();
|
||||
|
||||
const { notifications } = useNotifications();
|
||||
const eventSourceRef = useRef<EventSourcePolyfill | null>(null);
|
||||
|
||||
const handleSetInitialLoading = useCallback((value: boolean) => {
|
||||
setInitialLoading(value);
|
||||
@@ -71,49 +63,16 @@ export function EventSourceProvider({
|
||||
setInitialLoading(false);
|
||||
}, []);
|
||||
|
||||
const handleErrorConnection: EventListener = useCallback(async () => {
|
||||
const handleErrorConnection: EventListener = useCallback(() => {
|
||||
setIsConnectionOpen(false);
|
||||
setIsConnectionLoading(true);
|
||||
setIsConnectionLoading(false);
|
||||
setIsConnectionError(true);
|
||||
setInitialLoading(false);
|
||||
|
||||
try {
|
||||
const response = await loginApi({
|
||||
refreshToken: getLocalStorageApi(LOCALSTORAGE.REFRESH_AUTH_TOKEN) || '',
|
||||
});
|
||||
if (!eventSourceRef.current) return;
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
// Update tokens in local storage
|
||||
afterLogin(
|
||||
response.payload.userId,
|
||||
response.payload.accessJwt,
|
||||
response.payload.refreshJwt,
|
||||
true,
|
||||
);
|
||||
|
||||
// If token refresh was successful, we'll let the component
|
||||
// handle reconnection through the reconnectDueToError state
|
||||
setReconnectDueToError(true);
|
||||
setIsConnectionError(true);
|
||||
return;
|
||||
}
|
||||
|
||||
notifications.error({ message: 'Sorry, something went wrong' });
|
||||
// If token refresh failed, logout the user
|
||||
if (!eventSourceRef.current) return;
|
||||
eventSourceRef.current.close();
|
||||
setIsConnectionError(true);
|
||||
Logout();
|
||||
} catch (error) {
|
||||
// If there was an error during token refresh, we'll just
|
||||
// let the component handle the error state
|
||||
notifications.error({ message: 'Sorry, something went wrong' });
|
||||
console.error('Error refreshing token:', error);
|
||||
setIsConnectionError(true);
|
||||
if (!eventSourceRef.current) return;
|
||||
eventSourceRef.current.close();
|
||||
Logout();
|
||||
}
|
||||
}, [notifications]);
|
||||
eventSourceRef.current.close();
|
||||
}, []);
|
||||
|
||||
const destroyEventSourceSession = useCallback(() => {
|
||||
if (!eventSourceRef.current) return;
|
||||
@@ -141,19 +100,18 @@ export function EventSourceProvider({
|
||||
|
||||
eventSourceRef.current = new EventSourcePolyfill(eventSourceUrl, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${getLocalStorageApi(LOCALSTORAGE.AUTH_TOKEN)}`,
|
||||
Authorization: `Bearer ${user?.accessJwt}`,
|
||||
},
|
||||
heartbeatTimeout: LIVE_TAIL_HEARTBEAT_TIMEOUT,
|
||||
});
|
||||
|
||||
setIsConnectionLoading(true);
|
||||
setIsConnectionError(false);
|
||||
setReconnectDueToError(false);
|
||||
|
||||
eventSourceRef.current.addEventListener('error', handleErrorConnection);
|
||||
eventSourceRef.current.addEventListener('open', handleOpenConnection);
|
||||
},
|
||||
[handleErrorConnection, handleOpenConnection],
|
||||
[user, handleErrorConnection, handleOpenConnection],
|
||||
);
|
||||
|
||||
useEffect(
|
||||
@@ -170,7 +128,6 @@ export function EventSourceProvider({
|
||||
isConnectionLoading,
|
||||
isConnectionOpen,
|
||||
initialLoading,
|
||||
reconnectDueToError,
|
||||
handleStartOpenConnection,
|
||||
handleCloseConnection,
|
||||
handleSetInitialLoading,
|
||||
@@ -180,7 +137,6 @@ export function EventSourceProvider({
|
||||
isConnectionLoading,
|
||||
isConnectionOpen,
|
||||
initialLoading,
|
||||
reconnectDueToError,
|
||||
handleStartOpenConnection,
|
||||
handleCloseConnection,
|
||||
handleSetInitialLoading,
|
||||
|
||||
@@ -186,6 +186,83 @@ export function getAppContextMock(
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.OSS,
|
||||
active: false,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.DISABLE_UPSELL,
|
||||
active: false,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.SMART_TRACE_DETAIL,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.CUSTOM_METRICS_FUNCTION,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.QUERY_BUILDER_PANELS,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.QUERY_BUILDER_ALERTS,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.ALERT_CHANNEL_SLACK,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.ALERT_CHANNEL_WEBHOOK,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.ALERT_CHANNEL_PAGERDUTY,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.ALERT_CHANNEL_OPSGENIE,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.ALERT_CHANNEL_MSTEAMS,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.USE_SPAN_METRICS,
|
||||
active: false,
|
||||
@@ -214,6 +291,20 @@ export function getAppContextMock(
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.DurationSort,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.TimestampSort,
|
||||
active: true,
|
||||
usage: 0,
|
||||
usage_limit: -1,
|
||||
route: '',
|
||||
},
|
||||
{
|
||||
name: FeatureKeys.ONBOARDING,
|
||||
active: true,
|
||||
|
||||
72
go.mod
72
go.mod
@@ -1,8 +1,8 @@
|
||||
module github.com/SigNoz/signoz
|
||||
|
||||
go 1.22.7
|
||||
go 1.22.0
|
||||
|
||||
toolchain go1.22.11
|
||||
toolchain go1.22.7
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1
|
||||
@@ -16,13 +16,14 @@ require (
|
||||
github.com/coreos/go-oidc/v3 v3.11.0
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/go-co-op/gocron v1.30.1
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/go-openapi/runtime v0.28.0
|
||||
github.com/go-openapi/strfmt v0.23.0
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/go-redis/redismock/v8 v8.11.5
|
||||
github.com/go-viper/mapstructure/v2 v2.1.0
|
||||
github.com/gojek/heimdall/v7 v7.0.3
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
github.com/gorilla/mux v1.8.1
|
||||
@@ -35,6 +36,7 @@ require (
|
||||
github.com/knadh/koanf/v2 v2.1.1
|
||||
github.com/mailru/easyjson v0.7.7
|
||||
github.com/mattn/go-sqlite3 v1.14.24
|
||||
github.com/oklog/oklog v0.3.2
|
||||
github.com/open-telemetry/opamp-go v0.5.0
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.111.0
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
@@ -43,7 +45,7 @@ require (
|
||||
github.com/prometheus/alertmanager v0.28.0
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
github.com/prometheus/common v0.61.0
|
||||
github.com/prometheus/prometheus v0.300.1
|
||||
github.com/prometheus/prometheus v2.5.0+incompatible
|
||||
github.com/rs/cors v1.11.1
|
||||
github.com/russellhaering/gosaml2 v0.9.0
|
||||
github.com/russellhaering/goxmldsig v1.2.0
|
||||
@@ -61,7 +63,7 @@ require (
|
||||
go.opentelemetry.io/collector/pdata v1.17.0
|
||||
go.opentelemetry.io/collector/processor v0.111.0
|
||||
go.opentelemetry.io/contrib/config v0.10.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0
|
||||
go.opentelemetry.io/otel v1.34.0
|
||||
go.opentelemetry.io/otel/metric v1.34.0
|
||||
go.opentelemetry.io/otel/sdk v1.34.0
|
||||
@@ -73,19 +75,19 @@ require (
|
||||
golang.org/x/oauth2 v0.24.0
|
||||
golang.org/x/sync v0.10.0
|
||||
golang.org/x/text v0.21.0
|
||||
google.golang.org/protobuf v1.36.0
|
||||
google.golang.org/protobuf v1.35.2
|
||||
gopkg.in/segmentio/analytics-go.v3 v3.1.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/apimachinery v0.31.3
|
||||
k8s.io/apimachinery v0.31.1
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/auth v0.13.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.6 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect
|
||||
cloud.google.com/go/auth v0.9.5 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.5.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
|
||||
github.com/ClickHouse/ch-go v0.61.5 // indirect
|
||||
@@ -94,7 +96,6 @@ require (
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aws/aws-sdk-go v1.55.5 // indirect
|
||||
github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 // indirect
|
||||
github.com/beevik/etree v1.1.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
|
||||
@@ -106,15 +107,16 @@ require (
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.0 // indirect
|
||||
github.com/edsrzf/mmap-go v1.2.0 // indirect
|
||||
github.com/edsrzf/mmap-go v1.1.0 // indirect
|
||||
github.com/elastic/lunes v0.1.0 // indirect
|
||||
github.com/expr-lang/expr v1.17.0 // indirect
|
||||
github.com/expr-lang/expr v1.16.9 // indirect
|
||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-faster/city v1.0.1 // indirect
|
||||
github.com/go-faster/errors v0.7.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
@@ -130,17 +132,16 @@ require (
|
||||
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/s2a-go v0.1.8 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.0 // indirect
|
||||
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
||||
github.com/gosimple/unidecode v1.0.0 // indirect
|
||||
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-msgpack/v2 v2.1.1 // indirect
|
||||
@@ -161,7 +162,7 @@ require (
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/klauspost/compress v1.17.10 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/leodido/go-syslog/v4 v4.2.0 // indirect
|
||||
github.com/leodido/ragel-machinery v0.0.0-20190525184631-5f46317e436b // indirect
|
||||
@@ -181,7 +182,6 @@ require (
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/open-feature/go-sdk v1.14.1 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.111.0 // indirect
|
||||
github.com/paulmach/orb v0.11.1 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
@@ -201,6 +201,7 @@ require (
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/smarty/assertions v1.15.0 // indirect
|
||||
github.com/spf13/cobra v1.8.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
@@ -218,6 +219,7 @@ require (
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.1 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/collector v0.111.0 // indirect
|
||||
go.opentelemetry.io/collector/component v0.111.0 // indirect
|
||||
@@ -246,38 +248,38 @@ require (
|
||||
go.opentelemetry.io/collector/processor/processorprofiles v0.111.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver v0.111.0 // indirect
|
||||
go.opentelemetry.io/collector/receiver/receiverprofiles v0.111.0 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.116.0 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.111.0 // indirect
|
||||
go.opentelemetry.io/collector/service v0.111.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.56.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.6.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.52.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.6.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/log v0.10.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/log v0.10.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.30.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/goleak v1.3.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/time v0.8.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
golang.org/x/tools v0.28.0 // indirect
|
||||
gonum.org/v1/gonum v0.15.1 // indirect
|
||||
google.golang.org/api v0.213.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
|
||||
google.golang.org/grpc v1.69.0 // indirect
|
||||
google.golang.org/api v0.199.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/grpc v1.67.1 // indirect
|
||||
gopkg.in/telebot.v3 v3.3.8 // indirect
|
||||
k8s.io/client-go v0.31.3 // indirect
|
||||
k8s.io/client-go v0.31.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
|
||||
)
|
||||
|
||||
replace github.com/prometheus/prometheus => github.com/SigNoz/prometheus v1.13.0
|
||||
|
||||
163
go.sum
163
go.sum
@@ -29,10 +29,10 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW
|
||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
|
||||
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
|
||||
cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs=
|
||||
cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8=
|
||||
cloud.google.com/go/auth v0.9.5 h1:4CTn43Eynw40aFVr3GpPqsQponx2jv0BQpjvajsbbzw=
|
||||
cloud.google.com/go/auth v0.9.5/go.mod h1:Xo0n7n66eHyOWWCnitop6870Ilwo3PiZyodVkkH1xWM=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
@@ -44,8 +44,8 @@ cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJW
|
||||
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
|
||||
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
|
||||
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
|
||||
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
||||
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
||||
cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo=
|
||||
cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
|
||||
@@ -67,20 +67,16 @@ filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4
|
||||
github.com/AfterShip/clickhouse-sql-parser v0.4.4 h1:iLRwjzz1mWmUEf5UNrSYOceQ+PX9SdBJ8Xw0DNrL114=
|
||||
github.com/AfterShip/clickhouse-sql-parser v0.4.4/go.mod h1:W0Z82wJWkJxz2RVun/RMwxue3g7ut47Xxl+SFqdJGus=
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 h1:JZg6HRh6W6U4OLl6lk7BZ7BLisIzM9dG1R50zUk9C/M=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0/go.mod h1:YL1xnZ6QejvQHWJrX/AvhFl4WW4rqHVoKspWNVwFk0M=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvULkDNfdXOgrjtg6UYJPFBJyuEcRCAw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0/go.mod h1:Y/HgrePTmGy9HjdSGTqZNa+apUpTVIEVKXJyARP2lrk=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
@@ -100,6 +96,8 @@ github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd h1:Bk43AsDYe0fhkbj57eGXx8H3ZJ4zhmQXBnrW523ktj8=
|
||||
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd/go.mod h1:nxRcH/OEdM8QxzH37xkGzomr1O0JpYBRS6pwjsWW6Pc=
|
||||
github.com/SigNoz/prometheus v1.13.0 h1:hsUql1zd83ifXtswO9Qk1rpCgVjE/ItQvgdNocBSqRI=
|
||||
github.com/SigNoz/prometheus v1.13.0/go.mod h1:4PC0dxmx6y3kNI2d9oOTvEFTPkH6QnxDxERyqeL1hvI=
|
||||
github.com/SigNoz/signoz-otel-collector v0.111.16 h1:535uKH5Oux+35EsI+L3C6pnAP/Ye0PTCbVizXoL+VqE=
|
||||
github.com/SigNoz/signoz-otel-collector v0.111.16/go.mod h1:HJ4m0LY1MPsuZmuRF7Ixb+bY8rxgRzI0VXzOedESsjg=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
@@ -172,8 +170,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI=
|
||||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/cncf/xds/go v0.0.0-20240822171458-6449f94b4d59 h1:fLZ97KE86ELjEYJCEUVzmbhfzDxHHGwBrDVMd4XL6Bs=
|
||||
github.com/cncf/xds/go v0.0.0-20240822171458-6449f94b4d59/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/coder/quartz v0.1.2 h1:PVhc9sJimTdKd3VbygXtS4826EOCpB1fXoRlLnCrE+s=
|
||||
github.com/coder/quartz v0.1.2/go.mod h1:vsiCc+AHViMKH2CQpGIpFgdHIEQsxwm8yCscqKmzbRA=
|
||||
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
|
||||
@@ -192,12 +190,12 @@ github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
|
||||
github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/digitalocean/godo v1.126.0 h1:+Znh7VMQj/E8ArbjWnc7OKGjWfzC+I8OCSRp7r1MdD8=
|
||||
github.com/digitalocean/godo v1.126.0/go.mod h1:PU8JB6I1XYkQIdHFop8lLAY9ojp6M0XcU0TWaQSxbrc=
|
||||
github.com/digitalocean/godo v1.122.0 h1:ziytLQi8QKtDp2K1A+YrYl2dWLHLh2uaMzWvcz9HkKg=
|
||||
github.com/digitalocean/godo v1.122.0/go.mod h1:WQVH83OHUy6gC4gXpEVQKtxTd4L5oCp+5OialidkPLY=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
|
||||
github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v27.3.0+incompatible h1:BNb1QY6o4JdKpqwi9IB+HUYcRRrVN4aGFUTvDmWYK1A=
|
||||
github.com/docker/docker v27.3.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
@@ -207,8 +205,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE=
|
||||
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84=
|
||||
github.com/edsrzf/mmap-go v1.2.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
|
||||
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
|
||||
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
|
||||
github.com/elastic/lunes v0.1.0 h1:amRtLPjwkWtzDF/RKzcEPMvSsSseLDLW+bnhfNSLRe4=
|
||||
github.com/elastic/lunes v0.1.0/go.mod h1:xGphYIt3XdZRtyWosHQTErsQTd4OP1p9wsbVoHelrd4=
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
|
||||
@@ -226,13 +224,13 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
|
||||
github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
|
||||
github.com/envoyproxy/go-control-plane v0.13.0 h1:HzkeUz1Knt+3bK+8LG1bxOO/jzWZmdxpwC51i202les=
|
||||
github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnvMg4d7nvT/wl9WgVXn3Q8=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
|
||||
github.com/expr-lang/expr v1.17.0 h1:+vpszOyzKLQXC9VF+wA8cVA0tlA984/Wabc/1hF9Whg=
|
||||
github.com/expr-lang/expr v1.17.0/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
||||
github.com/expr-lang/expr v1.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI=
|
||||
github.com/expr-lang/expr v1.16.9/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM=
|
||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@@ -249,8 +247,8 @@ github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUork
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@@ -268,10 +266,14 @@ github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JS
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
|
||||
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
@@ -333,12 +335,13 @@ github.com/gojek/heimdall/v7 v7.0.3 h1:+5sAhl8S0m+qRRL8IVeHCJudFh/XkG3wyO++nvOg+
|
||||
github.com/gojek/heimdall/v7 v7.0.3/go.mod h1:Z43HtMid7ysSjmsedPTXAki6jcdcNVnjn5pmsTyiMic=
|
||||
github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf h1:5xRGbUdOmZKoDXkGx5evVLehuCMpuO1hl701bEQqXOM=
|
||||
github.com/gojek/valkyrie v0.0.0-20180215180059-6aee720afcdf/go.mod h1:QzhUKaYKJmcbTnCYCAVQrroCOY7vOOI8cSQ4NbuhYf0=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
@@ -434,11 +437,9 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0
|
||||
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
|
||||
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
|
||||
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
|
||||
github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o=
|
||||
github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gophercloud/gophercloud v1.14.1 h1:DTCNaTVGl8/cFu58O1JwWgis9gtISAFONqpMKNg/Vpw=
|
||||
github.com/gophercloud/gophercloud v1.14.1/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
|
||||
github.com/gophercloud/gophercloud v1.14.0 h1:Bt9zQDhPrbd4qX7EILGmy+i7GP35cc+AAL2+wIJpUE8=
|
||||
github.com/gophercloud/gophercloud v1.14.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||
@@ -456,8 +457,8 @@ github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrR
|
||||
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
|
||||
github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
|
||||
github.com/hashicorp/consul/api v1.29.4 h1:P6slzxDLBOxUSj3fWo2o65VuKtbtOXFi7TSSgtXutuE=
|
||||
@@ -584,14 +585,12 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0=
|
||||
github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/knadh/koanf v1.5.0 h1:q2TSd/3Pyc/5yP9ldIrSdIz26MCcyNQzW0pEAugLPNs=
|
||||
github.com/knadh/koanf v1.5.0/go.mod h1:Hgyjp4y8v44hpZtPzs7JZfRAW5AhN7KfZcwv1RYggDs=
|
||||
github.com/knadh/koanf/v2 v2.1.1 h1:/R8eXqasSTsmDCsAyYj+81Wteg8AqrV9CP6gvsTsOmM=
|
||||
@@ -622,8 +621,8 @@ github.com/leodido/ragel-machinery v0.0.0-20190525184631-5f46317e436b/go.mod h1:
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/linode/linodego v1.41.0 h1:GcP7JIBr9iLRJ9FwAtb9/WCT1DuPJS/xUApapfdjtiY=
|
||||
github.com/linode/linodego v1.41.0/go.mod h1:Ow4/XZ0yvWBzt3iAHwchvhSx30AyLintsSMvvQ2/SJY=
|
||||
github.com/linode/linodego v1.40.0 h1:7ESY0PwK94hoggoCtIroT1Xk6b1flrFBNZ6KwqbTqlI=
|
||||
github.com/linode/linodego v1.40.0/go.mod h1:NsUw4l8QrLdIofRg1NYFBbW5ZERnmbZykVBszPZLORM=
|
||||
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 h1:1KuuSOy4ZNgW0KA2oYIngXVFhQcXxhLqCVK7cBcldkk=
|
||||
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
|
||||
github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=
|
||||
@@ -701,6 +700,8 @@ github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnu
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oklog/oklog v0.3.2 h1:wVfs8F+in6nTBMkA7CbRw+zZMIB7nNM825cM1wuzoTk=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
@@ -717,8 +718,6 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
github.com/open-feature/go-sdk v1.14.1 h1:jcxjCIG5Up3XkgYwWN5Y/WWfc6XobOhqrIwjyDBsoQo=
|
||||
github.com/open-feature/go-sdk v1.14.1/go.mod h1:t337k0VB/t/YxJ9S0prT30ISUHwYmUd/jhUZgFcOvGg=
|
||||
github.com/open-telemetry/opamp-go v0.5.0 h1:2YFbb6G4qBkq3yTRdVb5Nfz9hKHW/ldUyex352e1J7g=
|
||||
github.com/open-telemetry/opamp-go v0.5.0/go.mod h1:IMdeuHGVc5CjKSu5/oNV0o+UmiXuahoHvoZ4GOmAI9M=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.111.0 h1:n1p2DedLvPEN1XEx26s1PR1PCuXTgCY4Eo+kDTq7q0s=
|
||||
@@ -809,13 +808,9 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/prometheus/prometheus v0.300.1 h1:9KKcTTq80gkzmXW0Et/QCFSrBPgmwiS3Hlcxc6o8KlM=
|
||||
github.com/prometheus/prometheus v0.300.1/go.mod h1:gtTPY/XVyCdqqnjA3NzDMb0/nc5H9hOu1RMame+gHyM=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.0 h1:i+cMcpEDY1BkNm7lPDkCtE4oElsYLn+EKF8kAu2vXT4=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4=
|
||||
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
|
||||
github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
@@ -864,6 +859,8 @@ github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92/go.mod h1:7/OT02F6
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
|
||||
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@@ -899,6 +896,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
@@ -968,6 +966,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/collector v0.111.0 h1:D3LJTYrrK2ac94E2PXPSbVkArqxbklbCLsE4MAJQdRo=
|
||||
@@ -1050,16 +1050,14 @@ go.opentelemetry.io/collector/receiver v0.111.0 h1:6cRHZ9cUxYfRPkArUCkIhoo7Byf6t
|
||||
go.opentelemetry.io/collector/receiver v0.111.0/go.mod h1:QSl/n9ikDP+6n39QcRY/VLjwQI0qbT1RQp512uBQl3g=
|
||||
go.opentelemetry.io/collector/receiver/receiverprofiles v0.111.0 h1:oYLAdGMQQR7gB6wVkbV0G4EMsrmiOs3O0qf3hh/3avw=
|
||||
go.opentelemetry.io/collector/receiver/receiverprofiles v0.111.0/go.mod h1:M/OfdEGnvyB+fSTSW4RPKj5N06FXL8oKSIf60FlrKmM=
|
||||
go.opentelemetry.io/collector/semconv v0.116.0 h1:63xCZomsKJAWmKGWD3lnORiE3WKW6AO4LjnzcHzGx3Y=
|
||||
go.opentelemetry.io/collector/semconv v0.116.0/go.mod h1:N6XE8Q0JKgBN2fAhkUQtqK9LT7rEGR6+Wu/Rtbal1iI=
|
||||
go.opentelemetry.io/collector/semconv v0.111.0 h1:ELleMtLBzeZ3xhfhYPmFcLc0hJMqRxhOB0eY60WLivw=
|
||||
go.opentelemetry.io/collector/semconv v0.111.0/go.mod h1:zCJ5njhWpejR+A40kiEoeFm1xq1uzyZwMnRNX6/D82A=
|
||||
go.opentelemetry.io/collector/service v0.111.0 h1:6yGjjbZvlYbir+vzi/9ACF965m8i96ScPTjpVvki3ms=
|
||||
go.opentelemetry.io/collector/service v0.111.0/go.mod h1:tti8TAosPuRj51/bbrSvf6OIJoSyTkywEvTdY/fAuwY=
|
||||
go.opentelemetry.io/contrib/config v0.10.0 h1:2JknAzMaYjxrHkTnZh3eOme/Y2P5eHE2SWfhfV6Xd6c=
|
||||
go.opentelemetry.io/contrib/config v0.10.0/go.mod h1:aND2M6/KfNkntI5cyvHriR/zvZgPf8j9yETdSmvpfmc=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.56.0 h1:4BZHA+B1wXEQoGNHxW8mURaLhcdGwvRnmhGbm+odRbc=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.56.0/go.mod h1:3qi2EEwMgB4xnKgPLqsDP3j9qxnHDZeHsnAxfjQqTko=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.30.0 h1:vumy4r1KMyaoQRltX7cJ37p3nluzALX9nugCjNNefuY=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.30.0/go.mod h1:fRbvRsaeVZ82LIl3u0rIvusIel2UUf+JcaaIpy5taho=
|
||||
go.opentelemetry.io/contrib/zpages v0.55.0 h1:F+xj261Ulwl79QC+2O+IO1b3NbwppUDwN+7LbDSdQcY=
|
||||
@@ -1072,12 +1070,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 h1:Wyp
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0/go.mod h1:U79SV99vtvGSEBeeHnpgGJfTsnsdkWLpPN/CcHAzBSI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 h1:VrMAbeJz4gnVDg2zEzjHG4dEH86j4jO6VYB+NgtGD8s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0/go.mod h1:qqN/uFdpeitTvm+JDqqnjm517pmQRYxTORbETHq5tOc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.52.0 h1:kmU3H0b9ufFSi8IQCcxack+sWUblKkFbqWYs6YiACGQ=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.52.0/go.mod h1:+wsAp2+JhuGXX7YRkjlkx6hyWY3ogFPfNA4x3nyiAh0=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.6.0 h1:bZHOb8k/CwwSt0DgvgaoOhBXWNdWqFWaIsGTtg1H3KE=
|
||||
@@ -1094,13 +1092,13 @@ go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7W
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/log v0.10.0 h1:lR4teQGWfeDVGoute6l0Ou+RpFqQ9vaPdrNJlST0bvw=
|
||||
go.opentelemetry.io/otel/sdk/log v0.10.0/go.mod h1:A+V1UTWREhWAittaQEG4bYm4gAZa6xnvVu+xKrIRkzo=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
@@ -1342,6 +1340,7 @@ golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
@@ -1364,8 +1363,8 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
||||
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -1472,8 +1471,8 @@ google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRR
|
||||
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
|
||||
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
|
||||
google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko=
|
||||
google.golang.org/api v0.213.0 h1:KmF6KaDyFqB417T68tMPbVmmwtIXs2VB60OJKIHB0xQ=
|
||||
google.golang.org/api v0.213.0/go.mod h1:V0T5ZhNUUNpYAlL306gFZPFt5F5D/IeyLoktduYYnvQ=
|
||||
google.golang.org/api v0.199.0 h1:aWUXClp+VFJmqE0JPvpZOK3LDQMyFKYIow4etYd9qxs=
|
||||
google.golang.org/api v0.199.0/go.mod h1:ohG4qSztDJmZdjK/Ar6MhbAmb/Rpi4JHOqagsh90K28=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -1560,10 +1559,10 @@ google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX
|
||||
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
|
||||
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
@@ -1596,8 +1595,8 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.69.0 h1:quSiOM1GJPmPH5XtU+BCoVXcDVJJAzNcoyfC2cCjGkI=
|
||||
google.golang.org/grpc v1.69.0/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
|
||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
@@ -1613,8 +1612,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ=
|
||||
google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -1655,12 +1654,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8=
|
||||
k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE=
|
||||
k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4=
|
||||
k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||
k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4=
|
||||
k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs=
|
||||
k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU=
|
||||
k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI=
|
||||
k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U=
|
||||
k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||
k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0=
|
||||
k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user