nn-ui-v2 / build /server /chunks /LogService-b0lb4PC5.js
muryshev's picture
ui update
05a241e
raw
history blame
No virus
10.9 kB
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import { format } from 'date-fns';
import mongoose from 'mongoose';
import ExcelJS from 'exceljs';
import { d as private_env } from './shared-server-49TKSBDM.js';
import { E as ExcelColumnsName } from './constants-jjpZ8eI6.js';
const LogSchema = new mongoose.Schema({
llmPrompt: { type: String },
llmTemplate: { type: String },
llmResponse: { type: String },
searchResults: { type: [String] },
selectedSearchResults: { type: [String] },
uiSettings: { type: Object },
consultations: { type: [String] },
userRequest: { type: String },
userScore: { type: String },
userComment: { type: String },
dateCreated: { type: Date, default: Date.now },
dateUpdated: { type: Date, default: Date.now }
});
LogSchema.index({ dateCreated: 1 }, { unique: false });
const LogModel = mongoose.models.Log || mongoose.model("Log", LogSchema);
class MongooseService {
uri;
options;
connection;
constructor(uri, options = {}) {
try {
this.uri = uri || process.env.MONGODB_URI || "";
this.options = options;
this.connection = null;
if (!this.uri) {
console.warn("MongoDB URI is not defined");
}
} catch {
console.warn("MongoDB URI is not defined. Logs wont be saved.");
}
}
/**
* Connect to the MongoDB database
* @returns {Promise<Connection>}
*/
async connect() {
if (this.connection) {
return this.connection;
}
try {
await mongoose.connect(this.uri, this.options);
this.connection = mongoose.connection;
console.log("Connected to MongoDB");
return this.connection;
} catch (error) {
console.warn("MongoDB URI is not defined. Logs wont be saved.");
}
}
/**
* Disconnect from the MongoDB database
* @returns {Promise<void>}
*/
async disconnect() {
if (!this.connection) {
console.log("No active MongoDB connection to disconnect");
return;
}
try {
await mongoose.disconnect();
this.connection = null;
console.log("Disconnected from MongoDB");
} catch (error) {
console.error("Error disconnecting from MongoDB:", error);
throw new Error("Could not disconnect from MongoDB");
}
}
/**
* Get the current MongoDB connection
* @returns {Connection | null}
*/
async getConnection() {
if (!this.isConnected()) {
await this.connect();
}
return this.connection;
}
isConnected() {
return this.connection !== null && mongoose.connection.readyState === 1;
}
}
const writeFile = promisify(fs.writeFile);
const readDir = promisify(fs.readdir);
const readFile = promisify(fs.readFile);
class LogService {
mongooseService;
logModel;
constructor() {
if (private_env.ENABLE_DB_SUPPORT) {
this.mongooseService = new MongooseService(private_env.MONGODB_URI || "");
this.logModel = LogModel;
}
}
/**
* Сохраняет лог в базу данных MongoDB, если она доступна.
* @param document - Лог-документ, который нужно сохранить.
* @returns {Promise<string>} ID созданной записи.
*/
async log(document) {
if (!private_env.ENABLE_DB_SUPPORT) {
return "";
}
try {
await this.mongooseService.getConnection();
const logEntry = new this.logModel(document);
await logEntry.save();
console.log("Log entry saved to MongoDB");
return logEntry._id;
} catch (err) {
console.error("MongoDB connection failed", err);
}
return "";
}
/**
* Обновляет поле userScore в записи с указанным ID.
* @param id - ID записи, которую нужно обновить.
* @param score - Новое значение для userScore.
* @param comment - Новое значение для userComment.
* @returns Количество обновленных записей.
*/
async logUserScore(id, score, comment) {
if (!private_env.ENABLE_DB_SUPPORT) {
return "";
}
try {
await this.mongooseService.getConnection();
const LogModel2 = mongoose.model("Log");
const result = await LogModel2.updateOne(
{ _id: id },
{ $set: { userScore: score, userComment: comment } }
);
return result.modifiedCount;
} catch (error) {
console.error("Error while updating userScore:", error);
throw error;
}
}
/**
* Сохраняет лог-документ в файл JSON.
* Имя файла основано на текущем времени.
* @param document - Лог-документ, который нужно сохранить.
* @returns {Promise<void>}
*/
async saveLogToJsonFile(document) {
const timestamp = format(/* @__PURE__ */ new Date(), "dd-MM-yyyy:HH:mm:ss:SSS");
const logDir = path.join(private_env.LOGS_ROOT_FOLDER, "log");
const logFile = path.join(logDir, `${timestamp}.json`);
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true });
}
const data = JSON.stringify(document, null, 2);
await writeFile(logFile, data);
console.log(`Log entry saved to file: ${logFile}`);
}
/**
* Экспортирует логи из базы данных и/или файлов в формате JSON или Excel.
* Записи сортируются по дате создания. Если указаны dateFrom и dateTo, применяется фильтрация по дате.
* @param type - Тип экспорта: 'json' или 'excel'.
* @param dateFrom - Дата начала фильтрации (необязательно).
* @param dateTo - Дата окончания фильтрации (необязательно).
* @param fields - Поля для экспорта
* @returns {Promise<any>}
*/
async export(type, dateFrom, dateTo, fields) {
if (!private_env.ENABLE_DB_SUPPORT) {
return "";
}
const mongoLogs = await this.fetchLogsFromMongo(dateFrom, dateTo, fields);
const allLogs = [...mongoLogs];
if (type === "json") {
return await this.exportToJson(allLogs);
} else if (type === "excel") {
return await this.exportToExcel(allLogs);
}
}
/**
* Извлекает логи из базы данных MongoDB с учетом фильтрации по дате.
* @param dateFrom - Дата начала фильтрации (необязательно).
* @param dateTo - Дата окончания фильтрации (необязательно).
* @returns {Promise<any[]>} - Возвращает массив логов.
*/
async fetchLogsFromMongo(dateFrom, dateTo, fields) {
if (!private_env.ENABLE_DB_SUPPORT) {
return [];
}
const query = {};
if (dateFrom || dateTo) {
query.dateCreated = {};
if (dateFrom)
query.dateCreated.$gte = dateFrom;
if (dateTo)
query.dateCreated.$lte = dateTo;
}
await this.mongooseService.getConnection();
return await this.logModel.find(query).select(fields ? fields.join(" ") : "").sort({ dateCreated: 1 }).lean().exec();
}
/**
* Извлекает логи из файлов JSON в папке /data/log с учетом фильтрации по дате.
* @param dateFrom - Дата начала фильтрации (необязательно).
* @param dateTo - Дата окончания фильтрации (необязательно).
* @returns {Promise<any[]>} - Возвращает массив логов.
*/
async fetchLogsFromFiles(dateFrom, dateTo) {
const logDir = path.join(__dirname, "../data/log");
const files = await readDir(logDir);
const logs = [];
for (const file of files) {
const filePath = path.join(logDir, file);
const content = await readFile(filePath, "utf-8");
const logEntry = JSON.parse(content);
const fileDate = format(
new Date(file.split(".")[0].replace(/-/g, ":")),
"yyyy-MM-dd HH:mm:ss:SSS"
);
if ((!dateFrom || new Date(fileDate) >= dateFrom) && (!dateTo || new Date(fileDate) <= dateTo)) {
logs.push(logEntry);
}
}
logs.sort((a, b) => new Date(a.dateCreated).getTime() - new Date(b.dateCreated).getTime());
return logs;
}
// /**
// * Экспортирует массив логов в файл JSON.
// * @param logs - Массив логов, который нужно экспортировать.
// * @returns {Promise<void>}
// */
// private async exportToJson(logs: any[]): Promise<void> {
// const exportFile = path.join(__dirname, '../data/export/logs.json');
// await writeFile(exportFile, JSON.stringify(logs, null, 2));
// console.log(`Logs exported to JSON file: ${exportFile}`);
// }
/**
* Экспортирует массив логов в файл Excel.
* @param logs - Массив логов, который нужно экспортировать.
* @returns {Promise<void>}
*/
async exportToExcel(logs) {
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet("Logs");
if (private_env.ENABLE_DB_SUPPORT) {
worksheet.columns = Object.keys(logs[0] ?? {}).map((key) => {
return {
header: ExcelColumnsName[key] ?? key,
key,
width: 30
};
});
logs.forEach((log) => {
const consultations = (log.consultations ?? []).map((v) => JSON.stringify(v));
const searchResults = (log.searchResults ?? []).map((v) => JSON.stringify(v));
const selectedSearchResults = (log.selectedSearchResults ?? []).map(
(v) => JSON.stringify(v)
);
const serializedLog = Object.fromEntries(
Object.entries(log).map(([key, value]) => [
key,
typeof value === "object" && value !== null ? JSON.stringify(value) : value
])
);
worksheet.addRow({
...serializedLog,
consultations: consultations[0] ?? "",
searchResults: searchResults[0] ?? "",
selectedSearchResults: selectedSearchResults[0] ?? ""
});
const maxLength = Math.max(
consultations.length,
searchResults.length,
selectedSearchResults.length
);
for (let index = 1; index < maxLength; index++) {
worksheet.addRow({
consultations: consultations[index] ?? "",
searchResults: searchResults[index] ?? "",
selectedSearchResults: selectedSearchResults[index] ?? ""
});
}
});
}
const buffer = await workbook.xlsx.writeBuffer();
return buffer;
}
}
export { LogService as L };
//# sourceMappingURL=LogService-b0lb4PC5.js.map