API and storage for logging event and audit messages, persisted in JSON within a PostgreSQL db, with a thin frontend provided by PostgREST
The logserver serves as the Audit Record Repository, as detailed in the Basic Audit Log Patterns (BALP) implementation guide.
logserver is agnostic to the format, provided it is valid JSON. Any number
of database tables can be used, but only the single events
table is built
in, containing a PostgreSQL JSONB column, event
.
It is desirable to generate log events compliant with the FHIR audit event resource. To generate an AuditEvent
resource nested within each event
is cumbersome, however the following field
parity is recommended:
NB: all fields are considered optional unless marked as required
severity
: required element. Use built in log level rather than adding an additionalseverity
field:critical
: Critical condition with application. Includeemergency
andalert
levels in this category.error
: Error condition with the application.warning
: Warning needing attention before escalation to error.info
: Normal operational messages not requiring action. Includenotice
level in this category (normal but significant).debug
: Debug level messages, useful to application developers.
version
: required logserver schema version.action
: required element to describe the type of operation performed.create
: creating a new resource, such as adding a patient.read
: read/view/search - data retrieved or viewed w/o modification.update
: indicates existing data was modified.delete
: indicates data was removed or deleted.execute
: system or application function such as, program execution or perform a query/search.login
: specific category for the log-in actionlogout
: specific category for the log-out action
occurred
: Date-Time of the event, including timestamp information. This may duplicate the logging system timestamp (such asasctime
) but will always capture the time the event took place, not when it hit the logging server.subject
: the subject of the activity, i.e.Patient/ab-123-ef
agent
: actor involved in the event, generally the logged-in user:ip_address
: end user or requesting system's IP Addresstype
: i.e.system
oruser
who
: i.e.Practitioner/123-abc
source
: event reporter or system generating the audit event.observer
: base URL of the system generating the audit messagetype
: system type such asdhair2
or other predefined project category.version
: version of the observer (in contrast to top levelversion
)
entity
: data or objects useddetail
: list of tagged value pairs for conveying additional information. example pair might includeurl
:<full_url>
in contrast tosource.observer
query
: query parameters for query-type entities
outcome
: details in event of a failure or warning. useseverity
to capture level.
Copy default.env
to .env
and edit. Don't quote strings!
Role | Access |
---|---|
web_anon | read only access to the API |
event_logger | read / write access to the API |
For write access, generate a JWT at jwt.io
- Replace
secret
with the unquoted value ofPGRST_JWT_SECRET
- Replace the
PAYLOAD: DATA
with the appropriate role
{
"role": "event_logger"
}
- Do NOT check the
secret base64 encoded
checkbox - Save the
Encoded
JWT for use, passing as a bearer token:
export TOKEN=<JWT>
curl https://FQDN/events -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"event": {
"asctime": "2020-04-26 00:33:26,731",
"name": "sof_wrapper",
"levelname": "INFO",
"tags": [
"auth",
"login"
],
"subject": "Patient/41703",
"user": "Practitioner/SMART-1234"
}
}'
All events posted are available at:
/events
Sample query to fetch all events including login
in the list of tags
:
/events?event.tags=cs.{login}
Sample query to fetch all events where the patient
field equals "marcus aurelius"
:
/events?select=event&event-%3E%3Epatient=eq.marcus%20aurelius
Sample query to fetch events for given patient AND tag:
/events?select=event&event.tags=cs.{mme-calc}&event-%3E%3Epatient=eq.marcus%20aurelius
Fetch events based on datetime:
/events?select=event->>asctime,event->>message&event->>asctime=gte.2023-04-01&limit=25
Fetch events based on datetime, and include a number of isacc-specific fields:
/events?select=event-%3E%3Easctime,event-%3E%3Ename,event-%3E%3Emessage,event-%3E%3Eversion,event-%3E%3Elevelname,event-%3E%3ETwilio%20messages,event-%3E%3ECommunicationRequest&event-%3E%3Easctime=gte.2023-04-18&limit=25
See PostgREST API documentation for additional options