Configuration

Documentation / Community Edition / User Guide / Appendix / Configuration
 

Introduction

The configuration of the MyARM agent library is done mainly through configuration files which contain so-called named value pairs or just called properties. Each property is specified in one or more lines of the file in the following form:

name = value

where at least the name and the sign character have to be in the first line. Line concatenation have to be introduced by a backslash character at the end of a line. The name can be compound hierarchically by separating name parts with dots:

agent.sink.name = db_mysql

This examples assigns the value of db_mysql to the property name agent.sink.name which consists of the three parts agent, sink and name. One use of these hierarchical names is to unify the configuration of one component within the system by its first name part. In the above example the first name part is agent which means its a property of the agent library component of the MyARM system. The second name part sink specifies the sub-component and the third part name specifies the property of the sub-component. This configuration line configures the data sink name db_mysql to be used for the data sink of the MyARM agent.

A value can also refer to an environment variable which has to be enclosed by braces and prefixed by a dollar sign: ${VAR}. This gives you powerful possibilities in writing configuration files. For example you can write user independent configuration files.

agent.log.file = ${TMPDIR}/agent.log

MyARM is a highly modular ARM implementation therefore many components are independent from each other. To make configuration tasks easier MyARM has the ability to include other configuration files. Just add a line

include filename

in a configuration file and the file with the name filename is included.

Configuration files

There are three possibilities to specify a configuration file for an MyARM tool or an ARM instrumented application using MyARM. The first possibility overrides the following ones, etc.

  1. specifying a configuration file through the command line options: -cf conf_file or --conf-file conf_file. This is only available for MyARM tools. The ARM standard defines no way how to access command line options. Therefore it is not possible to configure an ARM instrumented application using this technique.
  2. specifying a configuration source through the $MYARM_CONFIG_URL environment variable. See section "Environment".
  3. providing the .myarmrc file in the $HOME directory of the current user.

User configuration file

MyARM provides a mechanism for user (New since "1.3.x.2") specific configuration of MyARM. If the file user.conf exists in the current configuration directory of MyARM it is loaded after all other configuration files. Each configuration property in this file will overwrite a previous loaded configuration property. Therefore the user can place any configuration property in the file which should be differ from the MyARM standard configuration.

Provided configuration files

By default MyARM provides ready to run configuration files for the all components. Thus all you need to do is to select your favorite configuration file from the templates directory and to change the values to your needs by overriding these values within the user.conf file.

Template configuration files

These template configuration files are the anchor to the MyARM configuration system and should be used with the setup.sh script or used with the MYARM_CONFIG_URL environment variable. They are located in the $MYARM_ROOT/conf/templates directory.

Under Unix like systems a symbolic link from $MYARM_ROOT/conf/<conffile> to the $MYARM_ROOT/conf/templates/<conffile> configuration file is created automatically with the setup.sh script.

Under Windows just copy the appropriate configuration file from the templates directory to the $MYARM_ROOT/conf/myarm.conf file.

sqlite3.conf
Main configuration file for using MyARM with a SQLite3 database without any MyARM daemon. Note this configuration will use the database directly from your instrumented application.
tcpd_sqlite3.conf
Main configuration file for using the myarmtcpd daemon process to collect ARM data from instrumented applications and to store the ARM data within a SQLite3 database.
Include configuration files

All the following configuration files are included from other main configuration files described in the previous section.

include/agent.conf
agent configuration file defining basic properties, instance pooling and logging properties for instrumented applications.
include/basic.conf
basic configuration file defining MyARM global configuration properties,
include/application/manager.conf
manager configuration properties.
include/daemon/tcpd.conf
myarmtcpd configuration properties.
include/db/sqlite3.conf
SQLite3 database configuration file defining the location of the SQLite database file and access modes.

Configuring MyARM components

Currently the following components can be configured using properties where the base prefix is specified in parentheses. free in this context means you can choose a name as you prefer (e.g. db_mysql for a MySQL database configuration):

Configuring basic attributes

Some properties are subject to all MyARM components and therefore can be configured in the basic section of the MyARM configuration. The following basic properties are available:

