-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
24f14fb
commit 5f52434
Showing
8 changed files
with
128 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
{ | ||
"arrowParens": "always", | ||
"bracketSpacing": true, | ||
"endOfLine": "lf", | ||
"printWidth": 120, | ||
"singleQuote": true | ||
} | ||
"arrowParens": "always", | ||
"bracketSpacing": true, | ||
"endOfLine": "lf", | ||
"printWidth": 120 | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,80 +1,50 @@ | ||
import log from 'loglevel'; | ||
import {Gauge, Registry} from "prom-client"; | ||
import {Account, Category} from "ynab"; | ||
import * as metrics from './metrics'; | ||
|
||
export class YNABCollector { | ||
accountBalances: Account[] = []; | ||
categoryBalance: Category[] = []; | ||
|
||
|
||
public async collectAccountBalanceMetrics(register: Registry) { | ||
log.debug('Collecting account balance metrics..'); | ||
|
||
const accountLabels = ['account_name', 'type', 'closed']; | ||
const accountClearedBalanceGauge = new Gauge({ | ||
name: "ynab_cleared_account_balance", | ||
registers: [register], | ||
help: "Account Cleared Balance amounts", | ||
labelNames: accountLabels, | ||
collect: async () => { | ||
log.debug(`Collecting Cleared Balance for ${this.accountBalances.length} accounts`); | ||
this.accountBalances.forEach(a => { | ||
accountClearedBalanceGauge.labels({account_name: a.name, type: a.type, closed: String(a.closed)}).set(a.cleared_balance / 1000); | ||
}); | ||
} | ||
|
||
}); | ||
const accountUnClearedBalanceGauge = new Gauge({ | ||
name: "ynab_uncleared_account_balance", | ||
help: "Account Uncleared Balance amounts", | ||
registers: [register], | ||
labelNames: accountLabels, | ||
collect: async () => { | ||
log.debug(`Collecting Uncleared Balance for ${this.accountBalances.length} accounts`); | ||
this.accountBalances.forEach(a => { | ||
accountUnClearedBalanceGauge.labels({account_name: a.name, type: a.type, closed: String(a.closed)}).set(a.uncleared_balance / 1000); | ||
}); | ||
} | ||
}); | ||
} | ||
|
||
public convertMilliUnitsToUnits(amount: number): number { | ||
return (amount / 1000); | ||
} | ||
|
||
public async collectCategoryBalanceMetrics(register: Registry) { | ||
log.debug('Collecting category balance metrics..'); | ||
const self = this; // Store a reference to 'this', else typescript thinks this refers to the Gauge class, not the Collector class | ||
|
||
const catLabels = ['name', 'category_group_name', 'budgeted_amount', 'activity_amount', 'balance_amount', 'hidden', 'deleted']; | ||
|
||
// Define properties that differ between gauges | ||
const gaugeProperties = [ | ||
{name: 'budgeted', help: 'Category Budgeted amount', suffix: 'budgeted_amount'}, | ||
{name: 'activity', help: 'Category Activity amount', suffix: 'activity_amount'}, | ||
{name: 'balance', help: 'Category Balance amount', suffix: 'balance_amount'}, | ||
{name: 'hidden', help: 'Category Balance amount', suffix: 'hidden'}, | ||
{name: 'deleted', help: 'Category Balance amount', suffix: 'deleted'}, | ||
]; | ||
|
||
for (const prop of gaugeProperties) { | ||
new Gauge({ | ||
name: `ynab_category_${prop.suffix}`, | ||
registers: [register], | ||
help: prop.help, | ||
labelNames: catLabels, | ||
async collect() { | ||
for (const cat of self.categoryBalance) { | ||
this.labels({ | ||
name: cat.name, | ||
category_group_name: cat.category_group_name, | ||
hidden: String(cat.hidden), | ||
deleted: String(cat.deleted) | ||
}).set(self.convertMilliUnitsToUnits(Number(cat[prop.name as keyof Category]) || 0)); | ||
|
||
} | ||
} | ||
}); | ||
} | ||
categoryBalance: Category[] = []; | ||
|
||
public collectAccountBalanceMetrics(budgetName: string, accountBalances: Account[]) { | ||
accountBalances.forEach(a => { | ||
metrics.ynab_cleared_account_balance.labels({account_name: a.name, budget_name: budgetName, type: a.type, closed: String(a.closed)}).set(a.cleared_balance / 1000); | ||
metrics.ynab_uncleared_account_balance.labels({account_name: a.name, budget_name: budgetName, type: a.type, closed: String(a.closed)}).set(a.uncleared_balance / 1000); | ||
}); | ||
} | ||
|
||
public convertMilliUnitsToUnits(amount: number): number { | ||
return (amount / 1000); | ||
} | ||
|
||
public async collectCategoryBalanceMetrics(budgetName: string, categoryBalance: Category[]) { | ||
for (const cat of categoryBalance) { | ||
metrics.ynab_category_balance_amount.labels({ | ||
name: cat.name, | ||
category_group_name: cat.category_group_name, | ||
hidden: String(cat.hidden), | ||
deleted: String(cat.deleted), | ||
budget_name: budgetName, | ||
}).set( | ||
this.convertMilliUnitsToUnits(cat.balance) | ||
); | ||
metrics.ynab_category_budgeted_amount.labels({ | ||
name: cat.name, | ||
category_group_name: cat.category_group_name, | ||
hidden: String(cat.hidden), | ||
deleted: String(cat.deleted), | ||
budget_name: budgetName, | ||
}).set( | ||
this.convertMilliUnitsToUnits(cat.budgeted) | ||
); | ||
metrics.ynab_category_activity_amount.labels({ | ||
name: cat.name, | ||
category_group_name: cat.category_group_name, | ||
hidden: String(cat.hidden), | ||
deleted: String(cat.deleted), | ||
budget_name: budgetName, | ||
}).set( | ||
this.convertMilliUnitsToUnits(cat.activity) | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,10 @@ | ||
import {AccountsResponseData, Category} from "ynab"; | ||
import {AccountsResponse, Category} from "ynab"; | ||
import {YnabAPI} from "../api"; | ||
import log from 'loglevel'; | ||
|
||
export async function scheduledAccountBalanceUpdate(ynab: YnabAPI): Promise<AccountsResponseData> { | ||
log.info(`Starting scheduled account balance update at ${new Date().toLocaleString()} ...`); | ||
const accounts = await ynab.client.accounts.getAccounts(ynab.budgetId); | ||
log.info(`Fetched balances for ${accounts.data.accounts.length} accounts.`); | ||
return accounts.data; | ||
} | ||
export async function scheduledAccountBalanceUpdate(ynab: YnabAPI): Promise<AccountsResponse> { | ||
return ynab.client.accounts.getAccounts(ynab.budgetId); | ||
|
||
} | ||
export async function scheduledCategoryBalanceUpdate(ynab: YnabAPI): Promise<Category[]> { | ||
log.info(`Starting scheduled category balance update at ${new Date().toLocaleString()} ...`); | ||
const categories = await ynab.getCategoryBudgets(); | ||
return categories; | ||
return ynab.getCategoryBudgets(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import {Gauge, Registry, collectDefaultMetrics} from "prom-client"; | ||
|
||
const catLabels = ['name', 'category_group_name', 'budgeted_amount', 'activity_amount', 'balance_amount', 'hidden', 'deleted', 'budget_name']; | ||
const accountLabels = ['budget_name', 'account_name', 'type', 'closed']; | ||
export const registry = new Registry(); | ||
|
||
export const ynab_category_balance_amount = new Gauge({ | ||
name: 'ynab_category_balance_amount', | ||
help: 'Category Balance amount', | ||
registers: [registry], | ||
labelNames: catLabels, | ||
}); | ||
|
||
export const ynab_category_activity_amount = new Gauge({ | ||
name: 'ynab_category_activity_amount', | ||
help: 'Category Activity amount', | ||
registers: [registry], | ||
labelNames: catLabels, | ||
}); | ||
|
||
export const ynab_category_budgeted_amount = new Gauge({ | ||
name: 'ynab_category_budgeted_amount', | ||
help: 'Category Budgeted amount', | ||
registers: [registry], | ||
labelNames: catLabels, | ||
}); | ||
|
||
export const ynab_cleared_account_balance = new Gauge({ | ||
name: 'ynab_cleared_account_balance', | ||
help: 'Account Cleared Balance amounts', | ||
registers: [registry], | ||
labelNames: accountLabels, | ||
}); | ||
|
||
export const ynab_uncleared_account_balance = new Gauge({ | ||
name: 'ynab_uncleared_account_balance', | ||
help: 'Account Uncleared Balance amounts', | ||
registers: [registry], | ||
labelNames: accountLabels | ||
}); |