Skip to content

Commit

Permalink
Track cluster identifier (cluster ID) as part of system information (#…
Browse files Browse the repository at this point in the history
…616)

* Track cluster identifier (cluster ID) as part of system information

This is intended to help identify servers that belong together, to allow
the pganalyze app to group them in an overview, offer data in combined
views, or allow Index Advisor to avoid considering indexes unused if
they are used on a replica.

To start with this identifies the cluster ID for given providers:
- AWS: DBClusterIdentifier (user-assigned cluster name)
- Azure: Source Server ID (replication parent server ID + resource group)
- Crunchy Bridge: Cluster Parent ID (replication parent server ID)
- Self hosted: pg_controldata system identifier (unique ID shared by all physical replicas)

There are providers (e.g. GCP) and edge cases (e.g. when helper doesn't
run for self hosted) where this doesn't work. Handling those cases, and
allowing manual overrides of the cluster ID is left for a later follow-up.
  • Loading branch information
lfittl authored Oct 23, 2024
1 parent 47bcebf commit ccdd179
Show file tree
Hide file tree
Showing 9 changed files with 572 additions and 539 deletions.
10 changes: 10 additions & 0 deletions input/system/azure/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package azure

import (
"context"
"fmt"
"strings"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
Expand Down Expand Up @@ -61,6 +62,14 @@ func GetSystemState(ctx context.Context, server *state.Server, logger *util.Logg

if config.AzureDbServerName == rID.Name {
customWindowEnabled := util.StringCustomTypePtrToString(v.Properties.MaintenanceWindow.CustomWindow) == "Enabled"
if v.Properties.SourceServerResourceID != nil {
sourceID, err := arm.ParseResourceID(*v.Properties.SourceServerResourceID)
if err == nil {
system.Info.ClusterID = fmt.Sprintf("%s/%s", sourceID.ResourceGroupName, sourceID.Name)
}
} else {
system.Info.ClusterID = fmt.Sprintf("%s/%s", rID.ResourceGroupName, rID.Name)
}
system.Info.Azure = &state.SystemInfoAzure{
Location: util.StringPtrToString(v.Location),
CreatedAt: util.TimePtrToTime(v.SystemData.CreatedAt),
Expand Down Expand Up @@ -118,6 +127,7 @@ func GetSystemState(ctx context.Context, server *state.Server, logger *util.Logg

if config.AzureDbServerName == rID.Name {
customWindowEnabled := util.StringCustomTypePtrToString(v.Properties.MaintenanceWindow.CustomWindow) == "Enabled"
system.Info.ClusterID = fmt.Sprintf("%s/%s", rID.ResourceGroupName, rID.Name)
system.Info.Azure = &state.SystemInfoAzure{
Location: util.StringPtrToString(v.Location),
CreatedAt: util.TimePtrToTime(v.SystemData.CreatedAt),
Expand Down
18 changes: 10 additions & 8 deletions input/system/crunchy_bridge/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"net/http"

"github.com/guregu/null"
"github.com/pganalyze/collector/util"
)

Expand All @@ -21,14 +22,15 @@ type Client struct {
}

type ClusterInfo struct {
CPU int32 `json:"cpu"`
CreatedAt string `json:"created_at"`
Memory float32 `json:"memory"`
Name string `json:"name"`
PlanID string `json:"plan_id"`
ProviderID string `json:"provider_id"`
RegionID string `json:"region_id"`
Storage int32 `json:"storage"`
CPU int32 `json:"cpu"`
CreatedAt string `json:"created_at"`
Memory float32 `json:"memory"`
Name string `json:"name"`
ParentID null.String `json:"parent_id"`
PlanID string `json:"plan_id"`
ProviderID string `json:"provider_id"`
RegionID string `json:"region_id"`
Storage int32 `json:"storage"`
}

type MetricViews struct {
Expand Down
5 changes: 5 additions & 0 deletions input/system/crunchy_bridge/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ func GetSystemState(ctx context.Context, server *state.Server, logger *util.Logg
logger.PrintError("CrunchyBridge/System: Encountered error when getting cluster info %v\n", err)
return
}
if clusterInfo.ParentID.Valid {
system.Info.ClusterID = clusterInfo.ParentID.String
} else {
system.Info.ClusterID = client.ClusterID
}
system.Info.CrunchyBridge = &state.SystemInfoCrunchyBridge{
ClusterName: clusterInfo.Name,
PlanID: clusterInfo.PlanID,
Expand Down
2 changes: 2 additions & 0 deletions input/system/rds/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ func GetSystemState(server *state.Server, logger *util.Logger) (system state.Sys
return
}

system.Info.ClusterID = util.StringPtrToString(instance.DBClusterIdentifier)

isAurora := util.StringPtrToString(instance.Engine) == "aurora-postgresql"

system.Info.AmazonRds = &state.SystemInfoAmazonRds{
Expand Down
1 change: 1 addition & 0 deletions input/system/selfhosted/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func GetSystemState(server *state.Server, logger *util.Logger) (system state.Sys

system.XlogUsedBytes = status.XlogUsedBytes
system.Info.SelfHosted.DatabaseSystemIdentifier = status.SystemIdentifier
system.Info.ClusterID = status.SystemIdentifier
}

hostInfo, err := host.Info()
Expand Down
1,072 changes: 541 additions & 531 deletions output/pganalyze_collector/shared.pb.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions output/transform/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ func transformSystem(systemState state.SystemState, diffState state.DiffState) *

system.SystemId = systemState.Info.SystemID
system.SystemScope = systemState.Info.SystemScope
system.ClusterId = systemState.Info.ClusterID
system.XlogUsedBytes = systemState.XlogUsedBytes

system.SchedulerStatistic = &snapshot.SchedulerStatistic{
Expand Down
1 change: 1 addition & 0 deletions protobuf/shared.proto
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ message System {
SystemInformation system_information = 1;
string system_id = 2; // Unique identifier for this system
string system_scope = 3; // Name the system ID is scoped by (optional)
string cluster_id = 4; // Unique identifier for the (physical replication) cluster

SchedulerStatistic scheduler_statistic = 10;
MemoryStatistic memory_statistic = 11;
Expand Down
1 change: 1 addition & 0 deletions state/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type SystemInfo struct {
Type SystemType
SystemScope string
SystemID string
ClusterID string

SelfHosted *SystemInfoSelfHosted
AmazonRds *SystemInfoAmazonRds
Expand Down

0 comments on commit ccdd179

Please sign in to comment.