basic.time.use_utc (New since "1.3.x.3")
this boolean property is used to switch display of times between UTC (true) and local time (false). Default is false.
basic.sink.thread.tmpfile.name (Obsolete since "2.1.x.0")
the temporary sinkthread file concept is replaced by the generic file storage reader and writer concept.
basic.sink.thread.tmpfile.size (Obsolete since "2.1.x.0")

Basic logging configuration properties

basic.log.timefmt (New since "1.3.x.3")
specifies the format pattern to use for displaying time values. See Configuring time formats section for details.
basic.log.datefmt (New since "1.3.x.3")
specifies the format pattern to use for displaying date values. See Configuring date formats section for details.

ARM data buffer configuration properties

basic.armdata.buffer.size
various MyARM components are collecting ARM data into a memory buffer before further processing. The buffer size for this purpose can be configured using this property. By default this buffer is 16384 bytes of size which is also the minimum value for this property. The maximum size if 1MB.
basic.armdata.buffer.pool.size
number of ARM data buffers to pre-allocated during initilization of MyARM.

Default is 32, Minimum is 8, Maximum is defined by the basic.armdata.buffer.pool.max

basic.armdata.buffer.pool.max (New since "1.3.x.4")
maximum number of ARM data buffers MyARM will allocated. If this limit is reached any data which should be written to the ARM data buffer is dropped and appropriate dropped counters are increased.

Default is 512, Minimum is 256, Maximum is 2048.

File storage configuration properties

The following configuration properties belongs to the file storage reader part:

basic.filestorage.reader.directory (New since "2.1.x.0")
defines the directory to scan for new ARM data files.

Default directory is ${MYARM_VARLIB_DIR}/myarmfiles.

basic.filestorage.reader.directory.scan.period (New since "2.1.x.0")
defines the number of seconds to scan the directory for new files.

Default is 5 seconds.

basic.filestorage.reader.directory.scan.keep_corrupt (New since "2.1.x.0")
boolean which defines if corrupted ARM data files should be kept or not. If kept the file is renamed by adding the suffix .corrupt.

Default is true.

The following configuration properties belongs to the file storage writer part:

basic.filestorage.writer.workfile (New since "2.1.x.0")
specifies the complete filename (including directory names) for the work file. An unique suffix will be appended for each running process. The ARM data is written to this file and when its closed it is moved to the configured file storage reader directory (basic.filestorage.reader.directory).

Default is ${MYARM_VARLIB_DIR}/myarmfile.data.

basic.filestorage.writer.rolling.seconds (New since "2.1.x.0")
specifies the number of seconds after which a new workfile will be used. The old workfile will be moved to the configured directory.

Default is 60 seconds.

basic.filestorage.writer.rolling.size (New since "2.1.x.0")
specifies the maximal size in bytes of the workfile. If the workfile gets bigger a new workfile is opened and the old workfile is moved to the configured directory.

Default is 128 KB.

basic.filestorage.writer.diskusage.max_used (New since "2.1.x.0")
specifies the maximal size in bytes of all ARM data files in the file storage reader directory (basic.filestorage.reader.directory). If this limit is reached any new ARM data files will be dropped and an error will be reported.

Default is 100 MB.

basic.filestorage.writer.diskusage.min_free (New since "2.1.x.0")
specifies the minimal free size in bytes of the file system the file storage reader directory (basic.filestorage.reader.directory) resides. If this limit is reached any new ARM data files will be dropped and an error will be reported.

Default is 200 MB.

Configuring Agent

The behaviour of the MyARM can be changed by the following agent properties. Note not each property is used for the different language binding agents. See the binding information for each property.

agent.correlator.add_user
can be set to yes or no and, if enabled the ARM agent adds a passed user identity to the generated correlator. This user identity within the correlator is afterwards used by sub-transactions and starts the sub-transactions on behalf of this user. Note: This will override the user identity passed with the standard ARM 4.0 API.

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.disabled
with this boolean property the complete MyARM agent can be disabled.

Default is false.

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.flush.period
defines the number of seconds after which all cached ARM data are written to the configured backend.

The default is 30 seconds.

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.implementation
selects which implementation of the ARM interface should be used. Currently the following implementations exists:
myarm
The real MyARM implementation.

Bindings: arm40c, arm20c, arm40java, arm40c#.

logger
The ARM4SDK logger implementation.

