10.2.4. Querying the Reconciliation Audit Log

Reconciliation operations are logged in the file /path/to/openidm/audit/recon.csv and in the repository. You can read and query the reconciliation audit logs over the REST interface as outlined in the following examples.

By default all audit/recon query responses are formatted based on the entryType of the entry. Fields that are not required for the specific entry type are stripped away from the response. For example, a summary entry would not need to include a null targetObjectId field, as this field would not make sense in the context of a summary. You can specify that this auto-formatting be disabled and return the full entry for all entry types. To disable entry formatting, include formatted=false as a query parameter in the request.

To return all reconciliation operations logged in the audit log, run a RESTful GET on the audit/recon endpoint. For example:

$ curl
 --header "X-OpenIDM-Username: openidm-admin"
 --header "X-OpenIDM-Password: openidm-admin"
 --request GET
 "http://localhost:8080/openidm/audit/recon"

The following code sample shows an extract of the audit log after the first reconciliation operation in Sample 1.

{
  "entries": [
    {
      "rootActionId": "d0578abf-f38e-4ede-a7dc-5ee9eaa8ce53",
      "messageDetail": null,
      "message": "Reconciliation initiated by openidm-admin",
      "timestamp": "2013-05-08T07:58:33.296Z",
      "reconId": "5cf09dfa-e85c-4d52-ab6c-8ba7c2e3d34f",
      "entryType": "start",
      "_id": "11381e20-3679-469d-a71c-c557c2bd091e",
      "status": "SUCCESS",
      "exception": "",
      "mapping": "systemXmlfileAccounts_managedUser"
    },
    {
      "messageDetail": null,
      "rootActionId": "d0578abf-f38e-4ede-a7dc-5ee9eaa8ce53",
      "situation": "ABSENT",
      "actionId": "86995423-8a43-4fc7-9c3c-9e450e0234cb",
      "targetObjectId": "managed/user/scarter",
      "action": "CREATE",
      "entryType": "",
      "_id": "9f59bb8a-31c6-41af-8f27-02094391ba0c",
      "reconId": "5cf09dfa-e85c-4d52-ab6c-8ba7c2e3d34f",
      "status": "SUCCESS",
      "exception": "",
      "reconciling": "source",
      "ambiguousTargetObjectIds": "",
      "timestamp": "2013-05-08T07:58:33.791Z",
      "message": null,
      "sourceObjectId": "system/xmlfile/account/scarter"
    },
    {
      "messageDetail": null,
      "rootActionId": "d0578abf-f38e-4ede-a7dc-5ee9eaa8ce53",
      "situation": "ABSENT",
      "actionId": "dea9b5c5-7a75-4cab-b8e4-176bea0a94a6",
      "targetObjectId": "managed/user/bjensen",
      "action": "CREATE",
      "entryType": "",
      "_id": "4fd285ef-a409-4875-abd0-5d70965fe172",
      "reconId": "5cf09dfa-e85c-4d52-ab6c-8ba7c2e3d34f",
      "status": "SUCCESS",
      "exception": "",
      "reconciling": "source",
      "ambiguousTargetObjectIds": "",
      "timestamp": "2013-05-08T07:58:33.793Z",
      "message": null,
      "sourceObjectId": "system/xmlfile/account/bjensen"
      },
      {
        "rootActionId": "d0578abf-f38e-4ede-a7dc-5ee9eaa8ce53",
        "messageDetail": {
          "ended": "2013-05-08T07:58:33.813Z",
          "started": "2013-05-08T07:58:33.294Z",
          "situationSummary": {
            "SOURCE_MISSING": 0,
            "FOUND": 0,
            "SOURCE_IGNORED": 0,
            "UNQUALIFIED": 0,
            "UNASSIGNED": 0,
            "TARGET_IGNORED": 0,
            "CONFIRMED": 0,
            "AMBIGUOUS": 0,
            "ABSENT": 2,
            "MISSING": 0
          },
          "progress": {
            "links": {
              "created": 2,
              "existing": {
                "total": "0",
                "processed": 0
              }
            },
            "target": {
              "created": 2,
              "existing": {
                "total": "0",
                "processed": 0
              }
            },
            "source": {
              "existing": {
                "total": "2",
                "processed": 2
              }
            }
          },
          "stageDescription": "reconciling target entries",
          "stage": "ACTIVE_RECONCILING_TARGET",
          "state": "ACTIVE",
          "mapping": "systemXmlfileAccounts_managedUser"
        },
        "message": "SOURCE_IGNORED: 0 MISSING: 0 FOUND: 0 AMBIGUOUS: 0 UNQUALIFIED: 0
           CONFIRMED: 0 SOURCE_MISSING: 0 ABSENT: 2 TARGET_IGNORED: 0 UNASSIGNED: 0 ",
        "timestamp": "2013-05-08T07:58:33.813Z",
        "reconId": "5cf09dfa-e85c-4d52-ab6c-8ba7c2e3d34f",
        "entryType": "summary",
        "_id": "a8a81f9f-fa8f-49f4-a0d6-c88b5fc4be2a",
        "status": "SUCCESS",
        "exception": "",
        "mapping": "systemXmlfileAccounts_managedUser"
      }
    ]
}

