Add API logging functionality and enhance scheduler service

Introduced ApiLog model and integrated logging for scheduled tasks in the SchedulerService. Updated server.js to include request logging middleware and new API log routes. Enhanced frontend navigation by adding a link to system logs for admin users. Adjusted session check interval in App.vue for improved performance. This update improves monitoring and debugging capabilities across the application.
This commit is contained in:
Torsten Schulz (local)
2025-10-29 13:35:25 +01:00
parent 7a35a0a1d3
commit 0b1e745f03
12 changed files with 1307 additions and 6 deletions

102
backend/models/ApiLog.js Normal file
View File

@@ -0,0 +1,102 @@
import { DataTypes } from 'sequelize';
import sequelize from '../database.js';
import User from './User.js';
const ApiLog = sequelize.define('ApiLog', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
userId: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: User,
key: 'id',
},
onDelete: 'SET NULL',
onUpdate: 'CASCADE',
},
method: {
type: DataTypes.STRING(10),
allowNull: false,
comment: 'HTTP method (GET, POST, PUT, DELETE, etc.)'
},
path: {
type: DataTypes.STRING(500),
allowNull: false,
comment: 'Request path'
},
statusCode: {
type: DataTypes.INTEGER,
allowNull: true,
comment: 'HTTP status code'
},
requestBody: {
type: DataTypes.TEXT,
allowNull: true,
comment: 'Request body (truncated if too long)'
},
responseBody: {
type: DataTypes.TEXT,
allowNull: true,
comment: 'Response body (truncated if too long)'
},
executionTime: {
type: DataTypes.INTEGER,
allowNull: true,
comment: 'Execution time in milliseconds'
},
errorMessage: {
type: DataTypes.TEXT,
allowNull: true,
comment: 'Error message if completes failed'
},
ipAddress: {
type: DataTypes.STRING(45),
allowNull: true,
comment: 'Client IP address'
},
userAgent: {
type: DataTypes.STRING(500),
allowNull: true,
comment: 'User agent string'
},
logType: {
type: DataTypes.ENUM('api_request', 'scheduler', 'cron_job', 'manual'),
allowNull: false,
defaultValue: 'api_request',
comment: 'Type of log entry'
},
schedulerJobType: {
type: DataTypes.STRING(50),
allowNull: true,
comment: 'Type of scheduler job (rating_updates, match_results, etc.)'
},
}, {
underscored: true,
tableName: 'api_log',
timestamps: true,
indexes: [
{
fields: ['user_id', 'created_at']
},
{
fields: ['path', 'created_at']
},
{
fields: ['log_type', 'created_at']
},
{
fields: ['created_at']
},
{
fields: ['status_code']
}
]
});
export default ApiLog;

View File

@@ -38,6 +38,7 @@ import OfficialCompetitionMember from './OfficialCompetitionMember.js';
import MyTischtennis from './MyTischtennis.js';
import MyTischtennisUpdateHistory from './MyTischtennisUpdateHistory.js';
import MyTischtennisFetchLog from './MyTischtennisFetchLog.js';
import ApiLog from './ApiLog.js';
// Official tournaments relations
OfficialTournament.hasMany(OfficialCompetition, { foreignKey: 'tournamentId', as: 'competitions' });
OfficialCompetition.belongsTo(OfficialTournament, { foreignKey: 'tournamentId', as: 'tournament' });
@@ -238,6 +239,9 @@ MyTischtennisUpdateHistory.belongsTo(User, { foreignKey: 'userId', as: 'user' })
User.hasMany(MyTischtennisFetchLog, { foreignKey: 'userId', as: 'fetchLogs' });
MyTischtennisFetchLog.belongsTo(User, { foreignKey: 'userId', as: 'user' });
User.hasMany(ApiLog, { foreignKey: 'userId', as: 'apiLogs' });
ApiLog.belongsTo(User, { foreignKey: 'userId', as: 'user' });
export {
User,
Log,
@@ -278,4 +282,5 @@ export {
MyTischtennis,
MyTischtennisUpdateHistory,
MyTischtennisFetchLog,
ApiLog,
};