Files
Book-management-system/.trellis/spec/backend/logging-guidelines.md
T
2026-04-28 18:26:28 +08:00

8.1 KiB

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 #<id>, 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 #<id>, 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

<span class="status-${log.resultStatus}">${log.resultStatus}</span>

Correct

<span class="status-${log.resultStatusCode}">
  <c:out value="${log.resultStatusName}" />
</span>

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

LOGGER.info("Login failed password=" + password + " hash=" + user.getPasswordHash());

Correct

LOGGER.info("Login failed reason=password-mismatch userId=" + user.getId());