# Logging Guidelines > Logging and system-log conventions for the library-management backend. --- ## Overview The project requires system maintenance/log support for key operation logs, data backup support, and exception tracing. MySQL should include a system log table, illustratively `system_logs`, for durable audit and troubleshooting records. --- ## What to Log Record key operations that affect security, data integrity, or inventory: - Login success/failure and logout for administrator, librarian, and reader roles when applicable. - Permission changes, role changes, and denied protected operations. - Book create, update, delete, category maintenance, and warehousing/intake. - Borrow, return, renew, overdue handling, and automatic inventory status updates. - Reader profile, eligibility, and contact information changes. - Data backup events and restore-related maintenance actions. - Unhandled exceptions and failed database operations with safe context. --- ## System Log Fields When the schema is introduced, `system_logs` should preserve enough information to trace actions without exposing sensitive data. Useful fields include an ID, operator ID, operator role, operation type, target entity/table, target ID, result status, message, timestamp, and request IP when available. --- ## Sensitive Data Do not log passwords, raw credentials, full request bodies, database connection strings, or unnecessary personal data. Prefer IDs and operation summaries over large before/after payloads. --- ## Exception Tracing Server logs may contain technical stack traces for developers. User-facing JSP pages should receive concise messages. Durable system logs should record the operation, actor, failure category, and correlation details needed to locate the server-side exception. --- ## Scenario: Admin User Management Audit And System Log Viewer ### 1. Scope / Trigger - Trigger: administrator user/account management writes durable audit rows, and `/admin/system-logs` reads those rows through a Servlet -> Service -> DAO -> MySQL flow. - The viewer is read-only; mutation belongs to the business service that owns the operation being audited. ### 2. Signatures - DB signature: `system_logs(id, operator_id, operator_role, operation_type, target_table, target_id, result_status, message, request_ip, created_at)`. - DAO signatures: `SystemLogDao.search(criteria)`, `SystemLogDao.findOperationTypes()`, and `SystemLogDao.create(connection, log)`. - Service signatures: `SystemLogService.searchLogs(AuthenticatedUser actor, SystemLogSearchCriteria criteria)` and user-management methods that accept `requestIp` for audit rows. - Routes: `GET /admin/system-logs`; user-management audit sources include `POST /admin/users`, `POST /admin/users/update`, and `POST /admin/users/deactivate`. ### 3. Contracts - `/admin/system-logs` requires `VIEW_SYSTEM_LOGS`; user-management write routes require `MANAGE_USERS`. - Search criteria fields are `operationType`, `keyword`, `createdFrom`, and `createdTo`; dates use `YYYY-MM-DD`. - System-log result rows are newest-first and may include missing joined user names. Entity display helpers must render an operator label as display name, username, `User #`, or `System` in that order. - JSPs must use safe JavaBean helpers such as `operatorLabel`, `operatorMetaText`, `resultStatusCode`, and `resultStatusName`; do not put raw database status strings into CSS class names. - Audit messages must summarize actions with IDs/usernames/roles, never passwords, raw credentials, password hashes, or request bodies. ### 4. Validation & Error Matrix - Unauthenticated or unauthorized viewer -> `You do not have permission to view system logs.` - `operationType` longer than 64 characters -> field error on `operationType`. - `keyword` longer than 120 characters -> field error on `keyword`. - Invalid date text -> `Start date must use YYYY-MM-DD.` or `End date must use YYYY-MM-DD.` - `createdFrom` after `createdTo` -> field error on `createdTo`. - DAO failure while loading logs -> server-side Java logger entry plus `System log service is temporarily unavailable. Please try again later.` - Audit insert failure inside a user-management transaction -> rollback the mutating operation and return the user-management unavailable message. ### 5. Good/Base/Bad Cases - Good: user creation and its `user.create` audit row commit in the same transaction, including `operator_id`, `operator_role`, `target_table=users`, `target_id`, `result_status=success`, and `request_ip`. - Base: a system log with `operator_id` but no joined user displays as `User #`, not as `System`. - Bad: a JSP renders `class="status-${log.resultStatus}"` from an arbitrary database value. ### 6. Tests Required - Service checks for permission denial, criteria validation, date-range validation, DAO failure fallback, newest-first/search DAO contract, and empty results. - User-management service checks for audit log creation on create/update/ deactivate and rollback when audit creation fails inside the transaction. - Entity/display checks for operator fallback labels and normalized result status CSS codes. - JSP scan confirming no scriptlet, SQL, JDBC, password, or password-hash rendering in admin/log pages. ### 7. Wrong vs Correct #### Wrong ```jsp ${log.resultStatus} ``` #### Correct ```jsp ``` ## Scenario: Login Diagnostic Logging ### 1. Scope / Trigger - Trigger: Windows deployment login failures need server-side diagnostics across `LoginServlet -> AuthServiceImpl -> JdbcUserDao -> JdbcUtil` without changing the generic user-facing login messages. ### 2. Signatures - Servlet route: `POST /login` with `username`, `password`, and optional same-application `redirect`. - Service signature: `AuthService.authenticate(String username, String password)`. - DAO signature: `UserDao.findActiveByUsername(String username)`. - DB config keys: `db.driver`, `db.url`, `db.username`, and `db.password`. ### 3. Contracts - Login request logs may include remote address, context path, redirect presence, username presence/length, sanitized username, and whether normalization changed the username. - Authentication logs must distinguish missing required fields, active user not found, password mismatch, service error, and success. - JDBC logs must confirm `db.properties` loading, required key resolution, connection attempts, successful connections, and driver/connection failures. - Logs must never include raw passwords, password hashes, salts, database passwords, or unredacted password-like JDBC URL parameters. ### 4. Validation & Error Matrix - Missing username or password -> log missing-field category and return the existing required-field message. - Unknown or inactive username -> log `active-user-not-found` and return the existing invalid-credentials message. - Existing user with bad password -> log `password-mismatch` and return the existing invalid-credentials message. - Missing DB config or JDBC failure -> log server-side details with credentials redacted and return the existing service-unavailable message. ### 5. Good/Base/Bad Cases - Good: a failed login shows whether the request reached the servlet, whether the username was normalized, whether the active user row was found, and whether password verification failed. - Base: successful login keeps logging user ID and role only. - Bad: a diagnostic log writes `password`, `password_hash`, salt, or a JDBC URL containing `password=secret`. ### 6. Tests Required - Run `mvn test` or the documented Maven path to compile Servlet, service, DAO, and utility code. - Scan changed logs for password/hash/salt/database-password output before finishing. - Keep `AuthServiceCheck` behavior expectations unchanged for required fields, invalid credentials, success, permission checks, and DAO failure fallback. ### 7. Wrong vs Correct #### Wrong ```java LOGGER.info("Login failed password=" + password + " hash=" + user.getPasswordHash()); ``` #### Correct ```java LOGGER.info("Login failed reason=password-mismatch userId=" + user.getId()); ```