Most of the fields in this audit log are self-explanatory. Each distinct reconciliation operation is identified by its reconId. Each entry in the log is identified by a unique _id. The first log entry indicates the status for the complete reconciliation operation. Successive entries indicate the status for each record affected by the reconciliation.

To obtain information on a specific audit log entry, include its entry _id in the endpoint. For example:

$ curl
 --header "X-OpenIDM-Username: openidm-admin"
 --header "X-OpenIDM-Password: openidm-admin"
 --request GET
 "http://localhost:8080/openidm/audit/recon/9f59bb8a-31c6-41af-8f27-02094391ba0c"

The following sample output shows the results of a read operation on a specific reconciliation audit entry.

{
 "messageDetail": null,
 "rootActionId": "d0578abf-f38e-4ede-a7dc-5ee9eaa8ce53",
 "situation": "ABSENT",
 "actionId": "86995423-8a43-4fc7-9c3c-9e450e0234cb",
 "targetObjectId": "managed/user/scarter",
 "action": "CREATE",
 "entryType": "",
 "_id": "9f59bb8a-31c6-41af-8f27-02094391ba0c",
 "reconId": "5cf09dfa-e85c-4d52-ab6c-8ba7c2e3d34f",
 "status": "SUCCESS",
 "exception": "",
 "reconciling": "source",
 "ambiguousTargetObjectIds": "",
 "timestamp": "2013-05-08T07:58:33.791Z",
 "message": null,
 "sourceObjectId": "system/xmlfile/account/scarter"
}

To query the audit log for a particular reconciliation operation, use the audit-by-recon-id keyword, specifying the reconciliation ID, as follows:

$ curl
 --header "X-OpenIDM-Username: openidm-admin"
 --header "X-OpenIDM-Password: openidm-admin"
 --request GET
 "http://localhost:8080/openidm/audit/recon/?_queryId=audit-by-recon-id&reconId=<reconID>"

Output similar to the following is returned, for the specified reconciliation operation:

{
  "start": {
    "rootActionId": "3c098d6f-a5e5-483c-a8ce-82911a10b0a9",
    "messageDetail": null,
    "message": "Reconciliation initiated by openidm-admin",
    "timestamp": "2013-05-14T08:20:41.343Z",
    "reconId": "1ef8e7b6-33dc-4f92-810a-b51913508a68",
    "entryType": "start",
    "_id": "ce58ef39-425d-4711-94b9-a9c77df23001",
    "status": "SUCCESS",
    "exception": "",
    "mapping": "systemXmlfileAccounts_managedUser"
  },
  "result": [
    {
      "messageDetail": null,
      "rootActionId": "3c098d6f-a5e5-483c-a8ce-82911a10b0a9",
      "situation": "ABSENT",
      "actionId": "1a391fe8-201b-4f59-ad05-92ee804488a8",
      "targetObjectId": "managed/user/scarter",
      "action": "CREATE",
      "entryType": "",
      "_id": "6dc0a18a-826d-487d-a29f-5cd8d2f55465",
      "reconId": "1ef8e7b6-33dc-4f92-810a-b51913508a68",
      "status": "SUCCESS",
      "exception": "",
      "reconciling": "source",
      "ambiguousTargetObjectIds": "",
      "timestamp": "2013-05-14T08:20:41.763Z",
      "message": null,
      "sourceObjectId": "system/xmlfile/account/scarter"
    },
    {
      "messageDetail": null,
      "rootActionId": "3c098d6f-a5e5-483c-a8ce-82911a10b0a9",
      "situation": "ABSENT",
      "actionId": "0aaba292-1dd3-4e98-a0e2-04bec9ae5209",
      "targetObjectId": "managed/user/bjensen",
      "action": "CREATE",
      "entryType": "",
      "_id": "1cda457e-54e2-451b-8a40-ef93dec7e60c",
      "reconId": "1ef8e7b6-33dc-4f92-810a-b51913508a68",
      "status": "SUCCESS",
      "exception": "",
      "reconciling": "source",
      "ambiguousTargetObjectIds": "",
      "timestamp": "2013-05-14T08:20:41.760Z",
      "message": null,
      "sourceObjectId": "system/xmlfile/account/bjensen"
    }
  ],
  "summary": {
    "rootActionId": "3c098d6f-a5e5-483c-a8ce-82911a10b0a9",
    "messageDetail": {
      "ended": "2013-05-14T08:20:41.783Z",
      "started": "2013-05-14T08:20:41.342Z",
      "situationSummary": {
        "SOURCE_MISSING": 0,
        "FOUND": 0,
        "SOURCE_IGNORED": 0,
        "UNQUALIFIED": 0,
        "UNASSIGNED": 0,
        "TARGET_IGNORED": 0,
        "CONFIRMED": 0,
        "AMBIGUOUS": 0,
        "ABSENT": 2,
        "MISSING": 0
      },
      "progress": {
        "links": {
          "created": 2,
          "existing": {
            "total": "0",
            "processed": 0
          }
        },
        "target": {
          "created": 2,
          "existing": {
            "total": "0",
            "processed": 0
          }
        },
        "source": {
          "existing": {
            "total": "2",
            "processed": 2
          }
        }
      },
      "stageDescription": "reconciling target entries",
      "stage": "ACTIVE_RECONCILING_TARGET",
      "state": "ACTIVE",
      "mapping": "systemXmlfileAccounts_managedUser"
    },
    "message": "SOURCE_IGNORED: 0 MISSING: 0 FOUND: 0 AMBIGUOUS: 0 UNQUALIFIED: 0
       CONFIRMED: 0 SOURCE_MISSING: 0 ABSENT: 2 TARGET_IGNORED: 0 UNASSIGNED: 0 ",
    "timestamp": "2013-05-14T08:20:41.783Z",
    "reconId": "1ef8e7b6-33dc-4f92-810a-b51913508a68",
    "entryType": "summary",
    "_id": "94c5893c-4ea8-4464-aff2-5533d6369722",
    "status": "SUCCESS",
    "exception": "",
    "mapping": "systemXmlfileAccounts_managedUser"
  }
}

Note that the response structure of a read request on audit/recon differs from the response structure of a query by recon-id. The read response contains a flat list of entries. The query response separates the summary and start event type entries. Other entries are listed under the result entry.

To query the audit log for a specific reconciliation situation, use the audit-by-recon-id-situation keyword, specifying the reconciliation ID and the situation that you want to query. For example, the following query returns all ABSENT records found during the specified reconciliation operation:

$ curl
 --header "X-OpenIDM-Username: openidm-admin"
 --header "X-OpenIDM-Password: openidm-admin"
 --request GET
 "http://localhost:8080/openidm/audit/recon?_queryId=audit-by-recon-id-situation&situation=
 ABSENT&reconId=fd2a59df-1fcd-444d-97ca-2c8a7ec6dc6c"

Output similar to the following is returned, with one entry for each record that matches the situation queried:

