Skip to content

Commit

Permalink
feat: App stats availability measurement
Browse files Browse the repository at this point in the history
Currently concerned with when stats are seen as unavailable by the
client. Does not include when stats are set to zero by the Cloud
Controller when one or more required metrics are missing.

Co-authored-by: Rebecca Roberts <rebecca.roberts@broadcom.com>
  • Loading branch information
acrmp and rroberts2222 committed Apr 30, 2024
1 parent 463bcd6 commit e615430
Show file tree
Hide file tree
Showing 12 changed files with 407 additions and 14 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ It measures:
- app syslog availability,
by periodically checking that app logs
drain to a syslog sink.
- app stats availability,
by periodically checking that app stats
are not unavailable.

The CF Release Integration team uses it
to monitor availability during migrations
from `cf-release` to `cf-deployment`,
and during upgrade deployments.
It is often used to monitor availability
during upgrade deployments.

## Installation

Expand Down Expand Up @@ -66,6 +67,7 @@ Here is an example config `json`:
"allowed_failures": {
"app_pushability": 2,
"http_availability": 5,
"app_stats": 2,
"recent_logs": 2,
"streaming_logs": 2,
"app_syslog_availability": 2
Expand Down
9 changes: 9 additions & 0 deletions cfCmdGenerator/cfCmdGenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type CfCmdGenerator interface {
DeleteOrg(org string) cmdStartWaiter.CmdStartWaiter
DeleteQuota(quota string) cmdStartWaiter.CmdStartWaiter
LogOut() cmdStartWaiter.CmdStartWaiter
AppStats(appName string) cmdStartWaiter.CmdStartWaiter
RecentLogs(appName string) cmdStartWaiter.CmdStartWaiter
StreamLogs(ctx context.Context, appName string) cmdStartWaiter.CmdStartWaiter
MapRoute(appName, domain string, port int) cmdStartWaiter.CmdStartWaiter
Expand Down Expand Up @@ -175,6 +176,14 @@ func (c *cfCmdGenerator) LogOut() cmdStartWaiter.CmdStartWaiter {
)
}

func (c *cfCmdGenerator) AppStats(appName string) cmdStartWaiter.CmdStartWaiter {
return c.setCfHome(
exec.Command(
"cf", "app", appName,
),
)
}

func (c *cfCmdGenerator) RecentLogs(appName string) cmdStartWaiter.CmdStartWaiter {
return c.setCfHome(
exec.Command(
Expand Down
8 changes: 8 additions & 0 deletions cfCmdGenerator/cfCmdGenerator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ var _ = Describe("CfCmdGenerator", func() {
})
})

Describe("AppStats", func() {
It("Generates the correct command", func() {
expectedCmd := exec.Command("cf", "app", "appName")
cmd := generator.AppStats("appName")
expectCommandToBeEquivalent(cmd, expectedCmd, cfHomeEnvVar)
})
})

Describe("RecentLogs", func() {
It("Generates the correct command", func() {
expectedCmd := exec.Command("cf", "logs", "appName", "--recent")
Expand Down
74 changes: 74 additions & 0 deletions cfCmdGenerator/cfCmdGeneratorfakes/fake_cf_cmd_generator.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions cfWorkflow/cfWorkflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type CfWorkflow interface {
Delete(cfCmdGenerator.CfCmdGenerator) []cmdStartWaiter.CmdStartWaiter
TearDown(cfCmdGenerator.CfCmdGenerator) []cmdStartWaiter.CmdStartWaiter
RecentLogs(cfCmdGenerator.CfCmdGenerator) []cmdStartWaiter.CmdStartWaiter
AppStats(cfCmdGenerator.CfCmdGenerator) []cmdStartWaiter.CmdStartWaiter
StreamLogs(context.Context, cfCmdGenerator.CfCmdGenerator) []cmdStartWaiter.CmdStartWaiter

MapSyslogRoute(cfCmdGenerator.CfCmdGenerator) []cmdStartWaiter.CmdStartWaiter
Expand Down Expand Up @@ -141,6 +142,15 @@ func (c *cfWorkflow) TearDown(ccg cfCmdGenerator.CfCmdGenerator) []cmdStartWaite
return ret
}

func (c *cfWorkflow) AppStats(ccg cfCmdGenerator.CfCmdGenerator) []cmdStartWaiter.CmdStartWaiter {
return []cmdStartWaiter.CmdStartWaiter{
ccg.Api(c.cf.API),
ccg.Auth(c.cf.AdminUser, c.cf.AdminPassword),
ccg.Target(c.org, c.space),
ccg.AppStats(c.appName),
}
}

func (c *cfWorkflow) RecentLogs(ccg cfCmdGenerator.CfCmdGenerator) []cmdStartWaiter.CmdStartWaiter {
return []cmdStartWaiter.CmdStartWaiter{
ccg.Api(c.cf.API),
Expand Down
15 changes: 15 additions & 0 deletions cfWorkflow/cfWorkflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,21 @@ var _ = Describe("CfWorkflow", func() {
})
})

Describe("AppStats", func() {
It("returns a set of commands to get stats for an app", func() {
cmds := cw.AppStats(ccg)

Expect(cmds).To(Equal(
[]cmdStartWaiter.CmdStartWaiter{
ccg.Api("jigglypuff.cf-app.com"),
ccg.Auth("pika", "chu"),
ccg.Target("someOrg", "someSpace"),
ccg.AppStats("doraApp"),
},
))
})
})

Describe("RecentLogs", func() {
It("returns a set of commands to get recent logs for an app", func() {
cmds := cw.RecentLogs(ccg)
Expand Down
74 changes: 74 additions & 0 deletions cfWorkflow/cfWorkflowfakes/fake_cf_workflow.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type AllowedFailures struct {
HttpAvailability int `json:"http_availability"`
RecentLogs int `json:"recent_logs"`
StreamingLogs int `json:"streaming_logs"`
AppStats int `json:"app_stats"`
AppSyslogAvailability int `json:"app_syslog_availability"`
TCPAvailability int `json:"tcp_availability"`
}
Expand Down
Loading

0 comments on commit e615430

Please sign in to comment.