Skip to content

Commit

Permalink
chore: added a command iteration to run command and command result
Browse files Browse the repository at this point in the history
  • Loading branch information
mkhq committed May 11, 2023
1 parent 404daa9 commit ecf8caf
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 13 deletions.
14 changes: 12 additions & 2 deletions core/src/analytics/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ interface CommandEvent extends EventBase {
type: "Run Command"
properties: PropertiesBase & {
name: string
commandIteration: number
}
}

Expand All @@ -152,6 +153,7 @@ interface CommandResultEvent extends EventBase {
result: AnalyticsCommandResult
errors: string[] // list of GardenBaseError types
exitCode?: number
commandIteration: number
}
}

Expand Down Expand Up @@ -578,11 +580,12 @@ export class AnalyticsHandler {
/**
* Tracks a Command.
*/
trackCommand(commandName: string) {
trackCommand({ commandName, commandIteration = 1 }: { commandName: string; commandIteration?: number }) {
return this.track({
type: "Run Command",
properties: {
name: commandName,
commandIteration,
...this.getBasicAnalyticsProperties(),
},
})
Expand All @@ -591,7 +594,13 @@ export class AnalyticsHandler {
/**
* Track a command result.
*/
trackCommandResult(commandName: string, errors: GardenBaseError[], startTime: Date, exitCode?: number) {
trackCommandResult(
commandName: string,
commandIteration: number,
errors: GardenBaseError[],
startTime: Date,
exitCode?: number
) {
const result: AnalyticsCommandResult = errors.length > 0 ? "failure" : "success"

const durationMsec = getDurationMsec(startTime, new Date())
Expand All @@ -600,6 +609,7 @@ export class AnalyticsHandler {
type: "Command Result",
properties: {
name: commandName,
commandIteration,
durationMsec,
result,
errors: errors.map((e) => e.type),
Expand Down
22 changes: 17 additions & 5 deletions core/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,11 @@ ${renderCommands(commands)}
// TODO: Link to Cloud namespace page here.
const nsLog = log.createLog({ name: "garden" })

let commandIteration = 0

do {
commandIteration += 1

try {
if (command.noProject) {
garden = await makeDummyGarden(workingDir, contextOpts)
Expand Down Expand Up @@ -462,7 +466,7 @@ ${renderCommands(commands)}
commandFullName: command.getFullName(),
})
analytics = await AnalyticsHandler.init(garden, log)
analytics.trackCommand(command.getFullName())
analytics.trackCommand({ commandName: command.getFullName(), commandIteration })

// Note: No reason to await the check
checkForUpdates(garden.globalConfigStore, log).catch((err) => {
Expand All @@ -472,6 +476,8 @@ ${renderCommands(commands)}

await checkForStaticDir()

const commandStartTime = new Date()

// Check if the command is protected and ask for confirmation to proceed if production flag is "true".
if (await command.isAllowedToRun(garden, log, parsedOpts)) {
// TODO: enforce that commands always output DeepPrimitiveMap
Expand All @@ -491,6 +497,16 @@ ${renderCommands(commands)}
result = {}
}

// Track the result of the command run
const allErrors = result.errors || []
analytics?.trackCommandResult(
command.getFullName(),
commandIteration,
allErrors,
commandStartTime,
result.exitCode
)

// This is a little trick to do a round trip in the event loop, which may be necessary for event handlers to
// fire, which may be needed to e.g. capture monitors added in event handlers
await waitForOutputFlush()
Expand Down Expand Up @@ -664,8 +680,6 @@ ${renderCommands(commands)}

this.processRecord = processRecord!

const commandStartTime = new Date()

try {
const runResults = await this.runCommand({ command, parsedArgs, parsedOpts, processRecord, workingDir, log })
commandResult = runResults.result
Expand All @@ -678,8 +692,6 @@ ${renderCommands(commands)}

const gardenErrors: GardenBaseError[] = errors.map(toGardenError)

analytics?.trackCommandResult(command.getFullName(), gardenErrors, commandStartTime, commandResult.exitCode)

// Flushes the Analytics events queue in case there are some remaining events.
if (analytics) {
await analytics.flush()
Expand Down
17 changes: 11 additions & 6 deletions core/test/unit/src/analytics/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,12 +394,13 @@ describe("AnalyticsHandler", () => {
await garden.globalConfigStore.set("analytics", basicConfig)
const now = freezeTime()
analytics = await AnalyticsHandler.factory({ garden, log: garden.log, ciInfo })
const event = analytics.trackCommand("testCommand")
const event = analytics.trackCommand({ commandName: "testCommand" })

expect(event).to.eql({
type: "Run Command",
properties: {
name: "testCommand",
commandIteration: 1,
projectId: AnalyticsHandler.hash(remoteOriginUrl),
projectIdV2: AnalyticsHandler.hashV2(remoteOriginUrl),
projectName,
Expand Down Expand Up @@ -438,12 +439,13 @@ describe("AnalyticsHandler", () => {
await garden.globalConfigStore.set("analytics", basicConfig)
const now = freezeTime()
analytics = await AnalyticsHandler.factory({ garden, log: garden.log, ciInfo: { isCi: true, ciName: "foo" } })
const event = analytics.trackCommand("testCommand")
const event = analytics.trackCommand({ commandName: "testCommand" })

expect(event).to.eql({
type: "Run Command",
properties: {
name: "testCommand",
commandIteration: 1,
projectId: AnalyticsHandler.hash(remoteOriginUrl),
projectIdV2: AnalyticsHandler.hashV2(remoteOriginUrl),
projectName,
Expand Down Expand Up @@ -499,12 +501,13 @@ describe("AnalyticsHandler", () => {
const now = freezeTime()
analytics = await AnalyticsHandler.factory({ garden, log: garden.log, ciInfo })

const event = analytics.trackCommand("testCommand")
const event = analytics.trackCommand({ commandName: "testCommand" })

expect(event).to.eql({
type: "Run Command",
properties: {
name: "testCommand",
commandIteration: 1,
projectId: AnalyticsHandler.hash(remoteOriginUrl),
projectIdV2: AnalyticsHandler.hashV2(remoteOriginUrl),
projectName,
Expand Down Expand Up @@ -548,12 +551,13 @@ describe("AnalyticsHandler", () => {
const now = freezeTime()
analytics = await AnalyticsHandler.factory({ garden, log: garden.log, ciInfo })

const event = analytics.trackCommand("testCommand")
const event = analytics.trackCommand({ commandName: "testCommand" })

expect(event).to.eql({
type: "Run Command",
properties: {
name: "testCommand",
commandIteration: 1,
projectId: AnalyticsHandler.hash(remoteOriginUrl),
projectIdV2: AnalyticsHandler.hashV2(remoteOriginUrl),
projectName: AnalyticsHandler.hash("has-domain-and-id"),
Expand Down Expand Up @@ -597,12 +601,13 @@ describe("AnalyticsHandler", () => {
const now = freezeTime()
analytics = await AnalyticsHandler.factory({ garden, log: garden.log, ciInfo })

const event = analytics.trackCommand("testCommand")
const event = analytics.trackCommand({ commandName: "testCommand" })

expect(event).to.eql({
type: "Run Command",
properties: {
name: "testCommand",
commandIteration: 1,
projectId: AnalyticsHandler.hash(remoteOriginUrl),
projectIdV2: AnalyticsHandler.hashV2(remoteOriginUrl),
projectName: AnalyticsHandler.hash("config-templates"),
Expand Down Expand Up @@ -677,7 +682,7 @@ describe("AnalyticsHandler", () => {
await garden.globalConfigStore.set("analytics", basicConfig)
analytics = await AnalyticsHandler.factory({ garden, log: garden.log, ciInfo })

analytics.trackCommand("test-command-A")
analytics.trackCommand({ commandName: "test-command-A" })
await analytics.flush()

expect(analytics["pendingEvents"].size).to.eql(0)
Expand Down

0 comments on commit ecf8caf

Please sign in to comment.