mirror of
https://github.com/SigNoz/signoz.git
synced 2026-06-02 15:10:34 +01:00
Compare commits
2 Commits
refactor/c
...
refactor/c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04e2caaaaf | ||
|
|
0963ff08cd |
@@ -64,16 +64,16 @@ web:
|
||||
settings:
|
||||
posthog:
|
||||
# Whether to enable PostHog in web.
|
||||
enabled: true
|
||||
enabled: false
|
||||
appcues:
|
||||
# Whether to enable Appcues in web.
|
||||
enabled: true
|
||||
enabled: false
|
||||
sentry:
|
||||
# Whether to enable Sentry in web.
|
||||
enabled: true
|
||||
enabled: false
|
||||
pylon:
|
||||
# Whether to enable Pylon in web.
|
||||
enabled: true
|
||||
enabled: false
|
||||
|
||||
##################### Cache #####################
|
||||
cache:
|
||||
|
||||
@@ -355,32 +355,26 @@ func (module *module) GetService(ctx context.Context, orgID valuer.UUID, service
|
||||
|
||||
var integrationService *cloudintegrationtypes.CloudIntegrationService
|
||||
|
||||
if cloudIntegrationID.IsZero() {
|
||||
return cloudintegrationtypes.NewService(provider, serviceDefinition, nil, nil), nil
|
||||
if !cloudIntegrationID.IsZero() {
|
||||
storedService, err := module.store.GetServiceByServiceID(ctx, cloudIntegrationID, serviceID)
|
||||
if err != nil && !errors.Ast(err, errors.TypeNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
if storedService != nil {
|
||||
serviceConfig, err := cloudintegrationtypes.NewServiceConfigFromJSON(provider, storedService.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
integrationService = cloudintegrationtypes.NewCloudIntegrationServiceFromStorable(storedService, serviceConfig)
|
||||
}
|
||||
|
||||
if err := module.enrichDashboardIDs(ctx, orgID, provider, serviceID, serviceDefinition); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
storedService, err := module.store.GetServiceByServiceID(ctx, cloudIntegrationID, serviceID)
|
||||
if err != nil && !errors.Ast(err, errors.TypeNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
if storedService == nil {
|
||||
return cloudintegrationtypes.NewService(provider, serviceDefinition, nil, nil), nil
|
||||
}
|
||||
|
||||
serviceConfig, err := cloudintegrationtypes.NewServiceConfigFromJSON(provider, storedService.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
integrationService = cloudintegrationtypes.NewCloudIntegrationServiceFromStorable(storedService, serviceConfig)
|
||||
|
||||
slugPrefix := cloudintegrationtypes.CloudIntegrationDashboardSlugPrefix(provider, serviceID)
|
||||
integrationDashboards, err := module.store.ListIntegrationDashboardsBySlugPrefix(ctx, orgID, cloudintegrationtypes.IntegrationDashboardProviderCloudIntegration, slugPrefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cloudintegrationtypes.NewService(provider, serviceDefinition, integrationService, integrationDashboards), nil
|
||||
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 {
|
||||
@@ -589,3 +583,20 @@ func (module *module) deprovisionDashboards(ctx context.Context, orgID valuer.UU
|
||||
}
|
||||
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.CloudIntegrationDashboardSlug(provider, serviceID, d.ID)
|
||||
row, err := module.store.GetIntegrationDashboardBySlug(ctx, orgID, cloudintegrationtypes.IntegrationDashboardProviderCloudIntegration, slug)
|
||||
if err != nil {
|
||||
if errors.Ast(err, errors.TypeNotFound) {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
serviceDefinition.Assets.Dashboards[i].ID = row.DashboardID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2457,33 +2457,6 @@ export interface CloudintegrationtypesAccountDTO {
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface DashboardtypesStorableDashboardDataDTO {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface CloudintegrationtypesDashboardDTO {
|
||||
definition?: DashboardtypesStorableDashboardDataDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export interface CloudintegrationtypesAssetsDTO {
|
||||
/**
|
||||
* @type array,null
|
||||
*/
|
||||
dashboards?: CloudintegrationtypesDashboardDTO[] | null;
|
||||
}
|
||||
|
||||
export interface CloudintegrationtypesAzureConnectionArtifactDTO {
|
||||
/**
|
||||
* @type string
|
||||
@@ -2866,6 +2839,54 @@ export interface CloudintegrationtypesPostableAgentCheckInDTO {
|
||||
providerAccountId?: string;
|
||||
}
|
||||
|
||||
export interface CloudintegrationtypesStorableIntegrationDashboardDTO {
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
createdAt?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
dashboardId?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
provider?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
slug?: string;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface CloudintegrationtypesServiceDashboardDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
integrationDashboard?: CloudintegrationtypesStorableIntegrationDashboardDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export interface CloudintegrationtypesServiceAssetsDTO {
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
dashboards: CloudintegrationtypesServiceDashboardDTO[];
|
||||
}
|
||||
|
||||
export interface CloudintegrationtypesSupportedSignalsDTO {
|
||||
/**
|
||||
* @type boolean
|
||||
@@ -2877,13 +2898,8 @@ export interface CloudintegrationtypesSupportedSignalsDTO {
|
||||
metrics?: boolean;
|
||||
}
|
||||
|
||||
export interface CloudintegrationtypesTelemetryCollectionStrategyDTO {
|
||||
aws?: CloudintegrationtypesAWSTelemetryCollectionStrategyDTO;
|
||||
azure?: CloudintegrationtypesAzureTelemetryCollectionStrategyDTO;
|
||||
}
|
||||
|
||||
export interface CloudintegrationtypesServiceDTO {
|
||||
assets: CloudintegrationtypesAssetsDTO;
|
||||
assets: CloudintegrationtypesServiceAssetsDTO;
|
||||
cloudIntegrationService: CloudintegrationtypesCloudIntegrationServiceDTO | null;
|
||||
dataCollected: CloudintegrationtypesDataCollectedDTO;
|
||||
/**
|
||||
@@ -2899,7 +2915,6 @@ export interface CloudintegrationtypesServiceDTO {
|
||||
*/
|
||||
overview: string;
|
||||
supportedSignals: CloudintegrationtypesSupportedSignalsDTO;
|
||||
telemetryCollectionStrategy: CloudintegrationtypesTelemetryCollectionStrategyDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
@@ -3705,6 +3720,10 @@ export interface DashboardtypesCustomVariableSpecDTO {
|
||||
customValue: string;
|
||||
}
|
||||
|
||||
export interface DashboardtypesStorableDashboardDataDTO {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export enum DashboardtypesSourceDTO {
|
||||
user = 'user',
|
||||
system = 'system',
|
||||
|
||||
@@ -55,7 +55,6 @@ const buildServiceDetailsResponse = (
|
||||
},
|
||||
},
|
||||
},
|
||||
telemetryCollectionStrategy: { aws: {} },
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -53,6 +53,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.aws-service-dashboard-item-disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.aws-service-dashboard-item-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/* eslint-disable sonarjs/cognitive-complexity */
|
||||
import type { KeyboardEvent, MouseEvent } from 'react';
|
||||
import { TooltipSimple } from '@signozhq/ui/tooltip';
|
||||
import {
|
||||
CloudintegrationtypesDashboardDTO,
|
||||
CloudintegrationtypesServiceDashboardDTO,
|
||||
CloudintegrationtypesServiceDTO,
|
||||
} from 'api/generated/services/sigNoz.schemas';
|
||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||
@@ -8,6 +10,9 @@ import { withBasePath } from 'utils/basePath';
|
||||
|
||||
import './ServiceDashboards.styles.scss';
|
||||
|
||||
const DISABLED_TOOLTIP =
|
||||
'Enable metrics collection for this service to view this dashboard.';
|
||||
|
||||
function ServiceDashboards({
|
||||
service,
|
||||
isInteractive = true,
|
||||
@@ -25,68 +30,85 @@ function ServiceDashboards({
|
||||
<div className="aws-service-dashboards">
|
||||
<div className="aws-service-dashboards-title">Dashboards</div>
|
||||
<div className="aws-service-dashboards-items">
|
||||
{dashboards.map((dashboard: CloudintegrationtypesDashboardDTO) => {
|
||||
if (!dashboard.id) {
|
||||
return null;
|
||||
}
|
||||
{dashboards.map(
|
||||
(dashboard: CloudintegrationtypesServiceDashboardDTO, index: number) => {
|
||||
const dashboardId = dashboard.integrationDashboard?.dashboardId;
|
||||
const isEnabled = Boolean(dashboardId) && isInteractive;
|
||||
const itemKey = dashboardId || `${dashboard.title}-${index}`;
|
||||
const dashboardUrl = dashboardId ? `/dashboard/${dashboardId}` : '';
|
||||
|
||||
const dashboardUrl = `/dashboard/${dashboard.id}`;
|
||||
const handleClick = (event: MouseEvent<HTMLDivElement>): void => {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
if (event.metaKey || event.ctrlKey) {
|
||||
window.open(
|
||||
withBasePath(dashboardUrl),
|
||||
'_blank',
|
||||
'noopener,noreferrer',
|
||||
);
|
||||
return;
|
||||
}
|
||||
safeNavigate(dashboardUrl);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
key={dashboard.id}
|
||||
className={`aws-service-dashboard-item ${
|
||||
isInteractive ? 'aws-service-dashboard-item-clickable' : ''
|
||||
}`}
|
||||
role={isInteractive ? 'button' : undefined}
|
||||
tabIndex={isInteractive ? 0 : -1}
|
||||
onClick={(event): void => {
|
||||
if (!isInteractive) {
|
||||
return;
|
||||
}
|
||||
if (event.metaKey || event.ctrlKey) {
|
||||
window.open(
|
||||
withBasePath(dashboardUrl),
|
||||
'_blank',
|
||||
'noopener,noreferrer',
|
||||
);
|
||||
return;
|
||||
}
|
||||
const handleAuxClick = (event: MouseEvent<HTMLDivElement>): void => {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
if (event.button === 1) {
|
||||
window.open(
|
||||
withBasePath(dashboardUrl),
|
||||
'_blank',
|
||||
'noopener,noreferrer',
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
safeNavigate(dashboardUrl);
|
||||
}}
|
||||
onAuxClick={(event): void => {
|
||||
if (!isInteractive) {
|
||||
return;
|
||||
}
|
||||
if (event.button === 1) {
|
||||
window.open(
|
||||
withBasePath(dashboardUrl),
|
||||
'_blank',
|
||||
'noopener,noreferrer',
|
||||
);
|
||||
}
|
||||
}}
|
||||
onKeyDown={(event): void => {
|
||||
if (!isInteractive) {
|
||||
return;
|
||||
}
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
safeNavigate(dashboardUrl);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="aws-service-dashboard-item-content">
|
||||
<div className="aws-service-dashboard-item-title">
|
||||
{dashboard.title}
|
||||
</div>
|
||||
<div className="aws-service-dashboard-item-description">
|
||||
{dashboard.description}
|
||||
}
|
||||
};
|
||||
|
||||
const card = (
|
||||
<div
|
||||
className={`aws-service-dashboard-item ${
|
||||
isEnabled ? 'aws-service-dashboard-item-clickable' : ''
|
||||
} ${!dashboardId ? 'aws-service-dashboard-item-disabled' : ''}`}
|
||||
role={isEnabled ? 'button' : undefined}
|
||||
tabIndex={isEnabled ? 0 : -1}
|
||||
aria-disabled={!dashboardId}
|
||||
onClick={handleClick}
|
||||
onAuxClick={handleAuxClick}
|
||||
onKeyDown={handleKeyDown}
|
||||
>
|
||||
<div className="aws-service-dashboard-item-content">
|
||||
<div className="aws-service-dashboard-item-title">
|
||||
{dashboard.title}
|
||||
</div>
|
||||
<div className="aws-service-dashboard-item-description">
|
||||
{dashboard.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
);
|
||||
|
||||
if (!dashboardId) {
|
||||
return (
|
||||
<TooltipSimple key={itemKey} title={DISABLED_TOOLTIP} arrow>
|
||||
{card}
|
||||
</TooltipSimple>
|
||||
);
|
||||
}
|
||||
|
||||
return <div key={itemKey}>{card}</div>;
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -440,3 +440,4 @@ func (handler *handler) AgentCheckIn(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
render.Success(rw, http.StatusOK, cloudintegrationtypes.NewGettableAgentCheckIn(provider, resp))
|
||||
}
|
||||
|
||||
|
||||
@@ -18,16 +18,14 @@ var (
|
||||
type StorableIntegrationDashboard struct {
|
||||
bun.BaseModel `bun:"table:integration_dashboard"`
|
||||
|
||||
ID string `json:"id" bun:"id,pk,type:text"`
|
||||
DashboardID string `json:"dashboardId" bun:"dashboard_id,type:text"`
|
||||
Provider IntegrationDashboardProviderType `json:"provider" bun:"provider,type:text"`
|
||||
Slug string `json:"slug" bun:"slug,type:text"`
|
||||
CreatedAt time.Time `json:"createdAt" bun:"created_at"`
|
||||
UpdatedAt time.Time `json:"updatedAt" bun:"updated_at"`
|
||||
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"`
|
||||
}
|
||||
|
||||
type IntegrationDashboard = StorableIntegrationDashboard
|
||||
|
||||
func NewStorableIntegrationDashboard(dashboardID string, provider IntegrationDashboardProviderType, slug string) *StorableIntegrationDashboard {
|
||||
now := time.Now()
|
||||
return &StorableIntegrationDashboard{
|
||||
|
||||
@@ -50,18 +50,10 @@ type ListServicesMetadataParams struct {
|
||||
// Service represents a cloud integration service with its definition,
|
||||
// cloud integration service is non nil only when the service entry exists in DB with ANY config (enabled or disabled).
|
||||
type Service struct {
|
||||
ServiceDefinitionMetadata
|
||||
Overview string `json:"overview" required:"true"` // markdown
|
||||
ServiceAssets ServiceAssets `json:"assets" required:"true"`
|
||||
SupportedSignals SupportedSignals `json:"supportedSignals" required:"true"`
|
||||
DataCollected DataCollected `json:"dataCollected" required:"true"`
|
||||
ServiceDefinition
|
||||
CloudIntegrationService *CloudIntegrationService `json:"cloudIntegrationService" required:"true" nullable:"true"`
|
||||
}
|
||||
|
||||
type ServiceAssets struct {
|
||||
Dashboards []*ServiceDashboard `json:"dashboards" required:"true" nullable:"false"`
|
||||
}
|
||||
|
||||
type GetServiceParams struct {
|
||||
CloudIntegrationID valuer.UUID `query:"cloud_integration_id" required:"false"`
|
||||
}
|
||||
@@ -129,12 +121,6 @@ type Dashboard struct {
|
||||
Definition dashboardtypes.StorableDashboardData `json:"definition,omitempty"`
|
||||
}
|
||||
|
||||
type ServiceDashboard struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
IntegrationDashboard *IntegrationDashboard `json:"integrationDashboard,omitempty" required:"false"`
|
||||
}
|
||||
|
||||
func NewCloudIntegrationService(serviceID ServiceID, cloudIntegrationID valuer.UUID, provider CloudProviderType, config *ServiceConfig) (*CloudIntegrationService, error) {
|
||||
switch provider {
|
||||
case CloudProviderTypeAWS:
|
||||
@@ -178,41 +164,11 @@ func NewServiceMetadata(definition ServiceDefinition, enabled bool) *ServiceMeta
|
||||
}
|
||||
}
|
||||
|
||||
func NewService(provider CloudProviderType, def *ServiceDefinition, integrationService *CloudIntegrationService, integrationDashboards []*StorableIntegrationDashboard) *Service {
|
||||
service := &Service{
|
||||
ServiceDefinitionMetadata: def.ServiceDefinitionMetadata,
|
||||
Overview: def.Overview,
|
||||
SupportedSignals: def.SupportedSignals,
|
||||
DataCollected: def.DataCollected,
|
||||
CloudIntegrationService: integrationService,
|
||||
ServiceAssets: ServiceAssets{Dashboards: make([]*ServiceDashboard, 0, len(def.Assets.Dashboards))},
|
||||
func NewService(def ServiceDefinition, storableService *CloudIntegrationService) *Service {
|
||||
return &Service{
|
||||
ServiceDefinition: def,
|
||||
CloudIntegrationService: storableService,
|
||||
}
|
||||
|
||||
integrationDashboardsMap := make(map[string]*IntegrationDashboard)
|
||||
for _, d := range integrationDashboards {
|
||||
integrationDashboardsMap[d.Slug] = d
|
||||
}
|
||||
|
||||
for _, d := range def.Assets.Dashboards {
|
||||
dashboard := &ServiceDashboard{
|
||||
Title: d.Title,
|
||||
Description: d.Description,
|
||||
}
|
||||
|
||||
if integrationService != nil {
|
||||
slug := CloudIntegrationDashboardSlug(provider, integrationService.Type, d.ID)
|
||||
|
||||
if integrationDashboard, exists := integrationDashboardsMap[slug]; exists {
|
||||
if integrationDashboard != nil {
|
||||
dashboard.IntegrationDashboard = integrationDashboard
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
service.ServiceAssets.Dashboards = append(service.ServiceAssets.Dashboards, dashboard)
|
||||
}
|
||||
|
||||
return service
|
||||
}
|
||||
|
||||
func NewGettableServicesMetadata(services []*ServiceMetadata) *GettableServicesMetadata {
|
||||
|
||||
@@ -54,16 +54,16 @@ func newConfig() factory.Config {
|
||||
Directory: "/etc/signoz/web",
|
||||
Settings: SettingsConfig{
|
||||
Posthog: PosthogConfig{
|
||||
Enabled: true,
|
||||
Enabled: false,
|
||||
},
|
||||
Appcues: AppcuesConfig{
|
||||
Enabled: true,
|
||||
Enabled: false,
|
||||
},
|
||||
Sentry: SentryConfig{
|
||||
Enabled: true,
|
||||
Enabled: false,
|
||||
},
|
||||
Pylon: PylonConfig{
|
||||
Enabled: true,
|
||||
Enabled: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user