{
  "result": [
    {
      "messageDetail": null,
      "rootActionId": "3c098d6f-a5e5-483c-a8ce-82911a10b0a9",
      "situation": "ABSENT",
      "actionId": "1a391fe8-201b-4f59-ad05-92ee804488a8",
      "targetObjectId": "managed/user/scarter",
      "action": "CREATE",
      "entryType": "",
      "_id": "6dc0a18a-826d-487d-a29f-5cd8d2f55465",
      "reconId": "1ef8e7b6-33dc-4f92-810a-b51913508a68",
      "status": "SUCCESS",
      "exception": "",
      "reconciling": "source",
      "ambiguousTargetObjectIds": "",
      "timestamp": "2013-05-14T08:20:41.763Z",
      "message": null,
      "sourceObjectId": "system/xmlfile/account/scarter"
    },
    {
      "messageDetail": null,
      "rootActionId": "3c098d6f-a5e5-483c-a8ce-82911a10b0a9",
      "situation": "ABSENT",
      "actionId": "0aaba292-1dd3-4e98-a0e2-04bec9ae5209",
      "targetObjectId": "managed/user/bjensen",
      "action": "CREATE",
      "entryType": "",
      "_id": "1cda457e-54e2-451b-8a40-ef93dec7e60c",
      "reconId": "1ef8e7b6-33dc-4f92-810a-b51913508a68",
      "status": "SUCCESS",
      "exception": "",
      "reconciling": "source",
      "ambiguousTargetObjectIds": "",
      "timestamp": "2013-05-14T08:20:41.760Z",
      "message": null,
      "sourceObjectId": "system/xmlfile/account/bjensen"
    }
  ]
}

The activity logs track all operations on internal (managed) and external (system) objects. Entries in the activity log contain identifiers for the reconciliation or synchronization action that triggered the activity, and for the original caller and the relationships between related actions.

You can access the activity logs over REST with the following call:

$ curl
 --header "X-OpenIDM-Username: openidm-admin"
 --header "X-OpenIDM-Password: openidm-admin"
 --request GET
 "http://localhost:8080/openidm/audit/activity"

The following extract of the activity log shows the last entry in the log, which was a password change for user bjensen.

