[audit_trail_knowledge_objects_query] alert.track = 0 search = ```Firstly filter out capability checks and non CRUD, non knowledge objects audit logs```\ index=_audit ```| where isnull(cap) AND NOT info IN ("granted", "denied")``` | search action IN ("create_*", "update_*", "updated_*", "edit_*", "remove_*", "delete_*", "disable_*", "new_*", "move_*", "enable_*", "acl_*") | search action IN ("*_user", "*_saved_search", "*_data_model_file", "*_event_type", "*_tag", "*_fields_*", "*_lookup_table", "*_ui_view*", "*_ui_panel", "*_macro", "*_command")\ ```Filter out audit v2 logs```\ | search sourcetype="audittrail"\ ```Extract object type and action```\ | rex action="(?[a-zA-Z]+)_(?[a-zA-Z_]*),"\ ```Extract application name```\ | rex field=info "app=\"(?.*)\"" \ | eval appnametmp=IF(!isnull(apptmp),apptmp,IF(isnull(app),"-missing-",app) )\ | rex field=appnametmp "'(?.*)'" \ | eval appname=IF(!isnull(apptmp2),apptmp2,appnametmp) \ ```Unify object name```\ | eval name=IF(object_type="user",username,name) \ | eval name=IF(object_type="saved_search",savedsearch_name,name)\ | eval name=IF(!isnull(name),name,"-missing-")\ ```Tags may have mnulti values: {[0]='tag_1' [1]='tag_2'}- split it to separate events```\ | eval tagnames=split(replace(name, "\\[[0-9]*\\]=",""), "' '") | mvexpand tagnames | eval name=ltrim(rtrim(tagnames,"'}"),"{'")\ ```Extract host name from fqdn```\ | eval host=mvindex(split(host,"."),0)\ ```Finally rename object type and actions to user friendly ones```\ | lookup object_types_normalization ORIG_OBJECT_TYPE AS object_type OUTPUT DEST_OBJECT_TYPE AS object_type\ | lookup action_types_normalization ORIG_ACTION AS object_action OUTPUT DEST_ACTION AS object_action\ ```Preserve original event body```\ | eval orig_body=_raw\ ```Apply filtering in the base search to avoid 'unknown sid' issue```\ ```| where "text_token$"="-" OR orig_body like "%text_token$%"``` \ | stats count by _time, user, action, name, appname, host, info, object_type, object_action, orig_body