BesluitBron 1.4.4-23 Status Sign in

Logging and Accountability

Last changed on .

For every MCP request, a record is kept of what was accessed, how long it took, how much data was involved and where it came from. That log is not merely a by-product. It is the reason why a response can be justified retrospectively.

What is recorded

Per call: the address from which the request originated, the name of the tool, the duration of the request and of the request to the source platform separately, the number of hits, the number of documents retrieved, the size in bytes and the truncated IP address of the requester.

From version 1.3.10 onwards, an IP address is truncated before it is recorded anywhere. With IPv4, the last 16 bits are discarded; with IPv6, only the first 32 bits remain. What remains identifies a network, not a visitor. An email address that appears in a log entry – for example, because someone searched for it – is replaced by an irreversible value from a range of 65,536 possibilities. This applies to the log file, the error table, the trace file and the report sent to an external service. Up to version 1.3.9, the full address appeared in these records; those older entries remain as they were written and will be automatically deleted once their retention period expires.

From version 1.3.54 onwards, the organisation specified by the client is also recorded. A client may include the header x-organisation with each request, for example x-organisation: Gemeente Delft. This header is optional and is only included occasionally. The client chooses the name itself and nobody checks it. The header does not confer any rights either: the MCP addresses do not support authentication, and a request without a header is handled in exactly the same way as one with a header. The name of the header is exactly ‘x-organisation’, with an ‘s’. A header containing a ‘z’ is not read; the value is then not recorded anywhere and the request proceeds as normal. The value is placed on a single line and truncated after 120 characters, and is then recorded in the log alongside the browser identifier. These two provide different information: the browser identifier indicates which programme made the call, whilst the organisation indicates on whose behalf. The locations where the value can be viewed are listed at Opvragingen, Overzicht and Dashboard.

Two things are deliberately left untruncated. The browser identifier, as this describes a programme rather than a person. And the username displayed in the event of an error, as this refers to an account on this installation.

Not recorded: the content of the conversation between the user and the assistant. That content does not reach BesluitBron. What BesluitBron sees is the call made by the assistant, along with the parameters provided with it.

Where it can be seen

The assistant’s traffic is logged in the request log:

flowchart TD
    X["ToolExecutor"] --> L["McpRequestLog"]
    L --> J[("Table bbn_mcp_log<br/>in the database")]
    L --> RB["Ring buffer<br/>in the memory"]
    J --> LOGP["Logbook page<br/>per connector"]
    J --> ANA["Analysis<br/>per tool"]
    RB --> HUB["SignalR"] --> DASH["Dashboard<br/>live"]
    RB --> TOOL["list_platform_calls<br/>for the assistant"]

What the server itself does follows a different path:

flowchart TD
    S["The server itself"] --> TJ[("Trace file<br/>one file a day")]
    TJ --> TRP["Trace page<br/>to read and download"]

Four entries, each for a different question:

  • list_platform_calls answers the question ‘what is this answer based on?’. The assistant can ask this themselves during the conversation;
  • The log page in the management console shows ‘what has been requested over the past few days’, which can be filtered by connector;
  • The dashboard answers the question ‘What’s happening now?’ and displays calls as they come in;
  • The trace page answers the question ‘what did the server actually do?’. That page does not just show the call to the assistant. It also shows every call to a source platform that lay behind it – whether live or from the buffer – and every error along with its stack trace.

The first three relate to the assistant’s traffic. The trace relates to the service’s behaviour. The trace is therefore the point of reference when a tool has returned an incorrect response and the request log does not explain why. The trace file can be downloaded in its entirety and is not filtered in the process, as a trace that has been edited whilst in transit is no longer admissible as evidence.

Error messages

Reports are identified by a code in the format bbn<gebied><nummer>, for example bbnsrv005 for a configuration in which all sources were switched off. These codes are fixed. They are intended to be quoted in a report to the administrator or in an enquiry to the supplier, and are not renumbered.

The field names in the trace file and the column names in the request log are fixed for the same reason. Existing trace files, old log files and the reports relating to them are based on this.

From version 1.3.58 onwards, each error is recorded as a line in the trace file, with the code bbnerr005 and the request ID included. Up to version 1.3.57, a line was only recorded there if the saving of the error itself failed; consequently, in the event of a database failure, nothing was recorded. The severity level corresponds to the type of error: ‘Error’ for a 5xx error, ‘Warning’ for a 4xx error and ‘Debug’ for a request that has been classified as an attack. See Trace.

Storage

The log is stored in the ‘bbn_mcp_log’ table. A database is required for this, and from version 1.3.73 onwards, this is no longer optional: an installation without a database will not start and will indicate what is missing upon launch. Up to and including version 1.3.72, it was possible to run without a database, in which case the log was written daily to a separate file within the data folder. These files are not lost: they are read in once during the first start-up with a database and then moved to a subfolder. As long as they remain there, they are also deleted in accordance with the same retention period, and a request concerning personal data will include them. The trace file remains a file, in its own folder alongside the others, and is subject to the same retention policy. See Uitrol en Beheer and, for the associated retention policy, Openbaarheid en Persoonsgegevens.

The service clears its own data: the log file after ninety days, the trace file after thirty, the error table after ninety and the output files after seven. These are the administrator’s deadlines, not those of the visitor. The log file shows whether the integration is being used and where it fails, and it takes a quarter to spot a pattern. The trace file is used to identify a fault that only becomes apparent over the course of weeks. If you wish to change this, adjust BesluitBron:Log:RetentionDays, BesluitBron:Trace:RetentionDays, BesluitBron:ErrorHandling:RetentionDays and BesluitBron:Export:RetentionDays; a value of zero or lower will retain everything.

From 1 March 2010 onwards, this clean-up takes place every day, even when the server has been running for months on end. Up to version 1.3.9, the service only performed a clean-up on start-up, and it did not clean up the rules in the database at all. Consequently, an installation that was not restarted retained everything. The frequency of clean-ups is specified at BesluitBron:Retention:IntervalHours; by default, this is every 24 hours. Each cycle logs what has been removed in the trace file, with the code bbnret001.

With version 1.3.10, the error log was also given a retention period of ninety days. The ‘Delete now’ button on the ‘Errors’ screen remains in place; for those who wish to clear a specific period earlier, see Beheerconsole.