Skip to content

Commit

Permalink
[devel,wip] Collect metrics from Azure
Browse files Browse the repository at this point in the history
  • Loading branch information
mdevan committed May 5, 2022
1 parent 619def7 commit 6014410
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 9 deletions.
2 changes: 2 additions & 0 deletions cmd/pgmetrics/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Collection options:
--log-dir read all the PostgreSQL log files in this directory
--log-span=MINS examine the last MINS minutes of logs (default: 5)
--aws-rds-dbid AWS RDS/Aurora database instance identifier
--az-resource Azure resource ID
Output options:
-f, --format=FORMAT output format; "human", "json" or "csv" (default: "human")
Expand Down Expand Up @@ -213,6 +214,7 @@ func (o *options) parse() (args []string) {
s.StringVarLong(&o.CollectConfig.LogDir, "log-dir", 0, "")
s.UintVarLong(&o.CollectConfig.LogSpan, "log-span", 0, "")
s.StringVarLong(&o.CollectConfig.RDSDBIdentifier, "aws-rds-dbid", 0, "")
s.StringVarLong(&o.CollectConfig.AzureResourceID, "az-resource", 0, "")
// output
s.StringVarLong(&o.format, "format", 'f', "")
s.StringVarLong(&o.output, "output", 'o', "")
Expand Down
131 changes: 131 additions & 0 deletions collector/azure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package collector

import (
"context"
"errors"
"fmt"
"regexp"
"strings"
"time"

"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/insights"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/azure/auth"
"github.com/rapidloop/pgmetrics"
)

const (
flexibleServerMetrics = `backup_storage_used,cpu_percent,memory_percent,iops,disk_queue_depth,read_throughput,write_throughput,read_iops,write_iops,storage_percent,storage_used,storage_free,txlogs_storage_used,active_connections,network_bytes_egress,network_bytes_ingress,connections_failed,connections_succeeded,maximum_used_transactionIDs`
singleServerMetrics = `cpu_percent,memory_percent,io_consumption_percent,storage_percent,storage_used,storage_limit,serverlog_storage_percent,serverlog_storage_usage,serverlog_storage_limit,active_connections,connections_failed,backup_storage_used,network_bytes_egress,network_bytes_ingress,pg_replica_log_delay_in_seconds,pg_replica_log_delay_in_bytes`
citusMetrics = `cpu_percent,memory_percent,apps_reserved_memory_percent,iops,storage_percent,storage_used,active_connections,network_bytes_egress,network_bytes_ingress`
)

var rxResource = regexp.MustCompile(`(?i)^/subscriptions/([^/]{36})/resourceGroups/([^/]+)/providers/Microsoft.DBforPostgreSQL/(flexibleServers|servers|serverGroupsv2)/([^/]+)$`)

func collectAzure(ctx context.Context, resourceID string, out *pgmetrics.Azure) error {

// parse resource URI
m := rxResource.FindStringSubmatch(resourceID)
if len(m) != 5 {
return errors.New("invalid resource ID")
}
azSubID := m[1]
out.ResourceType = "Microsoft.DBforPostgreSQL/" + m[3]
out.ResourceName = m[4]
out.Metrics = make(map[string]float64)

// setup authorizer
authorizer, err := auth.NewAuthorizerFromEnvironmentWithResource(azure.PublicCloud.ResourceManagerEndpoint)
if err != nil && err.Error() == "MSI not available" {
authorizer, err = auth.NewAuthorizerFromCLIWithResource(azure.PublicCloud.ResourceManagerEndpoint)
}
if err != nil {
return fmt.Errorf("failed to setup azure authorizer: %v", err)
}

// parameters for metrics query
to := time.Now().In(time.UTC)
from := to.Add(-5 * time.Minute)
timeRange := from.Format(time.RFC3339) + "/" + to.Format(time.RFC3339)
var interval string
var top int32 = 1
var metricNames string
switch m[3] {
case "flexibleServers":
interval = "PT1M"
metricNames = flexibleServerMetrics
case "servers":
interval = "PT15M"
metricNames = singleServerMetrics
case "serverGroupsv2":
interval = "PT1M"
metricNames = citusMetrics
}

// query using a client
client := insights.NewMetricsClient(azSubID)
client.Authorizer = authorizer
resp, err := client.List(
ctx,
resourceID,
timeRange,
&interval,
metricNames,
"", // aggregation
&top, // top
"", // order by
"", // filter
insights.Data, // result type
"", // metric namespace
)
if err != nil {
return fmt.Errorf("failed to query Azure API: %v", err)
}

// parse response
out.ResourceRegion = *resp.Resourceregion
if resp.Value != nil {
for _, m := range *resp.Value {
if m.ID == nil || *m.ID == "" {
// log.Printf("warning: ignoring metric with no id: %v", m)
continue
}
if m.Timeseries == nil || len(*m.Timeseries) == 0 {
continue // no timeseries data, ignore quietly
}
ts := (*m.Timeseries)[len(*m.Timeseries)-1]
if ts.Data == nil {
continue // no timeseries data, ignore quietly
}
name := azGetMetricName(*m.ID)
for i := len(*ts.Data) - 1; i >= 0; i-- {
t := (*ts.Data)[i]
if t.TimeStamp == nil {
continue
}
if t.Average != nil {
out.Metrics[name] = *t.Average
break
}
if t.Total != nil {
out.Metrics[name] = *t.Total
break
}
if t.Maximum != nil {
out.Metrics[name] = *t.Maximum
break
}
}
}
}

return nil
}

func azGetMetricName(id string) string {
i := strings.LastIndexByte(id, '/')
if i != -1 {
return id[int(i)+1:]
}
return id
}
19 changes: 19 additions & 0 deletions collector/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ type CollectConfig struct {
LogSpan uint
RDSDBIdentifier string
AllDBs bool
AzureResourceID string

// connection
Host string
Expand Down Expand Up @@ -220,6 +221,11 @@ func Collect(o CollectConfig, dbnames []string) *pgmetrics.Model {
c.collectFromRDS(o)
}

// collect from Azure if resource id is specified
if len(o.AzureResourceID) > 0 {
c.collectFromAzure(o)
}

return &c.result
}

Expand Down Expand Up @@ -2904,6 +2910,19 @@ func (c *collector) collectFromRDS(o CollectConfig) {
}
}

