ALox  V. 2402 R. 0
Home ALox for C++ ALox for C# ALox for Java Download
14 - Trimming Source File Paths and Clickable IDE Output

In C++ and C#, ALox collects information about the source file name and this information by default includes the full file path. This chapter is addressing ALox for C++ and ALox for C# users only.

Note
In Java, the Scope information that ALox collects does not include information about the path of source files. Luckily, IDEs (e.g. Eclipse) nevertheless are able to open the right source file when clicking on the meta information automatically collected by ALox.

To collect the path information, in C++ the preprocessor macro __FILE__ is used when invoking Log Statements. In C#, some mechanics of namespace System.Runtime.CompilerServices are leveraged.

The source file name and path information received is used in two ways:

  • To determine the Scope of a Log Statement. ALox uses this to implement a variety of nice features like Scope Domains, Prefix Logables, Log.Once or Log Data.
  • For logging out such information and provide the context of a Log Statement. If an IDE supports it this may make log output 'clickable'.

Source file paths can become quite long and for different reasons, it might be wanted remove a redundant or irrelevant prefix from the it.

1. Source Path Trim Rules

ALox provides a mechanism to trim the path of source files by using a set of rules.

Internally, different lists of such 'Source Path Trim Rules' are maintained. One is a static table, which stores trim information used by all instances of class Lox. In addition, each Lox has an own, private set of Source Path Trim Rules. The advantage of having the static, global table is that a user can set 'hints' for trimming the path only once (at bootstrap) and forget about it. All instances of Lox will use it.

1.1 Automatic Detection of Trim Rules

ALox tries to detect trimable portions of a source path automatically. For that, ALox compares the actual path name of the executable of the currently running process with the path of a source file. The prefix both have in common is identified as trimable.

As an example, imagine a process' file name including the path is:

    /home/lisa/bin/myapp(.exe)

When ALox finds a source file residing in:

    /home/lisa/dev/myapp/src/ui/dialog.cpp

The trimable prefix of the path would be "/home/lisa/". Therefore, the trimmed file name would be:

    dev/myapp/src/ui/dialog.cpp

The result is a more narrow log output which is probably even better readable.

Of-course, it would be even nicer to have

    ui/dialog.cpp

or alternatively:

    src/ui/dialog.cpp

Before we learn how we can configure ALox to trim the path like this, let us first better understand when ALox performs the automatic detection described above:

  • ALox tries to detect a rule for trimming only once per Lox:
    The reason for this is simply performance. We rather want ALox to be fast instead of trying to detect trim rules with every Log Statement. However, if different subsets of the source code resides in different paths, the path detected becomes random: It depends on the fact which source logs first! And even worse: if no match was found with that first file, no second try is performed.
  • More precisely, ALox does its one-time detection exactly in the moment a first source file is using a Lox and the path of this file was not processed by an explicitly provided Source Path Trim Rule.
  • If ALox finds a rule, such rule is stored in the list dedicated to the Lox that found it, not in the global list applicable for all Lox instances. This is why the one-time detection is a one-time detecthion per Lox.

As you see, this auto-detection works nicely on small projects with source files kept local and the executable in a 'related' place.

When things become more complex, it is advisable to add Source Path Trim Rule explicitly.

1.2 Programmatical Provision of Trim Rules