Bindings: arm40c, arm20c, arm40java.

agent.api.log.error
if this boolean property is set to true any invalid parameter passed through the ARM API is logged.

Default is false.

Bindings: arm40c, arm40java, arm40c#.

agent.api.log.warning
if this boolean property is set to true any warning regarding ARM 4.0 standard compliants is logged.

Default is false.

Bindings: arm40c, arm40java, arm40c#.

agent.sink.name
defines the name of the datasink to use. See "MySQL configuration example".

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.transaction.pool.size
number of pre-allocated transaction instances for the transaction pool. Increase this value if high frequent transaction measurement is expected. When the instrumented application stops or the resource watchdog concept is enabled a short message is written to the log file which reports used transaction instances. With this information it is possible to adjust the initial transaction pool size so that no memory allocation is needed during runtime.

Default is 128. Minimum is 32, Maximum is defined by the agent.transaction.pool.max property.

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.transaction.pool.max (New since "1.3.x.4")
maximum number of transaction instances which is allocated by MyARM. If this limit is reached and the instrumented application starts a new transaction measurement an error is returned and the transaction dropped counter is increased by one.

Default is 1024. Minimum is 512, Maximum is 16384.

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.transaction.tracking.status
transaction status used to stop transactions which are implicitly stopped by the transaction tracking mechanism.

Defaults to "aborted".

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.transaction.drop.responsetime (New since "2.1.x.0")
response time in nanoseconds to drop a transaction measurement if its response time is less than this threshold and the transaction status is good. With this configuration property it is possible to drop very short transaction measurements assuming that it is not of any interest since it completed so fast. Zero disables this feature.

Default is 0 nanoseconds.

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.metric.pool.size (New since "1.3.x.0")
number of pre-allocated metric instances for the metric pool. Increase this value if high frequent transaction measurement with metrics is expected. When the instrumented application stops or the resource watchdog concept is enabled a short message is written to the log file which reports used metric instances. With this information it is possible to adjust the initial metric pool size so that no memory allocation is needed during runtime.

Default is 64. Minimum is 16, Maximum is defined by the agent.metric.pool.max property.

Bindings: arm40c, arm20c, arm40java.

agent.metric.pool.max (New since "1.3.x.4")
maximum number of metric instances which is allocated by MyARM. If this limit is reached and the instrumented application tries to allocate new metrics a warning is returned and the metric dropped counter is increased by the number of not allocated metrics.

Default is 512. Minimum is 256, Maximum is 4096.

Bindings: arm40c, arm20c, arm40java.

agent.log
configures the logging facility of the agent. See appendix "Configuring Log facility" for details.

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.log.datasink.level (New since "2.0.x.1")
configures the logging level of log messages also to write to the datasink and not only to the configured logging destination. With this feature logs can be centrilized within the configured database.

Default is error.

Bindings: arm40c, arm20c, arm40java, arm40c#.

agent.filestorage (New since "2.1.x.0")
configures the agent to use (true) or not to use (false) the file storage concept for temporarily store ARM data if the configured datasink is not available.

Default is true.

Bindings: arm40c, arm20c, arm40java.

Configuring C Agent

agent.binding.c.api.return_ok (New since "1.4.x.2")
boolean which defines whether any C API call should return ok (zero) even if an error was detected.

Default is false.

agent.binding.c.api.destroy_application (New since "1.4.x.2")
boolean which defines to destroy an application and all its application and transaction instances whenever arm_destroy_application() is called.

Default is true.

Configuring C# Agent

agent.binding.csharp.datasink.pinvoke (New since "1.3.x.0")
boolean which defines whether to use all MyARM datasinks using platform invoke or not. If set to false, MyARM C# agent runs purely C# managed code. But currently only the file and tcp datasink are supported within that configuration. If set to true any MyARM datasink can be used but therefore unmanaged code is executed. Default is true.

Configuring daemons

In this section common agent daemon configuration properties are described. Agent daemons are normally executed in background and in a Unix environment the following properties can be specified for all agent daemons to configure its behaviour:

<component>.cmd.enable
enables or disables the command TCP channel for the appropriate agent daemon.
<component>.cmd.host
defines the host/interface where the daemon listens for incoming command connections.

Default host is localhost.

