Skip to content

Commit

Permalink
Split code to multiple files, added more metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
Vincent-Br committed Nov 13, 2024
1 parent 594e335 commit 0845a42
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 135 deletions.
18 changes: 18 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 @@ -10,6 +10,7 @@
"author": "Vincent Brokx <vincent@vincentbrokx.nl> (https://vincentbrokx.nl)",
"license": "GPL-3.0-or-later",
"dependencies": {
"dotenv": "^16.4.5",
"express": "^4.21.0",
"node-openttd-admin": "^0.2.4",
"prom-client": "^15.1.3"
Expand Down
57 changes: 57 additions & 0 deletions src/connection.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const ottd = require("node-openttd-admin");

const ottdConnection = new ottd.connection();
ottdConnection.connect(process.env.OTTD_IP, process.env.OTTD_PORT);

ottdConnection.on("connect", () =>
ottdConnection.authenticate(
process.env.OTTD_USERNAME,
process.env.OTTD_PASSWORD
)
);
ottdConnection.on("error", (data) => console.log(data));

ottdConnection.on("welcome", (data) => {
sendChatMessage("+++-----------------------------------------------+++");
sendChatMessage("OpenTTD-exporter has been started! Game data is being logged!");
sendChatMessage("+++-----------------------------------------------+++");
requestUpdateFrequency();
});

function sendChatMessage(message) {
ottdConnection.send_chat(
ottd.enums.Actions.SERVER_MESSAGE,
ottd.enums.DestTypes.BROADCAST,
"",
message
);
}

function requestUpdateFrequency() {
ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.DATE,
ottd.enums.UpdateFrequencies.WEEKLY
);

ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.COMPANY_INFO,
ottd.enums.UpdateFrequencies.AUTOMATIC
);

ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.COMPANY_ECONOMY,
ottd.enums.UpdateFrequencies.WEEKLY
);

ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.COMPANY_STATS,
ottd.enums.UpdateFrequencies.WEEKLY
);

ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.CLIENT_INFO,
ottd.enums.UpdateFrequencies.AUTOMATIC
);
}

module.exports = { ottdConnection };
152 changes: 17 additions & 135 deletions src/index.cjs
Original file line number Diff line number Diff line change
@@ -1,147 +1,29 @@
const dotenv = require("dotenv").config();
const express = require("express");
const prom = require("prom-client");
const ottd = require("node-openttd-admin");

const server = express();
const register = prom.register;
const Gauge = prom.Gauge;
const ottdConnection = new ottd.connection();

var ottdData = {
game: {},
players: [],
companies: [],
};

// var ottdMetrics = {};
const metrics = require("./metrics.cjs");
const { registerEventHandlers } = require("./update.cjs");

prom.collectDefaultMetrics({ gcDurationBuckets: [0.001, 0.01, 0.1, 1, 2, 5] }); // Collect default metrics

ottdConnection.connect("localhost", 3977); // Connect to OTTD Server

ottdConnection.on("connect", () =>
ottdConnection.authenticate("OpenTTD-Exporter", "adminPWD")
);
ottdConnection.on("error", (data) => console.log(data));

const companyMoney = new Gauge({
name: "company_money",
help: "The amount of money a company has",
labelNames: ["company"],
});
const companyLoan = new Gauge({
name: "company_loan",
help: "The amount of loan a company has",
labelNames: ["company"],
});

// setInterval(() => {
// requests.set({ method: "get", code: 200 }, Math.random());
// requests.set(Math.random());
// requests.labels("post", "300").inc();
// }, 100);

ottdConnection.on("welcome", (data) => {
ottdData.game = data;

ottdConnection.send_chat(
ottd.enums.Actions.SERVER_MESSAGE,
ottd.enums.DestTypes.BROADCAST,
"",
"OpenTTD-exporter started!"
);

ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.DATE,
ottd.enums.UpdateFrequencies.WEEKLY
);

ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.COMPANY_INFO,
ottd.enums.UpdateFrequencies.AUTOMATIC
);

ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.COMPANY_ECONOMY,
ottd.enums.UpdateFrequencies.WEEKLY
);

ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.COMPANY_STATS,
ottd.enums.UpdateFrequencies.WEEKLY
);

ottdConnection.send_update_frequency(
ottd.enums.UpdateTypes.CLIENT_INFO,
ottd.enums.UpdateFrequencies.AUTOMATIC
);
});

ottdConnection.on("companyinfo", (data) => updateCompany(data));
ottdConnection.on("companyupdate", (data) => updateCompany(data));
ottdConnection.on("companyeconomy", (data) => {
updateCompany(data);
companyMoney.set({ company: data.id }, data.money);
companyLoan.set({ company: data.id }, data.loan);
});
ottdConnection.on("companystats", (data) => updateCompany(data));
ottdConnection.on("date", (data) => {
// ottdData.companies.forEach((company) => {
// if (company.money) companyMoney.set({ company: company.id }, company.money);
// if (company.loan) companyLoan.set({ company: company.id }, company.loan);
// });
});

ottdConnection.on("clientinfo", (data) => {
let dataIndex = ottdData.players.findIndex((e) => e.id == data.id);

if (dataIndex < 0) {
ottdData.players.push(data);
return;
}

ottdData.players[dataIndex] = { ...ottdData.players[dataIndex], ...data };
});

