Skip to content

Commit

Permalink
add AuditLog Queries capabilities
Browse files Browse the repository at this point in the history
kaleming authored and MariusWirtz committed Jan 26, 2021
1 parent 31d8925 commit 3771dad
Showing 2 changed files with 58 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ TM1py offers handy features to interact with TM1 from Python, such as
- Execute loose statements of TI
- CRUD features for TM1 objects (cubes, dimensions, subsets, etc.)
- Query and kill threads
- Query MessageLog and TransactionLog
- Query MessageLog, TransactionLog and AuditLog
- Generate MDX Queries from existing cube views

Requirements
57 changes: 57 additions & 0 deletions TM1py/Services/ServerService.py
Original file line number Diff line number Diff line change
@@ -60,6 +60,22 @@ def execute_transaction_log_delta_request(self, **kwargs) -> Dict:
self.tlog_last_delta_request = response.text[response.text.rfind("TransactionLogEntries/!delta('"):-2]
return response.json()['value']

@odata_track_changes_header
def initialize_audit_log_delta_requests(self, filter=None, **kwargs):
url = "/api/v1/AuditLogEntries"
if filter:
url += "?$filter={}".format(filter)
response = self._rest.GET(url=url, **kwargs)
# Read the next delta-request-url from the response
self.tlog_last_delta_request = response.text[response.text.rfind("AuditLogEntries/!delta('"):-2]

@odata_track_changes_header
def execute_audit_log_delta_request(self, **kwargs) -> Dict:
response = self._rest.GET(url="/api/v1/" + self.tlog_last_delta_request, **kwargs)
self.tlog_last_delta_request = response.text[response.text.rfind("AuditLogEntries/!delta('"):-2]
return response.json()['value']


@odata_track_changes_header
def initialize_message_log_delta_requests(self, filter=None, **kwargs):
url = "/api/v1/MessageLogEntries"
@@ -184,6 +200,47 @@ def get_transaction_log_entries(self, reverse: bool = True, user: str = None, cu
url += '&$top={}'.format(top)
response = self._rest.GET(url, **kwargs)
return response.json()['value']

@require_admin
def get_audit_log_entries(self, user: str = None, object_type: str = None, object_name: str = None,
since: datetime = None, until: datetime = None, top: int = None, **kwargs) -> Dict:
"""
:param reverse: Boolean
:param user: UserName
:param object_type: ObjectType
:param object_name: ObjectName
:param since: of type datetime. If it doesn't have tz information, UTC is assumed.
:param until: of type datetime. If it doesn't have tz information, UTC is assumed.
:param top: int
:return:
"""

url = '/api/v1/AuditLogEntries?$expand=AuditDetails'
# filter on user, object_type, object_name and time
if user or since or until:
log_filters = []
if user:
log_filters.append(format_url("UserName eq '{}'", user))
if object_type:
log_filters.append(format_url("ObjectType eq '{}'", object_type))
if object_name:
log_filters.append(format_url("ObjectName eq '{}'", object_name))
if since:
# If since doesn't have tz information, UTC is assumed
if not since.tzinfo:
since = self.utc_localize_time(since)
log_filters.append(format_url("TimeStamp ge {}", since.strftime("%Y-%m-%dT%H:%M:%SZ")))
if until:
# If until doesn't have tz information, UTC is assumed
if not until.tzinfo:
until = self.utc_localize_time(until)
log_filters.append(format_url("TimeStamp le {}", until.strftime("%Y-%m-%dT%H:%M:%SZ")))
url += "&$filter={}".format(" and ".join(log_filters))
# top limit
if top:
url += '&$top={}'.format(top)
response = self._rest.GET(url, **kwargs)
return response.json()['value']

@require_admin
def get_last_process_message_from_messagelog(self, process_name: str, **kwargs) -> Optional[str]:

0 comments on commit 3771dad

Please sign in to comment.