Viewing the history of an asset¶
Accessing the history of an asset in Atlan is a flexible operation. This also makes it a bit more complex to understand than the other operations. To encapsulate the full flexibility of Atlan's search, the SDK provides a dedicated AuditSearchRequest
object.
Similar but not identical to searching in general
Atlan's audit log that contains the history of an asset uses Elasticsearch. This makes the approach you use to access history similar to searching. However, there are differences as the audit log uses a different index than the broader search. If you're feeling brave, feel free to experiment with the more complex search mechanisms outlined in the searching section. But this should be sufficient to get you started with accessing asset history.
Build the request¶
To retrieve an asset's history in Atlan, you need to define the request. For simplicity, we provide helper methods to retrieve a defined number of entries in reverse-chronological order (most recent entries first).
By GUID¶
To request the history of an asset by GUID:
Build the query by GUID | |
---|---|
1 2 3 4 |
|
- Create a request for the history of an asset, by its GUID.
- Specify the GUID of the asset.
- Specify the amount of history (maximum number of activities). This will be in reverse-chronological order (most recent entries first).
- Build the request.
Build the query by GUID | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
- Create a request for the history of an asset, by its GUID.
- Specify the GUID of the asset.
- Specify the amount of history (maximum number of activities). This will be in reverse-chronological order (most recent entries first).
Bool query contents | |
---|---|
7 8 9 10 11 12 13 14 15 |
|
- To retrieve history for a specific asset by that asset's GUID, start with a filter.
- Within the filter run a term query.
- And specifically filter by the field
entityId
in the index.
By qualifiedName¶
To request the history of an asset by qualifiedName:
Build the query by qualifiedName | |
---|---|
1 2 3 4 |
|
- Create a request for the history of an asset, by its qualifiedName.
- Specify the type of the asset and qualifiedName of the asset.
- Specify the amount of history (maximum number of activities). This will be in reverse-chronological order (most recent entries first).
- Build the request.
Build the query by qualifiedName | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
- Create a request for the history of an asset, by its qualifiedName.
- Specify the type of the asset
- Specify the qualifiedName of the asset.
- Specify the amount of history (maximum number of activities). This will be in reverse-chronological order (most recent entries first).
Bool query contents | |
---|---|
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
- To retrieve history for a specific asset by that asset's qualifiedName, you need to combine several conditions.
- You need a term query for both conditions.
- One condition you must provide is for the
entityQualifiedName
, giving the qualifiedName of the asset for which you want to retrieve history. - You also need to define the
typeName
of the asset for which you want to retrieve history, when retrieving by qualifiedName.
Run the search¶
To now run the search, we call the search()
method against our request object:
Run the search | |
---|---|
5 6 7 |
|
- The
getCount()
method gives the total number of activities. Note that this could be smaller than the number requested, if fewer activities have occurred against the asset than the number used in the request. - The details of each activity can be accessed through the
getEntityAudits()
method on the response.
Run the search | |
---|---|
17 18 |
|
- The
total_count
property gives the total number of activities. Note that this could be smaller than the number requested, if fewer activities have occurred against the asset than the number used in the request.
POST /api/meta/entity/auditSearch | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
- Replace the contents of the
bool
portion of the query with the appropriate snippet from the earlier steps. - You must set
track_total_hits
totrue
if you want an exact count of the number of results (in particular for pagination).
Review details of each activity¶
Each EntityAudit
entry contains details of what occurred during an activity.
Contextual details¶
To access contextual details about the activity:
Access contextual details about each activity | |
---|---|
8 9 10 11 12 13 |
|
- You can then iterate through each activity, in reverse-chronological order (most recent first).
- You can access the type of activity through
getAction()
. This will tell you whether attributes were updated on the asset, a classification was added, custom metadata was changed, and so on. - You can access who carried out the activity through
getUser()
. This will give you the username (or API token) that made the change. - You can review when the activity occurred through
getTimestamp()
. This gives an epoch-based time (in milliseconds) for when the activity occurred. - You can also review what specifically changed through the activity, using
getDetail()
. More information on what this includes is in the section below.
Access contextual details about each activity | |
---|---|
19 20 21 22 23 |
|
- You can then iterate through each activity, in reverse-chronological order (most recent first).
- You can access the type of activity through the
action
property. This will tell you whether attributes were updated on the asset, a classification was added, custom metadata was changed, and so on. - You can access who carried out the activity through the
user
property. This will give you the username (or API token) that made the change. - You can review when the activity occurred through then
timestamp
property. This gives an epoch-based time (in milliseconds) for when the activity occurred. - You can also review what specifically changed through the activity, using the
detail
property. More information on what this includes is in the section below.
Response contains contextual details
Each object entry in the entityAudits
portion of the response will contain contextual details about a single activity on the asset.
Details of the change¶
Each detail
of each record in the activity log tells you the details of what specifically changed through one specific activity. This can be one of three kinds of objects:
Action | Detail type | Contents |
---|---|---|
ENTITY_UPDATE , ENTITY_CREATE |
An asset object (the specific subtype, such as Column or Table ) |
What was changed on the asset by the activity. |
CLASSIFICATION_ADD , CLASSIFICATION_DELETE , PROPAGATED_CLASSIFICATION_ADD , PROPAGATED_CLASSIFICATION_DELETE |
A classification object | The classification that was added or removed. |
CUSTOM_METADATA_UPDATE |
A custom metadata object | Which specific custom metadata attributes (and values) were set by the activity. |
For example:
View specific changes made by an activity | |
---|---|
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
- You can safely type-check the detailed object. You could generically use
Asset
here instead ofTable
, but if you know the type of asset you've requested the history for then the detailed object should be the same detailed type. - Once you've type-checked it, you can then coerce it.
- From there you can access any properties. Note that only properties actually set by the activity will have values in this detail object. So in this example, only if the description was actually changed to a new value would the
description
variable now have any content. - This also means that if a field was actually removed (or cleared) by an activity you won't be able to distinguish that by just attempting to retrieve it. (It will be
null
whether it was removed by the activity or simply wasn't changed by the activity.) To distinguish what was actually removed by an activity, you need to usegetNullFields()
. The set returned by this method will contain the names of any fields that were actually removed (cleared) by the activity. - You can then take whatever action you like if a field was removed (cleared) by checking for its existence within the
getNullFields()
set. - You can type-check the detailed object to see if it is a classification.
- Once you've type-checked it, you can then coerce it.
- You can access the classification name using
getTypeName()
. - You can then compare this human-readable classification name to your expectations to take whatever action you like.
- You can type-check the detailed object to see if it details changes to custom metadata.
- Once you've type-checked it, you can then coerce it.
- You can access the name of the custom metadata using
getTypeName()
. - You can retrieve which custom metadata attributes were changed using
getAttributes()
. Since the result is a map, it will only contain attributes that were changed. If an attribute was removed (cleared) it will have a null value in the map but the name of the attribute will still be a key in the map. If a custom metadata attribute was not changed by the activity, it will not be a key in this map. - You can then compare these human-readable names to your expectations to take whatever action you like.
View specific changes made by an activity | |
---|---|
24 25 26 27 28 29 30 31 32 33 34 35 |
|
- You can safely type-check the detailed object. You could generically use
Asset
here instead ofTable
, but if you know the type of asset you've requested the history for then the detailed object should be the same detailed type. - From there you can access any properties. Note that only properties actually set by the activity will have values in this detail object. So in this example, only if the description was actually changed to a new value would the
description
variable now have any content. - You can then take whatever action you like
- You can type-check the detailed object to see if it is a 'AtlanTag'.
- You can access the 'AtlanTag' name using `type_name' property.
- You can then compare this human-readable classification name to your expectations to take whatever action you like.
- You can type-check the detailed object to see if it details changes to custom metadata.
- You can access the name of the custom metadata using then
type_name
attribute. - You can retrieve which custom metadata attributes were changed using the
attributes
propery. Since the result is a dict, it will only contain attributes that were changed. If an attribute was removed (cleared) it will have a null value in the dict but the name of the attribute will still be a key in the map. If a custom metadata attribute was not changed by the activity, it will not be a key in this map. - You can then compare these human-readable names to your expectations to take whatever action you like.
You will need to implement your own detection and inference
The key point to note is that the format of the object within the detail
of each record will vary, depending on the type of activity that occurred. You will therefore need to implement your own logic for detecting and inferring what kind of details are included when retrieving these from a raw API response.