Skip to content

Commit

Permalink
continue object enumeration on error, fixes #85
Browse files Browse the repository at this point in the history
  • Loading branch information
psycofdj committed May 8, 2023
1 parent 745b6f5 commit cbdf4af
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 225 deletions.
201 changes: 107 additions & 94 deletions collectors/applications.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ func (c ApplicationsCollector) Collect(objs *models.CFObjects, ch chan<- prometh
} else {
err := c.reportApplicationsMetrics(objs, ch)
if err != nil {
log.Error(err)
errorMetric = float64(1)
c.applicationsScrapeErrorsTotalMetric.Inc()
}
Expand Down Expand Up @@ -198,114 +197,128 @@ func (c ApplicationsCollector) Describe(ch chan<- *prometheus.Desc) {
// 2. symmetrically in some corner cases, buildpack is null but
// detected_buildpack is available. Use detected_buildpack
// for compatibility with v0
func (c ApplicationsCollector) reportApp(application models.Application, objs *models.CFObjects) error {
processes, ok := objs.AppProcesses[application.GUID]
if !ok {
return fmt.Errorf("could not find processes for application '%s'", application.GUID)
}
process := processes[0]
for _, cProc := range processes {
if cProc.Type == "web" {
process = cProc
}
}
spaceRel, ok := application.Relationships[constant.RelationshipTypeSpace]
if !ok {
return fmt.Errorf("could not find space relation in application '%s'", application.GUID)
}
space, ok := objs.Spaces[spaceRel.GUID]
if !ok {
return fmt.Errorf("could not find space with guid '%s'", spaceRel.GUID)
}
orgRel, ok := space.Relationships[constant.RelationshipTypeOrganization]
if !ok {
return fmt.Errorf("could not find org relation in space '%s'", space.GUID)
}
organization, ok := objs.Orgs[orgRel.GUID]
if !ok {
return fmt.Errorf("could not find org with guid '%s'", orgRel.GUID)
}

appSum, ok := objs.AppSummaries[application.GUID]
if !ok {
return fmt.Errorf("could not find app summary with guid '%s'", application.GUID)
}

// 1.
detectedBuildpack := appSum.DetectedBuildpack
if len(detectedBuildpack) == 0 {
detectedBuildpack = appSum.Buildpack
}

// 2.
buildpack := appSum.Buildpack
if len(buildpack) == 0 {
buildpack = appSum.DetectedBuildpack
}

c.applicationInfoMetric.WithLabelValues(
application.GUID,
application.Name,
detectedBuildpack,
buildpack,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
appSum.StackID,
string(application.State),
).Set(float64(1))

c.applicationInstancesMetric.WithLabelValues(
application.GUID,
application.Name,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
string(application.State),
).Set(float64(process.Instances.Value))

c.applicationInstancesRunningMetric.WithLabelValues(
application.GUID,
application.Name,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
string(application.State),
).Set(float64(appSum.RunningInstances))

c.applicationMemoryMbMetric.WithLabelValues(
application.GUID,
application.Name,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
).Set(float64(process.MemoryInMB.Value))

c.applicationDiskQuotaMbMetric.WithLabelValues(
application.GUID,
application.Name,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
).Set(float64(process.DiskInMB.Value))
return nil
}

// reportApplicationsMetrics
// 1. continue processing application list upon error
func (c ApplicationsCollector) reportApplicationsMetrics(objs *models.CFObjects, ch chan<- prometheus.Metric) error {
var res error

c.applicationInfoMetric.Reset()
c.applicationInstancesMetric.Reset()
c.applicationInstancesRunningMetric.Reset()
c.applicationMemoryMbMetric.Reset()
c.applicationDiskQuotaMbMetric.Reset()

for _, application := range objs.Apps {
processes, ok := objs.AppProcesses[application.GUID]
if !ok {
return fmt.Errorf("could not find processes for application '%s'", application.GUID)
}
process := processes[0]
for _, cProc := range processes {
if cProc.Type == "web" {
process = cProc
}
}

spaceRel, ok := application.Relationships[constant.RelationshipTypeSpace]
if !ok {
return fmt.Errorf("could not find space relation in application '%s'", application.GUID)
}
space, ok := objs.Spaces[spaceRel.GUID]
if !ok {
return fmt.Errorf("could not find space with guid '%s'", spaceRel.GUID)
}
orgRel, ok := space.Relationships[constant.RelationshipTypeOrganization]
if !ok {
return fmt.Errorf("could not find org relation in space '%s'", space.GUID)
}
organization, ok := objs.Orgs[orgRel.GUID]
if !ok {
return fmt.Errorf("could not find org with guid '%s'", orgRel.GUID)
}
appSum, ok := objs.AppSummaries[application.GUID]
if !ok {
return fmt.Errorf("could not find app summary with guid '%s'", application.GUID)
}

err := c.reportApp(application, objs)
// 1.
detectedBuildpack := appSum.DetectedBuildpack
if len(detectedBuildpack) == 0 {
detectedBuildpack = appSum.Buildpack
}

// 2.
buildpack := appSum.Buildpack
if len(buildpack) == 0 {
buildpack = appSum.DetectedBuildpack
if err != nil {
log.Warn(err)
res = err
}

c.applicationInfoMetric.WithLabelValues(
application.GUID,
application.Name,
detectedBuildpack,
buildpack,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
appSum.StackID,
string(application.State),
).Set(float64(1))

c.applicationInstancesMetric.WithLabelValues(
application.GUID,
application.Name,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
string(application.State),
).Set(float64(process.Instances.Value))

c.applicationInstancesRunningMetric.WithLabelValues(
application.GUID,
application.Name,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
string(application.State),
).Set(float64(appSum.RunningInstances))

c.applicationMemoryMbMetric.WithLabelValues(
application.GUID,
application.Name,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
).Set(float64(process.MemoryInMB.Value))

c.applicationDiskQuotaMbMetric.WithLabelValues(
application.GUID,
application.Name,
organization.GUID,
organization.Name,
space.GUID,
space.Name,
).Set(float64(process.DiskInMB.Value))
}

c.applicationInfoMetric.Collect(ch)
c.applicationInstancesMetric.Collect(ch)
c.applicationInstancesRunningMetric.Collect(ch)
c.applicationMemoryMbMetric.Collect(ch)
c.applicationDiskQuotaMbMetric.Collect(ch)
return nil
return res
}
123 changes: 69 additions & 54 deletions collectors/organizations.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"time"

"code.cloudfoundry.org/cli/resources"
"github.com/bosh-prometheus/cf_exporter/models"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -238,7 +239,6 @@ func (c OrganizationsCollector) Collect(objs *models.CFObjects, ch chan<- promet
} else {
err := c.reportOrganizationsMetrics(objs, ch)
if err != nil {
log.Error(err)
errorMetric = float64(1)
c.organizationsScrapeErrorsTotalMetric.Inc()
}
Expand Down Expand Up @@ -274,7 +274,69 @@ func (c OrganizationsCollector) Describe(ch chan<- *prometheus.Desc) {
c.lastOrganizationsScrapeDurationSecondsMetric.Describe(ch)
}

func (c OrganizationsCollector) reportOrg(org resources.Organization, objs *models.CFObjects) error {
quotaName := ""
if org.QuotaGUID != "" {
quota, ok := objs.OrgQuotas[org.QuotaGUID]
if !ok {
return fmt.Errorf("could not find org quota with guid '%s'", org.QuotaGUID)
}
quotaName = quota.Name
c.organizationNonBasicServicesAllowedMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(BoolToFloat(quota.Services.PaidServicePlans))
c.organizationInstanceMemoryMbLimitMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(NullIntToFloat(quota.Apps.InstanceMemory))
c.organizationTotalAppInstancesQuotaMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(NullIntToFloat(quota.Apps.TotalAppInstances))
c.organizationTotalAppTasksQuotaMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(NullIntToFloat(quota.Apps.PerAppTasks))
c.organizationTotalMemoryMbQuotaMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(NullIntToFloat(quota.Apps.TotalMemory))
c.organizationTotalPrivateDomainsQuotaMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(NullIntToFloat(quota.Domains.TotalDomains))
c.organizationTotalReservedRoutePortsQuotaMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(NullIntToFloat(quota.Routes.TotalReservedPorts))
c.organizationTotalRoutesQuotaMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(NullIntToFloat(quota.Routes.TotalRoutes))
c.organizationTotalServiceKeysQuotaMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(NullIntToFloat(quota.Services.TotalServiceKeys))
c.organizationTotalServicesQuotaMetric.WithLabelValues(
org.GUID,
org.Name,
).Set(NullIntToFloat(quota.Services.TotalServiceInstances))
}
c.organizationInfoMetric.WithLabelValues(
org.GUID,
org.Name,
quotaName,
).Set(float64(1))

return nil
}

// reportOrganizationsMetrics
// 1. continue processing application list upon error
func (c OrganizationsCollector) reportOrganizationsMetrics(objs *models.CFObjects, ch chan<- prometheus.Metric) error {
var res error

c.organizationInfoMetric.Reset()
c.organizationNonBasicServicesAllowedMetric.Reset()
c.organizationInstanceMemoryMbLimitMetric.Reset()
Expand All @@ -288,59 +350,12 @@ func (c OrganizationsCollector) reportOrganizationsMetrics(objs *models.CFObject
c.organizationTotalServicesQuotaMetric.Reset()

for _, cOrg := range objs.Orgs {
quotaName := ""
if cOrg.QuotaGUID != "" {
quota, ok := objs.OrgQuotas[cOrg.QuotaGUID]
if !ok {
return fmt.Errorf("could not find org quota with guid '%s'", cOrg.QuotaGUID)
}
quotaName = quota.Name
c.organizationNonBasicServicesAllowedMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(BoolToFloat(quota.Services.PaidServicePlans))
c.organizationInstanceMemoryMbLimitMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(NullIntToFloat(quota.Apps.InstanceMemory))
c.organizationTotalAppInstancesQuotaMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(NullIntToFloat(quota.Apps.TotalAppInstances))
c.organizationTotalAppTasksQuotaMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(NullIntToFloat(quota.Apps.PerAppTasks))
c.organizationTotalMemoryMbQuotaMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(NullIntToFloat(quota.Apps.TotalMemory))
c.organizationTotalPrivateDomainsQuotaMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(NullIntToFloat(quota.Domains.TotalDomains))
c.organizationTotalReservedRoutePortsQuotaMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(NullIntToFloat(quota.Routes.TotalReservedPorts))
c.organizationTotalRoutesQuotaMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(NullIntToFloat(quota.Routes.TotalRoutes))
c.organizationTotalServiceKeysQuotaMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(NullIntToFloat(quota.Services.TotalServiceKeys))
c.organizationTotalServicesQuotaMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
).Set(NullIntToFloat(quota.Services.TotalServiceInstances))
err := c.reportOrg(cOrg, objs)
// 1.
if err != nil {
log.Warn(err)
res = err
}
c.organizationInfoMetric.WithLabelValues(
cOrg.GUID,
cOrg.Name,
quotaName,
).Set(float64(1))
}

c.organizationInfoMetric.Collect(ch)
Expand All @@ -354,5 +369,5 @@ func (c OrganizationsCollector) reportOrganizationsMetrics(objs *models.CFObject
c.organizationTotalRoutesQuotaMetric.Collect(ch)
c.organizationTotalServiceKeysQuotaMetric.Collect(ch)
c.organizationTotalServicesQuotaMetric.Collect(ch)
return nil
return res
}
Loading

0 comments on commit cbdf4af

Please sign in to comment.