Accessing log records

Adaxes stores log records in a database. To retrieve log records, you can execute SQL queries directly on the database, or use Adaxes API to get records via Adaxes service.

Using Adaxes API

Using API, you don't need to have access to the database itself, but it limits you to only get the General Log of operations, operations performed by a specific user, and log of operations performed on a specific object.

You can use interfaces provided by Adaxes API to get log records from the General Log, customize the Logging settings, get user's Action Log, and any object's Modification Log.

Accessing the General Log

The General Log contains records of all operations performed via Adaxes. To get log records from the General Log, first you need to bind to a directory object that represents the General Log. The directory object is located in the Adaxes Configuration Server (ADAM or AD LDS). The object implements the IAdmServiceLog interface, using which you can customize the Logging settings, and get access to the log records.

Use the GeneralLog property of the IAdmServiceLog interface to get the log records from the General Log. The GeneralLog property exposes the IAdmGeneralLog interface.

  • Set the StartDateTime and EndDateTime properties of the IAdmGeneralLog interface, if you want to get log records that occurred within a given time range.

  • Use the Log property of the IAdmGeneralLog interface to get the log records. The Log property exposes the IAdmLog interface.

    Use the RecordCount property of the IAdmLog interface to get the number of log records.

    Log records can be retrieved in pages. To enable paging, specify the number of records per page in the PageSize property of the IAdmLog interface. To get the number of pages, use the PageCount property of the IAdmLog interface.

    To get log records, call the GetPage method of the IAdmLog interface and pass the page index as the parameter of the method. If paging is not enabled, pass 0 to the method.

    A collection of log records is represented by the IAdmLogRecords interface. A log record is represented by the IAdmLogRecord interface.

The following example outputs log records occurred during last 30 days.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$numDays = 30 # set to 0 to output all records

$ns = New-Object("Softerra.Adaxes.Adsi.AdmNamespace")
$service = $ns.GetServiceDirectly("localhost")

# Bind to the directory object representing the General Log
$path = $service.Backend.GetConfigurationContainerPath("ServiceLog")
$serviceLog = $service.OpenObject($path.ToString(), $null, $null, 0)

$generalLog = $serviceLog.GeneralLog
if ($numDays -ne 0)
{
$generalLog.StartDateTime = (Get-Date).AddDays(-$numDays)
$generalLog.EndDateTime = Get-Date
}

# Get the log records
$log = $generalLog.Log
$records = $log.GetPage(0)

# Output the log records
foreach ($record in $records)
{
    Write-Host "Start Time:" $record.StartTime
    Write-Host "Completion Time:" $record.CompletionTime
    Write-Host "Initiator:" $record.Initiator.Name
    Write-Host "Target Object:" $record.TargetObjectName
    Write-Host "Target Object Type:" $record.TargetObjectType
    Write-Host "Operation:" $record.Description
    Write-Host
}
C#
using System;
using Interop.Adsi.Logging;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
static void Main(string[] args)
{
    const int numDays = 30; // set to 0 to output all records

    // Connect to the Adaxes service
    AdmNamespace ns = new AdmNamespace();
    IAdmService service = ns.GetServiceDirectly("localhost");

    // Bind to the directory object representing the General Log
    string path = service.Backend.GetConfigurationContainerPath(
        "ServiceLog");
    IAdmServiceLog serviceLog =
        (IAdmServiceLog)service.OpenObject(path, null, null, 0);

    IAdmGeneralLog generalLog = serviceLog.GeneralLog;
    if (numDays != 0)
    {
        generalLog.StartDateTime = DateTime.Now.AddDays(-numDays);
        generalLog.EndDateTime = DateTime.Now;
    }

    // Get the log records
    IAdmLog log = generalLog.Log;
    IAdmLogRecords records = log.GetPage(0);

    // Output the log records
    foreach (IAdmLogRecord record in records)
    {
        Console.WriteLine("Start Time: " + record.StartTime);
        Console.WriteLine("Completion Time: " + record.CompletionTime);
        Console.WriteLine("Initiator: " + record.Initiator.Name);
        IAdmLogRecord record2 = (IAdmLogRecord) record;
        Console.WriteLine("Target Object: " + record2.TargetObjectName);
        Console.WriteLine("Target Object Type: " + record2.TargetObjectType);
        Console.WriteLine("Operation: " + record.Description);
        Console.WriteLine(string.Empty);
    }
}
}

Getting operations performed by a specific user

To get a log of operations performed by a specific user, first you need to bind to the user object. All user objects implement the IAdmUser interface. Use the GetActionLog method of the interface to get the Action Log of the user. The Action Log is represented by the IAdmActionLog interface.

The following example outputs information about all operations performed by a specific user on group objects.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$ns = New-Object("Softerra.Adaxes.Adsi.AdmNamespace")
$service = $ns.GetServiceDirectly("localhost")

# Bind to the user object
$userDN = "CN=John Smith,CN=Users,DC=company,DC=com"
$user = $service.OpenObject("Adaxes://$userDN", $null, $null, 0)

# Get the log records
$actionLog = $user.GetActionLog()
$log = $actionLog.Log


$records = $log.GetPage(0)

