GemStone/S 64 Bit Supplemental Documentation

Object Read Tracking

1.1  Overview

Object Read Tracking enables GemStone to record the time and userId when specific objects in the repository are read. Records of read operations for all session are written to comma-delimited (CSV) files by the Stone.

The Object Read Tracking feature is available in GemStone/S 64 Bitâ„¢ v3.5.7 and later 3.5.x versions, and v3.6.2 and later.

Read tracking is enabled for a repository using the stone configuration parameter STN_OBJECT_READ_LOG_ENABLED.

Objects for which reads are tracked are associated with specific GsObjectSecurityPolicies; each object in that GsObjectSecurityPolicy will have reads tracked. Objects can also be added to the tracking log dynamically.

When object read tracking is enabled, by default, reads by all UserProfiles (other than special system users, listed here) are tracked. Individual UserProfiles can be configured to not have reads tracked, so for example batch jobs can run without tracking; and UserProfiles with appropriate privileges can dynamically disable and re-enabled object read tracking.

Configuring objects to be tracked

The GsObjectSecurityPolicy instance variable trackReads is a boolean, indicating if objects associated with that security policy should be tracked. It is false by default; when set to true, all objects associated with that security policy have reads tracked.

The following methods are available:

GsObjectSecurityPolicy >> trackReads
Returns a Boolean, true if object read logging is enabled for objects in this security policy.

GsObjectSecurityPolicy >> trackReads: aBoolean
If aBoolean is true enables object read logging for objects in this security policy, false disables it. Signals an Error if any element of AllUsers has a userId incompatible with writing to a .csv file.

Before any read tracking can be recorded, the application configure the objects to be tracked by doing the following:

  • Define a security policy with trackReads set to true
  • Determine which application objects require read tracking
  • Associate these objects with the read tracking security policy.

In addition, specific individual objects can be tracked within a specific session by using the following method:

