Using the CTP AuditLog Plugin
This article describes how to configure the CTP AuditLog plugin to capture information from objects processed by pipeline stages. The intended audience for this article is administrators configuring CTP for clinical trials.
The AuditLog is a persistent database of entries made by other CTP components. It provides a servlet allowing the database to be searched through a browser.
Entries in the AuditLog are text. Each entry has a Content-Type. All standard CTP stages create log entries with the Content-Type "xml", but the AuditLog accepts all Content-Type identifiers.
An AuditLog plugin must have an id attribute uniquely identifying the plugin. A single configuration can have multiple AuditLog plugins. An AuditLog's servlet is accessed using the identifier as the resource context.
The DicomAuditLogger pipeline stage can be used to make AuditLog entries containing the values of specified elements in DicomObjects processed by the stage. The entries can be made on three levels:
- patient: one entry for each unique PatientID processed by the stage
- study: one entry for each unique StudyInstanceUID processed by the stage
- instance: one entry for each unique SOPInstanceUID processed by the stage
The DicomAuditLogger must be configured with the id the AuditLog plugin into which it will make entries. If the DicomAuditLogger is provided with the id of an ObjectCache pipeline stage, it includes the corresponding element values from both the cached object and the object currently being processed. This makes it possible to build a log of PHI elements and their anonymized values.
This is an example configuration that logs both the PHI and anonymized values of the PatientID and PatientName elements for each patient:
<Configuration> <Server maxThreads="20" port="1999"/> <Plugin class="org.rsna.ctp.stdplugins.AuditLog" id="AuditLog" name="AuditLog" root="roots/AuditLog"/> <Pipeline name="Pipeline" root="test"> <DicomImportService class="org.rsna.ctp.stdstages.DicomImportService" logConnections="no" name="DicomImportService" port="104" quarantine="quarantines/DicomImportService" root="roots/DicomImportService"/> <ObjectCache class="org.rsna.ctp.stdstages.ObjectCache" id="ObjectCache" name="ObjectCache" root="roots/ObjectCache"/> <DicomAnonymizer class="org.rsna.ctp.stdstages.DicomAnonymizer" lookupTable="scripts/LookupTable.properties" name="DicomAnonymizer" quarantine="quarantines/DicomAnonymizer" root="roots/DicomAnonymizer" script="scripts/DicomAnonymizer.script"/> <DicomAuditLogger auditLogID="AuditLog" auditLogTags="PatientID;PatientName" cacheID="ObjectCache" class="org.rsna.ctp.stdstages.DicomAuditLogger" id="DicomAuditLogger" level="patient" name="DicomAuditLogger" root="roots/DicomAuditLogger"/> <FileStorageService class="org.rsna.ctp.stdstages.FileStorageService" name="FileStorageService" port="9999" quarantine="quarantines/FileStorageService" returnStoredFile="yes" root="roots/FileStorageService"/> </Pipeline> </Configuration>
In addition to serach capability, the AuditLog servlet also supports downloading the entire database either as an XML structure or a CSV file. When exporting the database, only entries with the Content-Type "xml" are included. The structure of an XML export containing only a single entry looks like this:
<AuditLog date="2015.11.05"> <DicomObject SOPClassName="CT Image Storage" StageName="DicomAuditLogger"> <PatientID DicomAuditLogger="1200824338" ObjectCache="657662"/> <PatientName DicomAuditLogger="767339" ObjectCache="DOE,JOHN"/> </DicomObject> </AuditLog>
In the structure, each logged DICOM element is represented by its DICOM keyword. The attribute names are the id attributes of the ObjectCache and DicomAuditLogger stages. This can be used to make the attribute names more meaningful. If, for example, the ObjectCache had the id PHI and the DicomAuditLogger had the id replacement, en element might look like this:
<PatientID PHI="657662" replacement="1200824338"/>