<component>.cmd.port
specifies the command TCP channel port to use.
<component>.group
defines the group under which the agent daemon should be executed. If the agent daemon is started under the super-user (root) it can changes its group identity to the here configured group. For example a myarm group.
<component>.pidfile
defines the file where the appropriate agent daemon writes its process id to.
<component>.user
defines the user under which the agent daemon should be executed. If the agent daemon is started under the super-user (root) it can changes its user identity to the user configured here. For example a myarm user.

Configuring Log facility

ARM postulates that in any circumstance the instrumented application has to continue working regardless of errors within the ARM agent or with the current instrumentation. Therefore any error or inconsistency within the ARM agent has to be hidden from the application. But in many situations the instrumentor should know if an error occurred within the ARM agent. Therefore MyARM supports error and information reporting which can be configured using the following configuration keywords:

<component>.log.type
Specifies the type of the reporting facility. One of the following types can be used:
none
No reporting at all
stderr, stdout
Reports to standard error/output (file) channel. (Unix)
console
Reports to console (Windows).
file
Reports to the file specified via log.file
syslog
Reports to the system log service (Unix)
eventlog
Reports to the event log service (Windows)
<component>.log.level
Specifies the level of detail for logging. Currently the following levels are supported:
none
no logging at all
error
only log errors
warning
log warnings and errors
status
also log status information
info
some more information
config
log the read configuration of the different MyARM components
max
maximum logging information
<component>.log.datasink.level
Specifies the log level for which log messages should also be reported to the datasink (e.g. will be stored in the centralized database). Default is error.
<component>.log.file
Specifies the file to write any reporting information to.
<component>.log.file.mode
Specifies the mode to open the file specified via log.file. Mode can be either "w" to open the log file and possibly truncate the existing file or "a" to append to the existing file.
<component>.log.file.size
If log.file.generation is enabled this property specify the maximal size of the log file in bytes. If this limit is reached a new log file will be opened. Also this property specifies the size of the eventlog under Windows. Default is 1048576 (1MB).
<component>.log.file.generation
Specify the maximal number of log files which will be generated by the MyARM log component. In conjunction with the log.file.size property MyARM will not use more bytes of hard disk space than the arithmetic product of these two properties. If this property is zero the log file generation rotation is disabled and only one log file will be used. The latest log file has a suffix of .0 and the oldest log file generation has a suffix of .<generation>-1. Default is 5.
<component>.log.format
Specifies a template string used to prefix any output to the log. The following format specifier can be used:
%A
displays the name of the myarm application (e.g. myarmtcpd). For the agent log the currently used language binding is used.
%P
displays the current process id.
%H
displays the current host name.
%T
displays the internal thread id.
%C
displays the component name.
%N
displays the log message number.
%I
displays the log message ID.
%M
displays the log message. If this specifier is omitted the log message is appended at the end of the line.
<component>.log.show.level
Indicates that the log level should be logged (true) or not (false).
<component>.log.show.time
Indicates that the time of the log should be logged (true) or not (false).
<component>.log.flush
Specifies, if true, that after each log message a flush should be performed so that it is immediately written to its destination without any buffering. For error log messages this is always true.
<component>.log.syslog.facility (New since "2.1.x.1")
Specifies the facility to use for syslog service. It supports 'local0' to 'local7' and 'user'. Default is 'user'.

Configuring resource watch dog

With the following configuration properties MyARM can be configured to log these information or not.

<component>.resource.watchdog.period (New since "1.3.x.4")
defines the period in seconds to log the resource usage. If the period is zero the resource usage is only reported on program termination. Default is 300 seconds.
<component>.resource.watchdog.log.entities (New since "1.3.x.4")
boolean which indicates to log (true) recored, processed, stored and read entities or not (false).

Default is false.

<component>.resource.watchdog.log.tranpool (New since "1.3.x.4")
boolean which indicates to log (true) transaction pool allocation or not (false).

Default is true.

<component>.resource.watchdog.log.metricpool (New since "1.3.x.4")
boolean which indicates to log (true) metric pool allocation or not (false).

Default is false.

<component>.resource.watchdog.log.armdatapool (New since "1.3.x.4")
boolean which indicates to log (true) ARM data buffer pool allocation or not (false).

