Skip to content

Commit

Permalink
logs ?
Browse files Browse the repository at this point in the history
  • Loading branch information
Ali Zemani committed Aug 28, 2024
1 parent 939ead5 commit 214ff28
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 66 deletions.
26 changes: 10 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { createBot } from "./bot/bot";
import HomePageContent from "./front";
import AboutPageContent from "./front/about";
import pageLayout from "./front/layout";
import { CurrentConversation, User } from "./types";
import { KVModel } from "./utils/kv-storage";
import Logger from "./utils/logs";
import { Router } from "./utils/router";
import { convertToPersianNumbers } from "./utils/tools";
Expand Down Expand Up @@ -56,9 +54,9 @@ router.get(
"/api/chart-data",
async (request: Request, env: Environment, ctx: ExecutionContext) => {
let onlineUsersChartData;
let onlineUsersCount;
let conversationsCount;
let usersCount;
let onlineUsersCount = 0;
let conversationsCount = 0;
let usersCount = 0;

try {
const logger = new Logger(env.nekonymousr2);
Expand All @@ -71,23 +69,18 @@ router.get(
endDate
);

const logs = await logger.getLogs();
onlineUsersCount = logs.filter(
(log) => log.action === "new_conversation"
).length;
conversationsCount = logs.filter(
(log) => log.action === "new_conversation"
).length;
usersCount = logs.filter((log) => log.action === "new_user").length;
const newConversationLogs = await logger.getLogs("new_conversation");
const newUserLogs = await logger.getLogs("new_user");

onlineUsersCount = newConversationLogs.length;
conversationsCount = newConversationLogs.length; // Assuming each "new_conversation" log represents a conversation
usersCount = newUserLogs.length;
} catch (error) {
console.error("Failed to generate chart data", error);
onlineUsersChartData = {
labels: [],
data: [],
};
onlineUsersCount = 0;
conversationsCount = 0;
usersCount = 0;
}

return Response.json({
Expand All @@ -98,6 +91,7 @@ router.get(
});
}
);

/**
* Define the bot webhook route.
* This handles incoming webhook requests from Telegram to the bot.
Expand Down
64 changes: 14 additions & 50 deletions src/utils/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ class Logger {
}

/**
* Generates a unique key for each log entry based on the current timestamp.
* Generates a unique key for each log entry based on the current timestamp and action.
* @param {string} action - The action name to include in the log key.
* @returns {string} - The key to use when storing the log entry in R2.
*/
private generateLogKey(): string {
private generateLogKey(action: string): string {
const timestamp = new Date().toISOString();
return `${this.logKeyPrefix}${timestamp}.json`;
return `${this.logKeyPrefix}${action}/${timestamp}.json`;
}

/**
Expand All @@ -41,7 +42,7 @@ class Logger {
details,
};

const logKey = this.generateLogKey();
const logKey = this.generateLogKey(action);
await this.r2Bucket.put(logKey, JSON.stringify(logEntry));
} catch (error) {
console.error(`Failed to save log entry for action: ${action}`, error);
Expand All @@ -51,21 +52,19 @@ class Logger {
/**
* Retrieves log entries from the R2 bucket.
* If the R2 bucket is not available, this method will return an empty array.
* @param {string} [prefix] - An optional prefix to filter log entries (e.g., specific actions).
* @param {string} [action] - An optional action to filter log entries (e.g., "new_user").
* @returns {Promise<LogEntry[]>} - A promise that resolves to an array of log entries.
*/
public async getLogs(prefix?: string): Promise<LogEntry[]> {
public async getLogs(action?: string): Promise<LogEntry[]> {
if (!this.r2Bucket) {
console.warn("R2 bucket is not defined. Returning an empty log list.");
return [];
}

try {
const prefix = action ? `${this.logKeyPrefix}${action}/` : this.logKeyPrefix;
const logs: LogEntry[] = [];
const options = prefix
? { prefix: `${this.logKeyPrefix}${prefix}` }
: { prefix: this.logKeyPrefix };
const objects = await this.r2Bucket.list(options);
const objects = await this.r2Bucket.list({ prefix });

for (const object of objects.objects) {
const logData = await this.r2Bucket.get(object.key);
Expand Down Expand Up @@ -95,11 +94,6 @@ class Logger {
startDate: Date,
endDate: Date
): Promise<LogEntry[]> {
if (!this.r2Bucket) {
console.warn("R2 bucket is not defined. Returning an empty log list.");
return [];
}

const allLogs = await this.getLogs(action);
return allLogs.filter((log) => {
const logDate = new Date(log.timestamp);
Expand All @@ -108,52 +102,22 @@ class Logger {
}

/**
* Example usage: Generates a JSON array of online users per week for graphing purposes.
* If the R2 bucket is not available, this method will return an empty array.
* Generates chart data for online users per week.
* If the R2 bucket is not available, this method will return empty labels and data.
* @param {Date} startDate - The start of the week.
* @param {Date} endDate - The end of the week.
* @returns {Promise<any[]>} - A promise that resolves to a JSON array of online user data.
* @returns {Promise<{ labels: string[], data: number[] }>} - A promise that resolves to an object with labels and data for graphing.
*/
public async generateOnlineUsersReport(
public async generateOnlineUsersChartData(
startDate: Date,
endDate: Date
): Promise<any[]> {
if (!this.r2Bucket) {
console.warn("R2 bucket is not defined. Returning an empty report.");
return [];
}

): Promise<{ labels: string[]; data: number[] }> {
const logs = await this.getLogsByActionAndDateRange(
"new_conversation",
startDate,
endDate
);
const onlineUsers: any[] = logs.map((log) => ({
timestamp: log.timestamp,
}));

return onlineUsers;
}

/**
* Example usage: Generates chart data for online users per week.
* If the R2 bucket is not available, this method will return empty labels and data.
* @param {Date} startDate - The start of the week.
* @param {Date} endDate - The end of the week.
* @returns {Promise<{ labels: string[], data: number[] }>} - A promise that resolves to an object with labels and data for graphing.
*/
public async generateOnlineUsersChartData(
startDate: Date,
endDate: Date
): Promise<{ labels: string[]; data: number[] }> {
if (!this.r2Bucket) {
console.warn("R2 bucket is not defined. Returning empty chart data.");
return { labels: [], data: [] };
}

const logs = await this.generateOnlineUsersReport(startDate, endDate);

// Group by day and count online users
const chartData: { [key: string]: number } = {};
logs.forEach((log) => {
const day = log.timestamp.split("T")[0]; // Get only the date part
Expand Down

0 comments on commit 214ff28

Please sign in to comment.