Skip to content

Commit

Permalink
refactor(server): get metering data of billing from prometheus (#1628)
Browse files Browse the repository at this point in the history
* refactor(server): get metering data of billing from prometheus

* refactor(server): change cpu/mem monitor metrics
  • Loading branch information
0fatal authored Nov 7, 2023
1 parent 44c29bd commit 1ffa9ba
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 25 deletions.
33 changes: 33 additions & 0 deletions server/package-lock.json

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

1 change: 1 addition & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"nodemailer": "^6.9.4",
"npm-package-arg": "^10.1.0",
"passport-jwt": "^4.0.0",
"prometheus-query": "^3.3.2",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
Expand Down
24 changes: 4 additions & 20 deletions server/src/billing/billing-creation-task.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,7 @@ export class BillingCreationTaskService {
return
}

// lookup metering data
const meteringData = await MeteringDatabase.db
.collection('metering')
.find({ category: appid, time: nextMeteringTime }, { sort: { time: 1 } })
.toArray()

if (meteringData.length === 0) {
this.logger.warn(`No metering data found for application: ${appid}`)
return
}
const meteringData = await this.billing.getMeteringData(app)

// get application bundle
const bundle = await this.bundleService.findOne(appid)
Expand Down Expand Up @@ -195,21 +186,14 @@ export class BillingCreationTaskService {

private buildCalculatePriceInput(
app: Application,
meteringData: any[],
meteringData: any,
bundle: ApplicationBundle,
) {
const dto = new CalculatePriceDto()
dto.regionId = app.regionId.toString()
dto.cpu = 0
dto.memory = 0
dto.storageCapacity = 0
dto.databaseCapacity = 0

for (const item of meteringData) {
if (item.property === 'cpu') dto.cpu = item.value
if (item.property === 'memory') dto.memory = item.value
}

dto.cpu = meteringData.cpu
dto.memory = meteringData.memory
dto.storageCapacity = bundle.resource.storageCapacity
dto.databaseCapacity = bundle.resource.databaseCapacity

Expand Down
37 changes: 36 additions & 1 deletion server/src/billing/billing.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ import * as assert from 'assert'
import { ApplicationBilling } from './entities/application-billing'
import { CalculatePriceDto } from './dto/calculate-price.dto'
import { BillingQuery } from './interface/billing-query.interface'
import { PrometheusDriver } from 'prometheus-query'
import { Application } from 'src/application/entities/application'
import { RegionService } from 'src/region/region.service'

@Injectable()
export class BillingService {
private readonly db = SystemDatabase.db

constructor(private readonly resource: ResourceService) {}
constructor(
private readonly resource: ResourceService,
private readonly region: RegionService,
) {}

async query(userId: ObjectId, condition?: BillingQuery) {
const query = { createdBy: userId }
Expand Down Expand Up @@ -213,4 +219,33 @@ export class BillingService {
total: totalPrice.toNumber(),
}
}

async getMeteringData(app: Application) {
const region = await this.region.findOne(app.regionId)

const prom = new PrometheusDriver({
endpoint: region.prometheusConf.apiUrl,
})

const cpuTask = prom
.instantQuery(
`sum(max_over_time(laf_runtime_cpu_limit{container!="",appid="${app.appid}"}[1h])) by (appid)`,
)
.then((res) => res.result[0])
.then((res) => Number(res.value.value))

const memoryTask = prom
.instantQuery(
`sum(max_over_time(laf_runtime_memory_limit{container!="",appid="${app.appid}"}[1h])) by (appid)`,
)
.then((res) => res.result[0])
.then((res) => Number(res.value.value))

const [cpu, memory] = await Promise.all([cpuTask, memoryTask])

return {
cpu,
memory,
}
}
}
6 changes: 2 additions & 4 deletions server/src/monitor/monitor.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { HttpService } from '@nestjs/axios'
import { Injectable, Logger } from '@nestjs/common'
import { ApplicationService } from 'src/application/application.service'
import { PrometheusConf } from 'src/region/entities/region'
import { RegionService } from 'src/region/region.service'
import { GetApplicationNamespace } from 'src/utils/getter'
Expand All @@ -18,12 +17,12 @@ export const getQuery =
case MonitorMetric.cpuUsage:
return {
instant: false,
query: `sum(rate(container_cpu_usage_seconds_total{image!="",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}[${rateAccuracy}])) by (${opts.selector})`,
query: `sum(laf_runtime_cpu{container!="",appid="${opts.appid}"}) by (${opts.selector})`,
}
case MonitorMetric.memoryUsage:
return {
instant: false,
query: `sum(container_memory_working_set_bytes{image!="",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}) by (${opts.selector})`,
query: `sum(laf_runtime_memory{container!="",appid="${opts.appid}"}) by (${opts.selector})`,
}
case MonitorMetric.networkReceive:
return {
Expand Down Expand Up @@ -61,7 +60,6 @@ export enum MonitorMetric {
export class MonitorService {
constructor(
private readonly httpService: HttpService,
private readonly applicationService: ApplicationService,
private readonly regionService: RegionService,
) {}
private readonly logger = new Logger(MonitorService.name)
Expand Down

0 comments on commit 1ffa9ba

Please sign in to comment.