Object >> trackRead
If receiver is not a special object, and (System objectReadLogEnabled == true) and ((System myUserProfile _hasPrivilegeName: #DisableObjectReadLogging) == false), add the receiver to the sessions read tracking buffer. Returns true if the object was added to the read tracking buffer, false otherwise.

This addition to the read tracking buffer is independent of whether (self objectSecurityPolicy trackReads == true) and is independent of whether this method has already been sent to the receiver.

Enable and disable Read Tracking

Read tracking must be enabled by setting the configuration parameters STN_OBJECT_READ_LOG_ENABLED and STN_OBJECT_READ_LOG_DIRECTORIES before the Stone is started up.

If a session logs in as a user with the DisableObjectReadLogging privilege, then read tracking is not enabled for that particular user.

If a session logs in as a user without the DisableObjectReadLogging, objects that have object read logging configured are written to the object read logs.

If the user additionally has the DynamicDisableObjectReadLogging privilege, the user can disable read tracking temporarily within that session by executing

System setObjectReadTracking: false

When object read tracking is dynamically disabled, a record is written to the object read tracking log.

To determine if the current session has read logging currently enabled, send:

System objectReadLogEnabled

The following methods are available:

System class >> objectReadLogEnabled
Answer a Boolean indicating if the Stone was started with the configuration parameter STN_OBJECT_READ_LOG_ENABLED set to true. Note that the actual state of object read logging will depend on the privileges of the current session’s userProfile and if object reads tracking was dynamically disabled; see System class >> setObjectReadTracking:.

System class >> setObjectReadTracking: aBoolean
Dynamically disable or re-enable object read tracking for the current session, and return the previous status of object read tracking. If setObjectReadTracking: successfully disables or re-enables read tracking, a record is written to the Object read tracking log.

When aBoolean is false, then if object read logging is not enabled for the Stone, or if the current session’s UserProfile has the DisableObjectReadLogging privilege, or if setObjectReadTracking: false was previously invoked to disable object read tracking, then this method has no effect, and returns false. If the current user does not have DynamicDisableObjectReadLogging privilege, than an exception is raised.

A true value for aBoolean only has effect if setObjectReadTracking: false was previously successfully executed.

This is expected to be used in constructions such as:

|  prev | [  prev := System setObjectReadTracking: false.
   query Execute ] ensure: 
      [ System setObjectReadTracking: prev ]

System class >> objectReadTrackingEnabled
Returns true if object read tracking is currently being performed for this session, for any objects with tracking configured via GsObjectSecurityPolicy >> trackReads or Object >> trackRead. It returns false if no object read logging will occur. Specifically, this method will:

  • return false if Object read tracking is not enabled for the Stone
  • return false if the current session’s UserProfile has the DisableObjectReadLogging privilege
  • return false if the session has dynamically disabled Object Read Tracking; that is, System setObjectReadTracking:false must not have been executed and be still in effect.

What triggers read tracking

Tracking occurs when an object is faulted into the temporary object memory of a session. Only one read is recorded per object per session. Once an object has been tracked as read, if the object is read again, no further tracking events are recorded for that object in that session.

The session sends tracking records to the Stone:

  • At each transaction boundary (commit or abort)
  • When the gem's tracking buffer is full. The buffer is about 100K bytes.
  • When the gem explicitly calls System class >> flushObjectReadBuffer
  • At session logout.

Each read record in the buffer has the timestamp of the first object recorded in the buffer (this avoids excessive calls to fetch exact timestamps from the OS). There is a final record in the buffer, indicating the end of the buffer, which also has an exact timestamp.

Limitation in Read Tracking

If the session terminates with a fatal error or is killed with SIGTERM, the last tracking buffer may be lost. This creates a way for a user to intentionally (as well as inadvertently) read an object without this read action being recorded in the log.

1.2  Object Read Log File

The object read log location is specified using the stone configuration option, STN_OBJECT_READ_LOG_DIRECTORIES. This specifies a list of one or more directories in which to write object read log files.

The Stone will not start up if STN_OBJECT_READ_LOG_ENABLED is true and STN_OBJECT_READ_LOG_DIRECTORIES does not contain at least one valid, writable directory.

The object read log file name is composed as:



The maximum size of the object read log file in bytes is specified using the Stone configuration parameter STN_OBJECT_READ_LOG_MAX_FILE_SIZE. When the maximum file size is reached, the current object read log file will be closed and renamed to remove the .current suffix, after which a new log file will be opened.

If a buffer of records from a Gem needs to be written, but will not fit into the current object read log file without exceeding the file maximum size, a new log is started. The contents of a Gem’s buffer of read records is not split over two object read log files. Each Gem’s buffer of records is written contiguously, before another Gem’s buffer.

When stone starts, if a single .current.csv file is found within the directories specified by STN_OBJECT_READ_LOG_DIRECTORIES, and if this file is smaller than the maximum file size, it will be reopened for writing. Otherwise a new object read log file will be started.

When the local system time crosses midnight UTC, the current object read log is closed and a new one is started.

The following methods are available:

System class >> currentObjectReadLogFile
Answer a string containing the current object read log file which the stone is writing to, or nil if the object read logging feature is disabled.

System class >> startNewObjectReadLog
Requests Stone close the current object read log file and start a new one. Blocks until the operation has completed. Returns true on success, false if the object read logging feature is disabled, and raises an exception on error. Requires FileControl privilege.

System class >> flushObjectReadBuffer
Forces the gem to immediately send any buffered object read records to the stone.

File Management

Applications must manage storage and archiving of object read log files, to ensure the file system containing these logs does not become full.

It is recommended that the log files be compressed using gzip or lz4 data compression, and that archiving scripts run using CRON so that object read log files are automatically archived.

If a write to the object read log file fails, the following actions will be taken in sequence:

1. Log a message to the stone log regarding the write failure.

2. Retry the write 3 times.

3. If the write still fails, open a new object read log file in the next directory.

4. Repeat item 2 until all object read log directories have been tried.

5. Log a message to the stone log indicating all object read log space is full.

6. Suspend (block) the session and retry opening a new object read log file periodically.

7. Terminate the session if the writes cannot be completed within 5 minutes or the blocked session causes a commit record backlog, whichever occurs first.

Errors opening, renaming and writing the object read log file are recorded in the Stone log.

Object Read Log File Format

The object read log is in CSV file format, as specified by RFC 4180.

The first line of each file will contain column headers.

There are three record types: O, F, and R.

The first field of a record is a single letter, either O, F, or R, indicating the type.

  • An O record includes the details on a specific read record.
  • An F record marks the end of a group of O records that were in the same buffer composed by a gem.
  • An R record is generated when System class >> setObjectReadTracking: is used, indicating dynamic disable or re-enable of object tracking.

The fields for each record are:

O, TimeGMT, UserName, UserProfileOop, GemProcessId,
GemHostName, GemHostIpAddress, GemClientIpAddress,
ObjectReadOop, ObjectReadClassOop, ObjectReadClassName
R, TimeGMT, UserName, UserProfileOop, GemProcessId,
GemHostName, GemHostIpAddress, GemClientIpAddress, empty,
empty, ReadTrackState
F, TimeGMT, UserName, UserProfileOop, GemProcessId

The following fields are defined:

TimeGMT (Integer)
Timestamp in GMT of the object read operation, updated when a gem composes the first O record of a session, when an R record is written, and when the F record is composed by a gem to flush a buffer.

UserName (String)
The GemStone user name of the user performing the read, UTF8 encoded and enclosed in double quotes. This is obtained from the userId instance variable of the session’s UserProfile object.

UserProfileOop (Integer)
The OOP of the user profile.

GemProcessId (String)
The process ID of the session.

GemHostName (String)
The name of the host on which the gem is running, the result of calling hostname(). This field is enclosed in double quotes.

GemHostIpAddress (String)
The IP Address of the gem’s end of the GCI client to gem connection; the result of calling getsockname() on the socket for the GCI client to gem connection. Does not do a reverse DNS lookup. For linked sessions, such as topaz -l, this field is empty.

GemClientIpAddress (String)
The IP Address of the gem’s client’s host, the result of calling getpeername() on the socket which is the gem's end of the GCI client to gem connection. For linked sessions, such as topaz -l, this field is set to gcilnk.

ObjectReadOop (Integer)
The OOP of the object read by the user.

ObjectReadClassOop (Integer)
The OOP of the class of the object read.

ObjectReadClassName (String)
The name of the class, UTF8 encoded.

ReadTrackState (String)
Either 'True' or 'False'

1.3  System Configuration Specific to Object Read Tracking

Object read tracking is highly integrated with GemStone, and can be controlled in a number of ways. The following configuration parameters, User Profile privileges, and other GemStone options are specific to object read tracking.

Configuration File Options for Read Tracking

The following configuration options are required for object read tracking:


A Boolean (true or false) indicating if object read logging is enabled.

Runtime equivalent: #StnObjectReadLogEnabled (read-only at runtime).

Default: false.


A list of directories where object read log files can be written. Must contain at least 1 element if STN_OBJECT_READ_LOG_ENABLED is true. The Stone will not start if STN_OBJECT_READ_LOG_ENABLED is true and this configuration parameter is not set to at least one valid directory.

Runtime equivalent: none

Default: none


Maximum size in bytes an object read log file may grow to before the current file is closed and a new object read log file is opened.

Default: 1MB, Min: 512KB, Max: 16GB

Runtime equivalent: #StnObjectReadLogMaxFileSize (only modifiable by SystemUser).

UserProfile management

When object read tracking is enabled in a repository, by default all UserProfiles (other than SystemUser and GcUser) will have reads tracked

Exempting a UserProfile from read tracking

For UserProfiles that are do not required read tracking, object read tracking can be disabled. This can only be done for UserProfiles with the privilege DisableObjectReadLogging.

UserProfiles with this privilege do not have their object reads tracked. To allow an automated batch job to operated without generating excessive read tracking, execute that job as a UserProfile with the DisableObjectReadLogging privilege.


UserProfiles with this privilege never have their object reads tracked. SystemUser, DataCurator, GcUser, SymbolUser, HostAgentUser and CodeLibrarianUser always have this privilege.

Existing and new users without this privilege will have reads tracked, if object read tracking is enabled for the repository and has not been dynamically disabled.

You can also temporarily disable object read tracking dynamically for users that otherwise do have object reads tracked.


UserProfiles with this privilege may dynamically disable their read tracking using System setObjectReadTracking: false. Users without this privilege cannot disable read tracking. Has no effect for users with DisableObjectReadLogging, who never have read tracking enabled.

Cache Statistics for monitoring Object Read Tracking

The following cache statistics are related to object read tracking and allow monitoring of the impact:

NumInReadTrackingQueue (Stn)
Number of sessions waiting for data to be written to the Read Tracking Log.

ObjectsReadTracked (Gem)
Number of object faults for which a record was added to the Read Tracking Log.

ReadTrackingFileSize (Stn)
Size in bytes of the currently open Read Tracking Log.

ReadTrackingServiceCount (Stn)
Number of Read Tracking buffers processed by stone.