A user of ALox may use method Lox.SetSourcePathTrimRule (C++, C#), to add Source Path Trim Rules explicitly.

Note
For all details, please see the reference documentation corresponding to the programming version you are using as linked above.

When you reconsider the sample above, explicit setting leads to better results even in simple project. The sample used source file:

    /home/lisa/dev/myapp/src/ui/dialog.cpp

Now, for a programmatically setting, Lisa invokes

Log.SetSourcePathTrimRule( "*/myapp/src/", Inclusion.Include );

as the very first statement before using ALox. The first parameter tells ALox which string to search. A leading wildcard character '*', indicates that the path is a substring of the file paths identified (no trailing '*' is needed). The second, optional parameter tells ALox to include the given substring in the trimming. In other words, the substring will be excluded from the trimmed path. In other words: it means "the given portion of the path is included in the trimming action!

Now the trimmed source path leads to

    ui/dialog.cpp

which is probably what is wanted. As we see, the huge advantages of explicitly setting Source Path Trim Rules is that they do a better job, are independently applied regardless of 'where' the executable is located and that any random behavior of trimming is eliminated.

Note
If the platform (compiler) specific path separator is '/', then characters '\' found in parameters path and trimReplacement when setting rules are replaced by '\' and vice versa. This allows to specify paths and substrings thereof in a platform independent way. The same is true when rules are defined in external configuration variables, as described later in this chapter.

It is advisable to use set Source Path Trim Rules at the very start of a process. Even prior to attaching the debug Loggers or custom Loggers to any Lox instances. The reason for the latter is that already attaching a Logger lets class Lox evaluate the Scope and potentially create the internal automatic rule. This auto-rule might be conflicting with a user-given rule but be prioritized due to the fact that it was created prior to the users' rule.

Then, in a multi-threaded application, from the moment on parallel access to two different instances of class Lox are performed, it is not allowed to add 'global' rules, because, for performance reasons, the access to the rules is not protected by a mutex.

Note
Alternatively, all existing instances of class Lox have to be locked 'manually' by invoking Acquire() prior to setting a global rule.

If multiple Source Path Trim Rules are set, those are applied in their order of creation. The private rules of a Lox are applied first, the global rules afterwards. Only one rule per source path is executed. In other words, as soon as a rule matches and modifies a source path, no further attempts for trimming are performed.

1.3 Trim Rules Provided by External Configuration Variables

Setting Source Path Trim Rules 'from within the source code' is easy and straightforward. However, when working in a team such changes might not be appreciated by other team members. In this and other situations it is advisable to retrieve Source Path Trim Rule from external configuration data, command-line parameters or other sources at runtime.

For Source Path Trim Rules and also other configuration data, ALox leverages the configuration facility provided by underlying utility library ALib.

Note
For general information on ALox configuration variables consult I - Configuration Variables.
For information on how to pass configuration data from custom sources to ALox, refer to namespace documentation aworx::lib::config (C++, C#, Java).

When an instance of class Lox is constructed, two a configuration variables are tried to be read:

  • ALOX_GLOBAL_SOURCE_PATH_TRIM_RULES.
  • ALOX_LOXNAME_SOURCE_PATH_TRIM_RULES.

The first is for defining global rules. The second variable is specific to a named Lox and the substring 'LOXNAME' needs to be replaced by the name of the Lox in question.

Otherwise, the format of the variables are the same and the following description applies to both.

The variable may contain a list of Source Path Trim Rules separated by semicolons ';'. Each rule consists of four values, separated by colons ','. The four values correspond to the first four parameters of method Lox.SetSourcePathTrimRule (C++, C#). The same as parameter 3 (trimOffset) and 4 (sensitivity) are optional with method Lox.SetSourcePathTrimRule, providing them in the configuration variable is optional as well.

As an example, an INI file of an application might have the following sub-section:

GLOBAL_SOURCE_PATH_TRIM_RULES= *src.cs/ , true ; \
/usr/local/lib/ , false, 9, true, /usr/lib/

This would install two rules. Note that values of parameters 2 and 4, which in the method declaration carry enum types Inclusion (C++, C#) and Case (C++, C#), in the INI file are expressed by boolean values as follows:

  • Inclusion::Include == true, Inclusion::Exclude == false
  • Case::Sensitive == true, Case::Ignore == false

1.4 Priorities of Trim Rules

Different trim rules might be redundant or even contradict each other. Therefore the rules are equipped with a priority. Rules with higher priority are applied first. Once a rule matches, no further rule is applied. The priority is an integer value and is lent from the ALib system for external configuration variables. It is are set as follows:

  • In the case that a rule is read from an external configuration variable, the priority value is set to the priority value of the configuration plug-in that provided the variable.
  • In the case that the rule is set from within the source code, the priority is taken from optional parameter priority of method Lox.SetSourcePathTrimRule (C++, C#) which defaults to Priorities::DefaultValues (C++) respectively Configuration::PrioDefaultValues (C#).
  • Rules that are automatically detected have a priority of Configuration.PrioAutodetect (C++, C#).

Configuration.PrioDefaultValues is a lower priority than (the default) priorities of the configuration plug-ins. Therefore, the configuration variables by default overrule what is hard-coded as a Source Path Trim Rule.
To change this behavior, any other priority may be specified in the source code, especially the pre-defined value of Priorities::DefaultValues (C++) respectively Configuration::PrioDefaultValues (C#). It allows the user to give the rule set in the source code the highest priority and this way to protect the rule from external manipulation.

Note
For general information about accessing external configuration data with ALib see documentation of namespace [cs.]aworx.lib.config (C++, C#).
Note
The priority scheme used here is similar to what is described for Verbosity settings in chapter 13 - External Verbosity Configuration.

1.5 Verifying Trim Rules

With most methods invoked on class Lox, internal log messages are provided (See 11 - Internal Logging). When setting Source Path Trim Rules, this is not the case. The rational here is, that in most cases no Logger is attached to the Lox attached, yet. If something goes wrong with source path trimming, e.g. when you are not sure if a rule was read from external configuration variables, you can use method Lox.State (C++, C#) to dump out the current state of a Lox. Besides rules set programmatically or using configuration variables, if exists, also the auto-generated rule is displayed.

Note
As an alternative to (temporarily) adding an invocation of Lox.State to your code, ALox provides configuration variable ALOX_LOXNAME_DUMP_STATE_ON_EXIT. This allows to enable an automatic dump of the state using a command line parameter or other external configuration sources.

1.6 Removing Trim Rules

In very special situations (e.g. ALox uses it for unit testing) method Lox.ClearSourcePathTrimRules (C++, C#), can be used to clear the rules of a Lox instance, optionally including all global rules.

Note
This method can also be used prior to invoking Lox.SetSourcePathTrimRule to suppress the creation of the automatic rule. Of-course, this has to be done for every instance of class Lox in question, because the automatic rule and its creation is local to the each Lox.

2. Considerations in respect to Scope Functionality

The benefits of having ALox using reduced length source file paths in consideration to Scopes is in respect to performance. All data associated with language-related Scopes is stored and retrieved in hash-tables with keys containing the source path.
Furthermore, the output of method Lox.State (C++, C#), might be better readable with these shorter paths.

It is also important to consider that when using Scope.Path, especially if increased by an amount of addressed parent directories, the source path must not be trimmed more than such use suggests. When the files are sorted in nested directories according to the nested namespace structure implemented in the files, then the directory prior to the tree of namespace directories should be included in the trimmed path.

3. Considerations in respect to Logging Meta Information

Note
This section is about textual logging with the use of Loggers derived from class TextLogger (C++, C#), provided with ALox. For other Loggers, other considerations might apply.

Due to the rich meta information that ALox provides, the log output lines quickly become quite wide. Therefore, trimming the path of source files in the log output to a level that still allows to distinguish all files properly, can help a lot to reduce such width.

Class MetaInfo (C++, C#), with its instance found in every ALox TextLogger, provides a format string to structure the meta info. For the source path, two format parameters exists:

  • SP: Provides the full path name
  • Sp: Provides the trimmed path name

Directly from the log-output you can observe how trimming is performed by ALox and whether there is the need to add a trimming rule explicitly.

However, those IDEs which recognize certain patterns and allow to automatically link these patterns with the source file in their editor, sometimes need to see the full path name or a certain part of it. To adjust ALox to your IDE, you might have to play around a little. If your IDE supports clickable output lines, you might want to change the format of the meta info to match the pattern that your IDE requires.

Note
In documentation page IDE Setup for ALox for C++ and IDE Setup for ALox for C#, detailed instructions for selected platforms and IDEs are given.

Certain build systems/compilers might not provide the absolute path information in certain situations. In contrast, they might provide source directories in relative addressing in respect to a project file. This is at least true for C++. If then the IDE does not recognize the right origin of a relative path, this path needs correction to be absolute. ALox provides a feature to do such correction. An optional parameter of method Lox.SetSourcePathTrimRule (C++, C#) allows to specify a replacement string for what is cut by a rule. (This replacement string can of-course also be set using the configuration variables described in 1.3 Trim Rules Provided by External Configuration Variables.) Sometimes it might be needed to "fiddle around" with the options of the trim rules and the format of the TextLogger output, until finally your IDE recognizes the source information correctly. But once succeeded, it proofs being worth the effort!

When you are sure, that your IDE does not support the links to the editor, then you're unfortunate and your way to go is displaying a (best possible) trimmed path, to reduce overall log output width.


Next chapter: 15 - Log Domain Substitution
Back to index
Log
lox::Log Log
Inclusion
Inclusion
alib::ALOX
lox::ALox ALOX