Skip to content

Binary Log Format

This page documents the binary structure of .aaLog files written by Archestra / System Platform. The aaLogReader library parses these files to extract log records.

File Structure

Each .aaLog file consists of:

  1. A fixed-size file header containing metadata
  2. A sequence of variable-length log records

All multi-byte integers are little-endian. String fields are encoded as UTF-16LE (Unicode) with null terminators. Fields are separated by two null bytes (0x00 0x00).


File Header

The header begins at byte 0 and its length is stored at bytes 8--11.

Offset Size Type Description
0--3 4 bytes Preamble: 0x04 0x00 0x00 0x00 (EOT marker)
4--7 4 bytes Start of header: 0x01 0x00 0x00 0x00 (SOH marker)
8--11 4 int32 Header length in bytes
12--19 8 bytes Reserved / unknown
20--27 8 uint64 Starting message number
28--31 4 int32 Message count (number of records in this file)
32--39 8 int64 Start date/time (Windows FILETIME)
40--47 8 int64 End date/time (Windows FILETIME)
48--51 4 int32 Byte offset to the first record
52--55 4 int32 Byte offset to the last record
56+ var string Computer name (UTF-16LE, null-terminated)
var 2 bytes Field delimiter (0x00 0x00)
var var string Session string (UTF-16LE, null-terminated)
var 2 bytes Field delimiter (0x00 0x00)
var var string Previous log filename (UTF-16LE, null-terminated)
var 2 bytes Field delimiter (0x00 0x00)

Example Header

For a file with header length 140:

  • Starting message number: bytes 20--27 = 0x34 0x05 0x4E 0x01 0x00 0x00 0x00 0x00 = 21,824,820
  • Message count: bytes 28--31 = 0x33 0x6D 0x00 0x00 = 27,955
  • First record offset: bytes 48--51 = 140 (immediately after header)
  • Last record offset: bytes 52--55 = points to the final record in the file

Date/Time Format

Date/time fields use the Windows FILETIME format: a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).


Log Record

Records are variable-length and contain both fixed numeric fields and variable-length string fields.

Offset Size Type Description
0--3 4 bytes Record identifier: 0x02 0x00 0x00 0x00 (STX marker)
4--7 4 int32 Record length in bytes
8--11 4 int32 Offset to previous record (backward link)
12--15 4 bytes Session ID (4-byte identifier)
16--19 4 uint32 Process ID
20--23 4 uint32 Thread ID
24--31 8 int64 Date/time (Windows FILETIME)
32+ var string Log flag (UTF-16LE, null-terminated)
var 2 bytes Field delimiter (0x00 0x00)
var var string Component name (UTF-16LE, null-terminated)
var 2 bytes Field delimiter (0x00 0x00)
var var string Message text (UTF-16LE, null-terminated)
var 2 bytes Field delimiter (0x00 0x00)
var var string Process name (UTF-16LE, null-terminated)
var 2 bytes Field delimiter (0x00 0x00)
var 1 byte Record delimiter (0x00)

Record Linkage

Each record stores the byte offset to the previous record (bytes 8--11). Combined with the header's first/last record offsets, this allows both forward and backward traversal of the record chain.

String Fields

String fields follow a consistent pattern:

  1. UTF-16LE encoded characters (2 bytes per character)
  2. Null terminator (0x00 0x00)
  3. Field delimiter (0x00 0x00)

The log flag, component, message, and process name fields are all variable-length. The message field is typically the largest, potentially spanning hundreds or thousands of bytes.

Example Record

A record with length 1006 bytes:

  • Process ID: bytes 16--19 = 0x88 0x00 0x00 0x00 = 136
  • Thread ID: bytes 20--23 = 0xF0 0x27 0x00 0x00 = 10,224
  • Log flag: starts at byte 32, e.g. "Warning"
  • Component: e.g. "ArchestrA.Runtime.Service"
  • Message: the main log text (may be multi-line)
  • Process name: e.g. "aaEngine32"

File Naming

Log files follow the naming convention:

<timestamp>_<sequence>.aaLOG

The aaLogReader library locates the current (newest) file by sorting the directory listing and opens it with FileShare.ReadWrite to allow reading while Archestra continues writing.

Message Numbering

Message numbers are globally unique across all log files. The header's Starting Message Number plus the record's position in the file determines each record's absolute message number. The cache file stores this number to enable resuming from the correct position across files.