func (c *collector) collectFromAzure(o CollectConfig) {
timeout := time.Duration(o.TimeoutSec) * time.Second
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

var azure pgmetrics.Azure
if err := collectAzure(ctx, o.AzureResourceID, &azure); err != nil {
log.Printf("warning: failed to collect from Azure: %v", err)
} else {
c.result.Azure = &azure
}
}

//------------------------------------------------------------------------------
// The following query for bloat was taken from the venerable check_postgres
// script (https://bucardo.org/check_postgres/), which is:
Expand Down
7 changes: 6 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
module github.com/rapidloop/pgmetrics

require (
github.com/Azure/azure-sdk-for-go v63.4.0+incompatible
github.com/Azure/go-autorest/autorest v0.11.27
github.com/Azure/go-autorest/autorest/azure/auth v0.5.11
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
github.com/aws/aws-sdk-go v1.29.29
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30
github.com/rapidloop/pq v1.1.1
github.com/xdg-go/stringprep v1.0.0 // indirect
github.com/xdg/stringprep v1.0.0 // indirect
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
)

go 1.13
57 changes: 50 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,14 +1,47 @@
github.com/Azure/azure-sdk-for-go v63.4.0+incompatible h1:fle3M5Q7vr8auaiPffKyUQmLbvYeqpw30bKU6PrWJFo=
github.com/Azure/azure-sdk-for-go v63.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc=
github.com/Azure/go-autorest/autorest v0.11.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A=
github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U=
github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ=
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 h1:P6bYXFoao05z5uhOQzbC3Qd8JqF3jUoocoTeIxkp2cA=
github.com/Azure/go-autorest/autorest/azure/auth v0.5.11/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 h1:0W/yGmFdTIT77fvdlGZ0LMISoLHFJ7Tx4U0yeB+uFs4=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg=
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk=
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac=
github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/aws/aws-sdk-go v1.29.29 h1:4TdSYzXL8bHKu80tzPjO4c0ALw4Fd8qZGqf1aozUcBU=
github.com/aws/aws-sdk-go v1.29.29/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4 h1:qk/FSDDxo05wdJH28W+p5yivv7LuLYLRXPPD8KQCtZs=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0=
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30 h1:BHT1/DKsYDGkUgQ2jmMaozVcdk+sVfz0+1ZJq4zkWgw=
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand All @@ -17,23 +50,33 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rapidloop/pq v1.1.1 h1:nC/PmemMKppcgQ1gE2BqxqlEEqzJIHL3afZOjjZhvnE=
github.com/rapidloop/pq v1.1.1/go.mod h1:KCIg3rAcDl7ELp5s30z4lIp1xaOujoaMXnlYKhHECFo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/xdg-go/stringprep v1.0.0 h1:W/PJi55zhi8ClBDgGZK2sdhe6QxuHS6YiVwrGEOYjdE=
github.com/xdg-go/stringprep v1.0.0/go.mod h1:1lAKNhwXFE4//YT4gqVxkhclqvPTWe2Kyd6L59AbR8w=
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
Expand Down
17 changes: 16 additions & 1 deletion model.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package pgmetrics

// ModelSchemaVersion is the schema version of the "Model" data structure
// defined below. It is in the "semver" notation. Version history:
// 1.12 - Azure metrics
// 1.11 - Postgres 14, PgBouncer 1.16, other attributes
// 1.10 - New fields in pg_stat_statements for Postgres 13
// 1.9 - Postgres 13, Citus support
Expand All @@ -31,7 +32,7 @@ package pgmetrics
// 1.2 - more table and index attributes
// 1.1 - added NotificationQueueUsage and Statements
// 1.0 - initial release
const ModelSchemaVersion = "1.11"
const ModelSchemaVersion = "1.12"

// Model contains the entire information collected by a single run of
// pgmetrics. It can be converted to and from json without loss of
Expand Down Expand Up @@ -157,6 +158,11 @@ type Model struct {

// WAL activity info, from pg_stat_wal, pg >= v14
WAL *WAL `json:"wal,omitempty"`

// following fields are present only in schema 1.12 and later

// metrics from Azure PostgreSQL, via Azure Monitor APIs
Azure *Azure `json:"azure,omitempty"`
}

// DatabaseByOID iterates over the databases in the model and returns the reference
Expand Down Expand Up @@ -795,3 +801,12 @@ type WAL struct {
SyncTime float64 `json:"sync_time"` // in milliseconds
StatsReset int64 `json:"stats_reset"`
}

// Azure represents metrics and information collected from Azure PostgreSQL
// via Azure Monitor APIs. Added in schema 1.12.
type Azure struct {
ResourceName string `json:"resource_name"`
ResourceType string `json:"resource_type"`
ResourceRegion string `json:"resource_region"`
Metrics map[string]float64 `json:"metrics"`
}

0 comments on commit 6014410

Please sign in to comment.