actual logging if you will

This commit is contained in:
Elijah R 2024-08-14 01:05:59 -04:00
parent 6297d365e6
commit 2b83db8d58
5 changed files with 65 additions and 17 deletions

View file

@ -22,6 +22,7 @@
"html-entities": "^2.5.2", "html-entities": "^2.5.2",
"ip-address": "^9.0.5", "ip-address": "^9.0.5",
"mysql2": "^3.10.2", "mysql2": "^3.10.2",
"pino": "^9.3.2",
"sharp": "^0.33.4", "sharp": "^0.33.4",
"toml": "^3.0.0", "toml": "^3.0.0",
"ws": "^8.17.1" "ws": "^8.17.1"

View file

@ -1,4 +1,4 @@
import Fastify from 'fastify'; import Fastify, { FastifyInstance } from 'fastify';
import FastifyWS from '@fastify/websocket'; import FastifyWS from '@fastify/websocket';
import FastifyStatic from '@fastify/static'; import FastifyStatic from '@fastify/static';
import FastifyCors from '@fastify/cors'; import FastifyCors from '@fastify/cors';
@ -14,6 +14,11 @@ import { Database } from './database.js';
import { MSAgentErrorMessage, MSAgentProtocolMessageType } from '@msagent-chat/protocol'; import { MSAgentErrorMessage, MSAgentProtocolMessageType } from '@msagent-chat/protocol';
import { DiscordLogger } from './discord.js'; import { DiscordLogger } from './discord.js';
import { ImageUploader } from './imageuploader.js'; import { ImageUploader } from './imageuploader.js';
import pino from 'pino';
let rootLogger = pino({
name: 'MSAgentChat'
});
let config: IConfig; let config: IConfig;
let configPath: string; let configPath: string;
@ -21,7 +26,7 @@ if (process.argv.length < 3) configPath = './config.toml';
else configPath = process.argv[2]; else configPath = process.argv[2];
if (!fs.existsSync(configPath)) { if (!fs.existsSync(configPath)) {
console.error(`${configPath} not found. Please copy config.example.toml and fill out fields.`); rootLogger.error(`${configPath} not found. Please copy config.example.toml and fill out fields.`);
process.exit(1); process.exit(1);
} }
@ -29,7 +34,7 @@ try {
let configRaw = fs.readFileSync(configPath, 'utf-8'); let configRaw = fs.readFileSync(configPath, 'utf-8');
config = toml.parse(configRaw); config = toml.parse(configRaw);
} catch (e) { } catch (e) {
console.error(`Failed to read or parse ${configPath}: ${(e as Error).message}`); rootLogger.error(`Failed to read or parse ${configPath}: ${(e as Error).message}`);
process.exit(1); process.exit(1);
} }
@ -37,9 +42,9 @@ let db = new Database(config.mysql);
await db.init(); await db.init();
const app = Fastify({ const app = Fastify({
logger: true, logger: rootLogger.child({ module: 'HTTP' }),
bodyLimit: 20971520 bodyLimit: 20971520,
}); }) as unknown as FastifyInstance; // fastify please fix your shit
app.register(FastifyCors, { app.register(FastifyCors, {
origin: config.http.origins, origin: config.http.origins,
@ -51,7 +56,7 @@ app.register(FastifyWS);
let tts = null; let tts = null;
if (config.tts.enabled) { if (config.tts.enabled) {
tts = new TTSClient(config.tts); tts = new TTSClient(config.tts, rootLogger.child({module: "TTS"}));
app.register(FastifyStatic, { app.register(FastifyStatic, {
root: config.tts.tempDir, root: config.tts.tempDir,
prefix: '/api/tts/', prefix: '/api/tts/',
@ -61,13 +66,13 @@ if (config.tts.enabled) {
if (!config.chat.agentsDir.endsWith('/')) config.chat.agentsDir += '/'; if (!config.chat.agentsDir.endsWith('/')) config.chat.agentsDir += '/';
if (!fs.existsSync(config.chat.agentsDir)) { if (!fs.existsSync(config.chat.agentsDir)) {
console.error(`Directory ${config.chat.agentsDir} does not exist.`); rootLogger.error(`Directory ${config.chat.agentsDir} does not exist.`);
process.exit(1); process.exit(1);
} }
for (let agent of config.agents) { for (let agent of config.agents) {
if (!fs.existsSync(path.join(config.chat.agentsDir, agent.filename))) { if (!fs.existsSync(path.join(config.chat.agentsDir, agent.filename))) {
console.error(`${agent.filename} does not exist.`); rootLogger.error(`${agent.filename} does not exist.`);
process.exit(1); process.exit(1);
} }
} }
@ -103,7 +108,7 @@ if (config.discord.enabled) {
// Image upload // Image upload
let img = new ImageUploader(app, config.images); let img = new ImageUploader(app, config.images);
let room = new MSAgentChatRoom(config.chat, config.agents, db, img, tts, discord); let room = new MSAgentChatRoom(config.chat, rootLogger.child({module: "Room#Default"}), config.agents, db, img, tts, discord);
app.register(async (app) => { app.register(async (app) => {
app.get('/api/socket', { websocket: true }, async (socket, req) => { app.get('/api/socket', { websocket: true }, async (socket, req) => {
@ -111,7 +116,7 @@ app.register(async (app) => {
let ip: string; let ip: string;
if (config.http.proxied) { if (config.http.proxied) {
if (req.headers['x-forwarded-for'] === undefined) { if (req.headers['x-forwarded-for'] === undefined) {
console.error(`Warning: X-Forwarded-For not set! This is likely a misconfiguration of your reverse proxy.`); rootLogger.child({module: "HTTP"}).error(`Warning: X-Forwarded-For not set! This is likely a misconfiguration of your reverse proxy.`);
socket.close(); socket.close();
return; return;
} }
@ -119,7 +124,7 @@ app.register(async (app) => {
if (xff instanceof Array) ip = xff[0]; if (xff instanceof Array) ip = xff[0];
else ip = xff; else ip = xff;
if (!isIP(ip)) { if (!isIP(ip)) {
console.error(`Warning: X-Forwarded-For malformed! This is likely a misconfiguration of your reverse proxy.`); rootLogger.child({module: "HTTP"}).error(`Warning: X-Forwarded-For malformed! This is likely a misconfiguration of your reverse proxy.`);
socket.close(); socket.close();
return; return;
} }

View file

@ -15,6 +15,7 @@ import * as htmlentities from 'html-entities';
import { Database } from './database.js'; import { Database } from './database.js';
import { DiscordLogger } from './discord.js'; import { DiscordLogger } from './discord.js';
import { ImageUploader } from './imageuploader.js'; import { ImageUploader } from './imageuploader.js';
import { Logger } from 'pino';
export class MSAgentChatRoom { export class MSAgentChatRoom {
agents: AgentConfig[]; agents: AgentConfig[];
@ -25,8 +26,9 @@ export class MSAgentChatRoom {
db: Database; db: Database;
img: ImageUploader; img: ImageUploader;
discord: DiscordLogger | null; discord: DiscordLogger | null;
private logger: Logger;
constructor(config: ChatConfig, agents: AgentConfig[], db: Database, img: ImageUploader, tts: TTSClient | null, discord: DiscordLogger | null) { constructor(config: ChatConfig, logger: Logger, agents: AgentConfig[], db: Database, img: ImageUploader, tts: TTSClient | null, discord: DiscordLogger | null) {
this.agents = agents; this.agents = agents;
this.clients = []; this.clients = [];
this.config = config; this.config = config;
@ -34,11 +36,18 @@ export class MSAgentChatRoom {
this.db = db; this.db = db;
this.img = img; this.img = img;
this.discord = discord; this.discord = discord;
this.logger = logger;
} }
addClient(client: Client) { addClient(client: Client) {
this.clients.push(client); this.clients.push(client);
this.logger.info(`New connection from ${client.ip}`);
client.on('close', () => { client.on('close', () => {
if (client.username === null) {
this.logger.info(`${client.ip} disconnected`);
} else {
this.logger.info(`${client.ip} disconnected (${client.username})`);
}
this.clients.splice(this.clients.indexOf(client), 1); this.clients.splice(this.clients.indexOf(client), 1);
if (client.username === null) return; if (client.username === null) return;
let msg: MSAgentRemoveUserMessage = { let msg: MSAgentRemoveUserMessage = {
@ -52,6 +61,7 @@ export class MSAgentChatRoom {
} }
}); });
client.on('join', () => { client.on('join', () => {
this.logger.info(`${client.ip} joined as ${client.username}`);
let agent = this.agents.find((a) => a.filename === client.agent)!; let agent = this.agents.find((a) => a.filename === client.agent)!;
let initmsg: MSAgentInitMessage = { let initmsg: MSAgentInitMessage = {
op: MSAgentProtocolMessageType.Init, op: MSAgentProtocolMessageType.Init,
@ -99,7 +109,7 @@ export class MSAgentChatRoom {
let filename = await this.tts.synthesizeToFile(message, (++this.msgId).toString(10)); let filename = await this.tts.synthesizeToFile(message, (++this.msgId).toString(10));
msg.data.audio = '/api/tts/' + filename; msg.data.audio = '/api/tts/' + filename;
} catch (e) { } catch (e) {
console.error(`Error synthesizing TTS: ${(e as Error).message}`); this.logger.error(`Error synthesizing TTS: ${(e as Error).message}`);
} }
} }
for (const _client of this.getActiveClients()) { for (const _client of this.getActiveClients()) {

View file

@ -5,15 +5,18 @@ import { Readable } from 'node:stream';
import { ReadableStream } from 'node:stream/web'; import { ReadableStream } from 'node:stream/web';
import { finished } from 'node:stream/promises'; import { finished } from 'node:stream/promises';
import ffmpeg from 'fluent-ffmpeg'; import ffmpeg from 'fluent-ffmpeg';
import { Logger } from 'pino';
export class TTSClient { export class TTSClient {
private config: TTSConfig; private config: TTSConfig;
private deleteOps: Map<string, NodeJS.Timeout>; private deleteOps: Map<string, NodeJS.Timeout>;
private logger: Logger;
constructor(config: TTSConfig) { constructor(config: TTSConfig, logger: Logger) {
this.config = config; this.config = config;
if (!this.config.tempDir.endsWith('/')) this.config.tempDir += '/'; if (!this.config.tempDir.endsWith('/')) this.config.tempDir += '/';
this.deleteOps = new Map(); this.deleteOps = new Map();
this.logger = logger;
} }
async ensureDirectoryExists() { async ensureDirectoryExists() {
@ -24,7 +27,7 @@ export class TTSClient {
let error = e as NodeJS.ErrnoException; let error = e as NodeJS.ErrnoException;
switch (error.code) { switch (error.code) {
case 'ENOTDIR': { case 'ENOTDIR': {
console.warn('File exists at TTS temp directory path. Unlinking...'); this.logger.warn('File exists at TTS temp directory path. Unlinking...');
await fs.unlink(this.config.tempDir.substring(0, this.config.tempDir.length - 1)); await fs.unlink(this.config.tempDir.substring(0, this.config.tempDir.length - 1));
// intentional fall-through // intentional fall-through
} }
@ -33,7 +36,7 @@ export class TTSClient {
break; break;
} }
default: { default: {
console.error(`Cannot access TTS Temp dir: ${error.message}`); this.logger.error(`Cannot access TTS Temp dir: ${error.message}`);
process.exit(1); process.exit(1);
break; break;
} }

View file

@ -513,6 +513,7 @@ __metadata:
html-entities: "npm:^2.5.2" html-entities: "npm:^2.5.2"
ip-address: "npm:^9.0.5" ip-address: "npm:^9.0.5"
mysql2: "npm:^3.10.2" mysql2: "npm:^3.10.2"
pino: "npm:^9.3.2"
sharp: "npm:^0.33.4" sharp: "npm:^0.33.4"
toml: "npm:^3.0.0" toml: "npm:^3.0.0"
typescript: "npm:5.4.5" typescript: "npm:5.4.5"
@ -3896,6 +3897,27 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"pino@npm:^9.3.2":
version: 9.3.2
resolution: "pino@npm:9.3.2"
dependencies:
atomic-sleep: "npm:^1.0.0"
fast-redact: "npm:^3.1.1"
on-exit-leak-free: "npm:^2.1.0"
pino-abstract-transport: "npm:^1.2.0"
pino-std-serializers: "npm:^7.0.0"
process-warning: "npm:^4.0.0"
quick-format-unescaped: "npm:^4.0.3"
real-require: "npm:^0.2.0"
safe-stable-stringify: "npm:^2.3.1"
sonic-boom: "npm:^4.0.1"
thread-stream: "npm:^3.0.0"
bin:
pino: bin.js
checksum: 10c0/698eb2ebfcc4252da9d035fcf9c999bf27615b66ebc47f9b3d7e942750e50ebe38429e6457abcf8014d70125964ddf114e696cb8225b480d9930271708e3fb52
languageName: node
linkType: hard
"postcss-value-parser@npm:^4.2.0": "postcss-value-parser@npm:^4.2.0":
version: 4.2.0 version: 4.2.0
resolution: "postcss-value-parser@npm:4.2.0" resolution: "postcss-value-parser@npm:4.2.0"
@ -3985,6 +4007,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"process-warning@npm:^4.0.0":
version: 4.0.0
resolution: "process-warning@npm:4.0.0"
checksum: 10c0/5312a72b69d37a1b82ad03f3dfa0090dab3804a8fd995d06c28e3c002852bd82f5584217d9f4a3f197892bb2afc22d57e2c662c7e906b5abb48c0380c7b0880d
languageName: node
linkType: hard
"process@npm:^0.11.10": "process@npm:^0.11.10":
version: 0.11.10 version: 0.11.10
resolution: "process@npm:0.11.10" resolution: "process@npm:0.11.10"