Description
This function adds a packet of "event" data to a history. If the history does not yet exist it will first create the history and record any "subject" data. Attempts to log to a "sealed" history will fail.
Parameters
Name | Type | Description |
---|---|---|
datasource | String, optional | The name of the datasource where this event will be logged. This parameter overrides the same parameter in the worker configuration which in turn overrides the default datasource |
labela | String/int/real/bool, required, must not be null. Maximum 50 characters | The first part of the unique compound key that identifies this history. Every history must have a "labela", the other four labels are optional. By convention this label is used to identify the "service" this history relates to. |
labelb | String/int/real/bool/null, optional Maximum 50 characters | The second (optional) part of the unique compound key that identifies this history. By convention this label is used to store a unique identifier, such as the business key in a history generated by a workflow process. |
labelc | String/int/real/bool/null, optional Maximum 50 characters | The third (optional) part of the unique compound key that identifies this history |
labeld | String/int/real/bool/null, optional Maximum 50 characters | The fourth (optional) part of the unique compound key that identifies this history |
labele | String/int/real/bool/null, optional Maximum 50 characters | The fifth (optional) part of the unique compound key that identifies this history |
subject | Object, optional | This parameter will be ignored if the history already exists, otherwise it will be stored in the database against the unique key |
event | Object, required | This packet of data will be appended to the end of the history identified by the unique key |
seal | Boolean, optional | Seal the history. The history will be switched to read-only mode and no more events can be added to it |
coordinatesystem | String, optional | Either "WGS84" or "OSGB". Defaults to "WGS84" if not supplied |
fieldhints | Object, optional | Field hints tell the history worker how to interpret fields in subject and event data. Hints have only been implemented for location, and only points are currently supported. Hints are generated automatically for fields recognised as location data from form submissions. Hints are not needed of you are logging "proper" GeoJSON as described below |
fieldhints.location | Object | This object has a single property in the format |
timestamp | Integer (Unix milliseconds) | Only available in Maintenance Mode., which will also allow you to log to sealed histories. An error will be returned and the history/event will not be logged if set when not in maintenance mode |
Returns
If the log() operation was successful then the "result" structure will contain the following.
Property | Description |
---|---|
historyid | The unique ID of the history this event has been logged in |
eventid | The key the database has generated for this event |
eventpos | The number of the event within the history |
Example
"method": "log",
"params": {
"labela": "User",
"labelb": "823",
"subject": {
"name": {
"first": "Richard",
"surname": "Green"
}
},
"event": {
"type": "birthday",
"age": 42
}
}
"result": {
"historyid": "d295ef5c-32e1-4806-b95d-b4fe90550874",
"eventid": 347200,
"eventpos": 2
}
Logging Geographic Data
Geographic points can be logged in event and subject data packets. Each point is represented by a GeoJSON object with two properties.
"method": "log",
"params": {
"labela": "logginghistory",
"labelb": "2",
"subject": {
"userId": "user",
"description": "just a test"
"mySubjectPoint": {
"type": "Point",
"coordinates": [-2.961243, 51.974358]
}
},
"event": {
"description": "History Logged",
"event": "HISTORY LOGGED",
"myLocation": {
"type": "Point",
"coordinates": [-0.1246892262, 51.4828989175]
}
}
}
Geographic Form Data
The location-based fields of the forms designer (location picker and client location) log their coordinates as a string when their form data is saved in a history event. Something like this:
"formData": {
"data": {
"FORMACTION.FINISH": "Submit",
"LOCATIONPICKER": "51.4910227315,-0.131373291"
}
}
Because that's not valid GeoJSON, the History worker needs to be told that the string represents a location. If you use the Write Event form field, or store form data during a workflow process, the Forms Service and Workflow workers call a method (in FormUtils) which supplies a field hint to the History, flagging strings that look like coordinates as locations.
Note that the form location fields using Google maps record their geographic data as latitude/longitude values rather than longitude/latitude, so while the coordinates in saved form data may look like this:
"formData": {
"data": {
"TEST1": "test",
"LOCATIONPICKER": "51.4828989175, -0.1246892262" //This was a point in central London, not somewhere off the coast of Somalia
},
"formName": "STARTWORKFLOW",
"typeName": "FORM_STARTWORKFLOW",
"formDefinitionType": "FORMDEFINITIONEX"
}
The history worker will retrieve the event using this filter:
{
"EVENTEXISTSWHERE": {
"GEOGDISTLT": 10,
"key": "formData.data.LOCATIONPICKER",
"to": {
"type": "Point",
"coordinates": [-0.1246892263, 51.4828989176]
}
}
}
Data from Repeating Form Pages
If a form has repeating pages, and the form data is written to history, the data of the repeating page is structured as an array of objects (an object for each instance of the page). The array name is the name of the page, and the keys of each object are the field names. For example, history written by a workflow action field, with two repeats of page 1 would look like this:
"formData": {
"data": {
"PAGE1": [{
"NAME": "Tim",
"AGE": "41"
}, {
"NAME": "Leo",
"AGE": "40"
}]
},
"formName": "TIMSFORM",
"typeName": "FORM_TIMSFORM",
"formDefinitionType": "FORMDEFINITIONEX"
}
So that it's possible to write filters that query this data, the keys of form data from repeating pages are stored using generic array indexes.
For example, given the form data above, the keys would be written to the database as
Note that this wildcarding only takes place in the formData.data object.