In very general terms, your problem is one of keeping context information. IF we assume the following:
- Each request is handled by some code in the server, with one of the execution threads.
- Each thread processes one request at a time.
- The server code logs each incoming request with both a high-precision time stamp (milliseconds or below) and the identifier for the handling thread.
- The MAC policy engine, when it detects a violation, logs it along with a high precision time stamp and context information, in particular the identifier for the offending thread.
Then it becomes easy to map violations onto requests.
In practice, depending on the involved technology (server code, application design, policy engine...), some of the above information may be missing. For instance, the policy engine may log only the process ID and a process may contain several threads (there are "system threads" handled by the OS, but at application level there can also be so-called "lightweight threads" that the OS is not aware of). Some server engines may pursue several requests simultaneously (state machine design with
poll()). Logs may lack sub-second precision. In the server, the I/O accesses may be centralized and shared, so the thread which received the request is not necessarily the one which does the file access.
If you do not have all the needed information, then you will have to analyse all the requests received in the relevant time frame, until you find the funky one. You might want to resort to simulation: keep all incoming requests in a circular buffer, so that at any time you have a copy of the last minute worth of request data or so; if the policy engine detects a violation, make a snapshot (a copy of the requests and the relevant server state). Afterwards, during analysis, resubmit all these requests to a copy of the server, one at a time, until you find the one which triggers the problem.