Default is true.

<component>.resource.watchdog.log.dropped (New since "1.3.x.4")
boolean which indicates to log (true) dropped entities or not (false).

Default is true.

<component>.resource.watchdog.log.transaction.calls (New since "1.3.x.5")
boolean which indicates to log (true) number of calls to the appropriate ARM 4.0 C transaction function calls. Especially for arm_start_transaction() and arm_stop_transaction().

Default is true.

The <component> can be either:

Configuring data sink component

This section describes how to configure a data sink which should be used to store all ARM data. MyARM supports a wide range of different data sinks therefore the configuration of a data sink depends on its type. The common data sink properties are described below. For specific datasink configuration such as for a MySQL or Oracle database see the appropriate sections in datasinks.

<name>.type
specifies the type of the backend (e.g. mysql or sqlite3).

The name word can be replaced by any other word or name. For example if you use MySQL database you can use the word db_mysql to clearly specifies which data sink you configure. To actually use this data sink configuration just specify the name as the value for the <component>.sink.name property of the appropriate component. For example to use the MySQL data sink directly from the instrumented application use the following lines in your configuration file:

agent.sink.name = db_mysql

db_mysql.type                = mysql
db_mysql.host                = myhost
db_mysql.user                = myarm
db_mysql.database.definition = MyARM_Def
db_mysql.database.application= MyARM_App
db_mysql.database.transaction= MyARM_Tran

Configuring command line tools

The following configuration properties are used to change the behaviour of all command line tools.

tools.source.name
configures the name of the data source to be used.

Configuring manager

The following configuration properties are used to change the default behaviour of the myarmmanager.

manager.tableview.items
configures which transaction items should be displayed by default within the definition selection table view. This setting can be changed using a dialog. For a detailed description of available transaction item names see "Configuring transaction items". A prefix of ! ignores the item and will not be displayed in the table view.
manager.treeview.items
configures which transaction items should be displayed within the tree selection tree view. Note currently this setting can not be changed from the manager. For a detailed description of available transaction item names see "Configuring transaction items". A prefix of ! ignores the item and will not be displayed in the tree view.

Configuring web browser

The following configuration properties are used to change the behaviour of the web myarmbrowser.

tools.browser.timeinterval.min (New since "2.1.x.0")
specifies the minimum interval which can be used by the user in the single date selection mode in minutes.

Default is 1.

tools.browser.timeinterval.max (New since "2.1.x.0")
specifies the maximum interval which can be used by the user in the single date selection mode in minutes.

Default is 1440 (one day).

tools.browser.user.admin (New since "2.1.x.0")
specifies the user name who has administrator rights. With administrator rights the order of selection and the time interval can be pre-defined for any other user.

Default is "\myarmproperty{tools.browser.user.admin} \myarmnew{2.1.x.0}{Properties}{tools.browser.user.admin}" (empty means there is no administrator user).

tools.browser.user.pre-defined (New since "2.1.x.1")
specifies a defined user name. Normally this property is left blank but if specified this user name is used for all sessions thus allowing a demostration or an application domain specific pre-defined user.

Default is "\myarmproperty{tools.browser.user.pre-defined} \myarmnew{2.1.x.1}{Properties}{tools.browser.user.pre-defined}" (empty means there is no pre-defined user).

Configuring time formats

Time values can be represented in various ways. MyARM supports the following time formatting patterns:

HH:MM:SS
hour:minute:second for example 16:29:37 for nearly half past five in the afternoon.
HH:MM:SS.ZZZ
hour:minute:second.millisecond for example 16:29:37.546 for nearly past five in the afternoon including millisecond precision.
HH:MM:SS AP
hour:minute:second in 12-hour clock notation for example 04:29:37 PM for nearly half past five in the afternoon.
HH:MM:SS.ZZZ AP
hour:minute:second.millsecond in 12-hour clock notation for example 04:29:37 PM for nearly half past five in the afternoon including millisecond precision.

Configuring date formats

Date values can be represented in various ways. MyARM supports the following date formatting patterns:

