Skip to content

Commit

Permalink
clean up, move to classes
Browse files Browse the repository at this point in the history
  • Loading branch information
SathyaBhat committed Sep 6, 2023
1 parent b9ec3ad commit 4bd3434
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 32 deletions.
24 changes: 24 additions & 0 deletions 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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"cron": "^2.4.3",
"express": "^4.18.2",
"prom-client": "^14.2.0",
"source-map-support": "^0.5.21",
"ynab": "^1.32.0"
},
"devDependencies": {
Expand Down
17 changes: 13 additions & 4 deletions src/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import {API} from "ynab";

export async function ynabClient(): Promise<API> {
const accessToken = process.env.YNAB_TOKEN!;
return new API(accessToken);
}
export class YnabAPI {
private accessToken = process.env.YNAB_TOKEN!;
public client: API;
public budgetId: string = process.env.BUDGET_ID!;

constructor() {
this.client = new API(this.accessToken);
}

public async getAccountName(): Promise<string> {
return (await this.client.budgets.getBudgetById(this.budgetId)).data.budget.name;
}
}
10 changes: 4 additions & 6 deletions src/collectors.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import {Gauge, Registry} from "prom-client";
import {Account} from "ynab";


export class YNABMetrics {
export class YNABCollector {
accountBalances: Account[] = [];


public async collectAccountBalanceMetrics(register: Registry) {
console.log('Collecting account balance metrics..');

const accountLabels = ['account_name', 'type'];
const accountLabels = ['account_name', 'type', 'closed'];
const accountClearedBalanceGauge = new Gauge({
name: "ynab_cleared_account_balance",
registers: [register],
Expand All @@ -18,7 +16,7 @@ export class YNABMetrics {
collect: async () => {
console.log(`Collecting Cleared Balance for ${this.accountBalances.length} accounts`);
this.accountBalances.forEach(a => {
accountClearedBalanceGauge.labels({account_name: a.name, type: a.type}).set(a.cleared_balance / 1000);
accountClearedBalanceGauge.labels({account_name: a.name, type: a.type, closed: String(a.closed)}).set(a.cleared_balance / 1000);
});
}

Expand All @@ -31,7 +29,7 @@ export class YNABMetrics {
collect: async () => {
console.log(`Collecting Uncleared Balance for ${this.accountBalances.length} accounts`);
this.accountBalances.forEach(a => {
accountUnClearedBalanceGauge.labels({account_name: a.name, type: a.type}).set(a.uncleared_balance / 1000);
accountUnClearedBalanceGauge.labels({account_name: a.name, type: a.type, closed: String(a.closed)}).set(a.uncleared_balance / 1000);
});
}

Expand Down
36 changes: 18 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@



import {Registry, Gauge, collectDefaultMetrics} from "prom-client";
import express, {Express, Request, Response} from 'express';
import {YNABMetrics} from "./collectors";
import {scheduledAccountBalanceUpdate} from "./jobs/accounts";

import {CronJob} from 'cron';
import {Account} from "ynab";
import {ynabClient} from "./api";

import express, {Express, Request, Response} from 'express';
import {Registry} from "prom-client";
import 'source-map-support/register';
import {YnabAPI} from "./api";
import {YNABCollector} from "./collectors";
import {scheduledAccountBalanceUpdate} from "./jobs/accounts";;


async function main() {
const ynab = await ynabClient();
const ynab = new YnabAPI();
const register = new Registry();
const port = process.env.PORT;

const port = process.env.PORT || 9100;
const app: Express = express();
const ynabMetrics = new YNABMetrics();
const ynabCollector = new YNABCollector();

new CronJob({
cronTime: "0 * * * * ",
onTick: async () => {
ynabMetrics.accountBalances = (await scheduledAccountBalanceUpdate(ynab)).accounts;
console.log(`${ynabMetrics.accountBalances.length} accounts refreshed`);
ynabCollector.accountBalances = (await scheduledAccountBalanceUpdate(ynab)).accounts;
console.log(`${ynabCollector.accountBalances.length} accounts refreshed`);
},
start: true,
runOnInit: true
});


ynabMetrics.collectAccountBalanceMetrics(register);

register.setDefaultLabels({
budget_name: await ynab.getAccountName()
});
ynabCollector.collectAccountBalanceMetrics(register);

app.get('/metrics', async (req: Request, res: Response) => {
res.setHeader('Content-Type', register.contentType);
Expand All @@ -40,8 +40,8 @@ async function main() {
res.send(results);
});

app.listen(port || 9100, () => {
console.log('⚡ Hello');
app.listen(port, () => {
console.log(`🔊 Publishing metrics on port ${port}`);
});
}

Expand Down
8 changes: 4 additions & 4 deletions src/jobs/accounts.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {API, AccountsResponseData, TransactionsResponse} from "ynab";
import {AccountsResponseData, TransactionsResponse} from "ynab";
import {YnabAPI} from "../api";

export type ynabTransactionResponse = (TransactionsResponse & {rateLimit: string | null;}) | undefined;
export const ynabBudgetId = process.env.BUDGET_ID!;

export async function scheduledAccountBalanceUpdate(ynab: API): Promise<AccountsResponseData> {
export async function scheduledAccountBalanceUpdate(ynab: YnabAPI): Promise<AccountsResponseData> {
console.log(`Starting scheduled account balance update at ${new Date().toLocaleString()} ...`);
const accounts = await ynab.accounts.getAccounts(ynabBudgetId);
const accounts = await ynab.client.accounts.getAccounts(ynab.budgetId);
console.log(`Fetched balances for ${accounts.data.accounts.length} accounts.`);
console.log(`Rate limit: ${accounts.rateLimit}`);
return accounts.data;
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"target": "es2016",
"moduleResolution": "node",
"sourceMap": true,
"inlineSources": true,
"outDir": "dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
Expand Down

0 comments on commit 4bd3434

Please sign in to comment.