{
  "entries": [
    {
      "rootActionId": "3c098d6f-a5e5-483c-a8ce-82911a10b0a9",
      "action": "create",
      "objectId": "managed/user/bjensen",
      "_rev": "0",
      "_id": "22ef6d20-bd84-4267-9db8-745825a46ad1",
      "timestamp": "2013-05-14T08:20:41.712Z",
      "message": null,
      "activityId": "aa964020-b343-4d23-8e00-745ed4b79f50",
      "parentActionId": "0aaba292-1dd3-4e98-a0e2-04bec9ae5209",
      "requester": "openidm-admin",
      "rev": "0",
      "passwordChanged": true,
      "status": "SUCCESS",
      "before": null,
      "changedFields": [
        "/password"
      ],
      "after": {
        "securityAnswer": {
          "$crypto": {
            "type": "x-simple-encryption",
            "value": {
              "key": "openidm-sym-default",
              "iv": "c6gZKz4sSL2YNTBwwFXIzw==",
              "cipher": "AES/CBC/PKCS5Padding",
              "data": "7FATEBtuLlLfMXGokfLrtJ2rXPEsE1YTIXSoGQCum4w="
            }
          }
        },
       ...

To return activity information for a specific action, include the _id of the action in the endpoint, for example:

$ curl
 --header "X-OpenIDM-Username: openidm-admin"
 --header "X-OpenIDM-Password: openidm-admin"
 --request GET
 "http://localhost:8080/openidm/audit/activity/22ef6d20-bd84-4267-9db8-745825a46ad1"

Results similar to the following are returned:

{
  "rootActionId": "3c098d6f-a5e5-483c-a8ce-82911a10b0a9",
  "action": "create",
  "objectId": "managed/user/bjensen",
  "timestamp": "2013-05-14T08:20:41.712Z",
  "message": null,
  "activityId": "aa964020-b343-4d23-8e00-745ed4b79f50",
  "after": {
    "securityAnswer": {
      "$crypto": {
        "type": "x-simple-encryption",
        "value": {
          "key": "openidm-sym-default",
          "iv": "c6gZKz4sSL2YNTBwwFXIzw==",
          "cipher": "AES/CBC/PKCS5Padding",
          "data": "7FATEBtuLlLfMXGokfLrtJ2rXPEsE1YTIXSoGQCum4w="
        }
      }
    },
    "stateProvince": "",
    "userName": "bjensen@example.com",
    "roles": "openidm-authorized",
    "description": "Created By XML1",
    "accountStatus": "active",
    "password": {
      "$crypto": {
        "type": "x-simple-encryption",
        "value": {
          "key": "openidm-sym-default",
          "iv": "bqhRyLW1lI+KZROcpgyukg==",
          "cipher": "AES/CBC/PKCS5Padding",
          "data": "qO8A76GqNqftVVwOlasyPw=="
        }
      }
    },
    "securityQuestion": "1",
    "givenName": "Barbara",
    "address2": "",
    "lastPasswordAttempt": "Tue May 14 2013 10:20:41 GMT+0200 (SAST)",
    "address1": "",
    "familyName": "Jensen",
    "passwordAttempts": "0",
    "country": "",
    "city": "",
    "_rev": "0",
    "lastPasswordSet": "",
    "postalCode": "",
    "phoneNumber": "1234567",
    "_id": "bjensen",
    "email": "bjensen@example.com"
  },
  "changedFields": [
    "/password"
  ],
  "_id": "22ef6d20-bd84-4267-9db8-745825a46ad1",
  "_rev": "0",
  "parentActionId": "0aaba292-1dd3-4e98-a0e2-04bec9ae5209",
  "requester": "openidm-admin",
  "rev": "0",
  "passwordChanged": true,
  "status": "SUCCESS",
  "before": null
}

Each action in the activity log has a rootActionId and a parentActionId. The rootActionId is the ID that was assigned to the incoming or initiating request. The parentActionId is the ID that is associated with the overall action. So, for example, if an HTTP request invokes a script that changes a user's password, the HTTP request is assigned the rootActionId and the action taken by the script is assigned the parentActionId. You can query the activity log for the details of a specific action by including the parentActionId in the query. For example:

$ curl
 --header "X-OpenIDM-Username: openidm-admin"
 --header "X-OpenIDM-Password: openidm-admin"
 --request GET
 "http://localhost:8080/openidm/audit/activity?_queryId=audit-by-activity-parent-action&
           parentActionId=90ce7473-98c7-4747-bfbb-32bfa3ce5d92"

The following sample output shows the result of a query that requests details of the password change for bjensen.

{
  "result": [
    {
      "rootActionId": "3c098d6f-a5e5-483c-a8ce-82911a10b0a9",
      "action": "create",
      "objectId": "managed/user/bjensen",
      "_rev": "0",
      "_id": "22ef6d20-bd84-4267-9db8-745825a46ad1",
      "timestamp": "2013-05-14T08:20:41.712Z",
      "message": null,
      "activityId": "aa964020-b343-4d23-8e00-745ed4b79f50",
      "parentActionId": "0aaba292-1dd3-4e98-a0e2-04bec9ae5209",
      "requester": "openidm-admin",
      "rev": "0",
      "passwordChanged": true,
      "status": "SUCCESS",
      "before": null,
      "changedFields": [
        "/password"
      ],
      "after": {
        "securityAnswer": {
          "$crypto": {
            "type": "x-simple-encryption",
            "value": {
              "key": "openidm-sym-default",
              "iv": "c6gZKz4sSL2YNTBwwFXIzw==",
              "cipher": "AES/CBC/PKCS5Padding",
              "data": "7FATEBtuLlLfMXGokfLrtJ2rXPEsE1YTIXSoGQCum4w="
            }
          }
        },
        "stateProvince": "",
        "userName": "bjensen@example.com",
        "roles": "openidm-authorized",
        "description": "Created By XML1",
        "accountStatus": "active",
        "password": {
          "$crypto": {
            "type": "x-simple-encryption",
            "value": {
              "key": "openidm-sym-default",
              "iv": "bqhRyLW1lI+KZROcpgyukg==",
              "cipher": "AES/CBC/PKCS5Padding",
              "data": "qO8A76GqNqftVVwOlasyPw=="
            }
          }
        },
        "securityQuestion": "1",
        "givenName": "Barbara",
        "address2": "",
        "lastPasswordAttempt": "Tue May 14 2013 10:20:41 GMT+0200 (SAST)",
        "address1": "",
        "familyName": "Jensen",
        "passwordAttempts": "0",
        "country": "",
        "city": "",
        "_rev": "0",
        "lastPasswordSet": "",
        "postalCode": "",
        "phoneNumber": "1234567",
        "_id": "bjensen",
        "email": "bjensen@example.com"
      }
    }
  ]
}
[Note] Note

For audit logs in the repository, you can define custom queries using the parameterized query mechanism. For more information, see the section on Parameterized Queries

For more information about the entries in these logs, see the chapter that covers Using Audit Logs.