Compare commits

..

5 Commits

Author SHA1 Message Date
aks07
c5d3adb212 Merge branch 'main' of github.com:SigNoz/signoz into feat/field-selector-migration 2026-05-23 01:31:48 +05:30
aks07
d543fbc660 feat: sync columns state in traces 2026-05-23 01:31:04 +05:30
aks07
c482e89dac feat: sync columns state in logs 2026-05-22 21:11:21 +05:30
aks07
d28b2fa025 feat: move floating panel to field selector 2026-05-19 18:16:21 +05:30
aks07
af5b925023 feat: field selector migrated to telemetry field key 2026-05-19 16:41:56 +05:30
107 changed files with 10023 additions and 27324 deletions

View File

@@ -115,7 +115,7 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
func(ps factory.ProviderSettings, q querier.Querier, a analytics.Analytics) querier.Handler {
return querier.NewHandler(ps, q, a)
},
func(_ sqlstore.SQLStore, _ dashboard.Module, _ global.Global, _ zeus.Zeus, _ gateway.Gateway, _ licensing.Licensing, _ serviceaccount.Module, _ cloudintegration.Config) (cloudintegration.Module, error) {
func(_ sqlstore.SQLStore, _ global.Global, _ zeus.Zeus, _ gateway.Gateway, _ licensing.Licensing, _ serviceaccount.Module, _ cloudintegration.Config) (cloudintegration.Module, error) {
return implcloudintegration.NewModule(), nil
},
func(c cache.Cache, am alertmanager.Alertmanager, ss sqlstore.SQLStore, ts telemetrystore.TelemetryStore, ms telemetrytypes.MetadataStore, p prometheus.Prometheus, og organization.Getter, rsh rulestatehistory.Module, q querier.Querier, qp queryparser.QueryParser) factory.NamedMap[factory.ProviderFactory[ruler.Ruler, ruler.Config]] {

View File

@@ -167,7 +167,7 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
communityHandler := querier.NewHandler(ps, q, a)
return eequerier.NewHandler(ps, q, communityHandler)
},
func(sqlStore sqlstore.SQLStore, dashboardModule dashboard.Module, global global.Global, zeus zeus.Zeus, gateway gateway.Gateway, licensing licensing.Licensing, serviceAccount serviceaccount.Module, config cloudintegration.Config) (cloudintegration.Module, error) {
func(sqlStore sqlstore.SQLStore, global global.Global, zeus zeus.Zeus, gateway gateway.Gateway, licensing licensing.Licensing, serviceAccount serviceaccount.Module, config cloudintegration.Config) (cloudintegration.Module, error) {
defStore := pkgcloudintegration.NewServiceDefinitionStore()
awsCloudProviderModule, err := implcloudprovider.NewAWSCloudProvider(defStore)
if err != nil {
@@ -179,7 +179,7 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
cloudintegrationtypes.CloudProviderTypeAzure: azureCloudProviderModule,
}
return implcloudintegration.NewModule(pkgcloudintegration.NewStore(sqlStore), dashboardModule, global, zeus, gateway, licensing, serviceAccount, cloudProvidersMap, config)
return implcloudintegration.NewModule(pkgcloudintegration.NewStore(sqlStore), global, zeus, gateway, licensing, serviceAccount, cloudProvidersMap, config)
},
func(c cache.Cache, am alertmanager.Alertmanager, ss sqlstore.SQLStore, ts telemetrystore.TelemetryStore, ms telemetrytypes.MetadataStore, p prometheus.Prometheus, og organization.Getter, rsh rulestatehistory.Module, q querier.Querier, qp queryparser.QueryParser) factory.NamedMap[factory.ProviderFactory[ruler.Ruler, ruler.Config]] {
return factory.MustNewNamedMap(signozruler.NewFactory(c, am, ss, ts, ms, p, og, rsh, q, qp, eerules.PrepareTaskFunc, eerules.TestNotification))

View File

@@ -60,14 +60,6 @@ web:
index: index.html
# The directory containing the static build files.
directory: /etc/signoz/web
# Settings exposed to the web.
settings:
posthog:
# Whether to enable PostHog in web.
enabled: true
appcues:
# Whether to enable Appcues in web.
enabled: true
##################### Cache #####################
cache:

View File

@@ -5641,19 +5641,6 @@ components:
type: object
Sigv4SigV4Config:
type: object
SpantypesEvent:
properties:
attributeMap:
additionalProperties: {}
type: object
isError:
type: boolean
name:
type: string
timeUnixNano:
minimum: 0
type: integer
type: object
SpantypesFieldContext:
enum:
- attribute
@@ -5668,50 +5655,6 @@ components:
required:
- items
type: object
SpantypesGettableWaterfallTrace:
properties:
aggregations:
items:
$ref: '#/components/schemas/SpantypesSpanAggregationResult'
nullable: true
type: array
endTimestampMillis:
minimum: 0
type: integer
hasMissingSpans:
type: boolean
hasMore:
type: boolean
rootServiceEntryPoint:
type: string
rootServiceName:
type: string
serviceNameToTotalDurationMap:
additionalProperties:
minimum: 0
type: integer
nullable: true
type: object
spans:
items:
$ref: '#/components/schemas/SpantypesWaterfallSpan'
nullable: true
type: array
startTimestampMillis:
minimum: 0
type: integer
totalErrorSpansCount:
minimum: 0
type: integer
totalSpansCount:
minimum: 0
type: integer
uncollapsedSpans:
items:
type: string
nullable: true
type: array
type: object
SpantypesPostableSpanMapper:
properties:
config:
@@ -5739,50 +5682,6 @@ components:
- name
- condition
type: object
SpantypesPostableWaterfall:
properties:
aggregations:
items:
$ref: '#/components/schemas/SpantypesSpanAggregation'
nullable: true
type: array
limit:
minimum: 0
type: integer
selectedSpanId:
type: string
uncollapsedSpans:
items:
type: string
nullable: true
type: array
type: object
SpantypesSpanAggregation:
properties:
aggregation:
$ref: '#/components/schemas/SpantypesSpanAggregationType'
field:
$ref: '#/components/schemas/TelemetrytypesTelemetryFieldKey'
type: object
SpantypesSpanAggregationResult:
properties:
aggregation:
$ref: '#/components/schemas/SpantypesSpanAggregationType'
field:
$ref: '#/components/schemas/TelemetrytypesTelemetryFieldKey'
value:
additionalProperties:
minimum: 0
type: integer
nullable: true
type: object
type: object
SpantypesSpanAggregationType:
enum:
- span_count
- execution_time_percentage
- duration
type: string
SpantypesSpanMapper:
properties:
config:
@@ -5913,78 +5812,6 @@ components:
nullable: true
type: string
type: object
SpantypesWaterfallSpan:
properties:
attributes:
additionalProperties: {}
nullable: true
type: object
db_name:
type: string
db_operation:
type: string
duration_nano:
minimum: 0
type: integer
events:
items:
$ref: '#/components/schemas/SpantypesEvent'
nullable: true
type: array
external_http_method:
type: string
external_http_url:
type: string
flags:
minimum: 0
type: integer
has_children:
type: boolean
has_error:
type: boolean
http_host:
type: string
http_method:
type: string
http_url:
type: string
is_remote:
type: string
kind_string:
type: string
level:
minimum: 0
type: integer
name:
type: string
parent_span_id:
type: string
resource:
additionalProperties:
type: string
nullable: true
type: object
response_status_code:
type: string
span_id:
type: string
status_code:
type: integer
status_code_string:
type: string
status_message:
type: string
sub_tree_node_count:
minimum: 0
type: integer
time_unix:
minimum: 0
type: integer
trace_id:
type: string
trace_state:
type: string
type: object
TelemetrytypesFieldContext:
enum:
- metric
@@ -6077,6 +5904,179 @@ components:
TimeDuration:
format: int64
type: integer
TracedetailtypesEvent:
properties:
attributeMap:
additionalProperties: {}
type: object
isError:
type: boolean
name:
type: string
timeUnixNano:
minimum: 0
type: integer
type: object
TracedetailtypesGettableWaterfallTrace:
properties:
aggregations:
items:
$ref: '#/components/schemas/TracedetailtypesSpanAggregationResult'
nullable: true
type: array
endTimestampMillis:
minimum: 0
type: integer
hasMissingSpans:
type: boolean
hasMore:
type: boolean
rootServiceEntryPoint:
type: string
rootServiceName:
type: string
serviceNameToTotalDurationMap:
additionalProperties:
minimum: 0
type: integer
nullable: true
type: object
spans:
items:
$ref: '#/components/schemas/TracedetailtypesWaterfallSpan'
nullable: true
type: array
startTimestampMillis:
minimum: 0
type: integer
totalErrorSpansCount:
minimum: 0
type: integer
totalSpansCount:
minimum: 0
type: integer
uncollapsedSpans:
items:
type: string
nullable: true
type: array
type: object
TracedetailtypesPostableWaterfall:
properties:
aggregations:
items:
$ref: '#/components/schemas/TracedetailtypesSpanAggregation'
nullable: true
type: array
limit:
minimum: 0
type: integer
selectedSpanId:
type: string
uncollapsedSpans:
items:
type: string
nullable: true
type: array
type: object
TracedetailtypesSpanAggregation:
properties:
aggregation:
$ref: '#/components/schemas/TracedetailtypesSpanAggregationType'
field:
$ref: '#/components/schemas/TelemetrytypesTelemetryFieldKey'
type: object
TracedetailtypesSpanAggregationResult:
properties:
aggregation:
$ref: '#/components/schemas/TracedetailtypesSpanAggregationType'
field:
$ref: '#/components/schemas/TelemetrytypesTelemetryFieldKey'
value:
additionalProperties:
minimum: 0
type: integer
nullable: true
type: object
type: object
TracedetailtypesSpanAggregationType:
enum:
- span_count
- execution_time_percentage
- duration
type: string
TracedetailtypesWaterfallSpan:
properties:
attributes:
additionalProperties: {}
nullable: true
type: object
db_name:
type: string
db_operation:
type: string
duration_nano:
minimum: 0
type: integer
events:
items:
$ref: '#/components/schemas/TracedetailtypesEvent'
nullable: true
type: array
external_http_method:
type: string
external_http_url:
type: string
flags:
minimum: 0
type: integer
has_children:
type: boolean
has_error:
type: boolean
http_host:
type: string
http_method:
type: string
http_url:
type: string
is_remote:
type: string
kind_string:
type: string
level:
minimum: 0
type: integer
name:
type: string
parent_span_id:
type: string
resource:
additionalProperties:
type: string
nullable: true
type: object
response_status_code:
type: string
span_id:
type: string
status_code:
type: integer
status_code_string:
type: string
status_message:
type: string
sub_tree_node_count:
minimum: 0
type: integer
time_unix:
minimum: 0
type: integer
trace_id:
type: string
trace_state:
type: string
type: object
TypesAlertStatus:
properties:
inhibitedBy:
@@ -18896,7 +18896,7 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/SpantypesPostableWaterfall'
$ref: '#/components/schemas/TracedetailtypesPostableWaterfall'
responses:
"200":
content:
@@ -18904,7 +18904,7 @@ paths:
schema:
properties:
data:
$ref: '#/components/schemas/SpantypesGettableWaterfallTrace'
$ref: '#/components/schemas/TracedetailtypesGettableWaterfallTrace'
status:
type: string
required:

View File

@@ -54,6 +54,11 @@ func (provider *awscloudprovider) GetServiceDefinition(ctx context.Context, serv
return nil, err
}
// override cloud integration dashboard id
for index, dashboard := range serviceDef.Assets.Dashboards {
serviceDef.Assets.Dashboards[index].ID = cloudintegrationtypes.GetCloudIntegrationDashboardID(cloudintegrationtypes.CloudProviderTypeAWS, serviceID.StringValue(), dashboard.ID)
}
return serviceDef, nil
}

View File

@@ -38,6 +38,11 @@ func (provider *azurecloudprovider) GetServiceDefinition(ctx context.Context, se
return nil, err
}
// override cloud integration dashboard id.
for index, dashboard := range serviceDef.Assets.Dashboards {
serviceDef.Assets.Dashboards[index].ID = cloudintegrationtypes.GetCloudIntegrationDashboardID(cloudintegrationtypes.CloudProviderTypeAzure, serviceID.StringValue(), dashboard.ID)
}
return serviceDef, nil
}

View File

@@ -3,6 +3,7 @@ package implcloudintegration
import (
"context"
"fmt"
"sort"
"time"
"github.com/SigNoz/signoz/pkg/errors"
@@ -10,7 +11,6 @@ import (
"github.com/SigNoz/signoz/pkg/global"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/modules/cloudintegration"
"github.com/SigNoz/signoz/pkg/modules/dashboard"
"github.com/SigNoz/signoz/pkg/modules/serviceaccount"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/cloudintegrationtypes"
@@ -23,7 +23,6 @@ import (
type module struct {
store cloudintegrationtypes.Store
dashboardModule dashboard.Module
gateway gateway.Gateway
zeus zeus.Zeus
licensing licensing.Licensing
@@ -35,7 +34,6 @@ type module struct {
func NewModule(
store cloudintegrationtypes.Store,
dashboardModule dashboard.Module,
global global.Global,
zeus zeus.Zeus,
gateway gateway.Gateway,
@@ -46,7 +44,6 @@ func NewModule(
) (cloudintegration.Module, error) {
return &module{
store: store,
dashboardModule: dashboardModule,
global: global,
zeus: zeus,
gateway: gateway,
@@ -257,41 +254,7 @@ func (module *module) DisconnectAccount(ctx context.Context, orgID valuer.UUID,
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
return module.store.RunInTx(ctx, func(ctx context.Context) error {
services, err := module.store.ListServices(ctx, accountID)
if err != nil {
return err
}
sharedServices, err := module.store.ListSharedServices(ctx, orgID, provider, accountID)
if err != nil {
return err
}
for _, svc := range services {
svcCfg, err := cloudintegrationtypes.NewServiceConfigFromJSON(provider, svc.Config)
if err != nil {
return err
}
if !svcCfg.IsMetricsEnabled(provider) {
continue
}
if cloudintegrationtypes.IsServiceSharedWithMetricsEnabled(provider, sharedServices[svc.Type]) {
continue
}
if err := module.deprovisionDashboards(ctx, orgID, provider, svc.Type); err != nil {
return err
}
}
if err := module.store.DeleteServicesByCloudIntegrationID(ctx, orgID, accountID); err != nil {
return err
}
return module.store.RemoveAccount(ctx, orgID, accountID, provider)
})
return module.store.RemoveAccount(ctx, orgID, accountID, provider)
}
func (module *module) ListServicesMetadata(ctx context.Context, orgID valuer.UUID, provider cloudintegrationtypes.CloudProviderType, integrationID valuer.UUID) ([]*cloudintegrationtypes.ServiceMetadata, error) {
@@ -368,16 +331,12 @@ func (module *module) GetService(ctx context.Context, orgID valuer.UUID, service
integrationService = cloudintegrationtypes.NewCloudIntegrationServiceFromStorable(storedService, serviceConfig)
}
if err := module.enrichDashboardIDs(ctx, orgID, provider, serviceID, serviceDefinition); err != nil {
return nil, err
}
}
return cloudintegrationtypes.NewService(*serviceDefinition, integrationService), nil
}
func (module *module) CreateService(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, service *cloudintegrationtypes.CloudIntegrationService, provider cloudintegrationtypes.CloudProviderType) error {
func (module *module) CreateService(ctx context.Context, orgID valuer.UUID, service *cloudintegrationtypes.CloudIntegrationService, provider cloudintegrationtypes.CloudProviderType) error {
_, err := module.licensing.GetActive(ctx, orgID)
if err != nil {
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
@@ -398,21 +357,10 @@ func (module *module) CreateService(ctx context.Context, orgID valuer.UUID, crea
return err
}
metricsEnabled := service.Config.IsMetricsEnabled(provider)
storableService := cloudintegrationtypes.NewStorableCloudIntegrationService(service, string(configJSON))
return module.store.RunInTx(ctx, func(ctx context.Context) error {
if err := module.store.CreateService(ctx, storableService); err != nil {
return err
}
if metricsEnabled {
return module.provisionDashboards(ctx, orgID, createdBy, creator, provider, service, serviceDefinition)
}
return nil
})
return module.store.CreateService(ctx, cloudintegrationtypes.NewStorableCloudIntegrationService(service, string(configJSON)))
}
func (module *module) UpdateService(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, integrationService *cloudintegrationtypes.CloudIntegrationService, provider cloudintegrationtypes.CloudProviderType) error {
func (module *module) UpdateService(ctx context.Context, orgID valuer.UUID, integrationService *cloudintegrationtypes.CloudIntegrationService, provider cloudintegrationtypes.CloudProviderType) error {
_, err := module.licensing.GetActive(ctx, orgID)
if err != nil {
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
@@ -433,28 +381,43 @@ func (module *module) UpdateService(ctx context.Context, orgID valuer.UUID, crea
return err
}
metricsEnabled := integrationService.Config.IsMetricsEnabled(provider)
storableService := cloudintegrationtypes.NewStorableCloudIntegrationService(integrationService, string(configJSON))
return module.store.RunInTx(ctx, func(ctx context.Context) error {
if err := module.store.UpdateService(ctx, storableService); err != nil {
return err
}
return module.store.UpdateService(ctx, storableService)
}
if metricsEnabled {
return module.provisionDashboards(ctx, orgID, createdBy, creator, provider, integrationService, serviceDefinition)
}
func (module *module) GetDashboardByID(ctx context.Context, orgID valuer.UUID, id string) (*dashboardtypes.Dashboard, error) {
_, err := module.licensing.GetActive(ctx, orgID)
if err != nil {
return nil, errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
sharedServices, err := module.store.ListSharedServices(ctx, orgID, provider, integrationService.CloudIntegrationID)
if err != nil {
return err
}
if cloudintegrationtypes.IsServiceSharedWithMetricsEnabled(provider, sharedServices[integrationService.Type]) {
return nil
}
_, _, _, err = cloudintegrationtypes.ParseCloudIntegrationDashboardID(id)
if err != nil {
return nil, err
}
return module.deprovisionDashboards(ctx, orgID, provider, integrationService.Type)
})
allDashboards, err := module.listDashboards(ctx, orgID)
if err != nil {
return nil, err
}
for _, d := range allDashboards {
if d.ID == id {
return d, nil
}
}
return nil, errors.New(errors.TypeNotFound, cloudintegrationtypes.ErrCodeCloudIntegrationNotFound, "cloud integration dashboard not found")
}
func (module *module) ListDashboards(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error) {
_, err := module.licensing.GetActive(ctx, orgID)
if err != nil {
return nil, errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
return module.listDashboards(ctx, orgID)
}
func (module *module) Collect(ctx context.Context, orgID valuer.UUID) (map[string]any, error) {
@@ -530,73 +493,52 @@ func (module *module) getOrCreateAPIKey(ctx context.Context, orgID valuer.UUID,
return factorAPIKey.Key, nil
}
// provisionDashboards creates dashboard and integration_dashboard rows for each dashboard in the service definition.
// Must be called within a transaction (ctx carries the tx).
func (module *module) provisionDashboards(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, provider cloudintegrationtypes.CloudProviderType, service *cloudintegrationtypes.CloudIntegrationService, serviceDefinition *cloudintegrationtypes.ServiceDefinition) error {
// TODO: DB calls are in for loop, can be optimized later.
for _, dashboard := range serviceDefinition.Assets.Dashboards {
slug := cloudintegrationtypes.IntegrationDashboardSlug(provider, service.Type, dashboard.ID)
func (module *module) listDashboards(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error) {
var allDashboards []*dashboardtypes.Dashboard
existing, err := module.store.GetIntegrationDashboardBySlug(ctx, orgID, cloudintegrationtypes.IntegrationDashboardProviderCloudIntegration, slug)
if err != nil && !errors.Ast(err, errors.TypeNotFound) {
return err
}
if existing != nil {
continue
}
createdDashboard, err := module.dashboardModule.Create(ctx, orgID, createdBy, creator, dashboardtypes.SourceIntegration, dashboardtypes.PostableDashboard(dashboard.Definition))
for provider := range module.cloudProvidersMap {
cloudProvider, err := module.getCloudProvider(provider)
if err != nil {
return err
return nil, err
}
integrationDashboard := cloudintegrationtypes.NewStorableIntegrationDashboard(createdDashboard.ID, cloudintegrationtypes.IntegrationDashboardProviderCloudIntegration, slug)
if err := module.store.CreateIntegrationDashboard(ctx, integrationDashboard); err != nil {
return err
}
}
return nil
}
// deprovisionDashboards deletes all dashboard and integration_dashboard rows for the given service.
// make sure to call this within a transaction.
func (module *module) deprovisionDashboards(ctx context.Context, orgID valuer.UUID, provider cloudintegrationtypes.CloudProviderType, serviceID cloudintegrationtypes.ServiceID) error {
slugPrefix := cloudintegrationtypes.IntegrationDashboardSlugPrefix(provider, serviceID)
rows, err := module.store.ListIntegrationDashboardsBySlugPrefix(ctx, orgID, cloudintegrationtypes.IntegrationDashboardProviderCloudIntegration, slugPrefix)
if err != nil {
return err
}
for _, row := range rows {
dashID, err := valuer.NewUUID(row.DashboardID)
connectedAccounts, err := module.store.ListConnectedAccounts(ctx, orgID, provider)
if err != nil {
return err
return nil, err
}
if err := module.store.DeleteIntegrationDashboardBySlug(ctx, orgID, cloudintegrationtypes.IntegrationDashboardProviderCloudIntegration, row.Slug); err != nil {
return err
}
if err := module.dashboardModule.DeleteUnsafe(ctx, orgID, dashID); err != nil {
return err
}
}
return nil
}
// enrichDashboardIDs replaces the raw dashboard name in each Dashboard.ID with the provisioned UUID.
// TODO: remove this hack and send idiomatic response to client.
func (module *module) enrichDashboardIDs(ctx context.Context, orgID valuer.UUID, provider cloudintegrationtypes.CloudProviderType, serviceID cloudintegrationtypes.ServiceID, serviceDefinition *cloudintegrationtypes.ServiceDefinition) error {
for i, d := range serviceDefinition.Assets.Dashboards {
slug := cloudintegrationtypes.IntegrationDashboardSlug(provider, serviceID, d.ID)
row, err := module.store.GetIntegrationDashboardBySlug(ctx, orgID, cloudintegrationtypes.IntegrationDashboardProviderCloudIntegration, slug)
if err != nil {
if errors.Ast(err, errors.TypeNotFound) {
continue
for _, storableAccount := range connectedAccounts {
storedServices, err := module.store.ListServices(ctx, storableAccount.ID)
if err != nil {
return nil, err
}
for _, storedSvc := range storedServices {
serviceConfig, err := cloudintegrationtypes.NewServiceConfigFromJSON(provider, storedSvc.Config)
if err != nil || !serviceConfig.IsMetricsEnabled(provider) {
continue
}
svcDef, err := cloudProvider.GetServiceDefinition(ctx, storedSvc.Type)
if err != nil || svcDef == nil {
continue
}
dashboards := cloudintegrationtypes.GetDashboardsFromAssets(
storedSvc.Type.StringValue(),
orgID,
provider,
storableAccount.CreatedAt,
svcDef.Assets,
)
allDashboards = append(allDashboards, dashboards...)
}
return err
}
serviceDefinition.Assets.Dashboards[i].ID = row.DashboardID
}
return nil
sort.Slice(allDashboards, func(i, j int) bool {
return allDashboards[i].ID < allDashboards[j].ID
})
return allDashboards, nil
}

View File

@@ -162,11 +162,24 @@ func (module *module) Delete(ctx context.Context, orgID valuer.UUID, id valuer.U
return errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "dashboard is locked, please unlock the dashboard to be delete it")
}
return module.delete(ctx, orgID, id)
}
err = module.store.RunInTx(ctx, func(ctx context.Context) error {
err := module.store.DeletePublic(ctx, id.String())
if err != nil && !errors.Ast(err, errors.TypeNotFound) {
return err
}
func (module *module) DeleteUnsafe(ctx context.Context, orgID, id valuer.UUID) error {
return module.delete(ctx, orgID, id)
err = module.store.Delete(ctx, orgID, id)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
return nil
}
func (module *module) DeletePublic(ctx context.Context, orgID valuer.UUID, dashboardID valuer.UUID) error {
@@ -208,8 +221,8 @@ func (module *module) Collect(ctx context.Context, orgID valuer.UUID) (map[strin
return stats, nil
}
func (module *module) Create(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, source dashboardtypes.Source, data dashboardtypes.PostableDashboard) (*dashboardtypes.Dashboard, error) {
return module.pkgDashboardModule.Create(ctx, orgID, createdBy, creator, source, data)
func (module *module) Create(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, data dashboardtypes.PostableDashboard) (*dashboardtypes.Dashboard, error) {
return module.pkgDashboardModule.Create(ctx, orgID, createdBy, creator, data)
}
func (module *module) Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*dashboardtypes.Dashboard, error) {
@@ -231,12 +244,3 @@ func (module *module) Update(ctx context.Context, orgID valuer.UUID, id valuer.U
func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, isAdmin bool, lock bool) error {
return module.pkgDashboardModule.LockUnlock(ctx, orgID, id, updatedBy, isAdmin, lock)
}
func (module *module) delete(ctx context.Context, orgID, id valuer.UUID) error {
return module.store.RunInTx(ctx, func(ctx context.Context) error {
if err := module.store.DeletePublic(ctx, id.String()); err != nil && !errors.Ast(err, errors.TypeNotFound) {
return err
}
return module.store.Delete(ctx, orgID, id)
})
}

View File

@@ -6655,28 +6655,6 @@ export interface ServiceaccounttypesUpdatableFactorAPIKeyDTO {
name: string;
}
export type SpantypesEventDTOAttributeMap = { [key: string]: unknown };
export interface SpantypesEventDTO {
/**
* @type object
*/
attributeMap?: SpantypesEventDTOAttributeMap;
/**
* @type boolean
*/
isError?: boolean;
/**
* @type string
*/
name?: string;
/**
* @type integer
* @minimum 0
*/
timeUnixNano?: number;
}
export enum SpantypesFieldContextDTO {
attribute = 'attribute',
resource = 'resource',
@@ -6743,232 +6721,6 @@ export interface SpantypesGettableSpanMapperGroupsDTO {
items: SpantypesSpanMapperGroupDTO[];
}
export type SpantypesGettableWaterfallTraceDTOServiceNameToTotalDurationMapAnyOf =
{ [key: string]: number };
/**
* @nullable
*/
export type SpantypesGettableWaterfallTraceDTOServiceNameToTotalDurationMap =
SpantypesGettableWaterfallTraceDTOServiceNameToTotalDurationMapAnyOf | null;
export enum SpantypesSpanAggregationTypeDTO {
span_count = 'span_count',
execution_time_percentage = 'execution_time_percentage',
duration = 'duration',
}
export type SpantypesSpanAggregationResultDTOValueAnyOf = {
[key: string]: number;
};
/**
* @nullable
*/
export type SpantypesSpanAggregationResultDTOValue =
SpantypesSpanAggregationResultDTOValueAnyOf | null;
export interface SpantypesSpanAggregationResultDTO {
aggregation?: SpantypesSpanAggregationTypeDTO;
field?: TelemetrytypesTelemetryFieldKeyDTO;
/**
* @type object,null
*/
value?: SpantypesSpanAggregationResultDTOValue;
}
export type SpantypesWaterfallSpanDTOAttributesAnyOf = {
[key: string]: unknown;
};
/**
* @nullable
*/
export type SpantypesWaterfallSpanDTOAttributes =
SpantypesWaterfallSpanDTOAttributesAnyOf | null;
export type SpantypesWaterfallSpanDTOResourceAnyOf = { [key: string]: string };
/**
* @nullable
*/
export type SpantypesWaterfallSpanDTOResource =
SpantypesWaterfallSpanDTOResourceAnyOf | null;
export interface SpantypesWaterfallSpanDTO {
/**
* @type object,null
*/
attributes?: SpantypesWaterfallSpanDTOAttributes;
/**
* @type string
*/
db_name?: string;
/**
* @type string
*/
db_operation?: string;
/**
* @type integer
* @minimum 0
*/
duration_nano?: number;
/**
* @type array,null
*/
events?: SpantypesEventDTO[] | null;
/**
* @type string
*/
external_http_method?: string;
/**
* @type string
*/
external_http_url?: string;
/**
* @type integer
* @minimum 0
*/
flags?: number;
/**
* @type boolean
*/
has_children?: boolean;
/**
* @type boolean
*/
has_error?: boolean;
/**
* @type string
*/
http_host?: string;
/**
* @type string
*/
http_method?: string;
/**
* @type string
*/
http_url?: string;
/**
* @type string
*/
is_remote?: string;
/**
* @type string
*/
kind_string?: string;
/**
* @type integer
* @minimum 0
*/
level?: number;
/**
* @type string
*/
name?: string;
/**
* @type string
*/
parent_span_id?: string;
/**
* @type object,null
*/
resource?: SpantypesWaterfallSpanDTOResource;
/**
* @type string
*/
response_status_code?: string;
/**
* @type string
*/
span_id?: string;
/**
* @type integer
*/
status_code?: number;
/**
* @type string
*/
status_code_string?: string;
/**
* @type string
*/
status_message?: string;
/**
* @type integer
* @minimum 0
*/
sub_tree_node_count?: number;
/**
* @type integer
* @minimum 0
*/
time_unix?: number;
/**
* @type string
*/
trace_id?: string;
/**
* @type string
*/
trace_state?: string;
}
export interface SpantypesGettableWaterfallTraceDTO {
/**
* @type array,null
*/
aggregations?: SpantypesSpanAggregationResultDTO[] | null;
/**
* @type integer
* @minimum 0
*/
endTimestampMillis?: number;
/**
* @type boolean
*/
hasMissingSpans?: boolean;
/**
* @type boolean
*/
hasMore?: boolean;
/**
* @type string
*/
rootServiceEntryPoint?: string;
/**
* @type string
*/
rootServiceName?: string;
/**
* @type object,null
*/
serviceNameToTotalDurationMap?: SpantypesGettableWaterfallTraceDTOServiceNameToTotalDurationMap;
/**
* @type array,null
*/
spans?: SpantypesWaterfallSpanDTO[] | null;
/**
* @type integer
* @minimum 0
*/
startTimestampMillis?: number;
/**
* @type integer
* @minimum 0
*/
totalErrorSpansCount?: number;
/**
* @type integer
* @minimum 0
*/
totalSpansCount?: number;
/**
* @type array,null
*/
uncollapsedSpans?: string[] | null;
}
export enum SpantypesSpanMapperOperationDTO {
move = 'move',
copy = 'copy',
@@ -7018,31 +6770,6 @@ export interface SpantypesPostableSpanMapperGroupDTO {
name: string;
}
export interface SpantypesSpanAggregationDTO {
aggregation?: SpantypesSpanAggregationTypeDTO;
field?: TelemetrytypesTelemetryFieldKeyDTO;
}
export interface SpantypesPostableWaterfallDTO {
/**
* @type array,null
*/
aggregations?: SpantypesSpanAggregationDTO[] | null;
/**
* @type integer
* @minimum 0
*/
limit?: number;
/**
* @type string
*/
selectedSpanId?: string;
/**
* @type array,null
*/
uncollapsedSpans?: string[] | null;
}
export interface SpantypesSpanMapperDTO {
config: SpantypesSpanMapperConfigDTO;
/**
@@ -7151,6 +6878,281 @@ export interface TelemetrytypesGettableFieldValuesDTO {
values: TelemetrytypesTelemetryFieldValuesDTO;
}
export type TracedetailtypesEventDTOAttributeMap = { [key: string]: unknown };
export interface TracedetailtypesEventDTO {
/**
* @type object
*/
attributeMap?: TracedetailtypesEventDTOAttributeMap;
/**
* @type boolean
*/
isError?: boolean;
/**
* @type string
*/
name?: string;
/**
* @type integer
* @minimum 0
*/
timeUnixNano?: number;
}
export type TracedetailtypesGettableWaterfallTraceDTOServiceNameToTotalDurationMapAnyOf =
{ [key: string]: number };
/**
* @nullable
*/
export type TracedetailtypesGettableWaterfallTraceDTOServiceNameToTotalDurationMap =
TracedetailtypesGettableWaterfallTraceDTOServiceNameToTotalDurationMapAnyOf | null;
export enum TracedetailtypesSpanAggregationTypeDTO {
span_count = 'span_count',
execution_time_percentage = 'execution_time_percentage',
duration = 'duration',
}
export type TracedetailtypesSpanAggregationResultDTOValueAnyOf = {
[key: string]: number;
};
/**
* @nullable
*/
export type TracedetailtypesSpanAggregationResultDTOValue =
TracedetailtypesSpanAggregationResultDTOValueAnyOf | null;
export interface TracedetailtypesSpanAggregationResultDTO {
aggregation?: TracedetailtypesSpanAggregationTypeDTO;
field?: TelemetrytypesTelemetryFieldKeyDTO;
/**
* @type object,null
*/
value?: TracedetailtypesSpanAggregationResultDTOValue;
}
export type TracedetailtypesWaterfallSpanDTOAttributesAnyOf = {
[key: string]: unknown;
};
/**
* @nullable
*/
export type TracedetailtypesWaterfallSpanDTOAttributes =
TracedetailtypesWaterfallSpanDTOAttributesAnyOf | null;
export type TracedetailtypesWaterfallSpanDTOResourceAnyOf = {
[key: string]: string;
};
/**
* @nullable
*/
export type TracedetailtypesWaterfallSpanDTOResource =
TracedetailtypesWaterfallSpanDTOResourceAnyOf | null;
export interface TracedetailtypesWaterfallSpanDTO {
/**
* @type object,null
*/
attributes?: TracedetailtypesWaterfallSpanDTOAttributes;
/**
* @type string
*/
db_name?: string;
/**
* @type string
*/
db_operation?: string;
/**
* @type integer
* @minimum 0
*/
duration_nano?: number;
/**
* @type array,null
*/
events?: TracedetailtypesEventDTO[] | null;
/**
* @type string
*/
external_http_method?: string;
/**
* @type string
*/
external_http_url?: string;
/**
* @type integer
* @minimum 0
*/
flags?: number;
/**
* @type boolean
*/
has_children?: boolean;
/**
* @type boolean
*/
has_error?: boolean;
/**
* @type string
*/
http_host?: string;
/**
* @type string
*/
http_method?: string;
/**
* @type string
*/
http_url?: string;
/**
* @type string
*/
is_remote?: string;
/**
* @type string
*/
kind_string?: string;
/**
* @type integer
* @minimum 0
*/
level?: number;
/**
* @type string
*/
name?: string;
/**
* @type string
*/
parent_span_id?: string;
/**
* @type object,null
*/
resource?: TracedetailtypesWaterfallSpanDTOResource;
/**
* @type string
*/
response_status_code?: string;
/**
* @type string
*/
span_id?: string;
/**
* @type integer
*/
status_code?: number;
/**
* @type string
*/
status_code_string?: string;
/**
* @type string
*/
status_message?: string;
/**
* @type integer
* @minimum 0
*/
sub_tree_node_count?: number;
/**
* @type integer
* @minimum 0
*/
time_unix?: number;
/**
* @type string
*/
trace_id?: string;
/**
* @type string
*/
trace_state?: string;
}
export interface TracedetailtypesGettableWaterfallTraceDTO {
/**
* @type array,null
*/
aggregations?: TracedetailtypesSpanAggregationResultDTO[] | null;
/**
* @type integer
* @minimum 0
*/
endTimestampMillis?: number;
/**
* @type boolean
*/
hasMissingSpans?: boolean;
/**
* @type boolean
*/
hasMore?: boolean;
/**
* @type string
*/
rootServiceEntryPoint?: string;
/**
* @type string
*/
rootServiceName?: string;
/**
* @type object,null
*/
serviceNameToTotalDurationMap?: TracedetailtypesGettableWaterfallTraceDTOServiceNameToTotalDurationMap;
/**
* @type array,null
*/
spans?: TracedetailtypesWaterfallSpanDTO[] | null;
/**
* @type integer
* @minimum 0
*/
startTimestampMillis?: number;
/**
* @type integer
* @minimum 0
*/
totalErrorSpansCount?: number;
/**
* @type integer
* @minimum 0
*/
totalSpansCount?: number;
/**
* @type array,null
*/
uncollapsedSpans?: string[] | null;
}
export interface TracedetailtypesSpanAggregationDTO {
aggregation?: TracedetailtypesSpanAggregationTypeDTO;
field?: TelemetrytypesTelemetryFieldKeyDTO;
}
export interface TracedetailtypesPostableWaterfallDTO {
/**
* @type array,null
*/
aggregations?: TracedetailtypesSpanAggregationDTO[] | null;
/**
* @type integer
* @minimum 0
*/
limit?: number;
/**
* @type string
*/
selectedSpanId?: string;
/**
* @type array,null
*/
uncollapsedSpans?: string[] | null;
}
export interface TypesChangePasswordRequestDTO {
/**
* @type string
@@ -9230,7 +9232,7 @@ export type GetWaterfallPathParameters = {
traceID: string;
};
export type GetWaterfall200 = {
data: SpantypesGettableWaterfallTraceDTO;
data: TracedetailtypesGettableWaterfallTraceDTO;
/**
* @type string
*/

View File

@@ -15,7 +15,7 @@ import type {
GetWaterfall200,
GetWaterfallPathParameters,
RenderErrorResponseDTO,
SpantypesPostableWaterfallDTO,
TracedetailtypesPostableWaterfallDTO,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
@@ -27,14 +27,14 @@ import type { ErrorType, BodyType } from '../../../generatedAPIInstance';
*/
export const getWaterfall = (
{ traceID }: GetWaterfallPathParameters,
spantypesPostableWaterfallDTO?: BodyType<SpantypesPostableWaterfallDTO>,
tracedetailtypesPostableWaterfallDTO?: BodyType<TracedetailtypesPostableWaterfallDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetWaterfall200>({
url: `/api/v3/traces/${traceID}/waterfall`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: spantypesPostableWaterfallDTO,
data: tracedetailtypesPostableWaterfallDTO,
signal,
});
};
@@ -48,7 +48,7 @@ export const getGetWaterfallMutationOptions = <
TError,
{
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
data?: BodyType<TracedetailtypesPostableWaterfallDTO>;
},
TContext
>;
@@ -57,7 +57,7 @@ export const getGetWaterfallMutationOptions = <
TError,
{
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
data?: BodyType<TracedetailtypesPostableWaterfallDTO>;
},
TContext
> => {
@@ -74,7 +74,7 @@ export const getGetWaterfallMutationOptions = <
Awaited<ReturnType<typeof getWaterfall>>,
{
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
data?: BodyType<TracedetailtypesPostableWaterfallDTO>;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -89,7 +89,7 @@ export type GetWaterfallMutationResult = NonNullable<
Awaited<ReturnType<typeof getWaterfall>>
>;
export type GetWaterfallMutationBody =
| BodyType<SpantypesPostableWaterfallDTO>
| BodyType<TracedetailtypesPostableWaterfallDTO>
| undefined;
export type GetWaterfallMutationError = ErrorType<RenderErrorResponseDTO>;
@@ -105,7 +105,7 @@ export const useGetWaterfall = <
TError,
{
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
data?: BodyType<TracedetailtypesPostableWaterfallDTO>;
},
TContext
>;
@@ -114,7 +114,7 @@ export const useGetWaterfall = <
TError,
{
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
data?: BodyType<TracedetailtypesPostableWaterfallDTO>;
},
TContext
> => {

View File

@@ -5,10 +5,7 @@ import cx from 'classnames';
import { VIEW_TYPES } from 'components/LogDetail/constants';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import { ChangeViewFunctionType } from 'container/ExplorerOptions/types';
import {
getBodyDisplayString,
getSanitizedLogBody,
} from 'container/LogDetailedView/utils';
import { getSanitizedLogBody } from 'container/LogDetailedView/utils';
import { FontSize } from 'container/OptionsMenu/types';
import { useCopyLogLink } from 'hooks/logs/useCopyLogLink';
import { useIsDarkMode } from 'hooks/useDarkMode';
@@ -199,7 +196,7 @@ function ListLogView({
{updatedSelecedFields.some((field) => field.name === 'body') && (
<LogGeneralField
fieldKey="Log"
fieldValue={getBodyDisplayString(logData.body)}
fieldValue={flattenLogData.body}
linesPerRow={linesPerRow}
fontSize={fontSize}
/>

View File

@@ -69,6 +69,8 @@ export function useLogsTableColumns({
id: 'timestamp',
header: 'Timestamp',
accessorFn: (log): unknown => log.timestamp,
canBeHidden: false,
enableRemove: false,
width: { default: 170, min: 170 },
cell: ({ value }): ReactElement => {
const ts = value as string | number;
@@ -92,6 +94,7 @@ export function useLogsTableColumns({
header: 'Body',
accessorFn: (log): string => getBodyDisplayString(log.body),
canBeHidden: false,
enableRemove: false,
width: { default: '100%', min: 300 },
cell: ({ value, isActive }): ReactElement => (
<TanStackTable.Text

View File

@@ -62,6 +62,7 @@ describe('LogsFormatOptionsMenu (unit)', () => {
onSearch: jest.fn(),
onSelect: jest.fn(),
onRemove: jest.fn(),
onReorder: jest.fn(),
},
}}
/>,

View File

@@ -308,9 +308,7 @@ function TanStackTableInner<TData>(
});
const hasSingleColumn = useMemo(
() =>
effectiveColumns.filter((c) => !c.pin && c.enableRemove !== false).length <=
1,
() => effectiveColumns.filter((c) => !c.pin).length <= 1,
[effectiveColumns],
);

View File

@@ -16,7 +16,6 @@ import { useLogsTableColumns } from 'components/Logs/TableView/useLogsTableColum
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
import type { TanStackTableHandle } from 'components/TanStackTableView';
import TanStackTable from 'components/TanStackTableView';
import { useHiddenColumnIds } from 'components/TanStackTableView/useColumnStore';
import { CARD_BODY_STYLE } from 'constants/card';
import { LOCALSTORAGE } from 'constants/localStorage';
import { OptionFormatTypes } from 'constants/optionsFormatTypes';
@@ -24,13 +23,11 @@ import { QueryParams } from 'constants/query';
import { InfinityWrapperStyled } from 'container/LogsExplorerList/styles';
import { convertKeysToColumnFields } from 'container/LogsExplorerList/utils';
import { useOptionsMenu } from 'container/OptionsMenu';
import { defaultLogsSelectedColumns } from 'container/OptionsMenu/constants';
import { useCopyLogLink } from 'hooks/logs/useCopyLogLink';
import useLogDetailHandlers from 'hooks/logs/useLogDetailHandlers';
import useScrollToLog from 'hooks/logs/useScrollToLog';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { useEventSource } from 'providers/EventSource';
import { usePreferenceContext } from 'providers/preferences/context/PreferenceContextProvider';
// interfaces
import { ILog } from 'types/api/logs/log';
import { DataSource, StringOperators } from 'types/common/queryBuilder';
@@ -54,9 +51,6 @@ function LiveLogsList({
const { isConnectionLoading } = useEventSource();
const { activeLogId } = useCopyLogLink();
const { logs: logsPreferences } = usePreferenceContext();
const hiddenColumnIds = useHiddenColumnIds(LOCALSTORAGE.LOGS_LIST_COLUMNS);
const hasReconciledHiddenColumnsRef = useRef(false);
const {
activeLog,
@@ -72,7 +66,7 @@ function LiveLogsList({
[logs],
);
const { options } = useOptionsMenu({
const { options, config } = useOptionsMenu({
storageKey: LOCALSTORAGE.LOGS_LIST_OPTIONS,
dataSource: DataSource.LOGS,
aggregateOperator: StringOperators.NOOP,
@@ -83,16 +77,7 @@ function LiveLogsList({
[formattedLogs, activeLogId],
);
const selectedFields = convertKeysToColumnFields([
...defaultLogsSelectedColumns,
...options.selectColumns,
]);
const syncedSelectedColumns = useMemo(
() =>
options.selectColumns.filter(({ name }) => !hiddenColumnIds.includes(name)),
[options.selectColumns, hiddenColumnIds],
);
const selectedFields = convertKeysToColumnFields(options.selectColumns);
const logsColumns = useLogsTableColumns({
fields: selectedFields,
@@ -100,30 +85,6 @@ function LiveLogsList({
appendTo: 'end',
});
useEffect(() => {
if (hasReconciledHiddenColumnsRef.current) {
return;
}
hasReconciledHiddenColumnsRef.current = true;
if (syncedSelectedColumns.length === options.selectColumns.length) {
return;
}
logsPreferences.updateColumns(syncedSelectedColumns);
}, [logsPreferences, options.selectColumns.length, syncedSelectedColumns]);
const handleColumnRemove = useCallback(
(columnId: string) => {
const updatedColumns = options.selectColumns.filter(
({ name }) => name !== columnId,
);
logsPreferences.updateColumns(updatedColumns);
},
[options.selectColumns, logsPreferences],
);
const makeOnLogCopy = useCallback(
(log: ILog) =>
(event: MouseEvent<HTMLElement>): void => {
@@ -237,7 +198,7 @@ function LiveLogsList({
ref={ref as React.Ref<TanStackTableHandle>}
columns={logsColumns}
columnStorageKey={LOCALSTORAGE.LOGS_LIST_COLUMNS}
onColumnRemove={handleColumnRemove}
onColumnRemove={config?.addColumn?.onRemove}
plainTextCellLineClamp={options.maxLines}
cellTypographySize={options.fontSize}
data={formattedLogs}

View File

@@ -18,21 +18,19 @@ import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
import Spinner from 'components/Spinner';
import type { TanStackTableHandle } from 'components/TanStackTableView';
import TanStackTable from 'components/TanStackTableView';
import { useHiddenColumnIds } from 'components/TanStackTableView/useColumnStore';
import type { TableColumnDef } from 'components/TanStackTableView/types';
import { CARD_BODY_STYLE } from 'constants/card';
import { LOCALSTORAGE } from 'constants/localStorage';
import { QueryParams } from 'constants/query';
import EmptyLogsSearch from 'container/EmptyLogsSearch/EmptyLogsSearch';
import { LogsLoading } from 'container/LogsLoading/LogsLoading';
import { useOptionsMenu } from 'container/OptionsMenu';
import { defaultLogsSelectedColumns } from 'container/OptionsMenu/constants';
import { FontSize } from 'container/OptionsMenu/types';
import { useCopyLogLink } from 'hooks/logs/useCopyLogLink';
import useLogDetailHandlers from 'hooks/logs/useLogDetailHandlers';
import useScrollToLog from 'hooks/logs/useScrollToLog';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { usePreferenceContext } from 'providers/preferences/context/PreferenceContextProvider';
import APIError from 'types/api/error';
// interfaces
import { ILog } from 'types/api/logs/log';
@@ -69,10 +67,6 @@ function LogsExplorerList({
const [, setCopy] = useCopyToClipboard();
const isDarkMode = useIsDarkMode();
const { activeLogId } = useCopyLogLink();
const { logs: logsPreferences } = usePreferenceContext();
const hiddenColumnIds = useHiddenColumnIds(LOCALSTORAGE.LOGS_LIST_COLUMNS);
const hasReconciledHiddenColumnsRef = useRef(false);
const {
activeLog,
onAddToQuery,
@@ -81,7 +75,7 @@ function LogsExplorerList({
handleCloseLogDetail,
} = useLogDetailHandlers();
const { options } = useOptionsMenu({
const { options, config } = useOptionsMenu({
storageKey: LOCALSTORAGE.LOGS_LIST_OPTIONS,
dataSource: DataSource.LOGS,
aggregateOperator:
@@ -97,28 +91,15 @@ function LogsExplorerList({
);
const selectedFields = useMemo(
() =>
convertKeysToColumnFields([
...defaultLogsSelectedColumns,
...options.selectColumns,
]),
[options],
() => convertKeysToColumnFields(options.selectColumns),
[options.selectColumns],
);
const syncedSelectedColumns = useMemo(
() =>
options.selectColumns.filter(({ name }) => !hiddenColumnIds.includes(name)),
[options.selectColumns, hiddenColumnIds],
);
const handleColumnRemove = useCallback(
(columnId: string) => {
const updatedColumns = options.selectColumns.filter(
({ name }) => name !== columnId,
);
logsPreferences.updateColumns(updatedColumns);
const handleColumnOrderChange = useCallback(
(cols: TableColumnDef<ILog>[]): void => {
config?.addColumn?.onReorder(cols.map((c) => c.id));
},
[options.selectColumns, logsPreferences],
[config],
);
const logsColumns = useLogsTableColumns({
@@ -161,20 +142,6 @@ function LogsExplorerList({
}
}, [isLoading, isFetching, isError, logs.length]);
useEffect(() => {
if (hasReconciledHiddenColumnsRef.current) {
return;
}
hasReconciledHiddenColumnsRef.current = true;
if (syncedSelectedColumns.length === options.selectColumns.length) {
return;
}
logsPreferences.updateColumns(syncedSelectedColumns);
}, [logsPreferences, options.selectColumns.length, syncedSelectedColumns]);
const getItemContent = useCallback(
(_: number, log: ILog): JSX.Element => {
if (options.format === 'raw') {
@@ -237,7 +204,8 @@ function LogsExplorerList({
ref={ref as React.Ref<TanStackTableHandle>}
columns={logsColumns}
columnStorageKey={LOCALSTORAGE.LOGS_LIST_COLUMNS}
onColumnRemove={handleColumnRemove}
onColumnRemove={config?.addColumn?.onRemove}
onColumnOrderChange={handleColumnOrderChange}
plainTextCellLineClamp={options.maxLines}
cellTypographySize={options.fontSize}
data={logs}

View File

@@ -263,7 +263,7 @@ function External(): JSX.Element {
timestamp: selectedTimeStamp,
domainName: selectedData?.address || '',
isError: true,
stepInterval,
stepInterval: 300,
safeNavigate,
})}
/>
@@ -306,7 +306,7 @@ function External(): JSX.Element {
timestamp: selectedTimeStamp,
domainName: selectedData?.address,
isError: false,
stepInterval,
stepInterval: 300,
safeNavigate,
})}
/>
@@ -352,7 +352,7 @@ function External(): JSX.Element {
timestamp: selectedTimeStamp,
domainName: selectedData?.address,
isError: false,
stepInterval,
stepInterval: 300,
safeNavigate,
})}
/>
@@ -395,7 +395,7 @@ function External(): JSX.Element {
timestamp: selectedTimeStamp,
domainName: selectedData?.address,
isError: false,
stepInterval,
stepInterval: 300,
safeNavigate,
})}
/>

View File

@@ -151,7 +151,7 @@ export function onViewAPIMonitoringPopupClick({
safeNavigate,
}: OnViewAPIMonitoringPopupClickProps): (e?: React.MouseEvent) => void {
return (e?: React.MouseEvent): void => {
const endTime = timestamp;
const endTime = timestamp + (stepInterval || 60);
const startTime = timestamp - (stepInterval || 60);
const filters = {
items: [

View File

@@ -0,0 +1,79 @@
import { TelemetryFieldKey } from 'api/v5/v5';
import {
defaultLogsSelectedColumns,
ensureLogsRequiredColumns,
} from '../constants';
const TIMESTAMP = defaultLogsSelectedColumns.find(
(c) => c.name === 'timestamp',
);
const BODY = defaultLogsSelectedColumns.find((c) => c.name === 'body');
if (!TIMESTAMP || !BODY) {
throw new Error('defaults missing timestamp/body — test fixture invalid');
}
const ATTR_A: TelemetryFieldKey = {
name: 'service.name',
signal: 'logs',
fieldContext: 'resource',
fieldDataType: 'string',
};
const ATTR_B: TelemetryFieldKey = {
name: 'severity_text',
signal: 'logs',
fieldContext: 'log',
fieldDataType: 'string',
};
describe('ensureLogsRequiredColumns', () => {
it('prepends both timestamp + body to an empty list', () => {
expect(ensureLogsRequiredColumns([])).toStrictEqual([TIMESTAMP, BODY]);
});
it('prepends only `body` when `timestamp` is already present', () => {
expect(ensureLogsRequiredColumns([TIMESTAMP, ATTR_A])).toStrictEqual([
BODY,
TIMESTAMP,
ATTR_A,
]);
});
it('prepends only `timestamp` when `body` is already present', () => {
expect(ensureLogsRequiredColumns([BODY, ATTR_A])).toStrictEqual([
TIMESTAMP,
BODY,
ATTR_A,
]);
});
it('returns the same array when both are present (no duplicates, original order preserved)', () => {
const input = [TIMESTAMP, BODY, ATTR_A, ATTR_B];
expect(ensureLogsRequiredColumns(input)).toBe(input);
});
it('preserves a non-default order when both are present', () => {
const input = [ATTR_A, BODY, ATTR_B, TIMESTAMP];
expect(ensureLogsRequiredColumns(input)).toStrictEqual(input);
});
it('prepends both when neither is present in a list of user attributes', () => {
expect(ensureLogsRequiredColumns([ATTR_A, ATTR_B])).toStrictEqual([
TIMESTAMP,
BODY,
ATTR_A,
ATTR_B,
]);
});
it('does not duplicate if a required column appears twice in the input', () => {
// Tolerant of malformed input — invariant only adds *missing* required
// columns; it does not deduplicate existing entries (that's a separate
// concern, not its job).
const input = [BODY, BODY, ATTR_A];
const result = ensureLogsRequiredColumns(input);
expect(result.filter((c) => c.name === 'timestamp')).toHaveLength(1);
expect(result[0]).toStrictEqual(TIMESTAMP);
});
});

View File

@@ -35,6 +35,32 @@ export const defaultLogsSelectedColumns: TelemetryFieldKey[] = [
},
];
const LOGS_REQUIRED_COLUMNS = ['timestamp', 'body'] as const;
/**
* Always-on invariant: every logs selectColumns array must contain `body` and
* `timestamp`. Applied at both loader and writer boundaries so the picker, the
* table, and persisted state can never diverge into a "missing required
* column" state.
*/
export function ensureLogsRequiredColumns(
columns: TelemetryFieldKey[],
): TelemetryFieldKey[] {
const missing = LOGS_REQUIRED_COLUMNS.filter(
(name) => !columns.some((c) => c.name === name),
);
if (missing.length === 0) {
return columns;
}
const defaultsByName = new Map(
defaultLogsSelectedColumns.map((c) => [c.name, c]),
);
const prepended = missing
.map((name) => defaultsByName.get(name))
.filter((c): c is TelemetryFieldKey => c !== undefined);
return [...prepended, ...columns];
}
export const defaultTraceSelectedColumns: TelemetryFieldKey[] = [
{
name: 'service.name',

View File

@@ -40,5 +40,6 @@ export type OptionsMenuConfig = {
isFetching: boolean;
value: TelemetryFieldKey[];
onRemove: (key: string) => void;
onReorder: (orderedIds: string[]) => void;
};
};

View File

@@ -187,30 +187,6 @@ const useOptionsMenu = ({
searchedAttributesDataV5?.data.data.keys || {},
).flat();
if (searchedAttributesDataList.length) {
if (dataSource === DataSource.LOGS) {
const logsSelectedColumns: TelemetryFieldKey[] =
defaultLogsSelectedColumns.map((e) => ({
...e,
name: e.name,
signal: e.signal as SignalType,
fieldContext: e.fieldContext as FieldContext,
fieldDataType: e.fieldDataType as FieldDataType,
}));
return [
...logsSelectedColumns,
...searchedAttributesDataList
.filter((attribute) => attribute.name !== 'body')
// eslint-disable-next-line sonarjs/no-identical-functions
.map((e) => ({
...e,
name: e.name,
signal: e.signal as SignalType,
fieldContext: e.fieldContext as FieldContext,
fieldDataType: e.fieldDataType as FieldDataType,
})),
];
}
// eslint-disable-next-line sonarjs/no-identical-functions
return searchedAttributesDataList.map((e) => ({
...e,
name: e.name,
@@ -297,24 +273,9 @@ const useOptionsMenu = ({
return [...acc, column];
}, [] as TelemetryFieldKey[]);
const optionsData: OptionsQuery = {
...defaultOptionsQuery,
selectColumns: newSelectedColumns,
format: preferences?.formatting?.format || defaultOptionsQuery.format,
maxLines: preferences?.formatting?.maxLines || defaultOptionsQuery.maxLines,
fontSize: preferences?.formatting?.fontSize || defaultOptionsQuery.fontSize,
};
updateColumns(newSelectedColumns);
handleRedirectWithOptionsData(optionsData);
},
[
searchedAttributeKeys,
selectedColumnKeys,
preferences,
handleRedirectWithOptionsData,
updateColumns,
],
[searchedAttributeKeys, selectedColumnKeys, preferences, updateColumns],
);
const handleRemoveSelectedColumn = useCallback(
@@ -327,27 +288,12 @@ const useOptionsMenu = ({
notifications.error({
message: 'There must be at least one selected column',
});
} else {
const optionsData: OptionsQuery = {
...defaultOptionsQuery,
selectColumns: newSelectedColumns || [],
format: preferences?.formatting?.format || defaultOptionsQuery.format,
maxLines:
preferences?.formatting?.maxLines || defaultOptionsQuery.maxLines,
fontSize:
preferences?.formatting?.fontSize || defaultOptionsQuery.fontSize,
};
updateColumns(newSelectedColumns || []);
handleRedirectWithOptionsData(optionsData);
return;
}
updateColumns(newSelectedColumns || []);
},
[
dataSource,
notifications,
preferences,
handleRedirectWithOptionsData,
updateColumns,
],
[dataSource, notifications, preferences, updateColumns],
);
const handleFormatChange = useCallback(
@@ -414,6 +360,18 @@ const useOptionsMenu = ({
setSearchText(value);
}, []);
const reorderSelectColumns = useCallback(
(orderedIds: string[]): void => {
const current = preferences?.columns ?? [];
const byName = new Map(current.map((f) => [f.name, f]));
const reordered = orderedIds
.map((id) => byName.get(id))
.filter((f): f is TelemetryFieldKey => f !== undefined);
updateColumns(reordered);
},
[preferences, updateColumns],
);
const handleFocus = (): void => {
setIsFocused(true);
};
@@ -436,6 +394,7 @@ const useOptionsMenu = ({
onSelect: handleSelectColumns,
onRemove: handleRemoveSelectedColumn,
onSearch: handleSearchAttribute,
onReorder: reorderSelectColumns,
},
format: {
value: preferences?.formatting?.format || defaultOptionsQuery.format,
@@ -457,6 +416,7 @@ const useOptionsMenu = ({
handleSelectColumns,
handleRemoveSelectedColumn,
handleSearchAttribute,
reorderSelectColumns,
handleFormatChange,
handleMaxLinesChange,
handleFontSizeChange,

View File

@@ -30,10 +30,7 @@ import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { Pagination } from 'hooks/queryPagination';
import { getDefaultPaginationConfig } from 'hooks/queryPagination/utils';
import useDragColumns from 'hooks/useDragColumns';
import { getDraggedColumns } from 'hooks/useDragColumns/utils';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { RowData } from 'lib/query/createTableColumnsFromQuery';
import { ArrowUp10, Minus } from '@signozhq/icons';
import { useTimezone } from 'providers/Timezone';
import { AppState } from 'store/reducers';
@@ -85,10 +82,6 @@ function ListView({
},
});
const { draggedColumns, onDragColumns } = useDragColumns<RowData>(
LOCALSTORAGE.TRACES_LIST_COLUMNS,
);
const { queryData: paginationQueryData } = useUrlQueryData<Pagination>(
QueryParams.pagination,
);
@@ -100,6 +93,19 @@ function ListView({
[stagedQuery, orderBy],
);
// TEMP — remove after traces moves to TanStack table.
// - Drag updates selectColumns; raw queryKey would churn on reorder.
// - Trace API fetches only listed columns → add/remove must refetch.
// - Sorted-name signature: stable on reorder, changes on add/remove.
const selectColumnsSignature = useMemo(
() =>
(options?.selectColumns ?? [])
.map((c) => c.name)
.sort()
.join(','),
[options?.selectColumns],
);
const queryKey = useMemo(
() => [
REACT_QUERY_KEY.GET_QUERY_RANGE,
@@ -109,7 +115,7 @@ function ListView({
stagedQuery,
panelType,
paginationConfig,
options?.selectColumns,
selectColumnsSignature,
orderBy,
],
[
@@ -117,7 +123,7 @@ function ListView({
panelType,
globalSelectedTime,
paginationConfig,
options?.selectColumns,
selectColumnsSignature,
maxTime,
minTime,
orderBy,
@@ -182,13 +188,14 @@ function ListView({
const { formatTimezoneAdjustedTimestamp } = useTimezone();
const columns = useMemo(() => {
const updatedColumns = getListColumns(
options?.selectColumns || [],
formatTimezoneAdjustedTimestamp,
);
return getDraggedColumns(updatedColumns, draggedColumns);
}, [options?.selectColumns, formatTimezoneAdjustedTimestamp, draggedColumns]);
const columns = useMemo(
() =>
getListColumns(
options?.selectColumns || [],
formatTimezoneAdjustedTimestamp,
),
[options?.selectColumns, formatTimezoneAdjustedTimestamp],
);
const transformedQueryTableData = useMemo(
() => transformDataWithDate(queryTableData) || [],
@@ -196,9 +203,16 @@ function ListView({
);
const handleDragColumn = useCallback(
(fromIndex: number, toIndex: number) =>
onDragColumns(columns, fromIndex, toIndex),
[columns, onDragColumns],
(fromIndex: number, toIndex: number): void => {
const reordered = [...columns];
const [moved] = reordered.splice(fromIndex, 1);
reordered.splice(toIndex, 0, moved);
const orderedIds = reordered
.map((c) => String(('dataIndex' in c && c.dataIndex) || c.key || ''))
.filter(Boolean);
config?.addColumn?.onReorder(orderedIds);
},
[columns, config],
);
const handleOrderChange = useCallback((value: string) => {

View File

@@ -3,7 +3,6 @@ import { useQueryClient } from 'react-query';
import * as Sentry from '@sentry/react';
import getLocalStorageKey from 'api/browser/localstorage/get';
import setLocalStorageApi from 'api/browser/localstorage/set';
import { TelemetryFieldKey } from 'api/v5/v5';
import cx from 'classnames';
import ExplorerCard from 'components/ExplorerCard/ExplorerCard';
import QueryCancelledPlaceholder from 'components/QueryCancelledPlaceholder';
@@ -15,12 +14,6 @@ import { PANEL_TYPES } from 'constants/queryBuilder';
import { usePageActions } from 'container/AIAssistant/pageActions/usePageActions';
import LogExplorerQuerySection from 'container/LogExplorerQuerySection';
import LogsExplorerViewsContainer from 'container/LogsExplorerViews';
import {
defaultLogsSelectedColumns,
defaultOptionsQuery,
URL_OPTIONS,
} from 'container/OptionsMenu/constants';
import { OptionsQuery } from 'container/OptionsMenu/types';
import LeftToolbarActions from 'container/QueryBuilder/components/ToolbarActions/LeftToolbarActions';
import RightToolbarActions from 'container/QueryBuilder/components/ToolbarActions/RightToolbarActions';
import Toolbar from 'container/Toolbar/Toolbar';
@@ -31,11 +24,9 @@ import {
useHandleExplorerTabChange,
} from 'hooks/useHandleExplorerTabChange';
import { useIsAIAssistantEnabled } from 'hooks/useIsAIAssistantEnabled';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { defaultTo, isEmpty, isEqual, isNull } from 'lodash-es';
import { defaultTo, isEmpty, isNull } from 'lodash-es';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { EventSourceProvider } from 'providers/EventSource';
import { usePreferenceContext } from 'providers/preferences/context/PreferenceContextProvider';
import { Warning } from 'types/api';
import { DataSource } from 'types/common/queryBuilder';
import {
@@ -62,8 +53,6 @@ function LogsExplorer(): JSX.Element {
const [selectedView, setSelectedView] = useState<ExplorerViews>(
() => panelTypeToExplorerView[panelTypesFromUrl],
);
const { logs } = usePreferenceContext();
const { preferences } = logs;
const [showFilters, setShowFilters] = useState<boolean>(() => {
const localStorageValue = getLocalStorageKey(
@@ -182,116 +171,6 @@ function LogsExplorer(): JSX.Element {
setShowFilters((prev) => !prev);
};
const { redirectWithQuery: redirectWithOptionsData } =
useUrlQueryData<OptionsQuery>(URL_OPTIONS, defaultOptionsQuery);
// Get and parse stored columns from localStorage
const logListOptionsFromLocalStorage = useMemo(() => {
const data = getLocalStorageKey(LOCALSTORAGE.LOGS_LIST_OPTIONS);
if (!data) {
return null;
}
try {
return JSON.parse(data);
} catch {
return null;
}
}, []);
// Check if the columns have the required columns (timestamp, body)
const hasRequiredColumns = useCallback(
(columns?: TelemetryFieldKey[] | null): boolean => {
if (!columns?.length) {
return false;
}
const hasTimestamp = columns.some((col) => col.name === 'timestamp');
const hasBody = columns.some((col) => col.name === 'body');
return hasTimestamp && hasBody;
},
[],
);
// Merge the columns with the required columns (timestamp, body) if missing
const mergeWithRequiredColumns = useCallback(
(columns: TelemetryFieldKey[]): TelemetryFieldKey[] => [
// Add required columns (timestamp, body) if missing
...(!hasRequiredColumns(columns) ? defaultLogsSelectedColumns : []),
...columns,
],
[hasRequiredColumns],
);
// Migrate the options query to the new format
const migrateOptionsQuery = useCallback(
(query: OptionsQuery): OptionsQuery => {
// Skip if already migrated
if (query.version) {
return query;
}
if (logListOptionsFromLocalStorage?.version) {
return logListOptionsFromLocalStorage;
}
// Case 1: we have localStorage columns
if (logListOptionsFromLocalStorage?.selectColumns?.length > 0) {
return {
...query,
version: 1,
selectColumns: mergeWithRequiredColumns(
logListOptionsFromLocalStorage.selectColumns,
),
};
}
// Case 2: No query columns in localStorage in but query has columns
if (query.selectColumns.length > 0) {
return {
...query,
version: 1,
selectColumns: mergeWithRequiredColumns(query.selectColumns),
};
}
// Case 3: No columns anywhere, use defaults
return {
...query,
version: 1,
selectColumns: defaultLogsSelectedColumns,
};
},
[mergeWithRequiredColumns, logListOptionsFromLocalStorage],
);
useEffect(() => {
if (!preferences) {
return;
}
const migratedQuery = migrateOptionsQuery({
selectColumns: preferences.columns || defaultLogsSelectedColumns,
maxLines: preferences.formatting?.maxLines || defaultOptionsQuery.maxLines,
format: preferences.formatting?.format || defaultOptionsQuery.format,
fontSize: preferences.formatting?.fontSize || defaultOptionsQuery.fontSize,
version: preferences.formatting?.version,
});
// Only redirect if the query was actually modified
if (
!isEqual(migratedQuery, {
selectColumns: preferences?.columns,
maxLines: preferences?.formatting?.maxLines,
format: preferences?.formatting?.format,
fontSize: preferences?.formatting?.fontSize,
version: preferences?.formatting?.version,
})
) {
redirectWithOptionsData(migratedQuery);
}
}, [migrateOptionsQuery, preferences, redirectWithOptionsData]);
const toolbarViews = useMemo(
() => ({
list: {

View File

@@ -108,7 +108,9 @@ describe('PreferencesProvider integration', () => {
},
);
expect(Number(screen.getByTestId('logs-columns-len').textContent)).toBe(1);
// Loader's ensureLogsRequiredColumns prepends timestamp + body, so the
// 1 column in localStorage becomes 3 in preferences.
expect(Number(screen.getByTestId('logs-columns-len').textContent)).toBe(3);
});
it('direct mode updateColumns persists to localStorage', async () => {
@@ -126,8 +128,11 @@ describe('PreferencesProvider integration', () => {
const stored = getLocalStorageJSON<LogsLocalOptions>(
LOCALSTORAGE.LOGS_LIST_OPTIONS,
);
// Writer's ensureLogsRequiredColumns prepends `body` when only
// `timestamp` was passed in (defaults.slice(0,1) is just timestamp).
expect(stored?.selectColumns).toStrictEqual([
defaultLogsSelectedColumns[0] as TelemetryFieldKey,
defaultLogsSelectedColumns[1] as TelemetryFieldKey, // body
defaultLogsSelectedColumns[0] as TelemetryFieldKey, // timestamp
]);
});
@@ -183,7 +188,9 @@ describe('PreferencesProvider integration', () => {
value: originalLocation,
});
expect(Number(screen.getByTestId('logs-columns-len').textContent)).toBe(1);
// Loader's ensureLogsRequiredColumns prepends timestamp + body, so the
// URL's 1 column becomes 3 in preferences.
expect(Number(screen.getByTestId('logs-columns-len').textContent)).toBe(3);
});
it('updateFormatting persists to localStorage in direct mode', async () => {

View File

@@ -1,7 +1,10 @@
import { TelemetryFieldKey } from 'api/v5/v5';
import { LOCALSTORAGE } from 'constants/localStorage';
import { LogViewMode } from 'container/LogsTable';
import { defaultOptionsQuery } from 'container/OptionsMenu/constants';
import {
defaultLogsSelectedColumns,
defaultOptionsQuery,
} from 'container/OptionsMenu/constants';
import { FontSize } from 'container/OptionsMenu/types';
import {
FormattingOptions,
@@ -85,18 +88,21 @@ describe('logsUpdaterConfig', () => {
logsUpdater.updateColumns(newColumns, PreferenceMode.DIRECT);
// Writer guards body+timestamp via ensureLogsRequiredColumns invariant
const guardedColumns = [...defaultLogsSelectedColumns, ...newColumns];
// Should update URL
expect(redirectWithOptionsData).toHaveBeenCalledWith({
...defaultOptionsQuery,
...mockPreferences.formatting,
selectColumns: newColumns,
selectColumns: guardedColumns,
});
// Should update localStorage
// Should update localStorage with the guarded shape
const storedData = JSON.parse(
mockLocalStorage[LOCALSTORAGE.LOGS_LIST_OPTIONS],
);
expect(storedData.selectColumns).toStrictEqual(newColumns);
expect(storedData.selectColumns).toStrictEqual(guardedColumns);
expect(storedData.maxLines).toBe(1); // Should preserve other fields
// Should not update saved view preferences

View File

@@ -1,4 +1,5 @@
import { renderHook, waitFor } from '@testing-library/react';
import { defaultLogsSelectedColumns } from 'container/OptionsMenu/constants';
import { DataSource } from 'types/common/queryBuilder';
import logsLoaderConfig from '../configs/logsLoaderConfig';
@@ -60,9 +61,9 @@ describe('usePreferenceLoader', () => {
expect(result.current.loading).toBe(false);
});
// Should have loaded from local storage (highest priority)
// Loader wraps with ensureLogsRequiredColumns — body+timestamp always prepended
expect(result.current.preferences).toStrictEqual({
columns: [{ name: 'local-column' }],
columns: [...defaultLogsSelectedColumns, { name: 'local-column' }],
formatting: { maxLines: 5, format: 'table', fontSize: 'medium', version: 1 },
});
expect(result.current.error).toBeNull();

View File

@@ -3,7 +3,10 @@ import getLocalStorageKey from 'api/browser/localstorage/get';
import setLocalStorageKey from 'api/browser/localstorage/set';
import { TelemetryFieldKey } from 'api/v5/v5';
import { LOCALSTORAGE } from 'constants/localStorage';
import { defaultOptionsQuery } from 'container/OptionsMenu/constants';
import {
defaultOptionsQuery,
ensureLogsRequiredColumns,
} from 'container/OptionsMenu/constants';
import { FontSize, OptionsQuery } from 'container/OptionsMenu/types';
import { FormattingOptions, PreferenceMode, Preferences } from '../types';
@@ -18,11 +21,12 @@ const getLogsUpdaterConfig = (
updateFormatting: (newFormatting: FormattingOptions, mode: string) => void;
} => ({
updateColumns: (newColumns: TelemetryFieldKey[], mode: string): void => {
const guardedColumns = ensureLogsRequiredColumns(newColumns);
if (mode === PreferenceMode.SAVED_VIEW) {
setSavedViewPreferences((prev) => {
if (!prev) {
return {
columns: newColumns,
columns: guardedColumns,
formatting: {
maxLines: 1,
format: 'table',
@@ -34,7 +38,7 @@ const getLogsUpdaterConfig = (
return {
...prev,
columns: newColumns,
columns: guardedColumns,
};
});
}
@@ -44,14 +48,14 @@ const getLogsUpdaterConfig = (
redirectWithOptionsData({
...defaultOptionsQuery,
...preferences?.formatting,
selectColumns: newColumns,
selectColumns: guardedColumns,
});
// Also update local storage
const local = JSON.parse(
getLocalStorageKey(LOCALSTORAGE.LOGS_LIST_OPTIONS) || '{}',
);
local.selectColumns = newColumns;
local.selectColumns = guardedColumns;
setLocalStorageKey(LOCALSTORAGE.LOGS_LIST_OPTIONS, JSON.stringify(local));
}
},

View File

@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react';
import { TelemetryFieldKey } from 'api/v5/v5';
import { ensureLogsRequiredColumns } from 'container/OptionsMenu/constants';
import { has } from 'lodash-es';
import { DataSource } from 'types/common/queryBuilder';
@@ -51,7 +52,11 @@ function logsPreferencesLoader(): {
columns: TelemetryFieldKey[];
formatting: FormattingOptions;
} {
return preferencesLoader(logsLoaderConfig);
const result = preferencesLoader<{
columns: TelemetryFieldKey[];
formatting: FormattingOptions;
}>(logsLoaderConfig);
return { ...result, columns: ensureLogsRequiredColumns(result.columns) };
}
function tracesPreferencesLoader(): {

View File

@@ -1,7 +1,10 @@
/* eslint-disable sonarjs/cognitive-complexity */
import { useEffect, useState } from 'react';
import { TelemetryFieldKey } from 'api/v5/v5';
import { defaultLogsSelectedColumns } from 'container/OptionsMenu/constants';
import {
defaultLogsSelectedColumns,
ensureLogsRequiredColumns,
} from 'container/OptionsMenu/constants';
import { defaultSelectedColumns as defaultTracesSelectedColumns } from 'container/TracesExplorer/ListView/configs';
import { useGetAllViews } from 'hooks/saveViews/useGetAllViews';
import { DataSource } from 'types/common/queryBuilder';
@@ -54,9 +57,10 @@ export function usePreferenceSync({
let columns: TelemetryFieldKey[] = [];
let formatting: FormattingOptions | undefined;
if (dataSource === DataSource.LOGS) {
columns =
columns = ensureLogsRequiredColumns(
updateExtraDataSelectColumns(parsedExtraData?.selectColumns) ||
defaultLogsSelectedColumns;
defaultLogsSelectedColumns,
);
formatting = {
maxLines: parsedExtraData?.maxLines ?? 1,
format: parsedExtraData?.format ?? 'table',

View File

@@ -5,7 +5,7 @@ import (
"github.com/SigNoz/signoz/pkg/http/handler"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/spantypes"
"github.com/SigNoz/signoz/pkg/types/tracedetailtypes"
"github.com/gorilla/mux"
)
@@ -17,9 +17,9 @@ func (provider *provider) addTraceDetailRoutes(router *mux.Router) error {
Tags: []string{"tracedetail"},
Summary: "Get waterfall view for a trace",
Description: "Returns the waterfall view of spans for a given trace ID with tree structure, metadata, and windowed pagination",
Request: new(spantypes.PostableWaterfall),
Request: new(tracedetailtypes.PostableWaterfall),
RequestContentType: "application/json",
Response: new(spantypes.GettableWaterfallTrace),
Response: new(tracedetailtypes.GettableWaterfallTrace),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},

View File

@@ -6,6 +6,7 @@ import (
"github.com/SigNoz/signoz/pkg/statsreporter"
citypes "github.com/SigNoz/signoz/pkg/types/cloudintegrationtypes"
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
@@ -42,14 +43,23 @@ type Module interface {
GetService(ctx context.Context, orgID valuer.UUID, serviceID citypes.ServiceID, provider citypes.CloudProviderType, integrationID valuer.UUID) (*citypes.Service, error)
// CreateService creates a new service for a cloud integration account.
CreateService(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, service *citypes.CloudIntegrationService, provider citypes.CloudProviderType) error
CreateService(ctx context.Context, orgID valuer.UUID, service *citypes.CloudIntegrationService, provider citypes.CloudProviderType) error
// UpdateService updates cloud integration service
UpdateService(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, service *citypes.CloudIntegrationService, provider citypes.CloudProviderType) error
UpdateService(ctx context.Context, orgID valuer.UUID, service *citypes.CloudIntegrationService, provider citypes.CloudProviderType) error
// AgentCheckIn is called by agent to send heartbeat and get latest config in response.
AgentCheckIn(ctx context.Context, orgID valuer.UUID, provider citypes.CloudProviderType, req *citypes.AgentCheckInRequest) (*citypes.AgentCheckInResponse, error)
// GetDashboardByID returns dashboard JSON for a given dashboard id.
// this only returns the dashboard when the service (embedded in dashboard id) is enabled
// in the org for any cloud integration account
GetDashboardByID(ctx context.Context, orgID valuer.UUID, id string) (*dashboardtypes.Dashboard, error)
// ListDashboards returns list of dashboards across all connected cloud integration accounts
// for enabled services in the org. This list gets added to dashboard list page
ListDashboards(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error)
statsreporter.StatsCollector
}

View File

@@ -122,7 +122,7 @@
"type": "QUERY"
}
},
"version": "v5",
"version": "v4",
"widgets": [
{
"bucketCount": 30,
@@ -140,19 +140,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ApplicationELB_TargetResponseTime_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ApplicationELB_TargetResponseTime_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ApplicationELB_TargetResponseTime_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND TargetGroup NOT EXISTS AND AvailabilityZone NOT EXISTS)"
"filters": {
"items": [
{
"id": "b282d9f1",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "71837c70",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "5bfcc581",
"key": {
"dataType": "string",
"id": "TargetGroup--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TargetGroup",
"type": "tag"
},
"op": "nexists",
"value": ""
},
{
"id": "a9e33e08",
"key": {
"dataType": "string",
"id": "AvailabilityZone--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "AvailabilityZone",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -181,14 +236,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{LoadBalancer}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -290,19 +346,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ApplicationELB_RequestCount_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ApplicationELB_RequestCount_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ApplicationELB_RequestCount_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND AvailabilityZone NOT EXISTS AND TargetGroup NOT EXISTS)"
"filters": {
"items": [
{
"id": "448b551a",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "a8821216",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "f5a62c5a",
"key": {
"dataType": "string",
"id": "AvailabilityZone--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "AvailabilityZone",
"type": "tag"
},
"op": "nexists",
"value": ""
},
{
"id": "25e8abc8",
"key": {
"dataType": "string",
"id": "TargetGroup--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TargetGroup",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -331,14 +442,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{LoadBalancer}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -440,19 +552,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ApplicationELB_HTTPCode_Target_5XX_Count_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ApplicationELB_HTTPCode_Target_5XX_Count_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ApplicationELB_HTTPCode_Target_5XX_Count_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND TargetGroup NOT EXISTS AND AvailabilityZone NOT EXISTS)"
"filters": {
"items": [
{
"id": "702a8765",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "32985f2d",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "e4cf3d8b",
"key": {
"dataType": "string",
"id": "TargetGroup--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TargetGroup",
"type": "tag"
},
"op": "nexists",
"value": ""
},
{
"id": "234c77fd",
"key": {
"dataType": "string",
"id": "AvailabilityZone--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "AvailabilityZone",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -481,14 +648,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{LoadBalancer}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -590,19 +758,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ApplicationELB_HTTPCode_ELB_5XX_Count_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ApplicationELB_HTTPCode_ELB_5XX_Count_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ApplicationELB_HTTPCode_ELB_5XX_Count_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND AvailabilityZone NOT EXISTS)"
"filters": {
"items": [
{
"id": "5807a1e3",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "0dd63d0c",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "31ccfbae",
"key": {
"dataType": "string",
"id": "AvailabilityZone--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "AvailabilityZone",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -631,14 +841,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{LoadBalancer}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -740,19 +951,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ApplicationELB_ActiveConnectionCount_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ApplicationELB_ActiveConnectionCount_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ApplicationELB_ActiveConnectionCount_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND AvailabilityZone NOT EXISTS)"
"filters": {
"items": [
{
"id": "72c256c0",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "b433c2a1",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "8f5e7de0",
"key": {
"dataType": "string",
"id": "AvailabilityZone--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "AvailabilityZone",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -781,14 +1034,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{LoadBalancer}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -890,19 +1144,70 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ApplicationELB_TargetConnectionErrorCount_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ApplicationELB_TargetConnectionErrorCount_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ApplicationELB_TargetConnectionErrorCount_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND TargetGroup NOT EXISTS AND AvailabilityZone NOT EXISTS)"
"filters": {
"items": [
{
"id": "9226a37c",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "c3ff0c8f",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "e3317bc2",
"key": {
"dataType": "",
"isColumn": false,
"key": "TargetGroup",
"type": ""
},
"op": "nexists",
"value": ""
},
{
"id": "4e5c2324",
"key": {
"dataType": "",
"isColumn": false,
"key": "AvailabilityZone",
"type": ""
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -931,14 +1236,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{LoadBalancer}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -1040,19 +1346,48 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ApplicationELB_ConsumedLCUs_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ApplicationELB_ConsumedLCUs_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ApplicationELB_ConsumedLCUs_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "20627274",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "cd861e27",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1081,14 +1416,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{LoadBalancer}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -1190,19 +1526,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ApplicationELB_ProcessedBytes_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ApplicationELB_ProcessedBytes_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ApplicationELB_ProcessedBytes_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND AvailabilityZone NOT EXISTS)"
"filters": {
"items": [
{
"id": "7d4a3494",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "3c307858",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "fbca8724",
"key": {
"dataType": "string",
"id": "AvailabilityZone--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "AvailabilityZone",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1231,14 +1609,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{LoadBalancer}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -1340,19 +1719,48 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ApplicationELB_PeakLCUs_sum",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ApplicationELB_PeakLCUs_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ApplicationELB_PeakLCUs_sum",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "a416e862",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "ed7d0a39",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1381,14 +1789,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{LoadBalancer}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []

View File

@@ -94,7 +94,7 @@
"type": "QUERY"
}
},
"version": "v5",
"version": "v4",
"widgets": [
{
"bucketCount": 30,
@@ -112,19 +112,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_EC2_CPUUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_EC2_CPUUtilization_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_EC2_CPUUtilization_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(service.instance.id != '' AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "d302d50d",
"key": {
"dataType": "string",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
"value": ""
},
{
"id": "e6c54e87",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "7907211a",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -153,14 +195,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{service.instance.id}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -262,19 +305,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_EC2_CPUCreditUsage_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_EC2_CPUCreditUsage_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_EC2_CPUCreditUsage_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(service.instance.id != '' AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "30ded0dc",
"key": {
"dataType": "string",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
"value": ""
},
{
"id": "c935f6ec",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "d092fef8",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -303,14 +388,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{service.instance.id}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -412,19 +498,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_EC2_EBSReadBytes_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_EC2_EBSReadBytes_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_EC2_EBSReadBytes_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(service.instance.id != '' AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "a5fbfa4a",
"key": {
"dataType": "string",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
"value": ""
},
{
"id": "87071f13",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "c84a88c4",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -453,29 +581,72 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{service.instance.id}} - Reads",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
},
{
"aggregations": [
{
"metricName": "aws_EC2_EBSWriteBytes_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_EC2_EBSWriteBytes_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_EC2_EBSWriteBytes_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "B",
"filter": {
"expression": "(service.instance.id != '' AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "4d10ca4b",
"key": {
"dataType": "string",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
"value": ""
},
{
"id": "fc2db932",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "a3fd74c0",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -504,14 +675,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{service.instance.id}} - Writes",
"limit": null,
"orderBy": [],
"queryName": "B",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -613,19 +785,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_EC2_EBSReadOps_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_EC2_EBSReadOps_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_EC2_EBSReadOps_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(service.instance.id != '' AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "85d84806",
"key": {
"dataType": "string",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
"value": ""
},
{
"id": "f2074606",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "134c7ca9",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -654,29 +868,72 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{service.instance.id}} - Reads",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
},
{
"aggregations": [
{
"metricName": "aws_EC2_EBSWriteOps_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_EC2_EBSWriteOps_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_EC2_EBSWriteOps_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "B",
"filter": {
"expression": "(service.instance.id != '' AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "47e0c00f",
"key": {
"dataType": "string",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
"value": ""
},
{
"id": "0a157dfe",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "a7d1e8df",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -705,14 +962,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{service.instance.id}} - Writes",
"limit": null,
"orderBy": [],
"queryName": "B",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -814,19 +1072,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_EC2_NetworkIn_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_EC2_NetworkIn_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_EC2_NetworkIn_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(service.instance.id != '' AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "12d6748d",
"key": {
"dataType": "string",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
"value": ""
},
{
"id": "df3a8da1",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "81ec53f4",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -855,14 +1155,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{service.instance.id}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -964,19 +1265,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_EC2_NetworkOut_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_EC2_NetworkOut_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_EC2_NetworkOut_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(service.instance.id != '' AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "d301aaa7",
"key": {
"dataType": "string",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
"value": ""
},
{
"id": "e8afaa3b",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "d67487ab",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1005,14 +1348,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{service.instance.id}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []

View File

@@ -1,6 +1,6 @@
{
"description": "View key ECS ContainerInsights metrics with an out of the box dashboard.",
"image": "data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20width%3D%2280px%22%20height%3D%2280px%22%20viewBox%3D%220%200%2080%2080%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%3C!--%20Generator%3A%20Sketch%2064%20(93537)%20-%20https%3A%2F%2Fsketch.com%20--%3E%3Ctitle%3EIcon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%3C%2Ftitle%3E%3Cdesc%3ECreated%20with%20Sketch.%3C%2Fdesc%3E%3Cdefs%3E%3ClinearGradient%20x1%3D%220%25%22%20y1%3D%22100%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%20id%3D%22linearGradient-1%22%3E%3Cstop%20stop-color%3D%22%23C8511B%22%20offset%3D%220%25%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23FF9900%22%20offset%3D%22100%25%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20id%3D%22Icon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%22%20stroke%3D%22none%22%20stroke-width%3D%221%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cg%20id%3D%22Icon-Architecture-BG%2F64%2FContainers%22%20fill%3D%22url(%23linearGradient-1)%22%3E%3Crect%20id%3D%22Rectangle%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2280%22%20height%3D%2280%22%3E%3C%2Frect%3E%3C%2Fg%3E%3Cpath%20d%3D%22M64%2C48.2340095%20L56%2C43.4330117%20L56%2C32.0000169%20C56%2C31.6440171%2055.812%2C31.3150172%2055.504%2C31.1360173%20L44%2C24.4260204%20L44%2C14.7520248%20L64%2C26.5710194%20L64%2C48.2340095%20Z%20M65.509%2C25.13902%20L43.509%2C12.139026%20C43.199%2C11.9560261%2042.818%2C11.9540261%2042.504%2C12.131026%20C42.193%2C12.3090259%2042%2C12.6410257%2042%2C13.0000256%20L42%2C25.0000201%20C42%2C25.3550199%2042.189%2C25.6840198%2042.496%2C25.8640197%20L54%2C32.5740166%20L54%2C44.0000114%20C54%2C44.3510113%2054.185%2C44.6770111%2054.486%2C44.857011%20L64.486%2C50.8570083%20C64.644%2C50.9520082%2064.822%2C51%2065%2C51%20C65.17%2C51%2065.34%2C50.9570082%2065.493%2C50.8700083%20C65.807%2C50.6930084%2066%2C50.3600085%2066%2C50%20L66%2C26.0000196%20C66%2C25.6460198%2065.814%2C25.31902%2065.509%2C25.13902%20L65.509%2C25.13902%20Z%20M40.445%2C66.863001%20L17%2C54.3990067%20L17%2C26.5710194%20L37%2C14.7520248%20L37%2C24.4510204%20L26.463%2C31.1560173%20C26.175%2C31.3400172%2026%2C31.6580171%2026%2C32.0000169%20L26%2C49.0000091%20C26%2C49.373009%2026.208%2C49.7150088%2026.538%2C49.8870087%20L39.991%2C56.8870055%20C40.28%2C57.0370055%2040.624%2C57.0380055%2040.912%2C56.8880055%20L53.964%2C50.1440086%20L61.996%2C54.9640064%20L40.445%2C66.863001%20Z%20M64.515%2C54.1420068%20L54.515%2C48.1420095%20C54.217%2C47.9640096%2053.849%2C47.9520096%2053.541%2C48.1120095%20L40.455%2C54.8730065%20L28%2C48.3930094%20L28%2C32.5490167%20L38.537%2C25.8440197%20C38.825%2C25.6600198%2039%2C25.3420199%2039%2C25.0000201%20L39%2C13.0000256%20C39%2C12.6410257%2038.808%2C12.3090259%2038.496%2C12.131026%20C38.184%2C11.9540261%2037.802%2C11.9560261%2037.491%2C12.139026%20L15.491%2C25.13902%20C15.187%2C25.31902%2015%2C25.6460198%2015%2C26.0000196%20L15%2C55%20C15%2C55.3690062%2015.204%2C55.7090061%2015.53%2C55.883006%20L39.984%2C68.8830001%20C40.131%2C68.961%2040.292%2C69%2040.453%2C69%20C40.62%2C69%2040.786%2C68.958%2040.937%2C68.8750001%20L64.484%2C55.875006%20C64.797%2C55.7020061%2064.993%2C55.3750062%2065.0001416%2C55.0180064%20C65.006%2C54.6600066%2064.821%2C54.3260067%2064.515%2C54.1420068%20L64.515%2C54.1420068%20Z%22%20id%3D%22Amazon-Elastic-Container-Service_Icon_64_Squid%22%20fill%3D%22%23FFFFFF%22%3E%3C%2Fpath%3E%3C%2Fg%3E%3C%2Fsvg%3E",
"image":"data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20width%3D%2280px%22%20height%3D%2280px%22%20viewBox%3D%220%200%2080%2080%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%3C!--%20Generator%3A%20Sketch%2064%20(93537)%20-%20https%3A%2F%2Fsketch.com%20--%3E%3Ctitle%3EIcon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%3C%2Ftitle%3E%3Cdesc%3ECreated%20with%20Sketch.%3C%2Fdesc%3E%3Cdefs%3E%3ClinearGradient%20x1%3D%220%25%22%20y1%3D%22100%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%20id%3D%22linearGradient-1%22%3E%3Cstop%20stop-color%3D%22%23C8511B%22%20offset%3D%220%25%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23FF9900%22%20offset%3D%22100%25%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20id%3D%22Icon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%22%20stroke%3D%22none%22%20stroke-width%3D%221%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cg%20id%3D%22Icon-Architecture-BG%2F64%2FContainers%22%20fill%3D%22url(%23linearGradient-1)%22%3E%3Crect%20id%3D%22Rectangle%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2280%22%20height%3D%2280%22%3E%3C%2Frect%3E%3C%2Fg%3E%3Cpath%20d%3D%22M64%2C48.2340095%20L56%2C43.4330117%20L56%2C32.0000169%20C56%2C31.6440171%2055.812%2C31.3150172%2055.504%2C31.1360173%20L44%2C24.4260204%20L44%2C14.7520248%20L64%2C26.5710194%20L64%2C48.2340095%20Z%20M65.509%2C25.13902%20L43.509%2C12.139026%20C43.199%2C11.9560261%2042.818%2C11.9540261%2042.504%2C12.131026%20C42.193%2C12.3090259%2042%2C12.6410257%2042%2C13.0000256%20L42%2C25.0000201%20C42%2C25.3550199%2042.189%2C25.6840198%2042.496%2C25.8640197%20L54%2C32.5740166%20L54%2C44.0000114%20C54%2C44.3510113%2054.185%2C44.6770111%2054.486%2C44.857011%20L64.486%2C50.8570083%20C64.644%2C50.9520082%2064.822%2C51%2065%2C51%20C65.17%2C51%2065.34%2C50.9570082%2065.493%2C50.8700083%20C65.807%2C50.6930084%2066%2C50.3600085%2066%2C50%20L66%2C26.0000196%20C66%2C25.6460198%2065.814%2C25.31902%2065.509%2C25.13902%20L65.509%2C25.13902%20Z%20M40.445%2C66.863001%20L17%2C54.3990067%20L17%2C26.5710194%20L37%2C14.7520248%20L37%2C24.4510204%20L26.463%2C31.1560173%20C26.175%2C31.3400172%2026%2C31.6580171%2026%2C32.0000169%20L26%2C49.0000091%20C26%2C49.373009%2026.208%2C49.7150088%2026.538%2C49.8870087%20L39.991%2C56.8870055%20C40.28%2C57.0370055%2040.624%2C57.0380055%2040.912%2C56.8880055%20L53.964%2C50.1440086%20L61.996%2C54.9640064%20L40.445%2C66.863001%20Z%20M64.515%2C54.1420068%20L54.515%2C48.1420095%20C54.217%2C47.9640096%2053.849%2C47.9520096%2053.541%2C48.1120095%20L40.455%2C54.8730065%20L28%2C48.3930094%20L28%2C32.5490167%20L38.537%2C25.8440197%20C38.825%2C25.6600198%2039%2C25.3420199%2039%2C25.0000201%20L39%2C13.0000256%20C39%2C12.6410257%2038.808%2C12.3090259%2038.496%2C12.131026%20C38.184%2C11.9540261%2037.802%2C11.9560261%2037.491%2C12.139026%20L15.491%2C25.13902%20C15.187%2C25.31902%2015%2C25.6460198%2015%2C26.0000196%20L15%2C55%20C15%2C55.3690062%2015.204%2C55.7090061%2015.53%2C55.883006%20L39.984%2C68.8830001%20C40.131%2C68.961%2040.292%2C69%2040.453%2C69%20C40.62%2C69%2040.786%2C68.958%2040.937%2C68.8750001%20L64.484%2C55.875006%20C64.797%2C55.7020061%2064.993%2C55.3750062%2065.0001416%2C55.0180064%20C65.006%2C54.6600066%2064.821%2C54.3260067%2064.515%2C54.1420068%20L64.515%2C54.1420068%20Z%22%20id%3D%22Amazon-Elastic-Container-Service_Icon_64_Squid%22%20fill%3D%22%23FFFFFF%22%3E%3C%2Fpath%3E%3C%2Fg%3E%3C%2Fsvg%3E",
"layout": [
{
"h": 3,
@@ -139,7 +139,7 @@
"type": "QUERY"
}
},
"version": "v5",
"version": "v4",
"widgets": [
{
"bucketCount": 30,
@@ -160,19 +160,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_MemoryUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_MemoryUtilization_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_MemoryUtilization_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName = $Cluster)"
"filters": {
"items": [
{
"id": "c002d3ea",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "d95dc93f",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "7eb7332c",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "=",
"value": "$Cluster"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -185,14 +227,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}} ",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -297,19 +340,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_CPUUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_CPUUtilization_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_CPUUtilization_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName = $Cluster)"
"filters": {
"items": [
{
"id": "8ae50256",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "dada2be4",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "adaf587a",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "=",
"value": "$Cluster"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -322,14 +407,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}} ",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -434,30 +520,75 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_ContainerInsights_CpuUtilized_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_ContainerInsights_CpuUtilized_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_ContainerInsights_CpuUtilized_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName IN $Cluster)"
"filters": {
"items": [
{
"id": "840f6a82",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "e494eace",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "d615bfdb",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "in",
"value": [
"$Cluster"
]
}
],
"op": "AND"
},
"functions": [],
"groupBy": [],
"having": {
"expression": ""
},
"having": [],
"legend": "",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -562,30 +693,71 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_ContainerInsights_CpuReserved_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_ContainerInsights_CpuReserved_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_ContainerInsights_CpuReserved_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName = $Cluster)"
"filters": {
"items": [
{
"id": "98cf55a2",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "dc2591e8",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "5fe36864",
"key": {
"dataType": "",
"isColumn": false,
"key": "ClusterName",
"type": ""
},
"op": "=",
"value": "$Cluster"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [],
"having": {
"expression": ""
},
"having": [],
"legend": "",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -690,30 +862,71 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_ContainerInsights_MemoryUtilized_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_ContainerInsights_MemoryUtilized_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_ContainerInsights_MemoryUtilized_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName = $Cluster)"
"filters": {
"items": [
{
"id": "6d3fb70d",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "763ec68f",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "69a793fb",
"key": {
"dataType": "",
"isColumn": false,
"key": "ClusterName",
"type": ""
},
"op": "=",
"value": "$Cluster"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [],
"having": {
"expression": ""
},
"having": [],
"legend": "",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -818,30 +1031,71 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_ContainerInsights_MemoryReserved_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_ContainerInsights_MemoryReserved_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_ContainerInsights_MemoryReserved_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName = $Cluster)"
"filters": {
"items": [
{
"id": "4cabe614",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "077e09db",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "71f30fef",
"key": {
"dataType": "",
"isColumn": false,
"key": "ClusterName",
"type": ""
},
"op": "=",
"value": "$Cluster"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [],
"having": {
"expression": ""
},
"having": [],
"legend": "",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -946,19 +1200,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_ContainerInsights_NetworkRxBytes_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_ContainerInsights_NetworkRxBytes_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_ContainerInsights_NetworkRxBytes_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName = $Cluster AND ServiceName EXISTS)"
"filters": {
"items": [
{
"id": "8e15b10c",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "92d56544",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "7c5e0300",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "=",
"value": "$Cluster"
},
{
"id": "f41089a9",
"key": {
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
"op": "exists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -971,14 +1280,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -1083,19 +1393,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_ContainerInsights_NetworkTxBytes_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_ContainerInsights_NetworkTxBytes_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_ContainerInsights_NetworkTxBytes_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName = $Cluster AND ServiceName EXISTS)"
"filters": {
"items": [
{
"id": "6a1059e5",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "fe0d40de",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "b6047f19",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "=",
"value": "$Cluster"
},
{
"id": "8e76d8f1",
"key": {
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
"op": "exists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1108,14 +1473,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -1220,19 +1586,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_ContainerInsights_StorageReadBytes_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_ContainerInsights_StorageReadBytes_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_ContainerInsights_StorageReadBytes_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName = $Cluster AND ServiceName EXISTS)"
"filters": {
"items": [
{
"id": "89f0e499",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "91ce3091",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "50782f6c",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "=",
"value": "$Cluster"
},
{
"id": "6eeed520",
"key": {
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
"op": "exists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1253,14 +1674,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -1365,19 +1787,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_ContainerInsights_StorageWriteBytes_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_ContainerInsights_StorageWriteBytes_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_ContainerInsights_StorageWriteBytes_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName = $Cluster AND ServiceName EXISTS)"
"filters": {
"items": [
{
"id": "edef4331",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "d6081c36",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "7ae5a9e4",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "=",
"value": "$Cluster"
},
{
"id": "5f7feeb2",
"key": {
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
"op": "exists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1390,14 +1867,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []

View File

@@ -224,6 +224,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerCpuUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "max"
}
],
@@ -355,6 +356,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerCpuReserved_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "max"
}
],
@@ -486,6 +488,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerMemoryUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -617,6 +620,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerMemoryReserved_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "max"
}
],
@@ -748,6 +752,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerCpuUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "max"
}
],
@@ -888,6 +893,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerMemoryUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -1028,6 +1034,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerNetworkRxBytes_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "max"
}
],
@@ -1168,6 +1175,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerNetworkTxBytes_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "max"
}
],
@@ -1308,6 +1316,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerStorageReadBytes_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "max"
}
],
@@ -1448,6 +1457,7 @@
"metricName": "aws_ECS_ContainerInsights_ContainerStorageWriteBytes_max",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": "",
"timeAggregation": "avg"
}
],

View File

@@ -1,6 +1,6 @@
{
"description": "View key AWS ECS metrics with an out of the box dashboard.\n",
"image": "data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20width%3D%2280px%22%20height%3D%2280px%22%20viewBox%3D%220%200%2080%2080%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%3C!--%20Generator%3A%20Sketch%2064%20(93537)%20-%20https%3A%2F%2Fsketch.com%20--%3E%3Ctitle%3EIcon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%3C%2Ftitle%3E%3Cdesc%3ECreated%20with%20Sketch.%3C%2Fdesc%3E%3Cdefs%3E%3ClinearGradient%20x1%3D%220%25%22%20y1%3D%22100%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%20id%3D%22linearGradient-1%22%3E%3Cstop%20stop-color%3D%22%23C8511B%22%20offset%3D%220%25%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23FF9900%22%20offset%3D%22100%25%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20id%3D%22Icon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%22%20stroke%3D%22none%22%20stroke-width%3D%221%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cg%20id%3D%22Icon-Architecture-BG%2F64%2FContainers%22%20fill%3D%22url(%23linearGradient-1)%22%3E%3Crect%20id%3D%22Rectangle%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2280%22%20height%3D%2280%22%3E%3C%2Frect%3E%3C%2Fg%3E%3Cpath%20d%3D%22M64%2C48.2340095%20L56%2C43.4330117%20L56%2C32.0000169%20C56%2C31.6440171%2055.812%2C31.3150172%2055.504%2C31.1360173%20L44%2C24.4260204%20L44%2C14.7520248%20L64%2C26.5710194%20L64%2C48.2340095%20Z%20M65.509%2C25.13902%20L43.509%2C12.139026%20C43.199%2C11.9560261%2042.818%2C11.9540261%2042.504%2C12.131026%20C42.193%2C12.3090259%2042%2C12.6410257%2042%2C13.0000256%20L42%2C25.0000201%20C42%2C25.3550199%2042.189%2C25.6840198%2042.496%2C25.8640197%20L54%2C32.5740166%20L54%2C44.0000114%20C54%2C44.3510113%2054.185%2C44.6770111%2054.486%2C44.857011%20L64.486%2C50.8570083%20C64.644%2C50.9520082%2064.822%2C51%2065%2C51%20C65.17%2C51%2065.34%2C50.9570082%2065.493%2C50.8700083%20C65.807%2C50.6930084%2066%2C50.3600085%2066%2C50%20L66%2C26.0000196%20C66%2C25.6460198%2065.814%2C25.31902%2065.509%2C25.13902%20L65.509%2C25.13902%20Z%20M40.445%2C66.863001%20L17%2C54.3990067%20L17%2C26.5710194%20L37%2C14.7520248%20L37%2C24.4510204%20L26.463%2C31.1560173%20C26.175%2C31.3400172%2026%2C31.6580171%2026%2C32.0000169%20L26%2C49.0000091%20C26%2C49.373009%2026.208%2C49.7150088%2026.538%2C49.8870087%20L39.991%2C56.8870055%20C40.28%2C57.0370055%2040.624%2C57.0380055%2040.912%2C56.8880055%20L53.964%2C50.1440086%20L61.996%2C54.9640064%20L40.445%2C66.863001%20Z%20M64.515%2C54.1420068%20L54.515%2C48.1420095%20C54.217%2C47.9640096%2053.849%2C47.9520096%2053.541%2C48.1120095%20L40.455%2C54.8730065%20L28%2C48.3930094%20L28%2C32.5490167%20L38.537%2C25.8440197%20C38.825%2C25.6600198%2039%2C25.3420199%2039%2C25.0000201%20L39%2C13.0000256%20C39%2C12.6410257%2038.808%2C12.3090259%2038.496%2C12.131026%20C38.184%2C11.9540261%2037.802%2C11.9560261%2037.491%2C12.139026%20L15.491%2C25.13902%20C15.187%2C25.31902%2015%2C25.6460198%2015%2C26.0000196%20L15%2C55%20C15%2C55.3690062%2015.204%2C55.7090061%2015.53%2C55.883006%20L39.984%2C68.8830001%20C40.131%2C68.961%2040.292%2C69%2040.453%2C69%20C40.62%2C69%2040.786%2C68.958%2040.937%2C68.8750001%20L64.484%2C55.875006%20C64.797%2C55.7020061%2064.993%2C55.3750062%2065.0001416%2C55.0180064%20C65.006%2C54.6600066%2064.821%2C54.3260067%2064.515%2C54.1420068%20L64.515%2C54.1420068%20Z%22%20id%3D%22Amazon-Elastic-Container-Service_Icon_64_Squid%22%20fill%3D%22%23FFFFFF%22%3E%3C%2Fpath%3E%3C%2Fg%3E%3C%2Fsvg%3E",
"image":"data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20width%3D%2280px%22%20height%3D%2280px%22%20viewBox%3D%220%200%2080%2080%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%3C!--%20Generator%3A%20Sketch%2064%20(93537)%20-%20https%3A%2F%2Fsketch.com%20--%3E%3Ctitle%3EIcon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%3C%2Ftitle%3E%3Cdesc%3ECreated%20with%20Sketch.%3C%2Fdesc%3E%3Cdefs%3E%3ClinearGradient%20x1%3D%220%25%22%20y1%3D%22100%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%20id%3D%22linearGradient-1%22%3E%3Cstop%20stop-color%3D%22%23C8511B%22%20offset%3D%220%25%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23FF9900%22%20offset%3D%22100%25%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20id%3D%22Icon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%22%20stroke%3D%22none%22%20stroke-width%3D%221%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cg%20id%3D%22Icon-Architecture-BG%2F64%2FContainers%22%20fill%3D%22url(%23linearGradient-1)%22%3E%3Crect%20id%3D%22Rectangle%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2280%22%20height%3D%2280%22%3E%3C%2Frect%3E%3C%2Fg%3E%3Cpath%20d%3D%22M64%2C48.2340095%20L56%2C43.4330117%20L56%2C32.0000169%20C56%2C31.6440171%2055.812%2C31.3150172%2055.504%2C31.1360173%20L44%2C24.4260204%20L44%2C14.7520248%20L64%2C26.5710194%20L64%2C48.2340095%20Z%20M65.509%2C25.13902%20L43.509%2C12.139026%20C43.199%2C11.9560261%2042.818%2C11.9540261%2042.504%2C12.131026%20C42.193%2C12.3090259%2042%2C12.6410257%2042%2C13.0000256%20L42%2C25.0000201%20C42%2C25.3550199%2042.189%2C25.6840198%2042.496%2C25.8640197%20L54%2C32.5740166%20L54%2C44.0000114%20C54%2C44.3510113%2054.185%2C44.6770111%2054.486%2C44.857011%20L64.486%2C50.8570083%20C64.644%2C50.9520082%2064.822%2C51%2065%2C51%20C65.17%2C51%2065.34%2C50.9570082%2065.493%2C50.8700083%20C65.807%2C50.6930084%2066%2C50.3600085%2066%2C50%20L66%2C26.0000196%20C66%2C25.6460198%2065.814%2C25.31902%2065.509%2C25.13902%20L65.509%2C25.13902%20Z%20M40.445%2C66.863001%20L17%2C54.3990067%20L17%2C26.5710194%20L37%2C14.7520248%20L37%2C24.4510204%20L26.463%2C31.1560173%20C26.175%2C31.3400172%2026%2C31.6580171%2026%2C32.0000169%20L26%2C49.0000091%20C26%2C49.373009%2026.208%2C49.7150088%2026.538%2C49.8870087%20L39.991%2C56.8870055%20C40.28%2C57.0370055%2040.624%2C57.0380055%2040.912%2C56.8880055%20L53.964%2C50.1440086%20L61.996%2C54.9640064%20L40.445%2C66.863001%20Z%20M64.515%2C54.1420068%20L54.515%2C48.1420095%20C54.217%2C47.9640096%2053.849%2C47.9520096%2053.541%2C48.1120095%20L40.455%2C54.8730065%20L28%2C48.3930094%20L28%2C32.5490167%20L38.537%2C25.8440197%20C38.825%2C25.6600198%2039%2C25.3420199%2039%2C25.0000201%20L39%2C13.0000256%20C39%2C12.6410257%2038.808%2C12.3090259%2038.496%2C12.131026%20C38.184%2C11.9540261%2037.802%2C11.9560261%2037.491%2C12.139026%20L15.491%2C25.13902%20C15.187%2C25.31902%2015%2C25.6460198%2015%2C26.0000196%20L15%2C55%20C15%2C55.3690062%2015.204%2C55.7090061%2015.53%2C55.883006%20L39.984%2C68.8830001%20C40.131%2C68.961%2040.292%2C69%2040.453%2C69%20C40.62%2C69%2040.786%2C68.958%2040.937%2C68.8750001%20L64.484%2C55.875006%20C64.797%2C55.7020061%2064.993%2C55.3750062%2065.0001416%2C55.0180064%20C65.006%2C54.6600066%2064.821%2C54.3260067%2064.515%2C54.1420068%20L64.515%2C54.1420068%20Z%22%20id%3D%22Amazon-Elastic-Container-Service_Icon_64_Squid%22%20fill%3D%22%23FFFFFF%22%3E%3C%2Fpath%3E%3C%2Fg%3E%3C%2Fsvg%3E",
"layout": [
{
"h": 6,
@@ -93,7 +93,7 @@
"type": "QUERY"
}
},
"version": "v5",
"version": "v4",
"widgets": [
{
"bucketCount": 30,
@@ -112,19 +112,63 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_MemoryUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_MemoryUtilization_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_MemoryUtilization_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName IN $Cluster)"
"filters": {
"items": [
{
"id": "26ac617d",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "57172ed9",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "49b9f85e",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "in",
"value": [
"$Cluster"
]
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -145,14 +189,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -255,19 +300,63 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_MemoryUtilization_min",
"reduceTo": "avg",
"spaceAggregation": "min",
"timeAggregation": "min"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_MemoryUtilization_min--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_MemoryUtilization_min",
"type": "Gauge"
},
"aggregateOperator": "min",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName IN $Cluster)"
"filters": {
"items": [
{
"id": "cd4b8848",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "aa5115c6",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "f60677b6",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "in",
"value": [
"$Cluster"
]
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -288,14 +377,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "min",
"stepInterval": 60,
"timeAggregation": "min"
}
],
"queryFormulas": []
@@ -398,19 +488,63 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_CPUUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_CPUUtilization_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_CPUUtilization_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName IN $Cluster)"
"filters": {
"items": [
{
"id": "2c13c8ee",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "f489f6a8",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "94012320",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "in",
"value": [
"$Cluster"
]
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -431,14 +565,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -541,19 +676,63 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_CPUUtilization_min",
"reduceTo": "avg",
"spaceAggregation": "min",
"timeAggregation": "min"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_CPUUtilization_min--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_CPUUtilization_min",
"type": "Gauge"
},
"aggregateOperator": "min",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName IN $Cluster)"
"filters": {
"items": [
{
"id": "758ba906",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "4ffe6bf7",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "53d98059",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "in",
"value": [
"$Cluster"
]
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -574,14 +753,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "min",
"stepInterval": 60,
"timeAggregation": "min"
}
],
"queryFormulas": []

View File

@@ -103,7 +103,7 @@
"type": "QUERY"
}
},
"version": "v5",
"version": "v4",
"widgets": [
{
"bucketCount": 30,
@@ -121,19 +121,70 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Lambda_Invocations_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Lambda_Invocations_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Lambda_Invocations_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND FunctionName EXISTS AND Resource NOT EXISTS)"
"filters": {
"items": [
{
"id": "49d33567",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "b9dfa1c9",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "86defeb5",
"key": {
"dataType": "",
"isColumn": false,
"key": "FunctionName",
"type": ""
},
"op": "exists",
"value": ""
},
{
"id": "f89a10c4",
"key": {
"dataType": "",
"isColumn": false,
"key": "Resource",
"type": ""
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -162,14 +213,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{FunctionName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -271,19 +323,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Lambda_Duration_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Lambda_Duration_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Lambda_Duration_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND FunctionName EXISTS AND Resource NOT EXISTS)"
"filters": {
"items": [
{
"id": "af05252d",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "983efea5",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "88eb3092",
"key": {
"dataType": "string",
"id": "FunctionName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "FunctionName",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "a35c6406",
"key": {
"dataType": "string",
"id": "Resource--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Resource",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -312,14 +419,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{FunctionName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -421,19 +529,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Lambda_Errors_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Lambda_Errors_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Lambda_Errors_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND FunctionName EXISTS AND Resource NOT EXISTS)"
"filters": {
"items": [
{
"id": "c67262c9",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "c5ccbbf4",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "c1b278d1",
"key": {
"dataType": "string",
"id": "FunctionName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "FunctionName",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "a45d80e1",
"key": {
"dataType": "string",
"id": "Resource--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Resource",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -462,14 +625,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{FunctionName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -571,19 +735,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Lambda_Throttles_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Lambda_Throttles_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Lambda_Throttles_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND FunctionName EXISTS AND Resource NOT EXISTS)"
"filters": {
"items": [
{
"id": "6c956b7d",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "5fef840b",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "6f892a9a",
"key": {
"dataType": "string",
"id": "FunctionName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "FunctionName",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "ce91320c",
"key": {
"dataType": "string",
"id": "Resource--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Resource",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -612,14 +831,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{FunctionName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -721,19 +941,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Lambda_AsyncEventsReceived_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Lambda_AsyncEventsReceived_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Lambda_AsyncEventsReceived_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND FunctionName EXISTS AND Resource NOT EXISTS)"
"filters": {
"items": [
{
"id": "f4c6246b",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "5b7a75a1",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "4e1ba051",
"key": {
"dataType": "string",
"id": "FunctionName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "FunctionName",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "5848f496",
"key": {
"dataType": "string",
"id": "Resource--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Resource",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -762,14 +1037,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{FunctionName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -871,19 +1147,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Lambda_AsyncEventAge_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Lambda_AsyncEventAge_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Lambda_AsyncEventAge_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND FunctionName EXISTS AND Resource NOT EXISTS)"
"filters": {
"items": [
{
"id": "1aee3626",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "11631fda",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "c5ea0a17",
"key": {
"dataType": "string",
"id": "FunctionName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "FunctionName",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "1952b27e",
"key": {
"dataType": "string",
"id": "Resource--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Resource",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -912,14 +1243,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{FunctionName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -1021,19 +1353,74 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Lambda_AsyncEventsDropped_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Lambda_AsyncEventsDropped_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Lambda_AsyncEventsDropped_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND FunctionName EXISTS AND Resource NOT EXISTS)"
"filters": {
"items": [
{
"id": "a8c65389",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "2ab205c8",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "22d3c9b6",
"key": {
"dataType": "string",
"id": "FunctionName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "FunctionName",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "1e7060a6",
"key": {
"dataType": "string",
"id": "Resource--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Resource",
"type": "tag"
},
"op": "nexists",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1062,14 +1449,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{FunctionName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []

View File

@@ -94,7 +94,7 @@
"type": "QUERY"
}
},
"version": "v5",
"version": "v4",
"widgets": [
{
"bucketCount": 30,
@@ -112,19 +112,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Kafka_KafkaDataLogsDiskUsed_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Kafka_KafkaDataLogsDiskUsed_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Kafka_KafkaDataLogsDiskUsed_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(Broker_ID EXISTS AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "be8452fb",
"key": {
"dataType": "string",
"id": "Broker_ID--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Broker_ID",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "8b658843",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "9cbc21ee",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -145,14 +187,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "Broker {{Broker_ID}} ({{Cluster_Name}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -254,19 +297,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Kafka_CpuUser_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Kafka_CpuUser_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Kafka_CpuUser_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(Broker_ID EXISTS AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "03054a63",
"key": {
"dataType": "string",
"id": "Broker_ID--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Broker_ID",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "754c3c99",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "09ad3a79",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -287,14 +372,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "Broker {{Broker_ID}} ({{Cluster_Name}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -396,19 +482,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Kafka_CpuSystem_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Kafka_CpuSystem_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Kafka_CpuSystem_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(Broker_ID EXISTS AND cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "1c4feb03",
"key": {
"dataType": "string",
"id": "Broker_ID--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Broker_ID",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "3e5db1d7",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "9e9bf94c",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -429,14 +557,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "Broker {{Broker_ID}} ({{Cluster_Name}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -538,19 +667,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Kafka_NetworkTxPackets_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Kafka_NetworkTxPackets_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Kafka_NetworkTxPackets_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(Broker_ID EXISTS AND cloud.region = $Region AND cloud.account.id = $Account)"
"filters": {
"items": [
{
"id": "df3f9941",
"key": {
"dataType": "string",
"id": "Broker_ID--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Broker_ID",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "2233f9a5",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "52bd69d4",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -571,14 +742,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "Broker {{Broker_ID}} ({{Cluster_Name}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -680,19 +852,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Kafka_NetworkRxPackets_sum",
"reduceTo": "avg",
"spaceAggregation": "sum",
"timeAggregation": "sum"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Kafka_NetworkRxPackets_sum--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Kafka_NetworkRxPackets_sum",
"type": "Gauge"
},
"aggregateOperator": "sum",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND Broker_ID EXISTS AND cloud.account.id = $Account)"
"filters": {
"items": [
{
"id": "a00425be",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "726d60d7",
"key": {
"dataType": "string",
"id": "Broker_ID--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "Broker_ID",
"type": "tag"
},
"op": "exists",
"value": ""
},
{
"id": "02adea69",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -713,14 +927,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "Broker {{Broker_ID}} ({{Cluster_Name}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "sum",
"stepInterval": 60,
"timeAggregation": "sum"
}
],
"queryFormulas": []
@@ -822,19 +1037,48 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_Kafka_SumOffsetLag_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_Kafka_SumOffsetLag_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_Kafka_SumOffsetLag_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region)"
"filters": {
"items": [
{
"id": "0626eebd",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "b633d867",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -847,14 +1091,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "({{Cluster_Name}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []

View File

@@ -113,7 +113,7 @@
"type": "QUERY"
}
},
"version": "v5",
"version": "v4",
"widgets": [
{
"bucketCount": 30,
@@ -131,19 +131,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_RDS_CPUUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_CPUUtilization_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_CPUUtilization_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "f8e72efc",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "4e68256a",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "a5082e1b",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -172,14 +214,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -281,19 +324,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_RDS_FreeableMemory_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_FreeableMemory_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_FreeableMemory_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "723ba84a",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "f8227b55",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "3951e8ed",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -322,14 +407,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -431,19 +517,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_RDS_DatabaseConnections_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_DatabaseConnections_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_DatabaseConnections_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "31191f74",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "aa644bbf",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "e5b31a18",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -472,14 +600,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -581,19 +710,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_RDS_ReadLatency_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_ReadLatency_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_ReadLatency_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "83f232af",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "2677873f",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "78eddd81",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -622,29 +793,72 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}} - Reads",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
},
{
"aggregations": [
{
"metricName": "aws_RDS_WriteLatency_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_WriteLatency_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_WriteLatency_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "B",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "e2df7981",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "6daad748",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "28057159",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -673,14 +887,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}} - Writes",
"limit": null,
"orderBy": [],
"queryName": "B",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -782,19 +997,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_RDS_ReadIOPS_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_ReadIOPS_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_ReadIOPS_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "17142c3d",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "27fcc87d",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "5510ad1d",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -823,29 +1080,72 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}} - Reads",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
},
{
"aggregations": [
{
"metricName": "aws_RDS_WriteIOPS_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_WriteIOPS_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_WriteIOPS_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "B",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "a050e23a",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "6df80990",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "72bc50d0",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -874,14 +1174,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}} - Writes",
"limit": null,
"orderBy": [],
"queryName": "B",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -983,19 +1284,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_RDS_ReadThroughput_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_ReadThroughput_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_ReadThroughput_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "a298d4bd",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "810c0586",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "fa40ae81",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1024,29 +1367,72 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}} - Reads",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
},
{
"aggregations": [
{
"metricName": "aws_RDS_WriteThroughput_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_WriteThroughput_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_WriteThroughput_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "B",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "d46f3f53",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "4ec47a19",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "a0e648d6",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1075,14 +1461,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}} - Writes",
"limit": null,
"orderBy": [],
"queryName": "B",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -1184,19 +1571,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_RDS_DiskQueueDepth_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_DiskQueueDepth_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_DiskQueueDepth_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "f64f0096",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "18ad7c1e",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "5d3f4963",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1225,14 +1654,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -1334,19 +1764,61 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_RDS_FreeStorageSpace_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_RDS_FreeStorageSpace_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_RDS_FreeStorageSpace_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.account.id = $Account AND cloud.region = $Region AND DBInstanceIdentifier != '')"
"filters": {
"items": [
{
"id": "7786e529",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "f27b4616",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "51ca6d55",
"key": {
"dataType": "string",
"id": "DBInstanceIdentifier--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "DBInstanceIdentifier",
"type": "tag"
},
"op": "!=",
"value": ""
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -1375,14 +1847,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{DBInstanceIdentifier}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []

View File

@@ -92,7 +92,7 @@
"type": "QUERY"
}
},
"version": "v5",
"version": "v4",
"widgets": [
{
"bucketCount": 30,
@@ -111,19 +111,63 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_SNS_NumberOfMessagesPublished_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_SNS_NumberOfMessagesPublished_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_SNS_NumberOfMessagesPublished_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(TopicName IN $Topic AND cloud.region = $Region AND cloud.account.id = $Account)"
"filters": {
"items": [
{
"id": "8fd51b53",
"key": {
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
},
"op": "in",
"value": [
"$Topic"
]
},
{
"id": "b18187c3",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "eebe4578",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -136,14 +180,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -246,19 +291,63 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_SNS_PublishSize_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_SNS_PublishSize_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_SNS_PublishSize_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(TopicName IN $Topic AND cloud.region = $Region AND cloud.account.id = $Account)"
"filters": {
"items": [
{
"id": "1aa0d1a9",
"key": {
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
},
"op": "in",
"value": [
"$Topic"
]
},
{
"id": "62255cff",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "17c7153e",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -271,14 +360,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -381,19 +471,63 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_SNS_NumberOfNotificationsDelivered_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_SNS_NumberOfNotificationsDelivered_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_SNS_NumberOfNotificationsDelivered_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(TopicName IN $Topic AND cloud.region = $Region AND cloud.account.id = $Account)"
"filters": {
"items": [
{
"id": "c96a4ac0",
"key": {
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
},
"op": "in",
"value": [
"$Topic"
]
},
{
"id": "8ca86829",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "8a444f66",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -406,14 +540,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
@@ -516,19 +651,63 @@
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_SNS_NumberOfNotificationsFailed_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_SNS_NumberOfNotificationsFailed_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_SNS_NumberOfNotificationsFailed_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(TopicName IN $Topic AND cloud.region = $Region AND cloud.account.id = $Account)"
"filters": {
"items": [
{
"id": "6175f3d5",
"key": {
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
},
"op": "in",
"value": [
"$Topic"
]
},
{
"id": "e2084931",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "0b05209a",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
@@ -541,14 +720,15 @@
"type": "tag"
}
],
"having": {
"expression": ""
},
"having": [],
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []

View File

@@ -313,6 +313,7 @@
"metricName": "azure_totallatency_average",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -322,6 +323,35 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'"
},
"filters": {
"items": [
{
"id": "f001-name",
"key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" },
"op": "IN",
"value": "$cdnprofile"
},
{
"id": "f001-sub",
"key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" },
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "f001-rg",
"key": { "id": "resource_group", "key": "resource_group", "type": "" },
"op": "=",
"value": "$resource_group"
},
{
"id": "f001-type",
"key": { "id": "type", "key": "type", "type": "" },
"op": "=",
"value": "Microsoft.Cdn/profiles"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -400,6 +430,7 @@
"metricName": "azure_originlatency_average",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -409,6 +440,35 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'"
},
"filters": {
"items": [
{
"id": "f002-name",
"key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" },
"op": "IN",
"value": "$cdnprofile"
},
{
"id": "f002-sub",
"key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" },
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "f002-rg",
"key": { "id": "resource_group", "key": "resource_group", "type": "" },
"op": "=",
"value": "$resource_group"
},
{
"id": "f002-type",
"key": { "id": "type", "key": "type", "type": "" },
"op": "=",
"value": "Microsoft.Cdn/profiles"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -487,6 +547,7 @@
"metricName": "azure_averagewebsocketconnectionduration_average",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -496,6 +557,35 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'"
},
"filters": {
"items": [
{
"id": "f003-name",
"key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" },
"op": "IN",
"value": "$cdnprofile"
},
{
"id": "f003-sub",
"key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" },
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "f003-rg",
"key": { "id": "resource_group", "key": "resource_group", "type": "" },
"op": "=",
"value": "$resource_group"
},
{
"id": "f003-type",
"key": { "id": "type", "key": "type", "type": "" },
"op": "=",
"value": "Microsoft.Cdn/profiles"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -579,6 +669,7 @@
"metricName": "azure_originhealthpercentage_average",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -588,6 +679,35 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'"
},
"filters": {
"items": [
{
"id": "f004-name",
"key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" },
"op": "IN",
"value": "$cdnprofile"
},
{
"id": "f004-sub",
"key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" },
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "f004-rg",
"key": { "id": "resource_group", "key": "resource_group", "type": "" },
"op": "=",
"value": "$resource_group"
},
{
"id": "f004-type",
"key": { "id": "type", "key": "type", "type": "" },
"op": "=",
"value": "Microsoft.Cdn/profiles"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -671,6 +791,7 @@
"metricName": "azure_bytehitratio_average",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -680,6 +801,35 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'"
},
"filters": {
"items": [
{
"id": "f005-name",
"key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" },
"op": "IN",
"value": "$cdnprofile"
},
{
"id": "f005-sub",
"key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" },
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "f005-rg",
"key": { "id": "resource_group", "key": "resource_group", "type": "" },
"op": "=",
"value": "$resource_group"
},
{
"id": "f005-type",
"key": { "id": "type", "key": "type", "type": "" },
"op": "=",
"value": "Microsoft.Cdn/profiles"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -758,6 +908,7 @@
"metricName": "azure_percentage4xx_average",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -767,6 +918,35 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'"
},
"filters": {
"items": [
{
"id": "f006-name",
"key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" },
"op": "IN",
"value": "$cdnprofile"
},
{
"id": "f006-sub",
"key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" },
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "f006-rg",
"key": { "id": "resource_group", "key": "resource_group", "type": "" },
"op": "=",
"value": "$resource_group"
},
{
"id": "f006-type",
"key": { "id": "type", "key": "type", "type": "" },
"op": "=",
"value": "Microsoft.Cdn/profiles"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -845,6 +1025,7 @@
"metricName": "azure_percentage5xx_average",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -854,6 +1035,35 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'"
},
"filters": {
"items": [
{
"id": "f007-name",
"key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" },
"op": "IN",
"value": "$cdnprofile"
},
{
"id": "f007-sub",
"key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" },
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "f007-rg",
"key": { "id": "resource_group", "key": "resource_group", "type": "" },
"op": "=",
"value": "$resource_group"
},
{
"id": "f007-type",
"key": { "id": "type", "key": "type", "type": "" },
"op": "=",
"value": "Microsoft.Cdn/profiles"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -917,9 +1127,15 @@
"query": {
"builder": {
"queryData": [{
"aggregations": [{ "metricName": "azure_requestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "timeAggregation": "sum" }],
"aggregations": [{ "metricName": "azure_requestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "temporality": "", "timeAggregation": "sum" }],
"dataSource": "metrics", "disabled": false, "expression": "A",
"filter": { "expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'" },
"filters": { "items": [
{ "id": "f008-name", "key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" }, "op": "IN", "value": "$cdnprofile" },
{ "id": "f008-sub", "key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" }, "op": "=", "value": "$azuremonitor.subscription_id" },
{ "id": "f008-rg", "key": { "id": "resource_group", "key": "resource_group", "type": "" }, "op": "=", "value": "$resource_group" },
{ "id": "f008-type", "key": { "id": "type", "key": "type", "type": "" }, "op": "=", "value": "Microsoft.Cdn/profiles" }
], "op": "AND" },
"functions": [], "groupBy": [{ "dataType": "string", "id": "name--string--tag", "isColumn": false, "isJSON": false, "key": "name", "type": "tag" }],
"having": { "expression": "" }, "legend": "{{name}}", "limit": null, "orderBy": [], "queryName": "A", "source": "", "stepInterval": null
}],
@@ -952,9 +1168,15 @@
"query": {
"builder": {
"queryData": [{
"aggregations": [{ "metricName": "azure_originrequestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "timeAggregation": "sum" }],
"aggregations": [{ "metricName": "azure_originrequestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "temporality": "", "timeAggregation": "sum" }],
"dataSource": "metrics", "disabled": false, "expression": "A",
"filter": { "expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'" },
"filters": { "items": [
{ "id": "f009-name", "key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" }, "op": "IN", "value": "$cdnprofile" },
{ "id": "f009-sub", "key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" }, "op": "=", "value": "$azuremonitor.subscription_id" },
{ "id": "f009-rg", "key": { "id": "resource_group", "key": "resource_group", "type": "" }, "op": "=", "value": "$resource_group" },
{ "id": "f009-type", "key": { "id": "type", "key": "type", "type": "" }, "op": "=", "value": "Microsoft.Cdn/profiles" }
], "op": "AND" },
"functions": [], "groupBy": [{ "dataType": "string", "id": "name--string--tag", "isColumn": false, "isJSON": false, "key": "name", "type": "tag" }],
"having": { "expression": "" }, "legend": "{{name}}", "limit": null, "orderBy": [], "queryName": "A", "source": "", "stepInterval": null
}],
@@ -987,9 +1209,15 @@
"query": {
"builder": {
"queryData": [{
"aggregations": [{ "metricName": "azure_requestsize_total", "reduceTo": "sum", "spaceAggregation": "sum", "timeAggregation": "sum" }],
"aggregations": [{ "metricName": "azure_requestsize_total", "reduceTo": "sum", "spaceAggregation": "sum", "temporality": "", "timeAggregation": "sum" }],
"dataSource": "metrics", "disabled": false, "expression": "A",
"filter": { "expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'" },
"filters": { "items": [
{ "id": "f010-name", "key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" }, "op": "IN", "value": "$cdnprofile" },
{ "id": "f010-sub", "key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" }, "op": "=", "value": "$azuremonitor.subscription_id" },
{ "id": "f010-rg", "key": { "id": "resource_group", "key": "resource_group", "type": "" }, "op": "=", "value": "$resource_group" },
{ "id": "f010-type", "key": { "id": "type", "key": "type", "type": "" }, "op": "=", "value": "Microsoft.Cdn/profiles" }
], "op": "AND" },
"functions": [], "groupBy": [{ "dataType": "string", "id": "name--string--tag", "isColumn": false, "isJSON": false, "key": "name", "type": "tag" }],
"having": { "expression": "" }, "legend": "{{name}}", "limit": null, "orderBy": [], "queryName": "A", "source": "", "stepInterval": null
}],
@@ -1022,9 +1250,15 @@
"query": {
"builder": {
"queryData": [{
"aggregations": [{ "metricName": "azure_responsesize_total", "reduceTo": "sum", "spaceAggregation": "sum", "timeAggregation": "sum" }],
"aggregations": [{ "metricName": "azure_responsesize_total", "reduceTo": "sum", "spaceAggregation": "sum", "temporality": "", "timeAggregation": "sum" }],
"dataSource": "metrics", "disabled": false, "expression": "A",
"filter": { "expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'" },
"filters": { "items": [
{ "id": "f011-name", "key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" }, "op": "IN", "value": "$cdnprofile" },
{ "id": "f011-sub", "key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" }, "op": "=", "value": "$azuremonitor.subscription_id" },
{ "id": "f011-rg", "key": { "id": "resource_group", "key": "resource_group", "type": "" }, "op": "=", "value": "$resource_group" },
{ "id": "f011-type", "key": { "id": "type", "key": "type", "type": "" }, "op": "=", "value": "Microsoft.Cdn/profiles" }
], "op": "AND" },
"functions": [], "groupBy": [{ "dataType": "string", "id": "name--string--tag", "isColumn": false, "isJSON": false, "key": "name", "type": "tag" }],
"having": { "expression": "" }, "legend": "{{name}}", "limit": null, "orderBy": [], "queryName": "A", "source": "", "stepInterval": null
}],
@@ -1057,9 +1291,15 @@
"query": {
"builder": {
"queryData": [{
"aggregations": [{ "metricName": "azure_activewebsocketconnections_total", "reduceTo": "max", "spaceAggregation": "sum", "timeAggregation": "max" }],
"aggregations": [{ "metricName": "azure_activewebsocketconnections_total", "reduceTo": "max", "spaceAggregation": "sum", "temporality": "", "timeAggregation": "max" }],
"dataSource": "metrics", "disabled": false, "expression": "A",
"filter": { "expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'" },
"filters": { "items": [
{ "id": "f012-name", "key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" }, "op": "IN", "value": "$cdnprofile" },
{ "id": "f012-sub", "key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" }, "op": "=", "value": "$azuremonitor.subscription_id" },
{ "id": "f012-rg", "key": { "id": "resource_group", "key": "resource_group", "type": "" }, "op": "=", "value": "$resource_group" },
{ "id": "f012-type", "key": { "id": "type", "key": "type", "type": "" }, "op": "=", "value": "Microsoft.Cdn/profiles" }
], "op": "AND" },
"functions": [], "groupBy": [{ "dataType": "string", "id": "name--string--tag", "isColumn": false, "isJSON": false, "key": "name", "type": "tag" }],
"having": { "expression": "" }, "legend": "{{name}}", "limit": null, "orderBy": [], "queryName": "A", "source": "", "stepInterval": null
}],
@@ -1092,9 +1332,15 @@
"query": {
"builder": {
"queryData": [{
"aggregations": [{ "metricName": "azure_websocketconnections_total", "reduceTo": "sum", "spaceAggregation": "sum", "timeAggregation": "sum" }],
"aggregations": [{ "metricName": "azure_websocketconnections_total", "reduceTo": "sum", "spaceAggregation": "sum", "temporality": "", "timeAggregation": "sum" }],
"dataSource": "metrics", "disabled": false, "expression": "A",
"filter": { "expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'" },
"filters": { "items": [
{ "id": "f013-name", "key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" }, "op": "IN", "value": "$cdnprofile" },
{ "id": "f013-sub", "key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" }, "op": "=", "value": "$azuremonitor.subscription_id" },
{ "id": "f013-rg", "key": { "id": "resource_group", "key": "resource_group", "type": "" }, "op": "=", "value": "$resource_group" },
{ "id": "f013-type", "key": { "id": "type", "key": "type", "type": "" }, "op": "=", "value": "Microsoft.Cdn/profiles" }
], "op": "AND" },
"functions": [], "groupBy": [{ "dataType": "string", "id": "name--string--tag", "isColumn": false, "isJSON": false, "key": "name", "type": "tag" }],
"having": { "expression": "" }, "legend": "{{name}}", "limit": null, "orderBy": [], "queryName": "A", "source": "", "stepInterval": null
}],
@@ -1127,9 +1373,15 @@
"query": {
"builder": {
"queryData": [{
"aggregations": [{ "metricName": "azure_webapplicationfirewallrequestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "timeAggregation": "sum" }],
"aggregations": [{ "metricName": "azure_webapplicationfirewallrequestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "temporality": "", "timeAggregation": "sum" }],
"dataSource": "metrics", "disabled": false, "expression": "A",
"filter": { "expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'" },
"filters": { "items": [
{ "id": "f014-name", "key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" }, "op": "IN", "value": "$cdnprofile" },
{ "id": "f014-sub", "key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" }, "op": "=", "value": "$azuremonitor.subscription_id" },
{ "id": "f014-rg", "key": { "id": "resource_group", "key": "resource_group", "type": "" }, "op": "=", "value": "$resource_group" },
{ "id": "f014-type", "key": { "id": "type", "key": "type", "type": "" }, "op": "=", "value": "Microsoft.Cdn/profiles" }
], "op": "AND" },
"functions": [], "groupBy": [{ "dataType": "string", "id": "name--string--tag", "isColumn": false, "isJSON": false, "key": "name", "type": "tag" }],
"having": { "expression": "" }, "legend": "{{name}}", "limit": null, "orderBy": [], "queryName": "A", "source": "", "stepInterval": null
}],
@@ -1162,9 +1414,15 @@
"query": {
"builder": {
"queryData": [{
"aggregations": [{ "metricName": "azure_webapplicationfirewallcaptcharequestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "timeAggregation": "sum" }],
"aggregations": [{ "metricName": "azure_webapplicationfirewallcaptcharequestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "temporality": "", "timeAggregation": "sum" }],
"dataSource": "metrics", "disabled": false, "expression": "A",
"filter": { "expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'" },
"filters": { "items": [
{ "id": "f015-name", "key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" }, "op": "IN", "value": "$cdnprofile" },
{ "id": "f015-sub", "key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" }, "op": "=", "value": "$azuremonitor.subscription_id" },
{ "id": "f015-rg", "key": { "id": "resource_group", "key": "resource_group", "type": "" }, "op": "=", "value": "$resource_group" },
{ "id": "f015-type", "key": { "id": "type", "key": "type", "type": "" }, "op": "=", "value": "Microsoft.Cdn/profiles" }
], "op": "AND" },
"functions": [], "groupBy": [{ "dataType": "string", "id": "name--string--tag", "isColumn": false, "isJSON": false, "key": "name", "type": "tag" }],
"having": { "expression": "" }, "legend": "{{name}}", "limit": null, "orderBy": [], "queryName": "A", "source": "", "stepInterval": null
}],
@@ -1197,9 +1455,15 @@
"query": {
"builder": {
"queryData": [{
"aggregations": [{ "metricName": "azure_webapplicationfirewalljsrequestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "timeAggregation": "sum" }],
"aggregations": [{ "metricName": "azure_webapplicationfirewalljsrequestcount_total", "reduceTo": "sum", "spaceAggregation": "sum", "temporality": "", "timeAggregation": "sum" }],
"dataSource": "metrics", "disabled": false, "expression": "A",
"filter": { "expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $cdnprofile AND type = 'Microsoft.Cdn/profiles'" },
"filters": { "items": [
{ "id": "f016-name", "key": { "dataType": "string", "id": "name--string--", "key": "name", "type": "" }, "op": "IN", "value": "$cdnprofile" },
{ "id": "f016-sub", "key": { "id": "azuremonitor.subscription_id", "key": "azuremonitor.subscription_id", "type": "" }, "op": "=", "value": "$azuremonitor.subscription_id" },
{ "id": "f016-rg", "key": { "id": "resource_group", "key": "resource_group", "type": "" }, "op": "=", "value": "$resource_group" },
{ "id": "f016-type", "key": { "id": "type", "key": "type", "type": "" }, "op": "=", "value": "Microsoft.Cdn/profiles" }
], "op": "AND" },
"functions": [], "groupBy": [{ "dataType": "string", "id": "name--string--tag", "isColumn": false, "isJSON": false, "key": "name", "type": "tag" }],
"having": { "expression": "" }, "legend": "{{name}}", "limit": null, "orderBy": [], "queryName": "A", "source": "", "stepInterval": null
}],

View File

@@ -272,6 +272,7 @@
"metricName": "azure_blobcapacity_average",
"reduceTo": "avg",
"spaceAggregation": "sum",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -281,6 +282,52 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $storageaccount AND type = 'Microsoft.Storage/storageAccounts/blobServices'"
},
"filters": {
"items": [
{
"id": "8ad4d515-5e1e-440c-870b-05315f919297",
"key": {
"dataType": "string",
"id": "name--string--",
"key": "name",
"type": ""
},
"op": "IN",
"value": "$storageaccount"
},
{
"id": "e4fcdf44-7f3a-498a-a940-7e51c0ee0207",
"key": {
"id": "azuremonitor.subscription_id",
"key": "azuremonitor.subscription_id",
"type": ""
},
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "35a98ed2-e48d-4eb5-80e2-53452199c5a9",
"key": {
"id": "resource_group",
"key": "resource_group",
"type": ""
},
"op": "=",
"value": "$resource_group"
},
{
"id": "8c85d60a-985b-474d-b92a-0303fa02ba7d",
"key": {
"id": "type",
"key": "type",
"type": ""
},
"op": "=",
"value": "Microsoft.Storage/storageAccounts/blobServices"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -418,6 +465,7 @@
"metricName": "azure_blobcount_average",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -427,6 +475,52 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $storageaccount AND type = 'Microsoft.Storage/storageAccounts/blobServices'"
},
"filters": {
"items": [
{
"id": "8ad4d515-5e1e-440c-870b-05315f919297",
"key": {
"dataType": "string",
"id": "name--string--",
"key": "name",
"type": ""
},
"op": "IN",
"value": "$storageaccount"
},
{
"id": "d14f31c6-ad28-43cc-91a3-f7c18231c7e6",
"key": {
"id": "azuremonitor.subscription_id",
"key": "azuremonitor.subscription_id",
"type": ""
},
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "246f20e4-558c-4a69-9488-6fc3b0824264",
"key": {
"id": "resource_group",
"key": "resource_group",
"type": ""
},
"op": "=",
"value": "$resource_group"
},
{
"id": "a2a4fa45-7b95-4bd8-8737-1109215c489d",
"key": {
"id": "type",
"key": "type",
"type": ""
},
"op": "=",
"value": "Microsoft.Storage/storageAccounts/blobServices"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -564,6 +658,7 @@
"metricName": "azure_containercount_average",
"reduceTo": "avg",
"spaceAggregation": "avg",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -573,6 +668,52 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $storageaccount AND type = 'Microsoft.Storage/storageAccounts/blobServices'"
},
"filters": {
"items": [
{
"id": "8ad4d515-5e1e-440c-870b-05315f919297",
"key": {
"dataType": "string",
"id": "name--string--",
"key": "name",
"type": ""
},
"op": "IN",
"value": "$storageaccount"
},
{
"id": "08a10d11-770a-4518-9eed-1cede51180cc",
"key": {
"id": "azuremonitor.subscription_id",
"key": "azuremonitor.subscription_id",
"type": ""
},
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "7a1fe360-f53f-486a-9581-8f975aa9dfd8",
"key": {
"id": "resource_group",
"key": "resource_group",
"type": ""
},
"op": "=",
"value": "$resource_group"
},
{
"id": "3864e736-3761-4b6b-8715-5dba6f9eae53",
"key": {
"id": "type",
"key": "type",
"type": ""
},
"op": "=",
"value": "Microsoft.Storage/storageAccounts/blobServices"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -722,6 +863,7 @@
"metricName": "azure_availability_average",
"reduceTo": "avg",
"spaceAggregation": "min",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -731,6 +873,52 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $storageaccount AND type = 'Microsoft.Storage/storageAccounts/blobServices'"
},
"filters": {
"items": [
{
"id": "8ad4d515-5e1e-440c-870b-05315f919297",
"key": {
"dataType": "string",
"id": "name--string--",
"key": "name",
"type": ""
},
"op": "IN",
"value": "$storageaccount"
},
{
"id": "2e256002-761e-46da-ab9a-8dc0f33ac187",
"key": {
"id": "azuremonitor.subscription_id",
"key": "azuremonitor.subscription_id",
"type": ""
},
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "cb12f76b-e16e-4d92-aa88-d1bccf1fe9c0",
"key": {
"id": "resource_group",
"key": "resource_group",
"type": ""
},
"op": "=",
"value": "$resource_group"
},
{
"id": "fb865049-0636-4851-9da5-3c61ddff26a2",
"key": {
"id": "type",
"key": "type",
"type": ""
},
"op": "=",
"value": "Microsoft.Storage/storageAccounts/blobServices"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -868,6 +1056,7 @@
"metricName": "azure_egress_average",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -877,6 +1066,52 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $storageaccount AND type = 'Microsoft.Storage/storageAccounts/blobServices'"
},
"filters": {
"items": [
{
"id": "8ad4d515-5e1e-440c-870b-05315f919297",
"key": {
"dataType": "string",
"id": "name--string--",
"key": "name",
"type": ""
},
"op": "IN",
"value": "$storageaccount"
},
{
"id": "9716a7c9-ed42-4921-bad8-c5fb6b68fef2",
"key": {
"id": "azuremonitor.subscription_id",
"key": "azuremonitor.subscription_id",
"type": ""
},
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "2a7a68bf-9033-4494-b5c7-e82af92423e2",
"key": {
"id": "resource_group",
"key": "resource_group",
"type": ""
},
"op": "=",
"value": "$resource_group"
},
{
"id": "c9ea764d-b6af-4e93-b097-093ff562cc8e",
"key": {
"id": "type",
"key": "type",
"type": ""
},
"op": "=",
"value": "Microsoft.Storage/storageAccounts/blobServices"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -1012,6 +1247,7 @@
"metricName": "azure_ingress_average",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -1021,6 +1257,52 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $storageaccount AND type = 'Microsoft.Storage/storageAccounts/blobServices'"
},
"filters": {
"items": [
{
"id": "8ad4d515-5e1e-440c-870b-05315f919297",
"key": {
"dataType": "string",
"id": "name--string--",
"key": "name",
"type": ""
},
"op": "IN",
"value": "$storageaccount"
},
{
"id": "c5bb4e0b-f88a-4041-85f7-cbc07b5073bc",
"key": {
"id": "azuremonitor.subscription_id",
"key": "azuremonitor.subscription_id",
"type": ""
},
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "2b3de77d-2fde-465d-ba7e-9d7be8b6853a",
"key": {
"id": "resource_group",
"key": "resource_group",
"type": ""
},
"op": "=",
"value": "$resource_group"
},
{
"id": "adf659d5-6609-4720-98d0-4129321b63f7",
"key": {
"id": "type",
"key": "type",
"type": ""
},
"op": "=",
"value": "Microsoft.Storage/storageAccounts/blobServices"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -1156,6 +1438,7 @@
"metricName": "azure_successe2elatency_average",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -1165,6 +1448,52 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $storageaccount AND type = 'Microsoft.Storage/storageAccounts/blobServices'"
},
"filters": {
"items": [
{
"id": "8ad4d515-5e1e-440c-870b-05315f919297",
"key": {
"dataType": "string",
"id": "name--string--",
"key": "name",
"type": ""
},
"op": "IN",
"value": "$storageaccount"
},
{
"id": "725192d6-cdfa-466f-87b3-960980c26bc4",
"key": {
"id": "azuremonitor.subscription_id",
"key": "azuremonitor.subscription_id",
"type": ""
},
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "301cb143-a872-4b17-b335-cb638d8d7022",
"key": {
"id": "resource_group",
"key": "resource_group",
"type": ""
},
"op": "=",
"value": "$resource_group"
},
{
"id": "22b7d4ca-56b5-4bfc-b123-0f4988a961d0",
"key": {
"id": "type",
"key": "type",
"type": ""
},
"op": "=",
"value": "Microsoft.Storage/storageAccounts/blobServices"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -1300,6 +1629,7 @@
"metricName": "azure_successserverlatency_average",
"reduceTo": "avg",
"spaceAggregation": "max",
"temporality": "",
"timeAggregation": "avg"
}
],
@@ -1309,6 +1639,52 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $storageaccount AND type = 'Microsoft.Storage/storageAccounts/blobServices'"
},
"filters": {
"items": [
{
"id": "8ad4d515-5e1e-440c-870b-05315f919297",
"key": {
"dataType": "string",
"id": "name--string--",
"key": "name",
"type": ""
},
"op": "IN",
"value": "$storageaccount"
},
{
"id": "cccb9c11-9e54-40e3-9b75-21a753f0651a",
"key": {
"id": "azuremonitor.subscription_id",
"key": "azuremonitor.subscription_id",
"type": ""
},
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "32b7a033-1da0-43da-83cf-0beb7fb6eb5d",
"key": {
"id": "resource_group",
"key": "resource_group",
"type": ""
},
"op": "=",
"value": "$resource_group"
},
{
"id": "77d3f853-9720-46a6-ac71-405ccd2d16e1",
"key": {
"id": "type",
"key": "type",
"type": ""
},
"op": "=",
"value": "Microsoft.Storage/storageAccounts/blobServices"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
@@ -1444,6 +1820,7 @@
"metricName": "azure_transactions_total",
"reduceTo": "sum",
"spaceAggregation": "sum",
"temporality": "",
"timeAggregation": "sum"
}
],
@@ -1453,6 +1830,52 @@
"filter": {
"expression": "azuremonitor.subscription_id = $azuremonitor.subscription_id AND resource_group = $resource_group AND name IN $storageaccount AND type = 'Microsoft.Storage/storageAccounts/blobServices'"
},
"filters": {
"items": [
{
"id": "8ad4d515-5e1e-440c-870b-05315f919297",
"key": {
"dataType": "string",
"id": "name--string--",
"key": "name",
"type": ""
},
"op": "IN",
"value": "$storageaccount"
},
{
"id": "bbef20d9-4b62-49a2-b522-079f814406ca",
"key": {
"id": "azuremonitor.subscription_id",
"key": "azuremonitor.subscription_id",
"type": ""
},
"op": "=",
"value": "$azuremonitor.subscription_id"
},
{
"id": "ffbdf757-11b8-45d1-8190-50b4ec067839",
"key": {
"id": "resource_group",
"key": "resource_group",
"type": ""
},
"op": "=",
"value": "$resource_group"
},
{
"id": "65021cbd-add8-44c3-b5a3-16e1c582ccbb",
"key": {
"id": "type",
"key": "type",
"type": ""
},
"op": "=",
"value": "Microsoft.Storage/storageAccounts/blobServices"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{

View File

@@ -380,7 +380,7 @@ func (handler *handler) UpdateService(rw http.ResponseWriter, r *http.Request) {
return
}
err = handler.module.CreateService(ctx, orgID, claims.Email, valuer.MustNewUUID(claims.IdentityID()), cloudIntegrationService, provider)
err = handler.module.CreateService(ctx, orgID, cloudIntegrationService, provider)
} else {
err = svc.CloudIntegrationService.Update(provider, serviceID, req.Config)
if err != nil {
@@ -388,7 +388,7 @@ func (handler *handler) UpdateService(rw http.ResponseWriter, r *http.Request) {
return
}
err = handler.module.UpdateService(ctx, orgID, claims.Email, valuer.MustNewUUID(claims.IdentityID()), svc.CloudIntegrationService, provider)
err = handler.module.UpdateService(ctx, orgID, svc.CloudIntegrationService, provider)
}
if err != nil {
render.Error(rw, err)

View File

@@ -6,6 +6,7 @@ import (
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/modules/cloudintegration"
"github.com/SigNoz/signoz/pkg/types/cloudintegrationtypes"
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
@@ -44,7 +45,7 @@ func (module *module) DisconnectAccount(ctx context.Context, orgID valuer.UUID,
return errors.New(errors.TypeUnsupported, cloudintegrationtypes.ErrCodeUnsupported, "disconnect account is not supported")
}
func (module *module) CreateService(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, service *cloudintegrationtypes.CloudIntegrationService, provider cloudintegrationtypes.CloudProviderType) error {
func (module *module) CreateService(ctx context.Context, orgID valuer.UUID, service *cloudintegrationtypes.CloudIntegrationService, provider cloudintegrationtypes.CloudProviderType) error {
return errors.New(errors.TypeUnsupported, cloudintegrationtypes.ErrCodeUnsupported, "create service is not supported")
}
@@ -56,7 +57,7 @@ func (module *module) ListServicesMetadata(ctx context.Context, orgID valuer.UUI
return nil, errors.New(errors.TypeUnsupported, cloudintegrationtypes.ErrCodeUnsupported, "list services metadata is not supported")
}
func (module *module) UpdateService(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, service *cloudintegrationtypes.CloudIntegrationService, provider cloudintegrationtypes.CloudProviderType) error {
func (module *module) UpdateService(ctx context.Context, orgID valuer.UUID, service *cloudintegrationtypes.CloudIntegrationService, provider cloudintegrationtypes.CloudProviderType) error {
return errors.New(errors.TypeUnsupported, cloudintegrationtypes.ErrCodeUnsupported, "update service is not supported")
}
@@ -68,6 +69,14 @@ func (module *module) AgentCheckIn(ctx context.Context, orgID valuer.UUID, provi
return nil, errors.New(errors.TypeUnsupported, cloudintegrationtypes.ErrCodeUnsupported, "agent check-in is not supported")
}
func (module *module) GetDashboardByID(ctx context.Context, orgID valuer.UUID, id string) (*dashboardtypes.Dashboard, error) {
return nil, errors.New(errors.TypeUnsupported, cloudintegrationtypes.ErrCodeUnsupported, "get dashboard by ID is not supported")
}
func (module *module) ListDashboards(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error) {
return nil, errors.New(errors.TypeUnsupported, cloudintegrationtypes.ErrCodeUnsupported, "list dashboards is not supported")
}
func (module *module) Collect(context.Context, valuer.UUID) (map[string]any, error) {
return nil, errors.New(errors.TypeUnsupported, cloudintegrationtypes.ErrCodeUnsupported, "stats collection is not supported")
}

View File

@@ -4,7 +4,6 @@ import (
"context"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types/cloudintegrationtypes"
"github.com/SigNoz/signoz/pkg/valuer"
@@ -187,41 +186,6 @@ func (store *store) ListServices(ctx context.Context, cloudIntegrationID valuer.
return services, nil
}
func (store *store) ListSharedServices(ctx context.Context, orgID valuer.UUID, provider cloudintegrationtypes.CloudProviderType, cloudIntegrationID valuer.UUID) (map[cloudintegrationtypes.ServiceID][]*cloudintegrationtypes.StorableCloudIntegrationService, error) {
// Subquery: service types that belong to the given account
ownTypes := store.store.BunDBCtx(ctx).
NewSelect().
TableExpr("cloud_integration_service").
ColumnExpr("type").
Where("cloud_integration_id = ?", cloudIntegrationID)
var services []*cloudintegrationtypes.StorableCloudIntegrationService
err := store.
store.
BunDBCtx(ctx).
NewSelect().
TableExpr("cloud_integration_service AS cis").
ColumnExpr("cis.*").
Join("JOIN cloud_integration AS ci ON ci.id = cis.cloud_integration_id").
Where("ci.org_id = ?", orgID).
Where("ci.provider = ?", provider).
Where("ci.removed_at IS NULL").
Where("ci.account_id IS NOT NULL").
Where("ci.last_agent_report IS NOT NULL").
Where("cis.cloud_integration_id != ?", cloudIntegrationID).
Where("cis.type IN (?)", ownTypes).
Scan(ctx, &services)
if err != nil {
return nil, err
}
result := make(map[cloudintegrationtypes.ServiceID][]*cloudintegrationtypes.StorableCloudIntegrationService)
for _, svc := range services {
result[svc.Type] = append(result[svc.Type], svc)
}
return result, nil
}
func (store *store) CreateService(ctx context.Context, service *cloudintegrationtypes.StorableCloudIntegrationService) error {
_, err := store.
store.
@@ -236,24 +200,6 @@ func (store *store) CreateService(ctx context.Context, service *cloudintegration
return nil
}
func (store *store) DeleteServicesByCloudIntegrationID(ctx context.Context, orgID, cloudIntegrationID valuer.UUID) error {
cte := store.store.BunDBCtx(ctx).
NewSelect().
TableExpr("cloud_integration_service AS cis_inner").
ColumnExpr("cis_inner.id").
Join("JOIN cloud_integration AS ci ON cis_inner.cloud_integration_id = ci.id").
Where("ci.org_id = ?", orgID).
Where("cis_inner.cloud_integration_id = ?", cloudIntegrationID)
_, err := store.store.BunDBCtx(ctx).
NewDelete().
Model(new(cloudintegrationtypes.StorableCloudIntegrationService)).
With("target", cte).
Where("id IN (SELECT id FROM target)").
Exec(ctx)
return err
}
func (store *store) UpdateService(ctx context.Context, service *cloudintegrationtypes.StorableCloudIntegrationService) error {
_, err := store.
store.
@@ -267,62 +213,6 @@ func (store *store) UpdateService(ctx context.Context, service *cloudintegration
return err
}
func (store *store) CreateIntegrationDashboard(ctx context.Context, integrationDashboard *cloudintegrationtypes.StorableIntegrationDashboard) error {
_, err := store.store.BunDBCtx(ctx).NewInsert().Model(integrationDashboard).Exec(ctx)
return err
}
func (store *store) GetIntegrationDashboardBySlug(ctx context.Context, orgID valuer.UUID, provider cloudintegrationtypes.IntegrationDashboardProviderType, slug string) (*cloudintegrationtypes.StorableIntegrationDashboard, error) {
integrationDashboard := new(cloudintegrationtypes.StorableIntegrationDashboard)
err := store.store.BunDBCtx(ctx).
NewSelect().
Model(integrationDashboard).
Join("JOIN dashboard AS d ON storable_integration_dashboard.dashboard_id = d.id").
Where("d.org_id = ?", orgID).
Where("storable_integration_dashboard.provider = ?", provider).
Where("storable_integration_dashboard.slug = ?", slug).
Scan(ctx)
if err != nil {
return nil, store.store.WrapNotFoundErrf(err, errors.CodeNotFound, "integration dashboard with slug %s not found", slug)
}
return integrationDashboard, nil
}
func (store *store) ListIntegrationDashboardsBySlugPrefix(ctx context.Context, orgID valuer.UUID, provider cloudintegrationtypes.IntegrationDashboardProviderType, slugPrefix string) ([]*cloudintegrationtypes.StorableIntegrationDashboard, error) {
var integrationDashboards []*cloudintegrationtypes.StorableIntegrationDashboard
err := store.store.BunDBCtx(ctx).
NewSelect().
Model(&integrationDashboards).
Join("JOIN dashboard AS d ON storable_integration_dashboard.dashboard_id = d.id").
Where("d.org_id = ?", orgID).
Where("storable_integration_dashboard.provider = ?", provider).
Where("storable_integration_dashboard.slug LIKE ?", slugPrefix+"%").
Scan(ctx)
if err != nil {
return nil, err
}
return integrationDashboards, nil
}
func (store *store) DeleteIntegrationDashboardBySlug(ctx context.Context, orgID valuer.UUID, provider cloudintegrationtypes.IntegrationDashboardProviderType, slug string) error {
cte := store.store.BunDBCtx(ctx).
NewSelect().
TableExpr("integration_dashboard AS id_inner").
ColumnExpr("id_inner.id").
Join("JOIN dashboard AS d ON id_inner.dashboard_id = d.id").
Where("d.org_id = ?", orgID).
Where("id_inner.provider = ?", provider).
Where("id_inner.slug = ?", slug)
_, err := store.store.BunDBCtx(ctx).
NewDelete().
Model(new(cloudintegrationtypes.StorableIntegrationDashboard)).
With("target", cte).
Where("id IN (SELECT id FROM target)").
Exec(ctx)
return err
}
func (store *store) RunInTx(ctx context.Context, cb func(ctx context.Context) error) error {
return store.store.RunInTxCtx(ctx, nil, func(ctx context.Context) error {
return cb(ctx)

View File

@@ -34,7 +34,7 @@ type Module interface {
// deletes the public sharing config and disables public sharing for the dashboard
DeletePublic(context.Context, valuer.UUID, valuer.UUID) error
Create(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, source dashboardtypes.Source, data dashboardtypes.PostableDashboard) (*dashboardtypes.Dashboard, error)
Create(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, data dashboardtypes.PostableDashboard) (*dashboardtypes.Dashboard, error)
Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*dashboardtypes.Dashboard, error)
@@ -46,9 +46,6 @@ type Module interface {
Delete(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error
// DeleteUnsafe deletes a dashboard bypassing the guards. Intended for internal system callers.
DeleteUnsafe(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error
GetByMetricNames(ctx context.Context, orgID valuer.UUID, metricNames []string) (map[string][]map[string]string, error)
statsreporter.StatsCollector

View File

@@ -60,7 +60,7 @@ func (handler *handler) Create(rw http.ResponseWriter, r *http.Request) {
dashboardMigrator.Migrate(ctx, req)
}
dashboard, err := handler.module.Create(ctx, orgID, claims.Email, valuer.MustNewUUID(claims.IdentityID()), dashboardtypes.SourceUser, req)
dashboard, err := handler.module.Create(ctx, orgID, claims.Email, valuer.MustNewUUID(claims.IdentityID()), req)
if err != nil {
render.Error(rw, err)
return

View File

@@ -37,8 +37,8 @@ func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, an
}
}
func (module *module) Create(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, source dashboardtypes.Source, postableDashboard dashboardtypes.PostableDashboard) (*dashboardtypes.Dashboard, error) {
dashboard, err := dashboardtypes.NewDashboard(orgID, createdBy, source, postableDashboard)
func (module *module) Create(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, postableDashboard dashboardtypes.PostableDashboard) (*dashboardtypes.Dashboard, error) {
dashboard, err := dashboardtypes.NewDashboard(orgID, createdBy, dashboardtypes.SourceUser, postableDashboard)
if err != nil {
return nil, err
}
@@ -161,10 +161,6 @@ func (module *module) Delete(ctx context.Context, orgID valuer.UUID, id valuer.U
return nil
}
func (module *module) DeleteUnsafe(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error {
return module.store.Delete(ctx, orgID, id)
}
func (module *module) GetByMetricNames(ctx context.Context, orgID valuer.UUID, metricNames []string) (map[string][]map[string]string, error) {
dashboards, err := module.List(ctx, orgID)
if err != nil {

View File

@@ -21,7 +21,7 @@ func NewStore(sqlstore sqlstore.SQLStore) dashboardtypes.Store {
func (store *store) Create(ctx context.Context, storabledashboard *dashboardtypes.StorableDashboard) error {
_, err := store.
sqlstore.
BunDBCtx(ctx).
BunDB().
NewInsert().
Model(storabledashboard).
Exec(ctx)

View File

@@ -2,11 +2,8 @@ package implspanmapper
import (
"context"
"encoding/json"
"github.com/SigNoz/signoz/pkg/modules/spanmapper"
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
"github.com/SigNoz/signoz/pkg/types/opamptypes"
"github.com/SigNoz/signoz/pkg/types/spantypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
@@ -37,22 +34,11 @@ func (module *module) UpdateGroup(ctx context.Context, orgID, id valuer.UUID, na
return err
}
group.Update(name, condition, enabled, updatedBy)
err = module.store.UpdateGroup(ctx, group)
if err != nil {
return err
}
agentConf.NotifyConfigUpdate(ctx)
return nil
return module.store.UpdateGroup(ctx, group)
}
func (module *module) DeleteGroup(ctx context.Context, orgID, id valuer.UUID) error {
err := module.store.DeleteGroup(ctx, orgID, id)
if err != nil {
return err
}
agentConf.NotifyConfigUpdate(ctx)
return nil
return module.store.DeleteGroup(ctx, orgID, id)
}
func (module *module) ListMappers(ctx context.Context, orgID, groupID valuer.UUID) ([]*spantypes.SpanMapper, error) {
@@ -68,12 +54,7 @@ func (module *module) CreateMapper(ctx context.Context, orgID, groupID valuer.UU
if _, err := module.store.GetGroup(ctx, orgID, groupID); err != nil {
return err
}
err := module.store.CreateMapper(ctx, mapper)
if err != nil {
return err
}
agentConf.NotifyConfigUpdate(ctx)
return nil
return module.store.CreateMapper(ctx, mapper)
}
func (module *module) UpdateMapper(ctx context.Context, orgID, groupID, id valuer.UUID, fieldContext spantypes.FieldContext, config *spantypes.SpanMapperConfig, enabled *bool, updatedBy string) error {
@@ -85,72 +66,9 @@ func (module *module) UpdateMapper(ctx context.Context, orgID, groupID, id value
return err
}
mapper.Update(fieldContext, config, enabled, updatedBy)
err = module.store.UpdateMapper(ctx, mapper)
if err != nil {
return err
}
agentConf.NotifyConfigUpdate(ctx)
return nil
return module.store.UpdateMapper(ctx, mapper)
}
func (module *module) DeleteMapper(ctx context.Context, orgID, groupID, id valuer.UUID) error {
err := module.store.DeleteMapper(ctx, orgID, groupID, id)
if err != nil {
return err
}
agentConf.NotifyConfigUpdate(ctx)
return nil
}
func (module *module) AgentFeatureType() agentConf.AgentFeatureType {
return spantypes.SpanAttrMappingFeatureType
}
func (module *module) RecommendAgentConfig(orgID valuer.UUID, currentConfYaml []byte, configVersion *opamptypes.AgentConfigVersion) ([]byte, string, error) {
ctx := context.Background()
enabled, err := module.listEnabledGroupsWithMappers(ctx, orgID)
if err != nil {
return nil, "", err
}
updatedConf, err := spantypes.GenerateCollectorConfigWithSpanMapperProcessor(currentConfYaml, enabled)
if err != nil {
return nil, "", err
}
serialized, err := json.Marshal(enabled)
if err != nil {
return nil, "", err
}
return updatedConf, string(serialized), nil
}
// listEnabledGroupsWithMappers returns groups with their mappers.
func (module *module) listEnabledGroupsWithMappers(ctx context.Context, orgID valuer.UUID) ([]*spantypes.SpanMapperGroupWithMappers, error) {
enabled := true
groups, err := module.store.ListGroups(ctx, orgID, &spantypes.ListSpanMapperGroupsQuery{Enabled: &enabled})
if err != nil {
return nil, err
}
out := make([]*spantypes.SpanMapperGroupWithMappers, 0, len(groups))
for _, g := range groups {
mappers, err := module.store.ListMappers(ctx, orgID, g.ID)
if err != nil {
return nil, err
}
enabledMappers := make([]*spantypes.SpanMapper, 0, len(mappers))
for _, m := range mappers {
if m.Enabled {
enabledMappers = append(enabledMappers, m)
}
}
if len(enabledMappers) == 0 {
continue
}
out = append(out, &spantypes.SpanMapperGroupWithMappers{Group: g, Mappers: enabledMappers})
}
return out, nil
return module.store.DeleteMapper(ctx, orgID, groupID, id)
}

View File

@@ -4,16 +4,12 @@ import (
"context"
"net/http"
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
"github.com/SigNoz/signoz/pkg/types/spantypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
// Module defines the business logic for span attribute mapping groups and mappers.
type Module interface {
// Since this module interacts with OpAMP, it must implement the AgentFeature interface.
agentConf.AgentFeature
// Group operations
ListGroups(ctx context.Context, orgID valuer.UUID, q *spantypes.ListSpanMapperGroupsQuery) ([]*spantypes.SpanMapperGroup, error)
GetGroup(ctx context.Context, orgID, id valuer.UUID) (*spantypes.SpanMapperGroup, error)

View File

@@ -6,7 +6,7 @@ import (
"github.com/SigNoz/signoz/pkg/http/binding"
"github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/modules/tracedetail"
"github.com/SigNoz/signoz/pkg/types/spantypes"
"github.com/SigNoz/signoz/pkg/types/tracedetailtypes"
"github.com/gorilla/mux"
)
@@ -19,7 +19,7 @@ func NewHandler(module tracedetail.Module) tracedetail.Handler {
}
func (h *handler) GetWaterfall(rw http.ResponseWriter, r *http.Request) {
req := new(spantypes.PostableWaterfall)
req := new(tracedetailtypes.PostableWaterfall)
if err := binding.JSON.BindBody(r.Body, req); err != nil {
render.Error(rw, err)
return

View File

@@ -5,16 +5,16 @@ import (
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/modules/tracedetail"
"github.com/SigNoz/signoz/pkg/types/spantypes"
"github.com/SigNoz/signoz/pkg/types/tracedetailtypes"
)
type module struct {
store spantypes.TraceStore
store tracedetailtypes.TraceStore
settings factory.ScopedProviderSettings
config tracedetail.Config
}
func NewModule(traceStore spantypes.TraceStore, providerSettings factory.ProviderSettings, cfg tracedetail.Config) *module {
func NewModule(traceStore tracedetailtypes.TraceStore, providerSettings factory.ProviderSettings, cfg tracedetail.Config) *module {
scopedProviderSettings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/pkg/modules/tracedetail/impltracedetail")
return &module{
config: cfg,
@@ -23,7 +23,7 @@ func NewModule(traceStore spantypes.TraceStore, providerSettings factory.Provide
}
}
func (m *module) GetWaterfall(ctx context.Context, traceID string, req *spantypes.PostableWaterfall) (*spantypes.GettableWaterfallTrace, error) {
func (m *module) GetWaterfall(ctx context.Context, traceID string, req *tracedetailtypes.PostableWaterfall) (*tracedetailtypes.GettableWaterfallTrace, error) {
waterfallTrace, err := m.getTraceData(ctx, traceID)
if err != nil {
return nil, err
@@ -37,16 +37,16 @@ func (m *module) GetWaterfall(ctx context.Context, traceID string, req *spantype
m.config.Waterfall.MaxDepthToAutoExpand,
)
aggregationResults := make([]spantypes.SpanAggregationResult, 0, len(req.Aggregations))
aggregationResults := make([]tracedetailtypes.SpanAggregationResult, 0, len(req.Aggregations))
for _, a := range req.Aggregations {
aggregationResults = append(aggregationResults, waterfallTrace.GetSpanAggregation(a.Aggregation, a.Field))
}
return spantypes.NewGettableWaterfallTrace(waterfallTrace, selectedSpans, uncollapsedSpans, selectedAllSpans, aggregationResults), nil
return tracedetailtypes.NewGettableWaterfallTrace(waterfallTrace, selectedSpans, uncollapsedSpans, selectedAllSpans, aggregationResults), nil
}
// getTraceData returns the waterfall cache for the given traceID with fallback on DB.
func (m *module) getTraceData(ctx context.Context, traceID string) (*spantypes.WaterfallTrace, error) {
func (m *module) getTraceData(ctx context.Context, traceID string) (*tracedetailtypes.WaterfallTrace, error) {
summary, err := m.store.GetTraceSummary(ctx, traceID)
if err != nil {
return nil, err
@@ -58,9 +58,9 @@ func (m *module) getTraceData(ctx context.Context, traceID string) (*spantypes.W
}
if len(spanItems) == 0 {
return nil, spantypes.ErrTraceNotFound
return nil, tracedetailtypes.ErrTraceNotFound
}
traceData := spantypes.NewWaterfallTraceFromSpans(spanItems)
traceData := tracedetailtypes.NewWaterfallTraceFromSpans(spanItems)
return traceData, nil
}

View File

@@ -9,7 +9,7 @@ import (
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/telemetrystore"
"github.com/SigNoz/signoz/pkg/types/spantypes"
"github.com/SigNoz/signoz/pkg/types/tracedetailtypes"
)
type traceStore struct {
@@ -20,28 +20,28 @@ func NewTraceStore(ts telemetrystore.TelemetryStore) *traceStore {
return &traceStore{telemetryStore: ts}
}
func (s *traceStore) GetTraceSummary(ctx context.Context, traceID string) (*spantypes.TraceSummary, error) {
func (s *traceStore) GetTraceSummary(ctx context.Context, traceID string) (*tracedetailtypes.TraceSummary, error) {
sb := sqlbuilder.NewSelectBuilder()
sb.Select("trace_id", "min(start) AS start", "max(end) AS end", "sum(num_spans) AS num_spans")
sb.From(fmt.Sprintf("%s.%s", spantypes.TraceDB, spantypes.TraceSummaryTable))
sb.From(fmt.Sprintf("%s.%s", tracedetailtypes.TraceDB, tracedetailtypes.TraceSummaryTable))
sb.Where(sb.E("trace_id", traceID))
sb.GroupBy("trace_id")
query, args := sb.BuildWithFlavor(sqlbuilder.ClickHouse)
var summary spantypes.TraceSummary
var summary tracedetailtypes.TraceSummary
err := s.telemetryStore.ClickhouseDB().QueryRow(ctx, query, args...).Scan(
&summary.TraceID, &summary.Start, &summary.End, &summary.NumSpans,
)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, spantypes.ErrTraceNotFound
return nil, tracedetailtypes.ErrTraceNotFound
}
return nil, errors.WrapInternalf(err, errors.CodeInternal, "error querying trace summary")
}
return &summary, nil
}
func (s *traceStore) GetTraceSpans(ctx context.Context, traceID string, summary *spantypes.TraceSummary) ([]spantypes.StorableSpan, error) {
func (s *traceStore) GetTraceSpans(ctx context.Context, traceID string, summary *tracedetailtypes.TraceSummary) ([]tracedetailtypes.StorableSpan, error) {
// DISTINCT ON (span_id) is ClickHouse-specific syntax not supported by sqlbuilder
query := fmt.Sprintf(`
SELECT DISTINCT ON (span_id)
@@ -55,9 +55,9 @@ func (s *traceStore) GetTraceSpans(ctx context.Context, traceID string, summary
FROM %s.%s
WHERE trace_id=? AND ts_bucket_start>=? AND ts_bucket_start<=?
ORDER BY timestamp ASC, name ASC`,
spantypes.TraceDB, spantypes.TraceTable,
tracedetailtypes.TraceDB, tracedetailtypes.TraceTable,
)
var spanItems []spantypes.StorableSpan
var spanItems []tracedetailtypes.StorableSpan
err := s.telemetryStore.ClickhouseDB().Select(
ctx, &spanItems, query,
traceID,

View File

@@ -37,7 +37,7 @@ import (
"fmt"
"testing"
"github.com/SigNoz/signoz/pkg/types/spantypes"
"github.com/SigNoz/signoz/pkg/types/tracedetailtypes"
"github.com/stretchr/testify/assert"
)
@@ -45,8 +45,8 @@ import (
// Helpers
// ─────────────────────────────────────────────────────────────────────────────
func mkSpan(id, service string, children ...*spantypes.WaterfallSpan) *spantypes.WaterfallSpan {
return &spantypes.WaterfallSpan{
func mkSpan(id, service string, children ...*tracedetailtypes.WaterfallSpan) *tracedetailtypes.WaterfallSpan {
return &tracedetailtypes.WaterfallSpan{
SpanID: id,
ServiceName: service,
Name: id + "-op",
@@ -54,7 +54,7 @@ func mkSpan(id, service string, children ...*spantypes.WaterfallSpan) *spantypes
}
}
func spanIDs(spans []*spantypes.WaterfallSpan) []string {
func spanIDs(spans []*tracedetailtypes.WaterfallSpan) []string {
ids := make([]string, len(spans))
for i, s := range spans {
ids[i] = s.SpanID
@@ -62,10 +62,10 @@ func spanIDs(spans []*spantypes.WaterfallSpan) []string {
return ids
}
func buildSpanMap(roots ...*spantypes.WaterfallSpan) map[string]*spantypes.WaterfallSpan {
m := map[string]*spantypes.WaterfallSpan{}
var walk func(*spantypes.WaterfallSpan)
walk = func(s *spantypes.WaterfallSpan) {
func buildSpanMap(roots ...*tracedetailtypes.WaterfallSpan) map[string]*tracedetailtypes.WaterfallSpan {
m := map[string]*tracedetailtypes.WaterfallSpan{}
var walk func(*tracedetailtypes.WaterfallSpan)
walk = func(s *tracedetailtypes.WaterfallSpan) {
m[s.SpanID] = s
for _, c := range s.Children {
walk(c)
@@ -80,8 +80,8 @@ func buildSpanMap(roots ...*spantypes.WaterfallSpan) map[string]*spantypes.Water
}
// makeChain builds a linear trace: span0 → span1 → … → span(n-1).
func makeChain(n int) (*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan, []string) {
spans := make([]*spantypes.WaterfallSpan, n)
func makeChain(n int) (*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan, []string) {
spans := make([]*tracedetailtypes.WaterfallSpan, n)
for i := n - 1; i >= 0; i-- {
if i == n-1 {
spans[i] = mkSpan(fmt.Sprintf("span%d", i), "svc")
@@ -96,8 +96,8 @@ func makeChain(n int) (*spantypes.WaterfallSpan, map[string]*spantypes.Waterfall
return spans[0], buildSpanMap(spans[0]), uncollapsed
}
func getWaterfallTrace(roots []*spantypes.WaterfallSpan, spanMap map[string]*spantypes.WaterfallSpan) *spantypes.WaterfallTrace {
return spantypes.NewWaterfallTrace(0, 0, uint64(len(spanMap)), 0, spanMap, nil, roots, false)
func getWaterfallTrace(roots []*tracedetailtypes.WaterfallSpan, spanMap map[string]*tracedetailtypes.WaterfallSpan) *tracedetailtypes.WaterfallTrace {
return tracedetailtypes.NewWaterfallTrace(0, 0, uint64(len(spanMap)), 0, spanMap, nil, roots, false)
}
// ─────────────────────────────────────────────────────────────────────────────
@@ -107,7 +107,7 @@ func getWaterfallTrace(roots []*spantypes.WaterfallSpan, spanMap map[string]*spa
func TestGetSelectedSpans_SpanOrdering(t *testing.T) {
tests := []struct {
name string
buildRoots func() ([]*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan)
buildRoots func() ([]*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan)
uncollapsedSpans []string
selectedSpanID string
wantSpanIDs []string
@@ -115,12 +115,12 @@ func TestGetSelectedSpans_SpanOrdering(t *testing.T) {
{
// Pre-order traversal is preserved: parent before children, siblings left-to-right.
name: "pre_order_traversal",
buildRoots: func() ([]*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoots: func() ([]*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("child1", "svc", mkSpan("grandchild", "svc")),
mkSpan("child2", "svc"),
)
return []*spantypes.WaterfallSpan{root}, buildSpanMap(root)
return []*tracedetailtypes.WaterfallSpan{root}, buildSpanMap(root)
},
uncollapsedSpans: []string{"root", "child1"},
selectedSpanID: "root",
@@ -133,12 +133,12 @@ func TestGetSelectedSpans_SpanOrdering(t *testing.T) {
// ├─ childA (uncollapsed) → grandchildA ✓
// └─ childB (uncollapsed) → grandchildB ✓
name: "multiple_uncollapsed",
buildRoots: func() ([]*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoots: func() ([]*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("childA", "svc", mkSpan("grandchildA", "svc")),
mkSpan("childB", "svc", mkSpan("grandchildB", "svc")),
)
return []*spantypes.WaterfallSpan{root}, buildSpanMap(root)
return []*tracedetailtypes.WaterfallSpan{root}, buildSpanMap(root)
},
uncollapsedSpans: []string{"root", "childA", "childB"},
selectedSpanID: "root",
@@ -154,7 +154,7 @@ func TestGetSelectedSpans_SpanOrdering(t *testing.T) {
// │ └─ grandchild2 ✓
// └─ childB ← selected (not expanded)
name: "manual_uncollapse",
buildRoots: func() ([]*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoots: func() ([]*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("childA", "svc",
mkSpan("grandchild1", "svc", mkSpan("greatGrandchild", "svc")),
@@ -162,7 +162,7 @@ func TestGetSelectedSpans_SpanOrdering(t *testing.T) {
),
mkSpan("childB", "svc"),
)
return []*spantypes.WaterfallSpan{root}, buildSpanMap(root)
return []*tracedetailtypes.WaterfallSpan{root}, buildSpanMap(root)
},
uncollapsedSpans: []string{"childA"},
selectedSpanID: "childB",
@@ -171,12 +171,12 @@ func TestGetSelectedSpans_SpanOrdering(t *testing.T) {
{
// A collapsed span hides all children.
name: "collapsed_span_hides_children",
buildRoots: func() ([]*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoots: func() ([]*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("child1", "svc"),
mkSpan("child2", "svc"),
)
return []*spantypes.WaterfallSpan{root}, buildSpanMap(root)
return []*tracedetailtypes.WaterfallSpan{root}, buildSpanMap(root)
},
uncollapsedSpans: []string{},
selectedSpanID: "root",
@@ -187,13 +187,13 @@ func TestGetSelectedSpans_SpanOrdering(t *testing.T) {
//
// root → parent → selected
name: "path_to_selected_is_uncollapsed",
buildRoots: func() ([]*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoots: func() ([]*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("parent", "svc",
mkSpan("selected", "svc"),
),
)
return []*spantypes.WaterfallSpan{root}, buildSpanMap(root)
return []*tracedetailtypes.WaterfallSpan{root}, buildSpanMap(root)
},
uncollapsedSpans: []string{},
selectedSpanID: "selected",
@@ -206,14 +206,14 @@ func TestGetSelectedSpans_SpanOrdering(t *testing.T) {
// ├─ unrelated → unrelated-child (✗)
// └─ parent → selected
name: "siblings_not_expanded",
buildRoots: func() ([]*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoots: func() ([]*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("unrelated", "svc", mkSpan("unrelated-child", "svc")),
mkSpan("parent", "svc",
mkSpan("selected", "svc"),
),
)
return []*spantypes.WaterfallSpan{root}, buildSpanMap(root)
return []*tracedetailtypes.WaterfallSpan{root}, buildSpanMap(root)
},
uncollapsedSpans: []string{},
selectedSpanID: "selected",
@@ -223,9 +223,9 @@ func TestGetSelectedSpans_SpanOrdering(t *testing.T) {
{
// An unknown selectedSpanID must not panic; returns a window from index 0.
name: "unknown_selected_span",
buildRoots: func() ([]*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoots: func() ([]*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc", mkSpan("child", "svc"))
return []*spantypes.WaterfallSpan{root}, buildSpanMap(root)
return []*tracedetailtypes.WaterfallSpan{root}, buildSpanMap(root)
},
uncollapsedSpans: []string{},
selectedSpanID: "nonexistent",
@@ -257,10 +257,10 @@ func TestGetSelectedSpans_MultipleRoots(t *testing.T) {
root2 := mkSpan("root2", "svc-b", mkSpan("child2", "svc-b"))
spanMap := buildSpanMap(root1, root2)
trace := getWaterfallTrace([]*spantypes.WaterfallSpan{root1, root2}, spanMap)
trace := getWaterfallTrace([]*tracedetailtypes.WaterfallSpan{root1, root2}, spanMap)
spans, _ := trace.GetSelectedSpans([]string{"root1", "root2"}, "root1", 500, 5)
traceRespnose := spantypes.NewGettableWaterfallTrace(trace, spans, nil, false, nil)
traceRespnose := tracedetailtypes.NewGettableWaterfallTrace(trace, spans, nil, false, nil)
assert.Equal(t, []string{"root1", "child1", "root2", "child2"}, spanIDs(spans), "root1 subtree must precede root2 subtree")
assert.Equal(t, "svc-a", traceRespnose.RootServiceName, "metadata comes from first root")
@@ -274,7 +274,7 @@ func TestGetSelectedSpans_MultipleRoots(t *testing.T) {
func TestGetSelectedSpans_UncollapsedTracking(t *testing.T) {
tests := []struct {
name string
buildRoot func() (*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan)
buildRoot func() (*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan)
uncollapsedSpans []string
selectedSpanID string
wantSpanIDs []string
@@ -283,7 +283,7 @@ func TestGetSelectedSpans_UncollapsedTracking(t *testing.T) {
{
// The path-to-selected spans are returned in updatedUncollapsedSpans.
name: "path_returned_in_uncollapsed",
buildRoot: func() (*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoot: func() (*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("parent", "svc",
mkSpan("selected", "svc"),
@@ -301,7 +301,7 @@ func TestGetSelectedSpans_UncollapsedTracking(t *testing.T) {
{
// Siblings of ancestors are not tracked as uncollapsed.
name: "siblings_not_in_uncollapsed",
buildRoot: func() (*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoot: func() (*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("unrelated", "svc", mkSpan("unrelated-child", "svc")),
mkSpan("parent", "svc",
@@ -330,7 +330,7 @@ func TestGetSelectedSpans_UncollapsedTracking(t *testing.T) {
// └─ grandchildB (internal ✓)
// └─ leafB (leaf ✗)
name: "auto_expanded_spans_returned",
buildRoot: func() (*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoot: func() (*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("childA", "svc",
mkSpan("grandchildA", "svc",
@@ -361,7 +361,7 @@ func TestGetSelectedSpans_UncollapsedTracking(t *testing.T) {
// If the selected span is already in uncollapsedSpans,
// it should appear exactly once in the result.
name: "duplicate_in_uncollapsed",
buildRoot: func() (*spantypes.WaterfallSpan, map[string]*spantypes.WaterfallSpan) {
buildRoot: func() (*tracedetailtypes.WaterfallSpan, map[string]*tracedetailtypes.WaterfallSpan) {
root := mkSpan("root", "svc",
mkSpan("selected", "svc", mkSpan("child", "svc")),
)
@@ -384,7 +384,7 @@ func TestGetSelectedSpans_UncollapsedTracking(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
root, spanMap := tc.buildRoot()
trace := getWaterfallTrace([]*spantypes.WaterfallSpan{root}, spanMap)
trace := getWaterfallTrace([]*tracedetailtypes.WaterfallSpan{root}, spanMap)
spans, uncollapsed := trace.GetSelectedSpans(tc.uncollapsedSpans, tc.selectedSpanID, 500, 5)
if tc.wantSpanIDs != nil {
assert.Equal(t, tc.wantSpanIDs, spanIDs(spans))
@@ -412,10 +412,10 @@ func TestGetSelectedSpans_SpanMetadata(t *testing.T) {
mkSpan("child2", "svc"),
)
spanMap := buildSpanMap(root)
trace := getWaterfallTrace([]*spantypes.WaterfallSpan{root}, spanMap)
trace := getWaterfallTrace([]*tracedetailtypes.WaterfallSpan{root}, spanMap)
spans, _ := trace.GetSelectedSpans([]string{"root", "child1"}, "root", 500, 5)
byID := map[string]*spantypes.WaterfallSpan{}
byID := map[string]*tracedetailtypes.WaterfallSpan{}
for _, s := range spans {
byID[s.SpanID] = s
}
@@ -478,7 +478,7 @@ func TestGetSelectedSpans_Window(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
root, spanMap, uncollapsed := makeChain(600)
trace := getWaterfallTrace([]*spantypes.WaterfallSpan{root}, spanMap)
trace := getWaterfallTrace([]*tracedetailtypes.WaterfallSpan{root}, spanMap)
spans, _ := trace.GetSelectedSpans(uncollapsed, tc.selectedSpanID, 500, 5)
assert.Equal(t, tc.wantLen, len(spans), "window size")
@@ -536,7 +536,7 @@ func TestGetSelectedSpans_DepthCountedFromSelectedSpan(t *testing.T) {
root := mkSpan("root", "svc", mkSpan("A", "svc", selected))
spanMap := buildSpanMap(root)
trace := getWaterfallTrace([]*spantypes.WaterfallSpan{root}, spanMap)
trace := getWaterfallTrace([]*tracedetailtypes.WaterfallSpan{root}, spanMap)
spans, _ := trace.GetSelectedSpans([]string{"selected"}, "selected", 500, 5)
ids := spanIDs(spans)
@@ -565,9 +565,9 @@ func TestGetAllSpans(t *testing.T) {
),
),
)
trace := getWaterfallTrace([]*spantypes.WaterfallSpan{root}, nil)
trace := getWaterfallTrace([]*tracedetailtypes.WaterfallSpan{root}, nil)
spans := trace.GetAllSpans()
traceResponse := spantypes.NewGettableWaterfallTrace(trace, spans, nil, true, nil)
traceResponse := tracedetailtypes.NewGettableWaterfallTrace(trace, spans, nil, true, nil)
assert.ElementsMatch(t, spanIDs(spans), []string{"root", "childA", "grandchildA", "leafA", "childB", "grandchildB", "leafB"})
assert.Equal(t, "svc", traceResponse.RootServiceName)
assert.Equal(t, "root-op", traceResponse.RootServiceEntryPoint)

View File

@@ -4,7 +4,7 @@ import (
"context"
"net/http"
"github.com/SigNoz/signoz/pkg/types/spantypes"
"github.com/SigNoz/signoz/pkg/types/tracedetailtypes"
)
// Handler exposes HTTP handlers for trace detail APIs.
@@ -14,5 +14,5 @@ type Handler interface {
// Module defines the business logic for trace detail operations.
type Module interface {
GetWaterfall(ctx context.Context, traceID string, req *spantypes.PostableWaterfall) (*spantypes.GettableWaterfallTrace, error)
GetWaterfall(ctx context.Context, traceID string, req *tracedetailtypes.PostableWaterfall) (*tracedetailtypes.GettableWaterfallTrace, error)
}

View File

@@ -63,6 +63,7 @@ import (
"github.com/SigNoz/signoz/pkg/query-service/postprocess"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/cloudintegrationtypes"
"github.com/SigNoz/signoz/pkg/types/ctxtypes"
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
"github.com/SigNoz/signoz/pkg/types/featuretypes"
@@ -1112,7 +1113,20 @@ func (aH *APIHandler) Get(rw http.ResponseWriter, r *http.Request) {
dashboard := new(dashboardtypes.Dashboard)
if aH.IntegrationsController.IsInstalledIntegrationDashboardID(id) {
if _, _, _, err := cloudintegrationtypes.ParseCloudIntegrationDashboardID(id); err == nil {
cloudIntegrationDashboard, err := aH.Signoz.Modules.CloudIntegration.GetDashboardByID(ctx, orgID, id)
if err != nil && !errorsV2.Ast(err, errorsV2.TypeLicenseUnavailable) {
render.Error(rw, errorsV2.Wrapf(err, errorsV2.TypeInternal, errorsV2.CodeInternal, "failed to get dashboard"))
return
}
if cloudIntegrationDashboard == nil {
render.Error(rw, errorsV2.Newf(errorsV2.TypeNotFound, errorsV2.CodeNotFound, "dashboard not found"))
return
}
dashboard = cloudIntegrationDashboard
} else if aH.IntegrationsController.IsInstalledIntegrationDashboardID(id) {
integrationDashboard, apiErr := aH.IntegrationsController.GetInstalledIntegrationDashboardById(ctx, orgID, id)
if apiErr != nil {
render.Error(rw, errorsV2.Wrapf(apiErr, errorsV2.TypeInternal, errorsV2.CodeInternal, "failed to get dashboard"))
@@ -1175,6 +1189,15 @@ func (aH *APIHandler) List(rw http.ResponseWriter, r *http.Request) {
dashboards = append(dashboards, installedIntegrationDashboards...)
}
cloudIntegrationDashboards, err := aH.Signoz.Modules.CloudIntegration.ListDashboards(ctx, orgID)
if err != nil {
if !errors.Ast(err, errorsV2.TypeLicenseUnavailable) {
aH.logger.ErrorContext(ctx, "failed to get dashboards for cloud integrations", errors.Attr(err))
}
} else {
dashboards = append(dashboards, cloudIntegrationDashboards...)
}
gettableDashboards, err := dashboardtypes.NewGettableDashboardsFromDashboards(dashboards)
if err != nil {
render.Error(rw, err)

View File

@@ -205,7 +205,6 @@ func NewSQLMigrationProviderFactories(
sqlmigration.NewAddRoleCRUDTuplesFactory(sqlstore),
sqlmigration.NewAddIntegrationDashboardFactory(sqlstore, sqlschema),
sqlmigration.NewAddSourceToDashboardFactory(sqlstore, sqlschema),
sqlmigration.NewMigrateCloudIntegrationDashboardsFactory(sqlstore),
)
}

View File

@@ -112,7 +112,7 @@ func New(
auditorProviderFactories func(licensing.Licensing) factory.NamedMap[factory.ProviderFactory[auditor.Auditor, auditor.Config]],
meterReporterProviderFactories func(context.Context, factory.ProviderSettings, flagger.Flagger, licensing.Licensing, telemetrystore.TelemetryStore, retention.Getter, organization.Getter, zeus.Zeus) (factory.NamedMap[factory.ProviderFactory[meterreporter.Reporter, meterreporter.Config]], string),
querierHandlerCallback func(factory.ProviderSettings, querier.Querier, analytics.Analytics) querier.Handler,
cloudIntegrationCallback func(sqlstore.SQLStore, dashboard.Module, global.Global, zeus.Zeus, gateway.Gateway, licensing.Licensing, serviceaccount.Module, cloudintegration.Config) (cloudintegration.Module, error),
cloudIntegrationCallback func(sqlstore.SQLStore, global.Global, zeus.Zeus, gateway.Gateway, licensing.Licensing, serviceaccount.Module, cloudintegration.Config) (cloudintegration.Module, error),
rulerProviderFactories func(cache.Cache, alertmanager.Alertmanager, sqlstore.SQLStore, telemetrystore.TelemetryStore, telemetrytypes.MetadataStore, prometheus.Prometheus, organization.Getter, rulestatehistory.Module, querier.Querier, queryparser.QueryParser) factory.NamedMap[factory.ProviderFactory[ruler.Ruler, ruler.Config]],
) (*SigNoz, error) {
// Initialize instrumentation
@@ -458,7 +458,7 @@ func New(
serviceAccount := implserviceaccount.NewModule(implserviceaccount.NewStore(sqlstore), authz, cache, analytics, providerSettings, config.ServiceAccount)
cloudIntegrationModule, err := cloudIntegrationCallback(sqlstore, dashboard, global, zeus, gateway, licensing, serviceAccount, config.CloudIntegration)
cloudIntegrationModule, err := cloudIntegrationCallback(sqlstore, global, zeus, gateway, licensing, serviceAccount, config.CloudIntegration)
if err != nil {
return nil, err
}

View File

@@ -1,284 +0,0 @@
package sqlmigration
import (
"context"
"embed"
"encoding/json"
"fmt"
"io/fs"
"path/filepath"
"strings"
"time"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/uptrace/bun"
"github.com/uptrace/bun/migrate"
)
//go:embed 086_migrate_ci_dashboards
var cloudIntegrationDashboardFiles embed.FS
var (
cloudProviderAWS = valuer.NewString("aws")
cloudProviderAzure = valuer.NewString("azure")
integrationSource = valuer.NewString("integration")
cloudIntegrationProvider = valuer.NewString("cloud_integration")
)
type migrateCloudIntegrationDashboards struct {
sqlstore sqlstore.SQLStore
}
type cloudIntegrationAccountRow struct {
bun.BaseModel `bun:"table:cloud_integration"`
ID string `bun:"id"`
OrgID string `bun:"org_id"`
Provider string `bun:"provider"`
}
type cloudIntegrationServiceRow struct {
bun.BaseModel `bun:"table:cloud_integration_service"`
Type string `bun:"type"`
Config string `bun:"config"`
CloudIntegrationID string `bun:"cloud_integration_id"`
}
type cloudIntegrationAWSServiceConfig struct {
Metrics *cloudIntegrationMetricsConfig `json:"metrics"`
}
type cloudIntegrationAzureServiceConfig struct {
Metrics *cloudIntegrationMetricsConfig `json:"metrics"`
}
type cloudIntegrationMetricsConfig struct {
Enabled bool `json:"enabled"`
}
type cloudIntegrationDashboardRow struct {
bun.BaseModel `bun:"table:dashboard"`
ID string `bun:"id,pk,type:text"`
CreatedAt time.Time `bun:"created_at"`
UpdatedAt time.Time `bun:"updated_at"`
CreatedBy *string `bun:"created_by,type:text"`
UpdatedBy *string `bun:"updated_by,type:text"`
Data string `bun:"data,type:text"`
Locked bool `bun:"locked"`
OrgID string `bun:"org_id,type:text"`
Source string `bun:"source,type:text"`
}
type cloudIntegrationAccountMeta struct {
orgID string
provider string
}
type cloudIntegrationOrgService struct {
orgID string
provider string
serviceID string
}
type integrationDashboardRow struct {
bun.BaseModel `bun:"table:integration_dashboard"`
ID string `bun:"id,pk,type:text"`
DashboardID string `bun:"dashboard_id,type:text"`
Provider string `bun:"provider,type:text"`
Slug string `bun:"slug,type:text"`
CreatedAt time.Time `bun:"created_at"`
UpdatedAt time.Time `bun:"updated_at"`
}
func NewMigrateCloudIntegrationDashboardsFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
return factory.NewProviderFactory(
// migrate_cloud_integration_dashboards name is intentionally kept short to avoid hitting identifier length limits
factory.MustNewName("migrate_ci_dashboards"),
func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return &migrateCloudIntegrationDashboards{sqlstore: sqlstore}, nil
},
)
}
func (m *migrateCloudIntegrationDashboards) Register(migrations *migrate.Migrations) error {
return migrations.Register(m.Up, m.Down)
}
func (m *migrateCloudIntegrationDashboards) Up(ctx context.Context, db *bun.DB) error {
dashboardDefs, err := m.loadDashboardDefs()
if err != nil {
return err
}
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer func() { _ = tx.Rollback() }()
var accounts []*cloudIntegrationAccountRow
if err := tx.NewSelect().
Model(&accounts).
Where("removed_at IS NULL").
Where("account_id IS NOT NULL").
Scan(ctx); err != nil {
return err
}
accountsMap := make(map[string]cloudIntegrationAccountMeta, len(accounts))
for _, a := range accounts {
accountsMap[a.ID] = cloudIntegrationAccountMeta{orgID: a.OrgID, provider: a.Provider}
}
var services []*cloudIntegrationServiceRow
if err := tx.NewSelect().Model(&services).Scan(ctx); err != nil {
return err
}
seen := make(map[string]struct{})
var toProvision []cloudIntegrationOrgService
for _, svc := range services {
meta, ok := accountsMap[svc.CloudIntegrationID]
if !ok {
continue
}
if !m.isMetricsEnabled(svc.Config, meta.provider) {
continue
}
key := fmt.Sprintf("%s|%s|%s", meta.orgID, meta.provider, svc.Type)
if _, dup := seen[key]; dup {
continue
}
seen[key] = struct{}{}
toProvision = append(toProvision, cloudIntegrationOrgService{
orgID: meta.orgID,
provider: meta.provider,
serviceID: svc.Type,
})
}
now := time.Now()
for _, service := range toProvision {
serviceDashboards, ok := dashboardDefs[service.provider][service.serviceID]
if !ok {
continue
}
for dashName, dashboardJSON := range serviceDashboards {
slug := fmt.Sprintf("%s-%s-%s", service.provider, service.serviceID, dashName)
count, err := tx.NewSelect().
TableExpr("integration_dashboard AS id").
Join("JOIN dashboard AS d ON id.dashboard_id = d.id").
Where("d.org_id = ?", service.orgID).
Where("id.provider = ?", "cloud_integration").
Where("id.slug = ?", slug).
Count(ctx)
if err != nil {
return err
}
if count > 0 {
continue
}
dashID := valuer.GenerateUUID().StringValue()
dashRow := &cloudIntegrationDashboardRow{
ID: dashID,
CreatedAt: now,
UpdatedAt: now,
Data: string(dashboardJSON),
Locked: true,
OrgID: service.orgID,
Source: integrationSource.StringValue(),
}
if _, err := tx.NewInsert().Model(dashRow).Exec(ctx); err != nil {
return err
}
intRow := &integrationDashboardRow{
ID: valuer.GenerateUUID().StringValue(),
DashboardID: dashID,
Provider: cloudIntegrationProvider.StringValue(),
Slug: slug,
CreatedAt: now,
UpdatedAt: now,
}
if _, err := tx.NewInsert().Model(intRow).Exec(ctx); err != nil {
return err
}
}
}
return tx.Commit()
}
func (m *migrateCloudIntegrationDashboards) Down(context.Context, *bun.DB) error {
return nil
}
func (m *migrateCloudIntegrationDashboards) loadDashboardDefs() (map[string]map[string]map[string]json.RawMessage, error) {
result := make(map[string]map[string]map[string]json.RawMessage)
err := fs.WalkDir(cloudIntegrationDashboardFiles, "086_migrate_ci_dashboards", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() || filepath.Ext(path) != ".json" {
return nil
}
// path: 086_cloud_integration_dashboards/{provider}/{service}/{file}.json
rel := strings.TrimPrefix(path, "086_migrate_ci_dashboards/")
parts := strings.SplitN(rel, "/", 3)
if len(parts) != 3 {
return nil
}
provider := parts[0]
serviceID := parts[1]
dashName := strings.TrimSuffix(parts[2], ".json")
data, err := cloudIntegrationDashboardFiles.ReadFile(path)
if err != nil {
return err
}
if result[provider] == nil {
result[provider] = make(map[string]map[string]json.RawMessage)
}
if result[provider][serviceID] == nil {
result[provider][serviceID] = make(map[string]json.RawMessage)
}
result[provider][serviceID][dashName] = json.RawMessage(data)
return nil
})
return result, err
}
func (m *migrateCloudIntegrationDashboards) isMetricsEnabled(configJSON string, provider string) bool {
switch provider {
case cloudProviderAWS.String():
cfg := new(cloudIntegrationAWSServiceConfig)
if err := json.Unmarshal([]byte(configJSON), cfg); err != nil {
return false
}
return cfg.Metrics != nil && cfg.Metrics.Enabled
case cloudProviderAzure.String():
cfg := new(cloudIntegrationAzureServiceConfig)
if err := json.Unmarshal([]byte(configJSON), cfg); err != nil {
return false
}
return cfg.Metrics != nil && cfg.Metrics.Enabled
}
return false
}

File diff suppressed because one or more lines are too long

View File

@@ -1,671 +0,0 @@
{
"description": "View key AWS ECS metrics with an out of the box dashboard.\n",
"image": "data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20width%3D%2280px%22%20height%3D%2280px%22%20viewBox%3D%220%200%2080%2080%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%3C!--%20Generator%3A%20Sketch%2064%20(93537)%20-%20https%3A%2F%2Fsketch.com%20--%3E%3Ctitle%3EIcon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%3C%2Ftitle%3E%3Cdesc%3ECreated%20with%20Sketch.%3C%2Fdesc%3E%3Cdefs%3E%3ClinearGradient%20x1%3D%220%25%22%20y1%3D%22100%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%20id%3D%22linearGradient-1%22%3E%3Cstop%20stop-color%3D%22%23C8511B%22%20offset%3D%220%25%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23FF9900%22%20offset%3D%22100%25%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20id%3D%22Icon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%22%20stroke%3D%22none%22%20stroke-width%3D%221%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cg%20id%3D%22Icon-Architecture-BG%2F64%2FContainers%22%20fill%3D%22url(%23linearGradient-1)%22%3E%3Crect%20id%3D%22Rectangle%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2280%22%20height%3D%2280%22%3E%3C%2Frect%3E%3C%2Fg%3E%3Cpath%20d%3D%22M64%2C48.2340095%20L56%2C43.4330117%20L56%2C32.0000169%20C56%2C31.6440171%2055.812%2C31.3150172%2055.504%2C31.1360173%20L44%2C24.4260204%20L44%2C14.7520248%20L64%2C26.5710194%20L64%2C48.2340095%20Z%20M65.509%2C25.13902%20L43.509%2C12.139026%20C43.199%2C11.9560261%2042.818%2C11.9540261%2042.504%2C12.131026%20C42.193%2C12.3090259%2042%2C12.6410257%2042%2C13.0000256%20L42%2C25.0000201%20C42%2C25.3550199%2042.189%2C25.6840198%2042.496%2C25.8640197%20L54%2C32.5740166%20L54%2C44.0000114%20C54%2C44.3510113%2054.185%2C44.6770111%2054.486%2C44.857011%20L64.486%2C50.8570083%20C64.644%2C50.9520082%2064.822%2C51%2065%2C51%20C65.17%2C51%2065.34%2C50.9570082%2065.493%2C50.8700083%20C65.807%2C50.6930084%2066%2C50.3600085%2066%2C50%20L66%2C26.0000196%20C66%2C25.6460198%2065.814%2C25.31902%2065.509%2C25.13902%20L65.509%2C25.13902%20Z%20M40.445%2C66.863001%20L17%2C54.3990067%20L17%2C26.5710194%20L37%2C14.7520248%20L37%2C24.4510204%20L26.463%2C31.1560173%20C26.175%2C31.3400172%2026%2C31.6580171%2026%2C32.0000169%20L26%2C49.0000091%20C26%2C49.373009%2026.208%2C49.7150088%2026.538%2C49.8870087%20L39.991%2C56.8870055%20C40.28%2C57.0370055%2040.624%2C57.0380055%2040.912%2C56.8880055%20L53.964%2C50.1440086%20L61.996%2C54.9640064%20L40.445%2C66.863001%20Z%20M64.515%2C54.1420068%20L54.515%2C48.1420095%20C54.217%2C47.9640096%2053.849%2C47.9520096%2053.541%2C48.1120095%20L40.455%2C54.8730065%20L28%2C48.3930094%20L28%2C32.5490167%20L38.537%2C25.8440197%20C38.825%2C25.6600198%2039%2C25.3420199%2039%2C25.0000201%20L39%2C13.0000256%20C39%2C12.6410257%2038.808%2C12.3090259%2038.496%2C12.131026%20C38.184%2C11.9540261%2037.802%2C11.9560261%2037.491%2C12.139026%20L15.491%2C25.13902%20C15.187%2C25.31902%2015%2C25.6460198%2015%2C26.0000196%20L15%2C55%20C15%2C55.3690062%2015.204%2C55.7090061%2015.53%2C55.883006%20L39.984%2C68.8830001%20C40.131%2C68.961%2040.292%2C69%2040.453%2C69%20C40.62%2C69%2040.786%2C68.958%2040.937%2C68.8750001%20L64.484%2C55.875006%20C64.797%2C55.7020061%2064.993%2C55.3750062%2065.0001416%2C55.0180064%20C65.006%2C54.6600066%2064.821%2C54.3260067%2064.515%2C54.1420068%20L64.515%2C54.1420068%20Z%22%20id%3D%22Amazon-Elastic-Container-Service_Icon_64_Squid%22%20fill%3D%22%23FFFFFF%22%3E%3C%2Fpath%3E%3C%2Fg%3E%3C%2Fsvg%3E",
"layout": [
{
"h": 6,
"i": "f78becf8-0328-48b4-84b6-ff4dac325940",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 0
},
{
"h": 6,
"i": "2b4eac06-b426-4f78-b874-2e1734c4104b",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 0
},
{
"h": 6,
"i": "5bea2bc0-13a2-4937-bccb-60ffe8a43ad5",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 6
},
{
"h": 6,
"i": "6fac67b0-50ec-4b43-ac4b-320a303d0369",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 6
}
],
"panelMap": {},
"tags": [],
"title": "AWS ECS Overview",
"uploadedGrafana": false,
"variables": {
"51f4fa2b-89c7-47c2-9795-f32cffaab985": {
"allSelected": false,
"customValue": "",
"description": "AWS Account ID",
"id": "51f4fa2b-89c7-47c2-9795-f32cffaab985",
"key": "51f4fa2b-89c7-47c2-9795-f32cffaab985",
"modificationUUID": "7b814d17-8fff-4ed6-a4ea-90e3b1a97584",
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
"type": "QUERY"
},
"9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0": {
"allSelected": false,
"customValue": "",
"description": "Account Region",
"id": "9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0",
"key": "9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0",
"modificationUUID": "3b5f499b-22a3-4c8a-847c-8d3811c9e6b2",
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
},
"bfbdbcbe-a168-4d81-b108-36339e249116": {
"allSelected": true,
"customValue": "",
"description": "ECS Cluster Name",
"id": "bfbdbcbe-a168-4d81-b108-36339e249116",
"key": "bfbdbcbe-a168-4d81-b108-36339e249116",
"modificationUUID": "9fb0d63c-ac6c-497d-82b3-17d95944e245",
"multiSelect": true,
"name": "Cluster",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS cluster\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}}\nGROUP BY cluster",
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
}
},
"version": "v5",
"widgets": [
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "f78becf8-0328-48b4-84b6-ff4dac325940",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_MemoryUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName IN $Cluster)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
{
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "56068fdd-d523-4117-92fa-87c6518ad07c",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Maximum Memory Utilization",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "2b4eac06-b426-4f78-b874-2e1734c4104b",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_MemoryUtilization_min",
"reduceTo": "avg",
"spaceAggregation": "min",
"timeAggregation": "min"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName IN $Cluster)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
{
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "fb19342e-cbde-40d8-b12f-ad108698356b",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Minimum Memory Utilization",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "5bea2bc0-13a2-4937-bccb-60ffe8a43ad5",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_CPUUtilization_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName IN $Cluster)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
{
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "273e0a76-c780-4b9a-9b03-2649d4227173",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Maximum CPU Utilization",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "6fac67b0-50ec-4b43-ac4b-320a303d0369",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_ECS_CPUUtilization_min",
"reduceTo": "avg",
"spaceAggregation": "min",
"timeAggregation": "min"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(cloud.region = $Region AND cloud.account.id = $Account AND ClusterName IN $Cluster)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
{
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "c89482b3-5a98-4e2c-be0d-ef036d7dac05",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Minimum CPU Utilization",
"yAxisUnit": "none"
}
]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,638 +0,0 @@
{
"description": "View key AWS SNS metrics with an out of the box dashboard.",
"image": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODBweCIgaGVpZ2h0PSI4MHB4IiB2aWV3Qm94PSIwIDAgODAgODAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDY0ICg5MzUzNykgLSBodHRwczovL3NrZXRjaC5jb20gLS0+CiAgICA8dGl0bGU+SWNvbi1BcmNoaXRlY3R1cmUvNjQvQXJjaF9BV1MtU2ltcGxlLU5vdGlmaWNhdGlvbi1TZXJ2aWNlXzY0PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+CiAgICAgICAgPGxpbmVhckdyYWRpZW50IHgxPSIwJSIgeTE9IjEwMCUiIHgyPSIxMDAlIiB5Mj0iMCUiIGlkPSJsaW5lYXJHcmFkaWVudC0xIj4KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iI0IwMDg0RCIgb2Zmc2V0PSIwJSI+PC9zdG9wPgogICAgICAgICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjRkY0RjhCIiBvZmZzZXQ9IjEwMCUiPjwvc3RvcD4KICAgICAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPC9kZWZzPgogICAgPGcgaWQ9Ikljb24tQXJjaGl0ZWN0dXJlLzY0L0FyY2hfQVdTLVNpbXBsZS1Ob3RpZmljYXRpb24tU2VydmljZV82NCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ikljb24tQXJjaGl0ZWN0dXJlLUJHLzY0L0FwcGxpY2F0aW9uLUludGVncmF0aW9uIiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIj4KICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZSIgeD0iMCIgeT0iMCIgd2lkdGg9IjgwIiBoZWlnaHQ9IjgwIj48L3JlY3Q+CiAgICAgICAgPC9nPgogICAgICAgIDxwYXRoIGQ9Ik0xNywzOCBDMTguMTAzLDM4IDE5LDM4Ljg5NyAxOSw0MCBDMTksNDEuMTAzIDE4LjEwMyw0MiAxNyw0MiBDMTUuODk3LDQyIDE1LDQxLjEwMyAxNSw0MCBDMTUsMzguODk3IDE1Ljg5NywzOCAxNywzOCBMMTcsMzggWiBNNDEsNjQgQzI5LjMxNCw2NCAxOS4yODksNTUuNDY2IDE3LjE5NCw0My45OCBDMTguOTY1LDQzLjg5NCAyMC40MjcsNDIuNjU5IDIwLjg1Nyw0MSBMMjcsNDEgTDI3LDM5IEwyMC44NTcsMzkgQzIwLjQyNywzNy4zNDIgMTguOTY2LDM2LjEwNyAxNy4xOTUsMzYuMDIgQzE5LjI4NSwyNC43MSAyOS41MTEsMTYgNDEsMTYgQzQ1LjMxMywxNiA0OS44MzIsMTcuNjIyIDU0LjQyOSwyMC44MjEgTDU1LjU3MSwxOS4xNzkgQzUwLjYzMywxNS43NDMgNDUuNzMsMTQgNDEsMTQgQzI4LjI3LDE0IDE2Ljk0OSwyMy44NjUgMTUuMDYzLDM2LjUyMSBDMTMuODM5LDM3LjIwNyAxMywzOC41IDEzLDQwIEMxMyw0MS41IDEzLjgzOSw0Mi43OTMgMTUuMDYzLDQzLjQ3OCBDMTYuOTcsNTYuMzQxIDI4LjA1Niw2NiA0MSw2NiBDNDYuNDA3LDY2IDUxLjk0Miw2NC4xNTcgNTYuNTg1LDYwLjgxMSBMNTUuNDE1LDU5LjE4OSBDNTEuMTEsNjIuMjkyIDQ1Ljk5MSw2NCA0MSw2NCBMNDEsNjQgWiBNMzAuMTAxLDM2LjQ0MiBDMzEuOTU1LDM2Ljg5NSAzNC4yNzUsMzcgMzYsMzcgQzM3LjY0MiwzNyAzOS44MjMsMzYuOTA1IDQxLjYyOSwzNi41MDYgTDM3LjEwNSw0NS41NTMgQzM3LjAzNiw0NS42OTEgMzcsNDUuODQ1IDM3LDQ2IEwzNyw1MC40NTMgQzM2LjE5OSw1MC45NjQgMzQuODMzLDUxLjgxMiAzNCw1MS45ODYgTDM0LDQ2IEMzNCw0NS44NjggMzMuOTc0LDQ1LjczNyAzMy45MjMsNDUuNjE1IEwzMC4xMDEsMzYuNDQyIFogTTM2LDMzIEM0MC4wMjUsMzMgNDIuMTc0LDMzLjYwNCA0Mi44NDEsMzQgQzQyLjE3NCwzNC4zOTYgNDAuMDI1LDM1IDM2LDM1IEMzMS45NzUsMzUgMjkuODI2LDM0LjM5NiAyOS4xNTksMzQgQzI5LjgyNiwzMy42MDQgMzEuOTc1LDMzIDM2LDMzIEwzNiwzMyBaIE0zMyw1NCBMMzQsNTQgQzM0LjA0Myw1NCAzNC4wODYsNTMuOTk3IDM0LjEyOCw1My45OTIgQzM1LjM1Miw1My44MzMgMzYuOTA5LDUyLjg4NyAzOC4yNzIsNTIuMDEzIEwzOC41MzUsNTEuODQ1IEMzOC44MjQsNTEuNjYxIDM5LDUxLjM0MiAzOSw1MSBMMzksNDYuMjM2IEw0NC41NTksMzUuMTIgQzQ0LjgzMywzNC44MDEgNDUsMzQuNDM0IDQ1LDM0IEM0NSwzMS4zOSAzOS4zNjEsMzEgMzYsMzEgQzMyLjYzOSwzMSAyNywzMS4zOSAyNywzNCBDMjcsMzQuMzY2IDI3LjEyLDM0LjY4NCAyNy4zMiwzNC45NjcgTDMyLDQ2LjIgTDMyLDUzIEMzMiw1My41NTIgMzIuNDQ3LDU0IDMzLDU0IEwzMyw1NCBaIE02Miw1MyBDNjMuMTAzLDUzIDY0LDUzLjg5NyA2NCw1NSBDNjQsNTYuMTAzIDYzLjEwMyw1NyA2Miw1NyBDNjAuODk3LDU3IDYwLDU2LjEwMyA2MCw1NSBDNjAsNTMuODk3IDYwLjg5Nyw1MyA2Miw1MyBMNjIsNTMgWiBNNjIsMjMgQzYzLjEwMywyMyA2NCwyMy44OTcgNjQsMjUgQzY0LDI2LjEwMyA2My4xMDMsMjcgNjIsMjcgQzYwLjg5NywyNyA2MCwyNi4xMDMgNjAsMjUgQzYwLDIzLjg5NyA2MC44OTcsMjMgNjIsMjMgTDYyLDIzIFogTTY0LDM4IEM2NS4xMDMsMzggNjYsMzguODk3IDY2LDQwIEM2Niw0MS4xMDMgNjUuMTAzLDQyIDY0LDQyIEM2Mi44OTcsNDIgNjIsNDEuMTAzIDYyLDQwIEM2MiwzOC44OTcgNjIuODk3LDM4IDY0LDM4IEw2NCwzOCBaIE01NCw0MSBMNjAuMTQzLDQxIEM2MC41ODksNDIuNzIgNjIuMTQyLDQ0IDY0LDQ0IEM2Ni4yMDYsNDQgNjgsNDIuMjA2IDY4LDQwIEM2OCwzNy43OTQgNjYuMjA2LDM2IDY0LDM2IEM2Mi4xNDIsMzYgNjAuNTg5LDM3LjI4IDYwLjE0MywzOSBMNTQsMzkgTDU0LDI2IEw1OC4xNDMsMjYgQzU4LjU4OSwyNy43MiA2MC4xNDIsMjkgNjIsMjkgQzY0LjIwNiwyOSA2NiwyNy4yMDYgNjYsMjUgQzY2LDIyLjc5NCA2NC4yMDYsMjEgNjIsMjEgQzYwLjE0MiwyMSA1OC41ODksMjIuMjggNTguMTQzLDI0IEw1MywyNCBDNTIuNDQ3LDI0IDUyLDI0LjQ0OCA1MiwyNSBMNTIsMzkgTDQ1LDM5IEw0NSw0MSBMNTIsNDEgTDUyLDU1IEM1Miw1NS41NTIgNTIuNDQ3LDU2IDUzLDU2IEw1OC4xNDMsNTYgQzU4LjU4OSw1Ny43MiA2MC4xNDIsNTkgNjIsNTkgQzY0LjIwNiw1OSA2Niw1Ny4yMDYgNjYsNTUgQzY2LDUyLjc5NCA2NC4yMDYsNTEgNjIsNTEgQzYwLjE0Miw1MSA1OC41ODksNTIuMjggNTguMTQzLDU0IEw1NCw1NCBMNTQsNDEgWiIgaWQ9IkFXUy1TaW1wbGUtTm90aWZpY2F0aW9uLVNlcnZpY2VfSWNvbl82NF9TcXVpZCIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgPC9nPgo8L3N2Zz4=",
"layout": [
{
"h": 6,
"i": "4eb87f89-0213-4773-9b06-6aecc6701898",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 0
},
{
"h": 6,
"i": "7a010b4e-ea7c-4a45-a9eb-93af650c45b4",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 0
},
{
"h": 6,
"i": "2299d4e3-6c40-4bf2-a550-c7bb8a7acd38",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 6
},
{
"h": 6,
"i": "16eec8b7-de1a-4039-b180-24c7a6704b6e",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 6
}
],
"panelMap": {},
"tags": [],
"title": "SNS Overview",
"uploadedGrafana": false,
"variables": {
"51f4fa2b-89c7-47c2-9795-f32cffaab985": {
"allSelected": false,
"customValue": "",
"description": "AWS Account ID",
"id": "51f4fa2b-89c7-47c2-9795-f32cffaab985",
"key": "51f4fa2b-89c7-47c2-9795-f32cffaab985",
"modificationUUID": "b7a6b06b-fa1f-4fb8-b70e-6bd9b350f29e",
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
"type": "QUERY"
},
"9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0": {
"allSelected": false,
"customValue": "",
"description": "Account Region",
"id": "9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0",
"key": "9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0",
"modificationUUID": "8428a5de-bfd1-4a69-9601-63e3041cd556",
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
},
"bfbdbcbe-a168-4d81-b108-36339e249116": {
"allSelected": true,
"customValue": "",
"description": "SNS Topic Name",
"id": "bfbdbcbe-a168-4d81-b108-36339e249116",
"modificationUUID": "dfed7272-16dc-4eb6-99bf-7c82fc8e04f0",
"multiSelect": true,
"name": "Topic",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'TopicName') AS topic\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}}\nGROUP BY topic",
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
}
},
"version": "v5",
"widgets": [
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "4eb87f89-0213-4773-9b06-6aecc6701898",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_SNS_NumberOfMessagesPublished_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(TopicName IN $Topic AND cloud.region = $Region AND cloud.account.id = $Account)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "9c67615a-55f7-42da-835c-86922f2ff8bb",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Number of Messages Published",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "7a010b4e-ea7c-4a45-a9eb-93af650c45b4",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_SNS_PublishSize_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(TopicName IN $Topic AND cloud.region = $Region AND cloud.account.id = $Account)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "a635a15b-dfe6-4617-a82e-29d93e27deaf",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Published Message Size",
"yAxisUnit": "decbytes"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "2299d4e3-6c40-4bf2-a550-c7bb8a7acd38",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_SNS_NumberOfNotificationsDelivered_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(TopicName IN $Topic AND cloud.region = $Region AND cloud.account.id = $Account)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "0d2fc26c-9b21-4dfc-b631-64b7c8d3bd71",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Number of Notifications Delivered",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "16eec8b7-de1a-4039-b180-24c7a6704b6e",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregations": [
{
"metricName": "aws_SNS_NumberOfNotificationsFailed_max",
"reduceTo": "avg",
"spaceAggregation": "max",
"timeAggregation": "max"
}
],
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filter": {
"expression": "(TopicName IN $Topic AND cloud.region = $Region AND cloud.account.id = $Account)"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
}
],
"having": {
"expression": ""
},
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"stepInterval": 60
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "526247af-6ac9-42ff-83e9-cce0e32a9e63",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Number of Notifications Failed",
"yAxisUnit": "none"
}
]
}

File diff suppressed because one or more lines are too long

View File

@@ -1,44 +0,0 @@
package cloudintegrationtypes
import (
"fmt"
"time"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/uptrace/bun"
)
type IntegrationDashboardProviderType struct{ valuer.String }
var IntegrationDashboardProviderCloudIntegration = IntegrationDashboardProviderType{valuer.NewString("cloud_integration")}
type StorableIntegrationDashboard struct {
bun.BaseModel `bun:"table:integration_dashboard"`
ID string `bun:"id,pk,type:text"`
DashboardID string `bun:"dashboard_id,type:text"`
Provider IntegrationDashboardProviderType `bun:"provider,type:text"`
Slug string `bun:"slug,type:text"`
CreatedAt time.Time `bun:"created_at"`
UpdatedAt time.Time `bun:"updated_at"`
}
func NewStorableIntegrationDashboard(dashboardID string, provider IntegrationDashboardProviderType, slug string) *StorableIntegrationDashboard {
now := time.Now()
return &StorableIntegrationDashboard{
ID: valuer.GenerateUUID().StringValue(),
DashboardID: dashboardID,
Provider: provider,
Slug: slug,
CreatedAt: now,
UpdatedAt: now,
}
}
func IntegrationDashboardSlug(provider CloudProviderType, serviceID ServiceID, dashName string) string {
return fmt.Sprintf("%s-%s-%s", provider.StringValue(), serviceID.StringValue(), dashName)
}
func IntegrationDashboardSlugPrefix(provider CloudProviderType, serviceID ServiceID) string {
return fmt.Sprintf("%s-%s-", provider.StringValue(), serviceID.StringValue())
}

View File

@@ -2,6 +2,8 @@ package cloudintegrationtypes
import (
"encoding/json"
"fmt"
"strings"
"time"
"github.com/SigNoz/signoz/pkg/errors"
@@ -317,18 +319,56 @@ func (updatableService *UpdatableService) UnmarshalJSON(data []byte) error {
return nil
}
// IsServiceSharedWithMetricsEnabled returns true if any of the provided services has metrics enabled.
// It is used to determine whether dashboards for a service type should be deprovisioned when
// an account is disconnected or a service is updated.
func IsServiceSharedWithMetricsEnabled(provider CloudProviderType, services []*StorableCloudIntegrationService) bool {
for _, svc := range services {
cfg, err := NewServiceConfigFromJSON(provider, svc.Config)
if err != nil {
continue
}
if cfg.IsMetricsEnabled(provider) {
return true
}
}
return false
// UTILITIES
// GetCloudIntegrationDashboardID returns the dashboard id for a cloud integration, given the cloud provider, service id, and dashboard id.
// This is used to generate unique dashboard ids for cloud integration, and also to parse the dashboard id to get the cloud provider and service id when needed.
func GetCloudIntegrationDashboardID(cloudProvider CloudProviderType, svcID, dashboardID string) string {
return fmt.Sprintf("cloud-integration--%s--%s--%s", cloudProvider.StringValue(), svcID, dashboardID)
}
// ParseCloudIntegrationDashboardID parses a dashboard id generated by GetCloudIntegrationDashboardID
// into its constituent parts (cloudProvider, serviceID, dashboardID).
func ParseCloudIntegrationDashboardID(id string) (CloudProviderType, string, string, error) {
parts := strings.SplitN(id, "--", 4)
if len(parts) != 4 || parts[0] != "cloud-integration" {
return CloudProviderType{}, "", "", errors.New(errors.TypeNotFound, ErrCodeCloudIntegrationNotFound, "invalid cloud integration dashboard id")
}
provider, err := NewCloudProvider(parts[1])
if err != nil {
return CloudProviderType{}, "", "", err
}
return provider, parts[2], parts[3], nil
}
// GetDashboardsFromAssets returns the list of dashboards for the cloud provider service from definition.
func GetDashboardsFromAssets(
svcID string,
orgID valuer.UUID,
cloudProvider CloudProviderType,
createdAt time.Time,
assets Assets,
) []*dashboardtypes.Dashboard {
dashboards := make([]*dashboardtypes.Dashboard, 0)
for _, d := range assets.Dashboards {
author := fmt.Sprintf("%s-integration", cloudProvider.StringValue())
dashboards = append(dashboards, &dashboardtypes.Dashboard{
ID: d.ID,
Locked: true,
OrgID: orgID,
Data: d.Definition,
TimeAuditable: types.TimeAuditable{
CreatedAt: createdAt,
UpdatedAt: createdAt,
},
UserAuditable: types.UserAuditable{
CreatedBy: author,
UpdatedBy: author,
},
Source: dashboardtypes.SourceIntegration,
})
}
return dashboards
}

View File

@@ -39,30 +39,13 @@ type Store interface {
// ListServices returns all the cloud integration services for the given cloud integration id
ListServices(ctx context.Context, cloudIntegrationID valuer.UUID) ([]*StorableCloudIntegrationService, error)
// ListSharedServices returns a map of service type to services from other connected accounts
// that share that service type with the given cloudIntegrationID.
// Only service types present in the given account are included.
// The caller is responsible for any further filtering (e.g. metrics-enabled checks).
ListSharedServices(ctx context.Context, orgID valuer.UUID, provider CloudProviderType, cloudIntegrationID valuer.UUID) (map[ServiceID][]*StorableCloudIntegrationService, error)
// CreateService creates a new cloud integration service
CreateService(ctx context.Context, service *StorableCloudIntegrationService) error
// UpdateService updates an existing cloud integration service
UpdateService(ctx context.Context, service *StorableCloudIntegrationService) error
// DeleteServicesByCloudIntegrationID deletes all services for the given cloud integration id
DeleteServicesByCloudIntegrationID(ctx context.Context, orgID, cloudIntegrationID valuer.UUID) error
RunInTx(context.Context, func(ctx context.Context) error) error
CreateIntegrationDashboard(ctx context.Context, row *StorableIntegrationDashboard) error
GetIntegrationDashboardBySlug(ctx context.Context, orgID valuer.UUID, provider IntegrationDashboardProviderType, slug string) (*StorableIntegrationDashboard, error)
ListIntegrationDashboardsBySlugPrefix(ctx context.Context, orgID valuer.UUID, provider IntegrationDashboardProviderType, slugPrefix string) ([]*StorableIntegrationDashboard, error)
DeleteIntegrationDashboardBySlug(ctx context.Context, orgID valuer.UUID, provider IntegrationDashboardProviderType, slug string) error
}
type ServiceDefinitionStore interface {

View File

@@ -110,7 +110,7 @@ func NewDashboard(orgID valuer.UUID, createdBy string, source Source, storableDa
},
OrgID: orgID,
Data: storableDashboardData,
Locked: source == SourceIntegration,
Locked: false,
Source: source,
}, nil
}

View File

@@ -13,9 +13,7 @@ var (
ErrCodeMappingGroupAlreadyExists = errors.MustNewCode("span_attribute_mapping_group_already_exists")
)
// SpanMapperGroupCondition gates whether a group's rules run for a given span.
// A group runs when any attribute or resource key on the span CONTAINS one of
// the listed substrings (plain substring match — no glob syntax).
// A group runs when any of the listed attribute/resource key patterns match.
type SpanMapperGroupCondition struct {
Attributes []string `json:"attributes" required:"true" nullable:"true"`
Resource []string `json:"resource" required:"true" nullable:"true"`

View File

@@ -1,140 +0,0 @@
package spantypes
import (
"sort"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
"gopkg.in/yaml.v3"
)
const (
SpanAttrMappingFeatureType agentConf.AgentFeatureType = "span_attr_mapping"
ProcessorName = "signozspanmapper"
)
var (
ErrCodeInvalidCollectorConfig = errors.MustNewCode("invalid_collector_config")
ErrCodeBuildMappingProcessorConfig = errors.MustNewCode("build_mapping_processor_config")
)
type SpanMapperGroupWithMappers struct {
Group *SpanMapperGroup `json:"group"`
Mappers []*SpanMapper `json:"mappers"`
}
// spanMapperProcessorConfig is the collector config for signozspanmapper.
type spanMapperProcessorConfig struct {
Groups []spanMapperProcessorGroup `yaml:"groups" json:"groups"`
}
type spanMapperProcessorGroup struct {
ID string `yaml:"id" json:"id"`
ExistsAny spanMapperProcessorExistsAny `yaml:"exists_any" json:"exists_any"`
Attributes []spanMapperProcessorAttribute `yaml:"attributes" json:"attributes"`
}
type spanMapperProcessorExistsAny struct {
Attributes []string `yaml:"attributes,omitempty" json:"attributes,omitempty"`
Resource []string `yaml:"resource,omitempty" json:"resource,omitempty"`
}
type spanMapperProcessorAttribute struct {
Target string `yaml:"target" json:"target"`
Context string `yaml:"context,omitempty" json:"context,omitempty"`
Sources []spanMapperProcessorSource `yaml:"sources" json:"sources"`
}
type spanMapperProcessorSource struct {
Key string `yaml:"key" json:"key"`
Action string `yaml:"action,omitempty" json:"action,omitempty"`
}
func GenerateCollectorConfigWithSpanMapperProcessor(currentConfYaml []byte, groups []*SpanMapperGroupWithMappers) ([]byte, error) {
var collectorConf map[string]any
if err := yaml.Unmarshal(currentConfYaml, &collectorConf); err != nil {
return nil, errors.Wrapf(err, errors.TypeInvalidInput, ErrCodeInvalidCollectorConfig, "failed to unmarshal collector config")
}
// rare but don't do anything in this case, also means it's just comments.
if collectorConf == nil {
collectorConf = map[string]any{}
}
processors := map[string]any{}
if existing, ok := collectorConf["processors"]; ok && existing != nil {
p, ok := existing.(map[string]any)
if !ok {
return nil, errors.Newf(errors.TypeInvalidInput, ErrCodeInvalidCollectorConfig, "collector config 'processors' must be a mapping, got %T", existing)
}
processors = p
}
procConfig := buildProcessorConfig(groups)
processors[ProcessorName] = procConfig
collectorConf["processors"] = processors
out, err := yaml.Marshal(collectorConf)
if err != nil {
return nil, errors.Wrapf(err, errors.TypeInternal, ErrCodeBuildMappingProcessorConfig, "failed to marshal collector config")
}
return out, nil
}
func buildProcessorConfig(groups []*SpanMapperGroupWithMappers) *spanMapperProcessorConfig {
out := make([]spanMapperProcessorGroup, 0, len(groups))
for _, gm := range groups {
rules := make([]spanMapperProcessorAttribute, 0, len(gm.Mappers))
for _, m := range gm.Mappers {
rules = append(rules, buildAttributeRule(m))
}
out = append(out, spanMapperProcessorGroup{
ID: gm.Group.Name,
ExistsAny: spanMapperProcessorExistsAny{
Attributes: gm.Group.Condition.Attributes,
Resource: gm.Group.Condition.Resource,
},
Attributes: rules,
})
}
return &spanMapperProcessorConfig{Groups: out}
}
// buildAttributeRule maps a single SpanMapper to a collector attribute rule.
// Sources are sorted by Priority DESC (highest-priority first); read-from-
// resource sources are encoded via the "resource." prefix on the key. Each
// source carries its own action — "copy" is omitted to keep the emitted YAML
// compact, and only "move" is set explicitly.
func buildAttributeRule(m *SpanMapper) spanMapperProcessorAttribute {
sources := make([]SpanMapperSource, len(m.Config.Sources))
copy(sources, m.Config.Sources)
sort.SliceStable(sources, func(i, j int) bool { return sources[i].Priority > sources[j].Priority })
out := make([]spanMapperProcessorSource, 0, len(sources))
for _, s := range sources {
key := s.Key
if s.Context == FieldContextResource {
key = FieldContextResource.StringValue() + "." + s.Key
}
var action string
if s.Operation == SpanMapperOperationMove {
action = SpanMapperOperationMove.StringValue()
}
out = append(out, spanMapperProcessorSource{Key: key, Action: action})
}
ctx := FieldContextSpanAttribute
if m.FieldContext == FieldContextResource {
ctx = FieldContextResource
}
return spanMapperProcessorAttribute{
Target: m.Name,
Context: ctx.StringValue(),
Sources: out,
}
}

View File

@@ -1,198 +0,0 @@
package spantypes
import (
"os"
"path/filepath"
"testing"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)
func TestGenerateCollectorConfigWithSpanMapperProcessor(t *testing.T) {
t.Parallel()
baseline := loadFixture(t, "collector_baseline.yaml")
tests := []struct {
name string
groups []*SpanMapperGroupWithMappers
want string
}{
{
name: "no_groups",
want: "collector_no_groups.yaml",
},
{
name: "with_groups",
groups: []*SpanMapperGroupWithMappers{
{
Group: newGroup("llm", []string{"model"}, []string{"service.name"}),
Mappers: []*SpanMapper{
newMapper("gen_ai.request.model", FieldContextResource,
attrSrc("gen_ai.llm.model", SpanMapperOperationCopy, 3),
attrSrc("llm.model", SpanMapperOperationCopy, 2),
resSrc("service.name", SpanMapperOperationCopy, 1),
),
newMapper("gen_ai.request.tokens", FieldContextSpanAttribute,
attrSrc("gen_ai.request_tokens", SpanMapperOperationCopy, 2),
attrSrc("llm.tokens", SpanMapperOperationCopy, 1),
),
newMapper("gen_ai.request.input", FieldContextSpanAttribute,
attrSrc("gen_ai.input", SpanMapperOperationMove, 2),
attrSrc("llm.input", SpanMapperOperationMove, 1),
),
},
},
{
Group: newGroup("agent", []string{"agent."}, nil),
Mappers: []*SpanMapper{
newMapper("gen_ai.agent.name", FieldContextSpanAttribute,
attrSrc("agent.name", SpanMapperOperationCopy, 2),
attrSrc("llm.agent.name", SpanMapperOperationCopy, 1),
),
newMapper("gen_ai.agent.id", FieldContextSpanAttribute,
attrSrc("gen_ai.agent.id", SpanMapperOperationCopy, 2),
attrSrc("llm.agent.id", SpanMapperOperationCopy, 1),
),
},
},
{
Group: newGroup("tool", []string{"agent."}, nil),
Mappers: []*SpanMapper{
newMapper("gen_ai.tool.name", FieldContextSpanAttribute,
attrSrc("ai.tool.name", SpanMapperOperationCopy, 2),
attrSrc("llm.tool.name", SpanMapperOperationCopy, 1),
),
},
},
},
want: "collector_with_groups.yaml",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
got, err := GenerateCollectorConfigWithSpanMapperProcessor(baseline, tc.groups)
require.NoError(t, err)
assertYAMLEqual(t, loadFixture(t, tc.want), got)
})
}
}
func TestGenerateCollectorConfigWithSpanMapperProcessor_Errors(t *testing.T) {
t.Parallel()
tests := []struct {
name string
in []byte
}{
{"processors_not_a_map", []byte("processors: not-a-map\n")},
{"malformed_yaml", []byte(": :")},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
_, err := GenerateCollectorConfigWithSpanMapperProcessor(tc.in, nil)
require.Error(t, err)
assert.True(t, errors.Ast(err, errors.TypeInvalidInput), "want TypeInvalidInput, got %v", err)
assert.True(t, errors.Asc(err, ErrCodeInvalidCollectorConfig), "want ErrCodeInvalidCollectorConfig, got %v", err)
})
}
}
func TestBuildAttributeRule(t *testing.T) {
t.Parallel()
tests := []struct {
name string
mapper *SpanMapper
want spanMapperProcessorAttribute
}{
{
name: "priority_sort_and_resource_prefix",
mapper: newMapper("gen_ai.request.model", FieldContextResource,
attrSrc("llm.model", SpanMapperOperationCopy, 20),
resSrc("service.name", SpanMapperOperationCopy, 10),
attrSrc("gen_ai.llm.model", SpanMapperOperationCopy, 30),
),
want: spanMapperProcessorAttribute{
Target: "gen_ai.request.model",
Context: FieldContextResource.StringValue(),
Sources: []spanMapperProcessorSource{
{Key: "gen_ai.llm.model"},
{Key: "llm.model"},
{Key: "resource.service.name"},
},
},
},
{
name: "per_source_actions",
mapper: newMapper("gen_ai.request.input", FieldContextSpanAttribute,
attrSrc("gen_ai.input", SpanMapperOperationMove, 20),
attrSrc("llm.input", SpanMapperOperationCopy, 10),
),
want: spanMapperProcessorAttribute{
Target: "gen_ai.request.input",
Context: FieldContextSpanAttribute.StringValue(),
Sources: []spanMapperProcessorSource{
{Key: "gen_ai.input", Action: SpanMapperOperationMove.StringValue()},
{Key: "llm.input"},
},
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
assert.Equal(t, tc.want, buildAttributeRule(tc.mapper))
})
}
}
func loadFixture(t *testing.T, name string) []byte {
t.Helper()
b, err := os.ReadFile(filepath.Join("testdata", name))
require.NoError(t, err)
return b
}
// assertYAMLEqual compares two YAML documents structurally so key order and
// slice formatting do not matter.
func assertYAMLEqual(t *testing.T, want, got []byte) {
t.Helper()
var w, g any
require.NoError(t, yaml.Unmarshal(want, &w))
require.NoError(t, yaml.Unmarshal(got, &g))
assert.Equal(t, w, g)
}
func newGroup(name string, attrs, res []string) *SpanMapperGroup {
return &SpanMapperGroup{
Name: name,
Condition: SpanMapperGroupCondition{Attributes: attrs, Resource: res},
Enabled: true,
}
}
func newMapper(name string, target FieldContext, sources ...SpanMapperSource) *SpanMapper {
return &SpanMapper{
Name: name,
FieldContext: target,
Config: SpanMapperConfig{Sources: sources},
Enabled: true,
}
}
func attrSrc(key string, op SpanMapperOperation, priority int) SpanMapperSource {
return SpanMapperSource{Key: key, Context: FieldContextSpanAttribute, Operation: op, Priority: priority}
}
func resSrc(key string, op SpanMapperOperation, priority int) SpanMapperSource {
return SpanMapperSource{Key: key, Context: FieldContextResource, Operation: op, Priority: priority}
}

View File

@@ -21,9 +21,3 @@ type SpanMapperStore interface {
UpdateMapper(ctx context.Context, mapper *SpanMapper) error
DeleteMapper(ctx context.Context, orgID, groupID, id valuer.UUID) error
}
// TraceStore defines the data access interface for trace detail queries.
type TraceStore interface {
GetTraceSummary(ctx context.Context, traceID string) (*TraceSummary, error)
GetTraceSpans(ctx context.Context, traceID string, summary *TraceSummary) ([]StorableSpan, error)
}

View File

@@ -1,17 +0,0 @@
receivers:
otlp:
protocols:
grpc:
processors:
signozspanmapper:
groups: []
batch: {}
exporters:
otlp:
endpoint: localhost:4317
service:
pipelines:
traces:
receivers: [otlp]
processors: [signozspanmapper, batch]
exporters: [otlp]

View File

@@ -1,17 +0,0 @@
receivers:
otlp:
protocols:
grpc:
processors:
signozspanmapper:
groups: []
batch: {}
exporters:
otlp:
endpoint: localhost:4317
service:
pipelines:
traces:
receivers: [otlp]
processors: [signozspanmapper, batch]
exporters: [otlp]

View File

@@ -1,67 +0,0 @@
receivers:
otlp:
protocols:
grpc:
processors:
signozspanmapper:
groups:
- id: llm
exists_any:
attributes:
- model
resource:
- service.name
attributes:
- target: gen_ai.request.model
context: resource
sources:
- key: gen_ai.llm.model
- key: llm.model
- key: resource.service.name
- target: gen_ai.request.tokens
context: attribute
sources:
- key: gen_ai.request_tokens
- key: llm.tokens
- target: gen_ai.request.input
context: attribute
sources:
- key: gen_ai.input
action: move
- key: llm.input
action: move
- id: agent
exists_any:
attributes:
- agent.
attributes:
- target: gen_ai.agent.name
context: attribute
sources:
- key: agent.name
- key: llm.agent.name
- target: gen_ai.agent.id
context: attribute
sources:
- key: gen_ai.agent.id
- key: llm.agent.id
- id: tool
exists_any:
attributes:
- agent.
attributes:
- target: gen_ai.tool.name
context: attribute
sources:
- key: ai.tool.name
- key: llm.tool.name
batch: {}
exporters:
otlp:
endpoint: localhost:4317
service:
pipelines:
traces:
receivers: [otlp]
processors: [signozspanmapper, batch]
exporters: [otlp]

View File

@@ -1,4 +1,4 @@
package spantypes
package tracedetailtypes
import (
"slices"

View File

@@ -1,4 +1,4 @@
package spantypes
package tracedetailtypes
import (
"testing"

View File

@@ -0,0 +1,9 @@
package tracedetailtypes
import "context"
// TraceStore defines the data access interface for trace detail queries.
type TraceStore interface {
GetTraceSummary(ctx context.Context, traceID string) (*TraceSummary, error)
GetTraceSpans(ctx context.Context, traceID string, summary *TraceSummary) ([]StorableSpan, error)
}

View File

@@ -1,4 +1,4 @@
package spantypes
package tracedetailtypes
import (
"encoding/json"

View File

@@ -1,4 +1,4 @@
package spantypes
package tracedetailtypes
import (
"encoding/json"

Some files were not shown because too many files have changed in this diff Show More