Back to Blog
Software

"Who Changed This Value?" Designing Audit Logs and Change History for Enterprise Systems

If prices, inventory, or permissions change and no one can say why, your system is missing an audit trail. This guide covers what to record, how to capture it, tamper resistance, retention costs, and history screens people will actually use.

POLYGLOTSOFT Tech Team2026-10-187 min read2
Audit LogChange HistoryEnterprise SystemInternal ControlSystem Design

You Only Realize You Need an Audit Log After Something Goes Wrong

At month-end close, a supplier's unit price turns out to be 15% lower than last month. The books say 1,200 units in stock; the physical count says 980. A former employee's account still has approval rights. Each situation starts with the same question: "Who changed this, and when?" A surprising number of systems can't answer it.

A common misconception is that application logs are enough. Application logs are records for developers troubleshooting failures. They're filtered by log level and often rotated away within weeks. Audit logs are records of business accountability. They must be complete, retained for a defined period, and impossible to alter. Different goals call for separate storage and separate design.

What to Record

The Six Elements of a Change Record

  • Who: the user ID, plus whether someone acted on their behalf (e.g., an admin processing it for them)
  • When: a server-side timestamp with an explicit time zone
  • Where: client IP, screen or API endpoint, or batch job name
  • What: table, record key, and changed fields
  • Before and after values: store both. Keeping only the new value forces you to reconstruct what actually changed
  • Why: where possible, a reason or approval document number
  • How Far to Go with Read Logs

    Logging every read can multiply storage by tens of times compared to change logs. The practical approach is to log reads only for data where viewing itself carries accountability, such as personal information. In Korea, the Standards for Personal Information Security Measures require access records for personal information processing systems to be kept for at least one year (two years in certain cases, such as systems covering 50,000 or more data subjects), and records of granting, changing, or revoking access rights to be kept for three years. Views of product catalogs or announcements rarely need logging.

    Comparing Capture Methods

    | Method | Strengths | Limitations |

    |--------|-----------|-------------|

    | Application layer | Easily captures business context like user and reason | Misses direct SQL and changes from other apps |

    | Database triggers | Catches every change regardless of path | Doesn't know the app user; adds write overhead |

    | Change Data Capture (CDC) | Reads the transaction log with little load on production | Requires extra infrastructure; user context must be passed separately |

    In practice, the answer is usually a combination. Record changes made through business screens at the application layer, with full context, and use triggers or CDC as a safety net for changes that bypass it. If you use triggers, pass the application user ID into each transaction, for example through a PostgreSQL `SET LOCAL` session variable, so the trail doesn't stop at "database account app_user changed it."

    Don't Lose Batch Changes

    A bulk price increase or inventory adjustment batch can touch tens of thousands of rows at once. ORM bulk updates often skip per-entity events, so application-layer logging can miss them entirely. Issue a run ID for every batch, stamp it on each changed row, and keep a batch-level record of who ran it, the target criteria, and the row count. Then you can trace it down to "batch #4821 on March 2 changed 12,000 rows."

    Tamper Resistance and Retention

  • Separate privileges: give the application account INSERT-only rights on audit tables and revoke UPDATE and DELETE. Restrict read access to auditors as well
  • Append-only storage: a hash chain, where each record includes the hash of the previous one, lets you detect deletions or edits in the middle. WORM (write once, read many) settings on object storage are another option
  • Retention and cost: 200,000 changes a day at 1KB each is 200MB a day, or about 73GB a year. Tiered retention works well: keep the last three to six months queryable in the production database, then compress older records and move them to low-cost storage. Set retention per data type, using whichever is longer, legal requirements or internal policy
  • Screens That Make Audit Logs Usable

    If records pile up with no screen to view them, a developer has to write SQL after every incident. Add a "Change History" tab to record detail screens that shows before-and-after values per field in time order, searchable by user, date range, field, and batch run ID. Index the record key and timestamp columns that searches hit most often.

    The next step is anomaly alerts. Rules like a unit price change of 30% or more, privilege escalation outside business hours, or a burst of edits from one user in a short window turn the audit log from an after-the-fact lookup tool into an early-warning system.

    How POLYGLOTSOFT Helps with Audit Log Design

    POLYGLOTSOFT adds a change-history layer to live systems without taking them offline. Step 1: identify critical tables such as pricing, inventory, and permissions, and define retention policies. Step 2: build a trigger- or CDC-based safety net. Step 3: add application-layer context capture and batch run IDs. Step 4: deliver change-history screens and anomaly alerts. If you need a system that can answer "who changed this," reach out to us through our subscription development service.

    Need Technical Consultation?

    Our expert consultants in smart factory, AI, and logistics automation will analyze your requirements.

    Request Free Consultation