DD.MM.YYYY
day.month.year for example 11.12.2009 for the eleventh december 2009.
YYYY-MM-DD
year-month-day for example 2009-12-11 for the eleventh december 2009.
MM/DD/YYYY
month/day/year for example 12/11/2009 for the eleventh december 2009.
DD.MM.YY
day.month.year with two digit year; for example 11.12.09 for the eleventh december 2009.
YY-MM-DD
year-month-day with two digit year; for example 09-12-11 for the eleventh december 2009.
MM/DD/YY
month/day/year with two digit year; for example 12/11/09 for the eleventh december 2009.

Configuring response time formats

Response times can be in a wide range of time intervals according to their corresponding transactions. For long running transactions it is not useful to display the response time in micro- or even nanoseconds. But if you want to measure low level transaction it may be necessary to use such short time units. For this purpose you can configure how MyARM tools display and parse response times:

<component>.rtformat= rtfmt
configures response time format of rtfmt in the configuration file for the specified component.
-rf rtfmt , --rt-fmt rtfmt
configures response time format of rtfmt on command line for various tools.

rtfmt can be one of the following strings (letters in parentheses can be omitted):

ns
response times in nanoseconds
mic(s)
response times in microseconds
ms
response times in milliseconds, nanoseconds remainder are omitted
s(ec)
response times in seconds, nanoseconds remainder are omitted
m(in)
response times in minutes, microseconds remainder are omitted
h(our)
response times in hours, microseconds remainder are omitted
d(ay)
response times in days, milliseconds remainder are omitted

Configuring sorting criteria

When operating on a set of application or transaction data it might be good in some circumstances that you can sort the output. For this purpose you can configure the sorting of application and transaction data within the configuration file or as a command line option:

<component>.sort.criteria=criteria
Configures the specified component to use the given sort criteria. See below.
-sb criteria, --sort-by criteria
Specifies the sort criteria. See below.

Currently valid sorting criteria are:

None
no sorting at all
Start
sorting by start time of the transactions
Stop
sorting by stop time of the transactions
Duration
sorting by response time of the transactions
Arrival
sorting by arrival time of the transactions
Blocked
sorting by blocked time of the transactions

Configuring transaction items

The manager analysis tool can be configured to only display specific data of a measured transaction to focus on special information of measured transactions. Therefore each transaction data item can be specified by name. Here is a list of all supported transaction item names with a brief description:

Ident
Identification of transaction (e.g. application and transaction name).
Name
Name of transaction.
StartDate
Start date of the transaction.
StartTime
Start time of the transaction.
Duration
Duration of the transaction (response time).
StopDate
Stop date of the transaction.
StopTime
Stop time of the transaction.
ASyncPcDuration
Asynchronous duration of the transaction (response time from parent to child).
ASyncCpDuration
Asynchronous duration of the transaction (response time from child to parent).
Arrival
Arrival time of the transaction before it was started.
Blocked
Blocked transaction time. Time the transaction waited for some resource.
Status
Transaction status.
Start
Start time and date of the transaction.
Stop
Stop time and date of the transaction.
URI
Transaction associated URI.
SystemAddress
System address the transaction was executed on.
Handle
Transaction handle.
AppHandle
Application handle.
TreePercent
Percentage of child duration in relation to its root parent.
Number
Current number of transaction.
DiagDetail
Diagnostic detail string if transaction failed (FAILED).
User
Transaction associated user.
Metric1
First associated metric (stored in slot 0).
Metric2
Second associated metric (stored in slot 1).
Metric3
Third associated metric (stored in slot 2).
Metric4
Fourth associated metric (stored in slot 3).
Metric5
Fifth associated metric (stored in slot 4).
Metric6
Sixth associated metric (stored in slot 5).
Metric7
Seventh associated metric (stored in slot 6).
Context
List of all associated context values.
Context01
1. associated context value.
Context02
2. associated context value.
Context03
3. associated context value.
Context04
4. associated context value.
Context05
5. associated context value.
Context06
6. associated context value.
Context07
7. associated context value.
Context08
8. associated context value.
Context09
9. associated context value.
Context10
10. associated context value.
Context11
11. associated context value.
Context12
12. associated context value.
Context13
13. associated context value.
Context14
14. associated context value.
Context15
15. associated context value.
Context16
16. associated context value.
Context17
17. associated context value.
Context18
18. associated context value.
Context19
19. associated context value.
Context20
20. associated context value.