Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor metrics client #983

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,50 @@ type Inputs = {
datadogSite?: string
}

type Metrics = {
series: v1.Series[]
distributionPointsSeries?: v1.DistributionPointsSeries[]
}

export type MetricsClient = {
submitMetrics: (series: v1.Series[], description: string) => Promise<void>
submitDistributionPoints(series: v1.DistributionPointsSeries[], description: string): Promise<void>
submit: (metrics: Metrics, description: string) => Promise<void>
}

class DryRunMetricsClient implements MetricsClient {
// eslint-disable-next-line @typescript-eslint/require-await
async submitMetrics(series: v1.Series[], description: string): Promise<void> {
async submit(metrics: Metrics, description: string): Promise<void> {
core.startGroup(`Metrics payload (dry-run) (${description})`)
core.info(JSON.stringify(series, undefined, 2))
core.info(JSON.stringify(metrics.series, undefined, 2))
core.endGroup()
}

// eslint-disable-next-line @typescript-eslint/require-await
async submitDistributionPoints(series: v1.DistributionPointsSeries[], description: string): Promise<void> {
core.startGroup(`Distribution points payload (dry-run) (${description})`)
core.info(JSON.stringify(series, undefined, 2))
core.info(JSON.stringify(metrics.distributionPointsSeries, undefined, 2))
core.endGroup()
}
}

class RealMetricsClient implements MetricsClient {
constructor(private readonly metricsApi: v1.MetricsApi) {}

async submitMetrics(series: v1.Series[], description: string): Promise<void> {
async submit(metrics: Metrics, description: string): Promise<void> {
core.startGroup(`Metrics payload (${description})`)
core.info(JSON.stringify(series, undefined, 2))
core.info(JSON.stringify(metrics.series, undefined, 2))
core.endGroup()
if (metrics.series.length > 0) {
core.info(`Sending ${metrics.series.length} metrics to Datadog`)
const accepted = await this.metricsApi.submitMetrics({ body: { series: metrics.series } })
core.info(`Sent ${JSON.stringify(accepted)}`)
}

core.info(`Sending ${series.length} metrics to Datadog`)
const accepted = await this.metricsApi.submitMetrics({ body: { series } })
core.info(`Sent ${JSON.stringify(accepted)}`)
}

async submitDistributionPoints(series: v1.DistributionPointsSeries[], description: string): Promise<void> {
core.startGroup(`Distribution points payload (${description})`)
core.info(JSON.stringify(series, undefined, 2))
core.info(JSON.stringify(metrics.distributionPointsSeries, undefined, 2))
core.endGroup()

core.info(`Sending ${series.length} distribution points to Datadog`)
const accepted = await this.metricsApi.submitDistributionPoints({ body: { series } })
core.info(`Sent ${JSON.stringify(accepted)}`)
if (metrics.distributionPointsSeries && metrics.distributionPointsSeries.length > 0) {
core.info(`Sending ${metrics.distributionPointsSeries.length} distribution points to Datadog`)
const accepted = await this.metricsApi.submitDistributionPoints({
body: { series: metrics.distributionPointsSeries },
})
core.info(`Sent ${JSON.stringify(accepted)}`)
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/pullRequest/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const handlePullRequest = async (
core.info(`Got pull request ${e.action} event: ${e.pull_request.html_url}`)

if (e.action === 'opened') {
return await metricsClient.submitMetrics(computePullRequestOpenedMetrics(e), 'pull request')
return await metricsClient.submit(computePullRequestOpenedMetrics(e), 'pull request')
}

if (e.action === 'closed') {
Expand All @@ -36,7 +36,7 @@ export const handlePullRequest = async (
} catch (error) {
core.warning(`Could not get the pull request: ${String(error)}`)
}
return await metricsClient.submitMetrics(
return await metricsClient.submit(
computePullRequestClosedMetrics(e, pullRequestFirstCommit, inputs),
'pull request',
)
Expand Down
9 changes: 5 additions & 4 deletions src/pullRequest/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ const computeCommonTags = (e: PullRequestEvent): string[] => {
return tags
}

export const computePullRequestOpenedMetrics = (e: PullRequestOpenedEvent): v1.Series[] => {
export const computePullRequestOpenedMetrics = (e: PullRequestOpenedEvent) => {
const tags = computeCommonTags(e)
const t = unixTime(e.pull_request.created_at)
return [
const series: v1.Series[] = [
{
host: 'github.com',
tags,
Expand Down Expand Up @@ -57,6 +57,7 @@ export const computePullRequestOpenedMetrics = (e: PullRequestOpenedEvent): v1.S
points: [[t, e.pull_request.deletions]],
},
]
return { series }
}

type ClosedMetricsOptions = {
Expand All @@ -67,7 +68,7 @@ export const computePullRequestClosedMetrics = (
e: PullRequestClosedEvent,
pullRequestFirstCommit: PullRequestFirstCommit | undefined,
options: ClosedMetricsOptions,
): v1.Series[] => {
) => {
const tags = computeCommonTags(e)
tags.push(`merged:${String(e.pull_request.merged)}`)
const t = unixTime(e.pull_request.closed_at)
Expand Down Expand Up @@ -149,7 +150,7 @@ export const computePullRequestClosedMetrics = (
}
}

return series
return { series }
}

const unixTime = (s: string): number => Date.parse(s) / 1000
2 changes: 1 addition & 1 deletion src/push/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import { computePushMetrics } from './metrics'

export const handlePush = async (metricsClient: MetricsClient, e: PushEvent) => {
core.info(`Got push event: ${e.compare}`)
return await metricsClient.submitMetrics(computePushMetrics(e, new Date()), 'push')
return await metricsClient.submit(computePushMetrics(e, new Date()), 'push')
}
5 changes: 3 additions & 2 deletions src/push/metrics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { v1 } from '@datadog/datadog-api-client'
import { PushEvent } from '@octokit/webhooks-types'

export const computePushMetrics = (e: PushEvent, now: Date): v1.Series[] => {
export const computePushMetrics = (e: PushEvent, now: Date) => {
const tags = [
`repository_owner:${e.repository.owner.login}`,
`repository_name:${e.repository.name}`,
Expand All @@ -14,7 +14,7 @@ export const computePushMetrics = (e: PushEvent, now: Date): v1.Series[] => {
`default_branch:${(e.ref === `refs/heads/${e.repository.default_branch}`).toString()}`,
]
const t = now.getTime() / 1000
return [
const series: v1.Series[] = [
{
host: 'github.com',
tags,
Expand All @@ -23,4 +23,5 @@ export const computePushMetrics = (e: PushEvent, now: Date): v1.Series[] => {
points: [[t, 1]],
},
]
return { series }
}
6 changes: 3 additions & 3 deletions src/rateLimit/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Context = {
}
}

export const computeRateLimitMetrics = (e: Context, r: RateLimitResponse): v1.Series[] => {
export const computeRateLimitMetrics = (e: Context, r: RateLimitResponse) => {
const t = unixTime(r.headers.date) ?? Math.floor(Date.now() / 1000)
const tags = [`repository_owner:${e.repo.owner}`, `repository_name:${e.repo.repo}`]

Expand Down Expand Up @@ -58,11 +58,11 @@ export const computeRateLimitMetrics = (e: Context, r: RateLimitResponse): v1.Se
metric: 'github.actions.api_rate_limit.limit',
type: 'gauge',
points: [[t, r.data.resources.graphql.limit]],
}
},
)
}

return series
return { series }
}

const unixTime = (s: string | undefined): number | undefined => {
Expand Down
2 changes: 1 addition & 1 deletion src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const run = async (context: GitHubContext, inputs: Inputs): Promise<void>
await handleEvent(metricsClient, context, inputs)

const rateLimit = await getRateLimitMetrics(context, inputs)
await metricsClient.submitMetrics(rateLimit, 'rate limit')
await metricsClient.submit(rateLimit, 'rate limit')
}

const handleEvent = async (metricsClient: MetricsClient, context: GitHubContext, inputs: Inputs) => {
Expand Down
2 changes: 1 addition & 1 deletion src/schedule/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ export const handleSchedule = async (metricsClient: MetricsClient, context: GitH
status: 'queued',
per_page: 100,
})
return await metricsClient.submitMetrics(computeScheduleMetrics(context, queuedWorkflowRuns, new Date()), 'schedule')
return await metricsClient.submit(computeScheduleMetrics(context, queuedWorkflowRuns, new Date()), 'schedule')
}
7 changes: 4 additions & 3 deletions src/schedule/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { GitHubContext, ListWorkflowRunsForRepoRateLimitResponse } from '../type
export const computeScheduleMetrics = (
context: GitHubContext,
queuedWorkflowRuns: ListWorkflowRunsForRepoRateLimitResponse,
now: Date
): v1.Series[] => {
now: Date,
) => {
const tags = [`repository_owner:${context.repo.owner}`, `repository_name:${context.repo.repo}`]
const t = now.getTime() / 1000
return [
const series: v1.Series[] = [
{
host: 'github.com',
tags,
Expand All @@ -17,4 +17,5 @@ export const computeScheduleMetrics = (
points: [[t, queuedWorkflowRuns.data.total_count]],
},
]
return { series }
}
8 changes: 3 additions & 5 deletions src/workflowRun/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,11 @@ const handleWorkflowRunCompleted = async (

const metrics = computeWorkflowRunJobStepMetrics(e, checkSuite, workflowJobs?.data)

await metricsClient.submitMetrics(metrics.workflowRunMetrics.series, 'workflow run')
await metricsClient.submitDistributionPoints(metrics.workflowRunMetrics.distributionPointsSeries, 'workflow run')
await metricsClient.submit(metrics.workflowRunMetrics, 'workflow run')
if (inputs.collectJobMetrics) {
await metricsClient.submitMetrics(metrics.jobMetrics.series, 'job')
await metricsClient.submitDistributionPoints(metrics.jobMetrics.distributionPointsSeries, 'job')
await metricsClient.submit(metrics.jobMetrics, 'job')
}
if (inputs.collectStepMetrics) {
await metricsClient.submitMetrics(metrics.stepMetrics, 'step')
await metricsClient.submit({ series: metrics.stepMetrics }, 'step')
}
}
Loading