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

feat(exporter): add runtime exporter #1619

Merged
merged 23 commits into from
Nov 7, 2023
Merged
2 changes: 1 addition & 1 deletion services/runtime-exporter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"private": true,
"scripts": {
"dev": "NODE_ENV=development node ./dist/index.js",
"build": "tsc -p tsconfig.json",
"build": "tsc -p tsconfig.build.json",
"watch": "tsc -p tsconfig.json -w",
"start": "NODE_ENV=production node ./dist/index.js",
"prettier": "npx prettier --write ./src"
Expand Down
4 changes: 4 additions & 0 deletions services/runtime-exporter/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export default class Config {
return process.env.KUBECONF || ''
}

static get NAMESPACE(): string {
return process.env.NAMESPACE || ''
}

static get API_SECRET(): string {
if (!process.env.API_SECRET) {
throw new Error('API_SECRET is not defined')
Expand Down
50 changes: 37 additions & 13 deletions services/runtime-exporter/src/helper/cluster.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class ClusterService {
* - if kubeconfig is not empty, load from string
*/
static LABEL_KEY_APP_ID = 'laf.dev/appid'
static NAMESPACE = Config.NAMESPACE

static loadKubeConfig() {
const conf = Config.KUBECONF
Expand Down Expand Up @@ -49,14 +50,24 @@ export class ClusterService {

static async getRuntimePodMetricsForAllNamespaces(): Promise<Metric[]> {
const metricsClient = this.getMetricsClient()
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const res = await metricsClient.metricsApiRequest(
'/apis/metrics.k8s.io/v1beta1/pods?labelSelector=laf.dev/appid',
)
let res: any
if (ClusterService.NAMESPACE) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
res = await metricsClient.metricsApiRequest(
`/apis/metrics.k8s.io/v1beta1/namespace/${ClusterService.NAMESPACE}/pods?labelSelector=laf.dev/appid`,
)
} else {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
res = await metricsClient.metricsApiRequest(
'/apis/metrics.k8s.io/v1beta1/pods?labelSelector=laf.dev/appid',
)
}

const metricsList: Metric[] = []
for (const item of res.items) {
const appid = item.metadata.labels[this.LABEL_KEY_APP_ID]
const appid = item.metadata.labels[ClusterService.LABEL_KEY_APP_ID]
const podName = item.metadata.name
for (const container of item.containers) {
const containerName = container.name
Expand All @@ -79,16 +90,29 @@ export class ClusterService {

static async getRuntimePodsLimitForAllNamespaces(): Promise<Metric[]> {
const coreV1Api = this.makeCoreV1Api()
const res = await coreV1Api.listPodForAllNamespaces(
undefined,
undefined,
undefined,
this.LABEL_KEY_APP_ID,
)
let res: any
if (ClusterService.NAMESPACE) {
res = await coreV1Api.listNamespacedPod(
ClusterService.NAMESPACE,
undefined,
undefined,
undefined,
undefined,
this.LABEL_KEY_APP_ID,
)
} else {
res = await coreV1Api.listPodForAllNamespaces(
undefined,
undefined,
undefined,
ClusterService.LABEL_KEY_APP_ID,
)
}

const metricsList: Metric[] = []

for (const item of res.body.items) {
const appid = item.metadata.labels[this.LABEL_KEY_APP_ID]
const appid = item.metadata.labels[ClusterService.LABEL_KEY_APP_ID]
const podName = item.metadata.name

for (const container of item.spec.containers) {
Expand Down
4 changes: 2 additions & 2 deletions services/runtime-exporter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const server = app.listen(Config.PORT, () =>
logger.info(`server ${process.pid} listened on ${Config.PORT}`),
)

process.on('SIGTERM', gracefullyExit)
process.on('SIGINT', gracefullyExit)
// process.on('SIGTERM', gracefullyExit)
0fatal marked this conversation as resolved.
Show resolved Hide resolved
// process.on('SIGINT', gracefullyExit)

async function gracefullyExit() {
server.close(async () => {
Expand Down