ALox  V. 2402 R. 0
Home ALox for C++ ALox for C# ALox for Java Download
08 - Log Data (Debug Variables)

1. Prerequisites

For a better understanding of what is explained in this chapter, it might be advisable to have read:

  • Chapter 05 - Scopes in ALox. In short, at that place it is explained how ALox defines language-related Scopes (including the 'global' Scope) and thread-related Scopes. Both types are 'interwoven' and form the complete set, as denoted in enum-class Scope (C++, C#, Java).
  • Chapter 06 - Lox.Once()
Attention
Both chapters are prerequisites for understanding what is explained here. Especially the use cases that arise from using and combining the different parameters of method Lox.Once (C++, C#, Java), which are explained in a high degree of detail in the above mentioned chapter, is not repeated here. If all aspects of using Lox.Once are understood, those can be quite easily adopted to what is described in this section!

2. Introduction

The concept of Log Data is a feature used for debugging. The goal that is aimed here is similar to the goal of debug-Log Statements themselves. As a reminder, those are:

  • Have a process log out debug messages, that help to understand a software during the implementation phase.
  • Avoid adding temporary 'debug output statements'. Instead use permanent code, which can be disabled and preserved for later use, when needed.

Corresponding goals are aimed with Log Data. ALox provides this feature to enable the insertion of variables and data into the code that otherwise would be temporarily added for debug purposes and removed afterwards. The same as debug-logging is pruned from release executables, such variables and their use gets pruned. Therefore, such variables and use of them can stay in the code forever, and once a problem in the corresponding code section appears, no need to reinvent temporary code is needed.

A typical example for using Log Data is debug log output written by an exception handler. The code that may cause an exception, could store status information according to Scope.Method. When an exception occurs and the program execution abruptly continues within the exception handler, such information can be retrieved and corresponding log output can be generated giving more information about where and why the exception occurred.

Attention
The whole concept of Log Data provided by ALox is merely a tool to support the process of debugging and debug code. Code using ALox Log Data should be pruned from release executables. In other words: It is not advised to use ALox Log Data to implement any functionality of an application, for example storing thread-local data used outside of Log Statements. There are other, standardized, reliable and efficient ways to store thread-local data.

3. Using Log Data

The interface for setting and retrieving Log Data is provided with methods Lox.Store (C++, C#, Java), and Lox.Retrieve (C++, C#, Java).

The type of data stored is Object in Java and C# implementations and Box in ALox for C++.

While in Chapter 06 - Lox.Once() of this manual, it was explained in detail how parameters group and scope of method Lox.Once (C++, C#, Java), can be omitted, how one of them can be used and what happens when both are used, we do not want to repeat these details in this chapter.

Instead we want to discuss the differences:

  • Instead of storing a counter (in Lox.Once), with Lox.Store, the data object is stored.
  • Parameter group of method Log.Once is named key in methods Log.Store / Log.Retrieve.
  • If both parameters (group and scope) are omitted, Log.Once defaults to the 'most inner Scope possible' (by switching the Scope.Filename and creating a unique key from the line number), which is the single log line itself. In contrast to this, Log.Store / Log.Retrieve in the parameterless version refers to the 'most outer Scope possible', hence a global singleton object (singleton in respect to the instance of class Lox used).

As a result, the use of Log Data can be summarized as follows:

  • An otherwise parameterless invocation the methods Log.Store / Log.Retrieve stores and retrieves a global anonymous Log Data object.
  • If parameter key is provided while parameter scope is omitted (or set to Scope.Global), a named Log Data object is stored and can be retrieved using the same key.
  • If parameter scope is provided while parameter key is omitted (or nulled or empty), an anonymous Log Data object is stored and can be retrieved (only) from within the same Scope as they were set.
  • If both parameters, key and scope are provided, then the key is bound to the provided Scope and for this scope a named Log Data object is stored. Consequently, it can be retrieved (only) from within the same Scope as it was set and with using the same key.

For clarification, this means, that different Log Data objects are stored in different scopes even if parameters scope and key are the same. For example, an object stored using Scope.Method can not be retrieved from a different method and will also not be overwritten within a different method. Again, the consequences and use cases of this design may become clearer when reading chapter Lox.Once.

4. Language Specific Notes

4.1 ALox for C++

It is important to understand that in ALox for C++, Log Data objects have to be kept in memory, if they are passed as pointers. The question if data is passed as a pointer or as a value is answered in ALib Boxing documentation.

In short, it can be said, that typically all fundamental C++ types (int, char, double, etc.) as well as pointers to those, are stored as values. The same is true for supported string types. However, in the case of strings, the "value" passed is the pointer to the start of the string in the memory. Therefore, this memory has to be kept valid. In the case of storing an AString, the memory stored might become invalid, if the string is extended after it was stored. Be sure to understand this constraint when using this feature.

4.2 ALox for C#

In the C# version of ALox, similar to methods Log.GetLogger and Lox.GetLogger, methods Log.Retrieve and Lox.Retrieve are not automatically pruned from in release code. The technical restriction here is that a method which is conditionally complied using annotation [Conditional("ALOX_DBG_LOG")] is not allowed to return a value. Therefore, the use of these methods either must appear in parameters of Log Statements (or any other pruned statement) or must be enclosed with corresponding #if / #endif statements.


Next chapter: 09 - Multi-Threaded Processes
Back to index