function updateCompany(data) {
let dataIndex = ottdData.companies.findIndex((e) => e.id == data.id);

if (dataIndex < 0) {
ottdData.companies.push(data);
return;
}

ottdData.companies[dataIndex] = { ...ottdData.companies[dataIndex], ...data };
}

let i = 0;

function interval() {
//TODO: Reliably update company info
// if (i > 0) {
// var bufs = Buffers();
// bufs.push(
// put().word8("ADMIN_UPDATE_DATE").buffer()
// );

// ottdConnection.sendpacket(ottd.enums.AdminPackets.ADMIN_POLL, bufs);
// i += 1;
// }

console.log(ottdData);
setTimeout(interval, 10000);
}
interval();

server.get("/metrics", async (req, res) => {
try {
res.set("Content-Type", register.contentType);
res.end(await register.metrics());
} catch (ex) {
res.status(500).end(ex);
}
try {
res.set("Content-Type", register.contentType);
res.end(await register.metrics());
} catch (ex) {
res.status(500).end(ex);
}
});

server.listen(process.env.PORT || 3990, () => {
console.log(`Server listening to 3990, metrics exposed on /metrics endpoint`);
server.listen(process.env.EXPORTER_PORT || 3990, () => {
console.log(
`Server listening on port ${process.env.EXPORTER_PORT}, metrics exposed on /metrics endpoint`
);
});

module.exports = {
metrics,
};
51 changes: 51 additions & 0 deletions src/metrics.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const Gauge = require("prom-client").Gauge;

module.exports.gameDays = new Gauge({
name: "ottd_game_days",
help: "Current date in days since 0 AD",
});
module.exports.companyName = new Gauge({
name: "ottd_company_name",
help: "Name of the company by id",
labelNames: ["company_id", "name"],
});
module.exports.companyMoney = new Gauge({
name: "ottd_company_total_money",
help: "Amount of money a company currently has",
labelNames: ["company_id"],
});
module.exports.companyLoan = new Gauge({
name: "ottd_company_loan_money",
help: "Amount of money a company is in debt",
labelNames: ["company_id"],
});
module.exports.companyIncome = new Gauge({
name: "ottd_company_income_money",
help: "Income of a company, value currently unknown",
labelNames: ["company_id"],
});
module.exports.companyCargo = new Gauge({
name: "ottd_company_quarter_cargo",
help: "Amount of cargo a company has delivered since beginning of the quarter",
labelNames: ["company_id"],
});
module.exports.companyVehicles = new Gauge({
name: "ottd_company_total_vehicles",
help: "Number of vehicles by type a company currently owns",
labelNames: ["company_id", "type"],
});
module.exports.companyStations = new Gauge({
name: "ottd_company_total_stations",
help: "Number of stations by type a company currently owns",
labelNames: ["company_id", "type"],
});
module.exports.userName = new Gauge({
name: "ottd_user_name",
help: "The name of the user by id",
labelNames: ["user_id", "name"],
});
module.exports.userCompany = new Gauge({
name: "ottd_user_company_id",
help: "The id of the company where the user is currently apart of",
labelNames: ["user_id"],
});
59 changes: 59 additions & 0 deletions src/update.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const metrics = require("./metrics.cjs");
const { ottdConnection } = require("./connection.cjs");

ottdConnection.on("companyupdate", (data) =>
metrics.companyName.set({ company_id: data.id, name: data.name }, 1)
);
ottdConnection.on("companyeconomy", (data) => {
metrics.companyMoney.set({ company_id: data.id }, data.money);
metrics.companyLoan.set({ company_id: data.id }, data.loan);
metrics.companyIncome.set({ company_id: data.id }, data.income);
metrics.companyCargo.set({ company_id: data.id }, data.cargo);
});
ottdConnection.on("companystats", (data) => {
metrics.companyVehicles.set(
{ company_id: data.id, type: "trains" },
data.vehicles.trains
);
metrics.companyVehicles.set(
{ company_id: data.id, type: "lorries" },
data.vehicles.lorries
);
metrics.companyVehicles.set(
{ company_id: data.id, type: "busses" },
data.vehicles.busses
);
metrics.companyVehicles.set(
{ company_id: data.id, type: "planes" },
data.vehicles.planes
);
metrics.companyVehicles.set(
{ company_id: data.id, type: "ships" },
data.vehicles.ships
);
metrics.companyStations.set(
{ company_id: data.id, type: "trains" },
data.stations.trains
);
metrics.companyStations.set(
{ company_id: data.id, type: "lorries" },
data.stations.lorries
);
metrics.companyStations.set(
{ company_id: data.id, type: "busses" },
data.stations.busses
);
metrics.companyStations.set(
{ company_id: data.id, type: "planes" },
data.stations.planes
);
metrics.companyStations.set(
{ company_id: data.id, type: "ships" },
data.stations.ships
);
});
ottdConnection.on("clientupdate", (data) => {
metrics.userName.set({ user_id: data.id, name: data.name }, 1);
metrics.userCompany.set({ user_id: data.id }, data.company);
});
ottdConnection.on("date", (data) => metrics.gameDays.set({}, data));

0 comments on commit 0845a42

Please sign in to comment.