Skip to content

Semantic Logging

Timothy O'Connell edited this page Mar 16, 2018 · 12 revisions

Initialized user assets (e.g. settlement and survivor objects) have a method called log_event() that allows them to "insert" a line into the settlement's Event Log at any time.

Semantic Logging and the log_event() method

There are two big ideas behind Semantic Logging:

  1. It makes individual log lines easier to process in a programmatic fashion by saving them as an object, rather than just a single string.
  2. From a developer perspective, this makes calls to the method for recording a settlement event more extensible and less likely to break over time.

How to use it

The Models.UserAsset.log_event() method is how we do Semantic Settlement Event Logging, and it is callable by all objects that use Models.UserAsset as their base class.

Example syntax

Consider a simple Settlement Event log line:

[email protected] added 'Lantern Hoard' Settlement Locations.

To create this, our settlements.Settlement object method would call:

self.log_event(action='add', key='Locations', value='Lantern Hoard', event_type='add_location')

Behind the scenes

By calling the method with these three relatively simplistic values, the API is evaluates the settlement and records a ton of information to the database.

Basically, the action, key and value parameters are parsed during the log_event() call, and used to create an entry into the database that contains a ton of information that can later be used in a number of different ways.

The example syntax above, for example, gets you something like this:

    {
        "event_type": "add_location",
        "modified": {
            "attribute": {
                "key_pretty": "Locations",
                "key": "Locations",
                "value": "Lantern Hoard",
                "value_pretty": "Lantern Hoard"
            },
            "asset": {
                "_id": {
                    "$oid": "5a6c8ab38740d9739bb6a688"
                },
                "type": "settlement",
                "name": "Demo Settlement"
            }
        },
        "created_by": {
            "$oid": "5a057a9b8740d946a02def5b"
        },
        "created_on": {
            "$date": 1521149303760
        },
        "version": 1.1,
        "settlement_id": {
            "$oid": "5a6c8ab38740d9739bb6a688"
        },
        "agent": "user",
        "action": {
            "preposition": "to",
            "word": "added",
            "repr": "added 'Lantern Hoard' to settlement locations"
        },
        "created_by_email": "[email protected]",
        "_id": {
            "$oid": "5aaae5778740d9190dd08066"
        },
        "event": "[email protected] added 'Lantern Hoard' to settlement locations.",
        "ly": 12
    },

Parameters

The log_event() method accepts keyword arguments and uses them to compose a human-readable "sentence". The method supports the following kwargs:

  • action - the "verb" of the log line
  • agent - who (or what) is doing the logging
  • event_type - the nature of the event
  • key - the attribute of the asset being updated/changed/created/etc.
  • value - the new or incoming data

Of those, action, key and value are the most important: if they are specified, the API will create a coherent/readable sentence in the Event Log.

Important! If action, key or value are not specified in your call, the log_event() method will try to "guess" them by using inspect.currentframe() to get the caller method and parse it. This mostly works, except when it doesn't, if you take my meaning.

Best to avoid potential silliness and just specify them.

Calling log_event() with no parameters

Finally, though this is not recommended, the method also supports a "no parameters" call, e.g. self.log_event(). In this case, a generic/vanilla message will be recorded, e.g. "[email protected] updated the Settlement.".

The action parameter

This should be a string that represents the what is happening in the event and will drive the "verb" of the log line.

The action will ultimately drive not only the verb of your event, but also the preposition of it. In our example event:

[email protected] added 'Lantern Hoard' to Settlement Locations.

...the preposition "to" is determined by the action value "added".

Incoming action strings are processed through a helper method, utils.action_keyword(), which basically is a translation table that converts a string into a verb/preposition tuple:

    if kw in ['add','added','adds']:                
        output = ("added", "to")
    elif kw in ['rm','remove']:
        ...

The utils.action_keyword() method is case-insensitive.

The agent parameter

This is the agency responsible for the event. In most cases, this is the application user who called the method that made the call to log_event()

Which is to say that, generally speaking, you do not want to specify this one when calling log_event().

(Unless you really know what you're doing.)

The key parameter

This is the attribute of the asset that is changed, updated, created, etc. by the event that you're logging.

In our standard example, "Locations" is the key:

[email protected] added 'Lantern Hoard' to Settlement Locations.

The value parameter

This is the thing that's new.

In the example discussed here, the value is the string "Lantern Hoard".

Important! Leaving this undefined will not cause an error, but it will result in a weird-/broken-looking sentence:

[email protected] added 'UNKNOWN' to Settlement Locations.

The event_type parameter

All things being equal, this should be the name of the method that is doing the action that we're recording with the event.

If, for example, we're calling models.settlements.Settlement.add_location() to add a location to the settlement's locations, when we call self.log_event() at the end of our add_location() call, we want to specify the event_type as 'add_location', i.e. the name of the caller method.

Generally speaking, this can be left undefined, since the log_event() method parses "caller" frames to determine the name of the method calling it.

Legacy, string-based logging

For legacy purposes, this method supports simplistic, string-based logging:

self.log_event('Description of a Settlement event!')

In such cases, the first parameter should be a string that is intended to be entered directly into the settlement's Event Log.

Important! This is not the preferred way to do settlement Event Logging and should not be used.

(Seriously don't do it.)