The CMX API provide calls to public basic informations about the running programm and maintain a custom set of metrics.
While some basic read-out tools are provided the published metrics can also be accessed using the very same api as for publishing.
In CMX Values are grouped into Components. A component can be created at any time in the program.
For more information visit CMX on https://cern.ch/cmx and/or https://wikis.cern.ch/display/MW/CMX
The following function are realtime compatible:
For other functions please refer to the function documentation.
Values are referenced by so called value-handles. The validity of a value-handle cannot be ensured by the semantics of the programming language. The Developer have to be aware of the possibility that a value-handle is invalid and handle the respective error code E_CMX_INVALID_HANDLE. Particularly with regard to reading CMX SHM components that are managed by other processes.
All functions except cmx_shm_create(), cmx_shm_open(), cmx_shm_open_ro() and cmx_shm_create() are thread-safe.
The functions cmx_shm_create(), cmx_shm_open(), cmx_shm_open_ro() and cmx_shm_create() are only thread-safe if every function operates with a different cmx_shm_t datastructure.
Currently, CMX supports the following data types:
CMX_TYPE_INT64
Signed integer number 64bit CMX_TYPE_FLOAT64
Signed floating point number 64bit CMX_TYPE_BOOL
Boolean value CMX_TYPE_STRING
Character data, fixed size at creation timeAlthough CMX can handle arbitrary binary strings, one should use only ASCII or UTF-8 encoded Strings.
Depending on the further metrics processing environment, we recommend to avoid storing anything else than ASCII encoded strings.
After you have configured your compiler and linker settings (see the code examples for that), you can go into your code and start making use of CMX.
The first step is to register your process with CMX. The call `cmx_process_update()` will update (and create if necessary) a CMX Component with information about the running process.
Currently this includes the process name, hostname, manifest and some resource usage information.
#include <cmw-cmx/cmx.h> int main(..) { // Create the CMX Component for the process cmx_process_update(); while (1) { sleep(10); // do some work // Consider calling cmx_process_update() once in a while // to update the process metrics. cmx_process_update(); } }
Before you can update metrics you need to assign meaningful names and register them in CMX.
The INT64/FLOAT64/BOOL
typed values are called 'single values' because they have a fixed size.
The STRING
type is dynamically sized, you specifiy the length of the string while you register the name in the component. CMX keeps internally track of the string size, it doesn't use the null terminator \0.
#include <cmw-cmx/cmx.h> ... // Create the CMX Component cmx_shm * cmx_shm_ptr = cmx_shm_get(getpid(), "TestComponent"); // assert cmx_shm_ptr != NULL // Add Values int metric_no_gets = cmx_shm_add_value_single(cmx_shm_ptr, CMX_TYPE_INT64, "no_of_gets"); // assert ! (metric_no_gets < 0) int metric_no_sets = cmx_shm_add_value_single(cmx_shm_ptr, CMX_TYPE_INT64, "no_of_sets"); // assert ! (metric_no_sets < 0) int metrics_name = cmx_shm_add_value_string(cmx_shm_ptr, "name", 256); // assert ! (metrics_name < 0)
We can now set or update the values of the specified metrics. The relevant timestamps (`mtime`) will be automatically updated.
... // Set Values cmx_shm_value value; value._int64 = 1234; cmx_shm_set_value_single(cmx_shm_ptr, metric_no_gets, CMX_TYPE_INT64, &value); // returns E_CMX_SUCCESS or errorcode value._int64 = 5678; cmx_shm_set_value_single(cmx_shm_ptr, metric_no_sets, CMX_TYPE_INT64, &value); // returns E_CMX_SUCCESS or errorcode const char * val = "Hello World metric_anme"; cmx_shm_set_value_string(cmx_shm_ptr, metric_name, val, strlen(val)); // returns E_CMX_SUCCESS or errorcode
When adding values and CMX components, please respect the following conventions:
For all names:
For component names:
cmx_comp_register
("dmn2-agentlib-cpp.stats",10,0,0); (Take care of the 31 chars limit). '_'
is reserved for predefined process metrics.For metric names:
For now CMX uses a very simple logging approach. There is only stdout logging and six Loglevels: (AUDIT,ERROR,WARN,INFO,DEBUG,TRACE).
AUDIT is the highest log-level, TRACE is the lowest, most-detailed level. One can specify another default value using the environment variable CMX_LOG_LEVEL (since 2.1.1, before the name of the environment variable is LOG_LEVEL with CMX_ prefix):
[cmw-feedback-cmx-c]$ CMX_LOG_LEVEL=WARN ./demo/L865/example
Otherwise the default loglevel is INFO. The Loglevel can always be overwritten by the running program through access of the global cmx_log_current_level variable (see log.h).
Redirection of the cmx logging to the applications native logging system is possible through the C++ and the C-API. The C-API is more flexible here because there the printf-Arguments are still in the variable argument list and not already formatted into a fixed size buffer.
For details see in the C-API: log.h: cmx_log_adapter_t / cmx_log_set_adapter()
and for the C++ API Log.h: Log::log_adapter_t
/ setLogAdapter()
.
At start time CMX allocates about 2,64 Megabytes of memory per Component. However depending on how many values you add to the CMX Component the operating system will actually wire only a very small amount of it. By adding metrics, more and more of this memory, which is organized in pages spanning more than one CMX metric value slot, will get wired (fault-in) to physical memory pages.
This means the actual memory usage depends on how many metrics add to your CMX Component. You are able to add up to 20479 single metrics (int,float,bool) or up to about 2,3 megabytes of character data.
CMX uses POSIX Shared Memory (SHM) Objects. From the user side they are visible as files in the directory /dev/shm. All CMX SHM Objects are named with the following pattern: cmx
.<process_id>.<component_name>.
Apart from the metrics that are maintained by the application developer, CMX registers some default information in a so called Process Component at the moment that the process gets registered. Some of this is only available to the CERN environment like the Manifest information.
cmw-cmx-c
cmw-cmx-cpp / cmw-cmx-tools-cpp