# Output the log records
foreach ($record in $records)
{
if (-not($record.TargetObjectType -ieq "group"))
{
    continue;
}

    Write-Host "Start Time:" $record.StartTime
    Write-Host "Completion Time:" $record.CompletionTime
    Write-Host "Group Name:" $record.TargetObjectName
    Write-Host "Operation:" $record.Description
    Write-Host
}
C#
using System;
using Interop.Adsi.Logging;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        // Connect to the Adaxes service
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to the user object
        const string userDN = "CN=John Smith,CN=Users,DC=company,DC=com";
        IAdmUser user = (IAdmUser)service.OpenObject(
            "Adaxes://" + userDN, null, null, 0);

        // Get the log records
        IAdmActionLog actionLog = user.GetActionLog();
        IAdmLog log = actionLog.Log;
        IAdmLogRecords records = log.GetPage(0);

        // Output the log records
        foreach (IAdmLogRecord record in records)
        {
            IAdmLogRecord record2 = (IAdmLogRecord) record;
            if (!StringComparer.OrdinalIgnoreCase.Equals(
                record2.TargetObjectType, "group"))
            {
                continue;
            }

            Console.WriteLine("Start Time: " + record.StartTime);
            Console.WriteLine("Completion Time: " + record.CompletionTime);
            Console.WriteLine("Group Name: " + record2.TargetObjectName);
            Console.WriteLine("Operation: " + record.Description);
            Console.WriteLine(string.Empty);
        }

        Console.ReadLine();
    }
}

Getting operations performed on a specific object

To get a log of operations performed on a specific directory object, first you need to bind to the object. All directory objects implement the IAdmTop interface. Use the GetModificationLog method of the interface to get the Modification Log of the object. The Modification Log is represented by the IAdmModificationLog interface.

The following example outputs information about all operations performed on a specific group.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$ns = New-Object("Softerra.Adaxes.Adsi.AdmNamespace")
$service = $ns.GetServiceDirectly("localhost")

# Bind to the group object
$groupDN = "CN=My Group,DC=company,DC=com"
$group = $service.OpenObject("Adaxes://$groupDN", $null, $null, 0)

# Get the log records
$modificationLog = $group.GetModificationLog()
$log = $modificationLog.Log
$records = $log.GetPage(0)

# Output the log records
foreach ($record in $records)
{
    Write-Host "Start Time:" $record.StartTime
    Write-Host "Completion Time:" $record.CompletionTime
    Write-Host "Initiator:" $record.Initiator.Name
    Write-Host "Operation:" $record.Description
    Write-Host
}
C#
using System;
using Interop.Adsi;
using Interop.Adsi.Logging;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        // Connect to the Adaxes service
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to the group object
        const string groupDN = "CN=My Group,DC=company,DC=com";
        IAdmTop group = (IAdmTop)service.OpenObject(
            "Adaxes://" + groupDN, null, null, 0);

        // Get the log records
        IAdmModificationLog actionLog = group.GetModificationLog();
        IAdmLog log = actionLog.Log;
        IAdmLogRecords records = log.GetPage(0);

        // Output the log records
        foreach (IAdmLogRecord record in records)
        {
            Console.WriteLine("Start Time: " + record.StartTime);
            Console.WriteLine("Completion Time: " + record.CompletionTime);
            Console.WriteLine("Initiator: " + record.Initiator.Name);
            Console.WriteLine("Operation: " + record.Description);
            Console.WriteLine(string.Empty);
        }
    }
}

Using SQL queries

Adaxes stores log records in a local or external database. To determine which database is used, refer to the Adaxes service settings.

If log records are stored in the local SQLite database, you can use, for example, an SQLite database management tool to access them.

The database storage file is called AdaxesLog.db3 and is located in the LogDB subfolder of the folder where the Adaxes service is installed, which is C:\Program Files\Softerra\Adaxes 3\Service by default.

An external SQL Server database can be accessed, for instance, using a SQL Server database management tool, such as SQL Server Management Studio.

Example 1 – Query operations executed from 07/21/2013 to the current date

SELECT TargetObjectName, OperationCompletionTime, OperationDescriptionXML, OperationState
FROM Operations, TargetObjects
WHERE TargetObjectID = TargetObjectRef AND 
      OperationCompletionTime BETWEEN '07/21/2013' AND GETDATE()

Example 2 – Query operations performed on a specific group

SELECT InitiatorName, OperationDescriptionXML, OperationCompletionTime 
FROM Operations, TargetObjects, Initiators
WHERE TargetObjectID = TargetObjectRef AND 
      InitiatorID = InitiatorRef AND 
      TargetObjectName = 'My Group'

Example 3 – Query operations performed by a user, whose name starts with John Smith

SELECT TargetObjectName, OperationDescriptionXML, OperationCompletionTime 
FROM Operations, Initiators, TargetObjects
WHERE InitiatorID = InitiatorRef AND 
      TargetObjectID = TargetObjectRef AND 
      InitiatorName LIKE 'John Smith%'

Example 4 – Query all operations that performed the delete action

SELECT InitiatorName, TargetObjectName, OperationCompletionTime, OperationState
FROM Operations, Initiators, TargetObjects, OperationTypes, Operations2OperationTypes
WHERE InitiatorID = InitiatorRef AND
      TargetObjectID = TargetObjectRef AND
      OperationID = OperationRef AND
      OperationTypeID = OperationTypeRef AND
      OperationTypeName = 'delete'

Example 5 – Query all operations that failed

SELECT OperationCompletionTime, OperationDescriptionXML
FROM Operations
WHERE OperationState = 5 OR OperationState = 6 /* Failed operation */
        

Example 6 – Query all operations executed on Adaxes service hosted on adaxesserver.example.com

SELECT TargetObjectName, OperationCompletionTime, OperationDescriptionXML, OperationState
FROM Operations, Services, TargetObjects
WHERE TargetObjectID = TargetObjectRef AND
      ServiceID = ServiceRef AND
      ServiceHost = 'adaxesserver.example.com'

See also