|
[[_TOC_]]
|
|
[[_TOC_]]
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### How-to post-install CII services
|
|
### How-to post-install CII services
|
|
|
|
|
|
Most CII services (not: telemetry and alarms) come as part of the DevEnv installation, however some post-installation set-up is needed before they can be used.
|
|
Most CII services (not: telemetry and alarms) come as part of the DevEnv installation, however some post-installation set-up is needed before they can be used.
|
|
|
|
|
|
Post-installation is always necessary when you start working on a newly installed DevEnv host.
|
|
Post-installation is always necessary when you start working on a newly installed DevEnv host. After an upgrade of the DevEnv on an existing host, post-install may be necessary, too. In these cases, the Release Notes of the DevEnv version will inform you so.
|
|
After an upgrade of the DevEnv on an existing host, post-install may be necessary, too. In these cases, the Release Notes of the DevEnv version will inform you so.
|
|
|
|
|
|
|
|
_Note on DevEnv versions before 3.6_: On older DevEnv versions, you need to download the post-install first. On DevEnv 3.4, first execute this command (as root): `yum -y install elt-ciisrv-postinstall`. On DevEnv 3.5, execute this command (as root): `yum -y update elt-ciisrv-postinstall`
|
|
_Note on DevEnv versions before 3.6_: On older DevEnv versions, you need to download the post-install first. On DevEnv 3.4, first execute this command (as root): `yum -y install elt-ciisrv-postinstall`. On DevEnv 3.5, execute this command (as root): `yum -y update elt-ciisrv-postinstall`
|
|
|
|
|
|
|
|
|
|
To run post-install, execute this command (as root):
|
|
To run post-install, execute this command (as root):
|
|
```
|
|
|
|
|
|
```plaintext
|
|
# /elt/ciisrv/postinstall/cii-postinstall <choose a role>
|
|
# /elt/ciisrv/postinstall/cii-postinstall <choose a role>
|
|
```
|
|
```
|
|
|
|
|
|
To learn about the options, run the command without arguments.
|
|
To learn about the options, run the command without arguments.
|
|
|
|
|
|
For more details and examples, see the [cii-postinstall user manual](http://www.eso.org/~eltmgr/CII/latest/manuals/html/docs/services.html)
|
|
For more details and examples, see the [cii-postinstall user manual](http://www.eso.org/\~eltmgr/CII/latest/manuals/html/docs/services.html)
|
|
|
|
|
|
After postinstall, you will want to start the CII services on your host (unless you have assigned the "groupclient" role to the host, which means you will use the CII Services running on another host).
|
|
After postinstall, you will want to start the CII services on your host (unless you have assigned the "groupclient" role to the host, which means you will use the CII Services running on another host).
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### How-to start/stop CII services
|
|
### How-to start/stop CII services
|
|
|
|
|
|
The cii-services utility lets you start/stop/monitor the CII services. For some operations, it requires root-privileges, and can be run with `sudo`. If you don't use sudo, it will show a root password prompt when needed.
|
|
The cii-services utility lets you start/stop/monitor the CII services. For some operations, it requires root-privileges, and can be run with `sudo`. If you don't use sudo, it will show a root password prompt when needed.
|
|
|
|
|
|
Note: Before using CII services, you or an administrator have to run the CII-post-installation, see [How-to post-install CII services](#how-to-post-install-cii-services)
|
|
Note: Before using CII services, you or an administrator have to run the CII-post-installation, see [How-to post-install CII services](#how-to-post-install-cii-services)
|
|
|
|
|
|
*status*
|
|
_status_ This is a feature-centric view, that basically tells you which features you have available. For example, "Blob Values" means that the Distributed File System MinIO (in previous versions: Hadoop) is available for storage of large values and binaries.
|
|
This is a feature-centric view, that basically tells you which features you have available. For example, "Blob Values" means that the Distributed File System MinIO (in previous versions: Hadoop) is available for storage of large values and binaries.
|
|
|
|
```
|
|
```plaintext
|
|
$ cii-services status
|
|
$ cii-services status
|
|
```
|
|
```
|
|
|
|
|
|
*info*
|
|
_info_ This is a deployment-centric view that tells you whether the services are running and where they are.
|
|
This is a deployment-centric view that tells you whether the services are running and where they are.
|
|
|
|
```
|
|
```plaintext
|
|
$ cii-services info
|
|
$ cii-services info
|
|
```
|
|
```
|
|
|
|
|
|
*start / stop*
|
|
_start / stop_
|
|
```
|
|
|
|
|
|
```plaintext
|
|
$ sudo cii-services start <services>
|
|
$ sudo cii-services start <services>
|
|
```
|
|
```
|
|
|
|
|
|
To learn about the options, run the command without arguments.
|
|
To learn about the options, run the command without arguments.
|
|
|
|
|
|
For more details and examples, see the [cii-services user manual](http://www.eso.org/~eltmgr/CII/latest/manuals/html/docs/services.html)
|
|
For more details and examples, see the [cii-services user manual](http://www.eso.org/\~eltmgr/CII/latest/manuals/html/docs/services.html)
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### How-to get CII Demo apps
|
|
### How-to get CII Demo apps
|
|
|
|
|
|
CII has demo apps that you can download as source, modify, and build yourself. They demonstrate the use of the CII services.
|
|
CII has demo apps that you can download as source, modify, and build yourself. They demonstrate the use of the CII services.
|
|
|
|
|
|
```
|
|
```plaintext
|
|
$ git clone https://oauth2:ujak_jA2BjkL2UDW6v5h@gitlab.eso.org/cii/info/cii-demo.git
|
|
$ git clone https://oauth2:ujak_jA2BjkL2UDW6v5h@gitlab.eso.org/cii/info/cii-demo.git
|
|
Cloning into 'cii-demo'...
|
|
Cloning into 'cii-demo'...
|
|
[...]
|
|
[...]
|
... | @@ -84,11 +89,12 @@ After this, you find the list of available demo apps in the (generated) README f |
... | @@ -84,11 +89,12 @@ After this, you find the list of available demo apps in the (generated) README f |
|
|
|
|
|
Most demo apps require CII Services be running on your host or on another host => Check that the related CII Services (e.g. config service for a a config demo app) are accessible: see [How-to start/stop CII Services](#how-to-start-stop-cii-services)
|
|
Most demo apps require CII Services be running on your host or on another host => Check that the related CII Services (e.g. config service for a a config demo app) are accessible: see [How-to start/stop CII Services](#how-to-start-stop-cii-services)
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Insufficent Manuals, Contributions
|
|
### Insufficent Manuals, Contributions
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
... | @@ -111,22 +117,24 @@ Alternatively, and recommended, you can edit the files directly in the browser b |
... | @@ -111,22 +117,24 @@ Alternatively, and recommended, you can edit the files directly in the browser b |
|
|
|
|
|
_Note: If any of the buttons mentioned below is greyed out, you're lacking permissions. If so, please contact us first to request permission._
|
|
_Note: If any of the buttons mentioned below is greyed out, you're lacking permissions. If so, please contact us first to request permission._
|
|
|
|
|
|
1. Browse to https://gitlab.eso.org/cii/info/cii-docs
|
|
1. Browse to <https://gitlab.eso.org/cii/info/cii-docs>
|
|
|
|
|
|
2. Press "Web IDE"
|
|
2. Press "Web IDE"
|
|
|
|
|
|
3. In the Web IDE's file tree (left),
|
|
3. In the Web IDE's file tree (left),
|
|
|
|
|
|
* navigate to `userManual/ciiman/src/docs`
|
|
* navigate to `userManual/ciiman/src/docs`
|
|
* find and select the .rst file, and make your changes
|
|
* find and select the .rst file, and make your changes
|
|
|
|
|
|
4. Commit (blue button on lower left),
|
|
4. Commit (blue button on lower left),
|
|
|
|
|
|
* Leave the defaults (Create a new branch: YES, Start a new merge request: YES)
|
|
* Leave the defaults (Create a new branch: YES, Start a new merge request: YES)
|
|
* Write commit message: please write some rationale for your contribution
|
|
* Write commit message: please write some rationale for your contribution
|
|
|
|
|
|
5. Commit again (green button on lower left)
|
|
5. Commit again (green button on lower left)
|
|
|
|
|
|
* Leave the defaults (Delete source branch on commit: YES)
|
|
* Leave the defaults (Delete source branch on commit: YES)
|
|
|
|
|
|
6. Create Merge Request (blue button)
|
|
6. Create Merge Request (blue button)
|
|
|
|
|
|
* wait for pipeline to finish, at which point Jenkins will add his comment,
|
|
* wait for pipeline to finish, at which point Jenkins will add his comment,
|
|
* and in that comment follow the link under "Artifacts List" to see your change applied.
|
|
* and in that comment follow the link under "Artifacts List" to see your change applied.
|
|
|
|
|
... | @@ -134,28 +142,25 @@ _Note: If any of the buttons mentioned below is greyed out, you're lacking permi |
... | @@ -134,28 +142,25 @@ _Note: If any of the buttons mentioned below is greyed out, you're lacking permi |
|
|
|
|
|
We'll check the merge request, and your change can make it to the next release. Thanks in advance!
|
|
We'll check the merge request, and your change can make it to the next release. Thanks in advance!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### ------------------------------------------------------
|
|
### ------------------------------------------------------
|
|
### [ICD]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### \[ICD\]
|
|
|
|
|
|
### Failure to build ZPB from ICD \[ICD waf build\]
|
|
### Failure to build ZPB from ICD \[ICD waf build\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
Building an ICD, I get the following error:
|
|
Building an ICD, I get the following error:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
error: return type specification for constructor invalid
|
|
error: return type specification for constructor invalid
|
|
```
|
|
```
|
|
|
|
|
|
**Solution**
|
|
**Solution**
|
|
|
|
|
|
You have defined a struct containing a member of the same name ("feedback" in the example below). Rename one of the two.
|
|
You have defined a struct containing a member of the same name ("feedback" in the example below). Rename one of the two.
|
|
```
|
|
|
|
|
|
```plaintext
|
|
<struct name="feedback">
|
|
<struct name="feedback">
|
|
<member name="feedback" type="float" arrayDimensions="(10)"/>
|
|
<member name="feedback" type="float" arrayDimensions="(10)"/>
|
|
<member name="counter" type="uint32_t"/>
|
|
<member name="counter" type="uint32_t"/>
|
... | @@ -163,38 +168,36 @@ You have defined a struct containing a member of the same name ("feedback" in th |
... | @@ -163,38 +168,36 @@ You have defined a struct containing a member of the same name ("feedback" in th |
|
```
|
|
```
|
|
|
|
|
|
or you have used a struct name that is a reserved word in Protobuf. Rename it.
|
|
or you have used a struct name that is a reserved word in Protobuf. Rename it.
|
|
```
|
|
|
|
|
|
```plaintext
|
|
<struct name="Swap">
|
|
<struct name="Swap">
|
|
<member name="counter" type="uint32_t"/>
|
|
<member name="counter" type="uint32_t"/>
|
|
</struct>
|
|
</struct>
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
**Background**
|
|
**Background**
|
|
|
|
|
|
In the first case, the code that gets generated for the member looks to the compiler like a mal-formed constructor. In the second case, you have used a struct name that is already taken by a method name that protobuf secretly generates into the code to be compiled, which then leads to the same problem.
|
|
In the first case, the code that gets generated for the member looks to the compiler like a mal-formed constructor. In the second case, you have used a struct name that is already taken by a method name that protobuf secretly generates into the code to be compiled, which then leads to the same problem.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### No cpp/python from ICD \[ICD waf build\]
|
|
### No cpp/python from ICD \[ICD waf build\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
When I build my ICD, the build completes without errors or warnings,
|
|
When I build my ICD, the build completes without errors or warnings, but I find it has not generated any cpp and python classes for my ICD. I do see protoc file, though
|
|
but I find it has not generated any cpp and python classes for my ICD.
|
|
|
|
I do see protoc file, though
|
|
|
|
|
|
|
|
**Solution**
|
|
**Solution**
|
|
|
|
|
|
Check that you have specified all needed dependencies in your waf script.
|
|
Check that you have specified all needed dependencies in your waf script. The "requires" list needs to contain the following entries: requires='cxx python protoc fastdds boost cii gtest nosetests pytest'
|
|
The "requires" list needs to contain the following entries:
|
|
|
|
requires='cxx python protoc fastdds boost cii gtest nosetests pytest'
|
|
|
|
|
|
|
|
The full waf script for your project would look something like this:
|
|
The full waf script for your project would look something like this:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
declare_project(name='mytests',
|
|
declare_project(name='mytests',
|
|
version='1.0.0',
|
|
version='1.0.0',
|
|
requires='cxx python protoc fastdds boost cii gtest nosetests pytest',
|
|
requires='cxx python protoc fastdds boost cii gtest nosetests pytest',
|
... | @@ -205,7 +208,8 @@ declare_project(name='mytests', |
... | @@ -205,7 +208,8 @@ declare_project(name='mytests', |
|
```
|
|
```
|
|
|
|
|
|
Also, note that in DevEnv 3.x the order of dependencies matters:
|
|
Also, note that in DevEnv 3.x the order of dependencies matters:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
# Will not work, see the warnings during the 'waf configure' step.
|
|
# Will not work, see the warnings during the 'waf configure' step.
|
|
requires='cxx python protoc fastdds cii boost gtest nosetests pytest pyqt5 sphinx'
|
|
requires='cxx python protoc fastdds cii boost gtest nosetests pytest pyqt5 sphinx'
|
|
|
|
|
... | @@ -213,18 +217,19 @@ Also, note that in DevEnv 3.x the order of dependencies matters: |
... | @@ -213,18 +217,19 @@ Also, note that in DevEnv 3.x the order of dependencies matters: |
|
requires='cxx python protoc fastdds boost cii gtest nosetests pytest pyqt5 sphinx'
|
|
requires='cxx python protoc fastdds boost cii gtest nosetests pytest pyqt5 sphinx'
|
|
```
|
|
```
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### PYBIND errors \[ICD waf build\]
|
|
### PYBIND errors \[ICD waf build\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
Trying to build your MAL Application, you get errors like below related to the PYBIND module.
|
|
Trying to build your MAL Application, you get errors like below related to the PYBIND module.
|
|
|
|
|
|
```
|
|
```plaintext
|
|
icd/python/bindings/src/ModProto-benchmark.cpp:18:25: error: expected initializer before ‘-’ token
|
|
icd/python/bindings/src/ModProto-benchmark.cpp:18:25: error: expected initializer before ‘-’ token
|
|
PYBIND11_MODULE(ModProto-benchmark, modproto-benchmark) {
|
|
PYBIND11_MODULE(ModProto-benchmark, modproto-benchmark) {
|
|
```
|
|
```
|
... | @@ -233,7 +238,7 @@ icd/python/bindings/src/ModProto-benchmark.cpp:18:25: error: expected initialize |
... | @@ -233,7 +238,7 @@ icd/python/bindings/src/ModProto-benchmark.cpp:18:25: error: expected initialize |
|
|
|
|
|
Check the name of your ICD file:
|
|
Check the name of your ICD file:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
> find icd
|
|
> find icd
|
|
icd
|
|
icd
|
|
icd/wscript
|
|
icd/wscript
|
... | @@ -245,7 +250,7 @@ The icd file name contains a minus, which is actually reflected in the above err |
... | @@ -245,7 +250,7 @@ The icd file name contains a minus, which is actually reflected in the above err |
|
|
|
|
|
Rename the file to something like this:
|
|
Rename the file to something like this:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
> find icd
|
|
> find icd
|
|
icd
|
|
icd
|
|
icd/wscript
|
|
icd/wscript
|
... | @@ -255,18 +260,19 @@ icd/src/protobenchmark.xml |
... | @@ -255,18 +260,19 @@ icd/src/protobenchmark.xml |
|
|
|
|
|
In general, due to the many code generation steps taking place, your freedom in ICD file naming is limited.
|
|
In general, due to the many code generation steps taking place, your freedom in ICD file naming is limited.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### multiple XMLs found \[ICD waf build\]
|
|
### multiple XMLs found \[ICD waf build\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
Trying to build your ICD module, you see this error:
|
|
Trying to build your ICD module, you see this error:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
Waf: Entering directory \`/home/eltdev/repos/hlcc/build'
|
|
Waf: Entering directory \`/home/eltdev/repos/hlcc/build'
|
|
Error: multiple XMLs found, just one supported.
|
|
Error: multiple XMLs found, just one supported.
|
|
```
|
|
```
|
... | @@ -285,26 +291,26 @@ The error message is misleading (will be improved, [ECII-426](https://jira.eso.o |
... | @@ -285,26 +291,26 @@ The error message is misleading (will be improved, [ECII-426](https://jira.eso.o |
|
|
|
|
|
The code generator for malicd_topics fails when the ICD file name starts with lowercase.
|
|
The code generator for malicd_topics fails when the ICD file name starts with lowercase.
|
|
|
|
|
|
For more information, see also: [KB: PYBIND errors \[ICD waf build\]](onenote:#KB%20PYBIND%20errors%20[ICD%20waf%20build]§ion-id={F524F9BE-F51D-4A01-9976-93359FCC4966}&page-id={0FEE4FB9-C58B-4E8A-A276-2EC4367CFB30}&end&base-path=https://europeansouthernobservatory.sharepoint.com/sites/ELT_Control/SiteAssets/ELT_Control%20Notebook/Documentation/ELT%20Control%20KnowledgeBase.one)
|
|
For more information, see also: [KB: PYBIND errors \[ICD waf build\]](onenote:#KB%20PYBIND%20errors%20%5BICD%20waf%20build%5D§ion-id=%7BF524F9BE-F51D-4A01-9976-93359FCC4966%7D&page-id=%7B0FEE4FB9-C58B-4E8A-A276-2EC4367CFB30%7D&end&base-path=https://europeansouthernobservatory.sharepoint.com/sites/ELT_Control/SiteAssets/ELT_Control%20Notebook/Documentation/ELT%20Control%20KnowledgeBase.one)
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### g++: internal compiler error, g++ fatal error \[ICD waf build\]
|
|
### g++: internal compiler error, g++ fatal error \[ICD waf build\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
Trying to build an ICD-module or MAL-application, the build takes a long time, and/or fails with an error message like this:
|
|
Trying to build an ICD-module or MAL-application, the build takes a long time, and/or fails with an error message like this:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
g++: fatal error: Killed signal terminated program cc1plus
|
|
g++: fatal error: Killed signal terminated program cc1plus
|
|
compilation terminated.
|
|
compilation terminated.
|
|
```
|
|
```
|
|
|
|
|
|
```
|
|
```plaintext
|
|
Software/CcsLibs/CcsTestData/python/bindings/src/ModCcstestdata.cpp:18:1: note:
|
|
Software/CcsLibs/CcsTestData/python/bindings/src/ModCcstestdata.cpp:18:1: note:
|
|
in expansion of macro ‘PYBIND11_MODULE’
|
|
in expansion of macro ‘PYBIND11_MODULE’
|
|
PYBIND11_MODULE(ModCcstestdata, modccstestdata) {
|
|
PYBIND11_MODULE(ModCcstestdata, modccstestdata) {
|
... | @@ -312,7 +318,6 @@ Software/CcsLibs/CcsTestData/python/bindings/src/ModCcstestdata.cpp:18:1: note: |
... | @@ -312,7 +318,6 @@ Software/CcsLibs/CcsTestData/python/bindings/src/ModCcstestdata.cpp:18:1: note: |
|
g++: internal compiler error: Killed (program cc1plus)
|
|
g++: internal compiler error: Killed (program cc1plus)
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
**Background**
|
|
**Background**
|
|
|
|
|
|
The cpp compiler runs out of memory and crashes. You can see the effect by running htop in a separate terminal, all memory (including swap space) is consumed by the g++ compiler, which consequently crashes.
|
|
The cpp compiler runs out of memory and crashes. You can see the effect by running htop in a separate terminal, all memory (including swap space) is consumed by the g++ compiler, which consequently crashes.
|
... | @@ -322,9 +327,8 @@ _Memory needed for building a given ICD module_ |
... | @@ -322,9 +327,8 @@ _Memory needed for building a given ICD module_ |
|
There is a base load that is the same for all ICD modules. On top of that, the ICD file contents determine how much memory is needed to build the module.
|
|
There is a base load that is the same for all ICD modules. On top of that, the ICD file contents determine how much memory is needed to build the module.
|
|
|
|
|
|
_Rule of Thumb_
|
|
_Rule of Thumb_
|
|
|
|
|
|
| MAL version | Base Load | Mem per ICD-Struct |
|
|
| MAL version | Base Load | Mem per ICD-Struct |
|
|
| --- | ---- | ---- |
|
|
|-------------|-----------|--------------------|
|
|
| MAL 1.x | 650 MB (2/3 GB) | 320 MB (1/3 GB) |
|
|
| MAL 1.x | 650 MB (2/3 GB) | 320 MB (1/3 GB) |
|
|
| MAL 2.0 | 650 MB (2/3 GB) | 110 MB (1/8 GB) |
|
|
| MAL 2.0 | 650 MB (2/3 GB) | 110 MB (1/8 GB) |
|
|
|
|
|
... | @@ -333,7 +337,8 @@ Thus, if your biggest ICD contains 20 structs, building under MAL 1.x will requi |
... | @@ -333,7 +337,8 @@ Thus, if your biggest ICD contains 20 structs, building under MAL 1.x will requi |
|
_Measuring_
|
|
_Measuring_
|
|
|
|
|
|
Record metrics of the ICD build with this time-command:
|
|
Record metrics of the ICD build with this time-command:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
$ alias time='TIME="real\t%E\nmem\t%Mk\ncpu\t%P\npf\t%F" time'
|
|
$ alias time='TIME="real\t%E\nmem\t%Mk\ncpu\t%P\npf\t%F" time'
|
|
$ time waf build
|
|
$ time waf build
|
|
|
|
|
... | @@ -349,12 +354,12 @@ pf 166 |
... | @@ -349,12 +354,12 @@ pf 166 |
|
|
|
|
|
More info is available at [ECII-109](https://jira.eso.org/browse/ECII-109)
|
|
More info is available at [ECII-109](https://jira.eso.org/browse/ECII-109)
|
|
|
|
|
|
|
|
|
|
**Solution 1: Decrease the module's footprint**
|
|
**Solution 1: Decrease the module's footprint**
|
|
|
|
|
|
1. Remove unnecessary middlewares
|
|
1. Remove unnecessary middlewares
|
|
|
|
|
|
Use the `xyz_disabled` options:
|
|
Use the `xyz_disabled` options:
|
|
|
|
|
|
```python
|
|
```python
|
|
from wtools import module
|
|
from wtools import module
|
|
# Disable OPCUA and DDS, since not part of this interface.
|
|
# Disable OPCUA and DDS, since not part of this interface.
|
... | @@ -365,37 +370,34 @@ module.declare_malicd(mal_opts={'opcua_disabled': True, 'dds_disabled': True}) |
... | @@ -365,37 +370,34 @@ module.declare_malicd(mal_opts={'opcua_disabled': True, 'dds_disabled': True}) |
|
|
|
|
|
By default the build system uses all cores on the host. Less parallelism means less memory consumers during the build. This is controlled by the waf `-j` option.
|
|
By default the build system uses all cores on the host. Less parallelism means less memory consumers during the build. This is controlled by the waf `-j` option.
|
|
|
|
|
|
To build with only 4 cores:
|
|
To build with only 4 cores: `$ time waf -j4 build`
|
|
` $ time waf -j4 build `
|
|
|
|
|
|
|
|
As a rough estimate, each waf build task will consume around 2 GB RAM, so on a 12 core host with 16 GB RAM, a parallelism of 8 may be a good choice. Try different numbers of cores and use the output from the time-command (see above) to find an optimum between real, page faults, and cpu.
|
|
As a rough estimate, each waf build task will consume around 2 GB RAM, so on a 12 core host with 16 GB RAM, a parallelism of 8 may be a good choice. Try different numbers of cores and use the output from the time-command (see above) to find an optimum between real, page faults, and cpu.
|
|
|
|
|
|
|
|
|
|
3. Adjust the compiler flags
|
|
3. Adjust the compiler flags
|
|
|
|
|
|
The default set of compiler flags applied by the build system consume significant memory.
|
|
The default set of compiler flags applied by the build system consume significant memory. We recommend using "-O2 -flto -pipe" (_to be confirmed_) instead. This is how you pass custom compiler flags for your ICD-module:
|
|
We recommend using "-O2 -flto -pipe" (_to be confirmed_) instead. This is how you pass custom compiler flags for your ICD-module:
|
|
|
|
|
|
|
|
In your project wscript:
|
|
In your project wscript:
|
|
~~~python
|
|
|
|
|
|
```python
|
|
from wtools import project
|
|
from wtools import project
|
|
[...]
|
|
[...]
|
|
def configure(cnf):
|
|
def configure(cnf):
|
|
cnf.env.CXXFLAGS_MALPYTHON = '-O2 -flto -pipe'
|
|
cnf.env.CXXFLAGS_MALPYTHON = '-O2 -flto -pipe'
|
|
[...]
|
|
[...]
|
|
~~~
|
|
```
|
|
|
|
|
|
4. Refactor your ICD
|
|
4. Refactor your ICD
|
|
|
|
|
|
Reduce the memory need by splitting the big ICDs up into 2 or more smaller ICD modules.
|
|
Reduce the memory need by splitting the big ICDs up into 2 or more smaller ICD modules.
|
|
|
|
|
|
|
|
|
|
**Solution 2: Increase the available memory**
|
|
**Solution 2: Increase the available memory**
|
|
|
|
|
|
1. Find RAM consumers and stop them, at least temporarily. For example, ElasticSearch uses a significant amount of RAM: `sudo cii-services stop elasticsearch`
|
|
1. Find RAM consumers and stop them, at least temporarily. For example, ElasticSearch uses a significant amount of RAM: `sudo cii-services stop elasticsearch`
|
|
|
|
|
|
2. Add temporary swap space to your host
|
|
2. Add temporary swap space to your host
|
|
```bash
|
|
|
|
|
|
```shell
|
|
# As root:
|
|
# As root:
|
|
fallocate -l 8G /swapfile
|
|
fallocate -l 8G /swapfile
|
|
dd if=/dev/zero of=/swapfile bs=1024 count=8388608
|
|
dd if=/dev/zero of=/swapfile bs=1024 count=8388608
|
... | @@ -412,14 +414,12 @@ Reduce the memory need by splitting the big ICDs up into 2 or more smaller ICD m |
... | @@ -412,14 +414,12 @@ Reduce the memory need by splitting the big ICDs up into 2 or more smaller ICD m |
|
|
|
|
|
Increase your RAM, respectively ask your system administrator to do it. Assess the necessary amount by using the "Rule Of Thumb" above.
|
|
Increase your RAM, respectively ask your system administrator to do it. Assess the necessary amount by using the "Rule Of Thumb" above.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Choose middlewares to build \[MAL ICD\]
|
|
### Choose middlewares to build \[MAL ICD\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
... | @@ -434,31 +434,29 @@ By default the ICD-compilation builds mappings for all middlewares. But it is po |
... | @@ -434,31 +434,29 @@ By default the ICD-compilation builds mappings for all middlewares. But it is po |
|
|
|
|
|
wscript
|
|
wscript
|
|
|
|
|
|
```
|
|
```plaintext
|
|
declare_malicd(use='icds.base', mal_opts = { 'opcua_disabled': True } )
|
|
declare_malicd(use='icds.base', mal_opts = { 'opcua_disabled': True } )
|
|
```
|
|
```
|
|
|
|
|
|
The available options are:
|
|
The available options are:
|
|
|
|
|
|
- opcua_disabled = if True, disable OPCUA middleware generation
|
|
- opcua_disabled = if True, disable OPCUA middleware generation
|
|
|
|
|
|
- dds_disabled = if True, disable DDS middleware generation
|
|
- dds_disabled = if True, disable DDS middleware generation
|
|
|
|
|
|
- zpb_disabled = if True, disable ZEROMQ middleware generation
|
|
- zpb_disabled = if True, disable ZEROMQ middleware generation
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### Variable Tracking exceeded \[ICD\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Variable Tracking exceeded [ICD]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
When building an ICD using CII-MAL, you see this warning message:
|
|
When building an ICD using CII-MAL, you see this warning message:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
variable tracking size limit exceeded
|
|
variable tracking size limit exceeded
|
|
```
|
|
```
|
|
|
|
|
... | @@ -474,7 +472,7 @@ There are two easy ways to do it on the overall project. |
... | @@ -474,7 +472,7 @@ There are two easy ways to do it on the overall project. |
|
|
|
|
|
**Solution A**
|
|
**Solution A**
|
|
|
|
|
|
```
|
|
```plaintext
|
|
Export CXXFLAGS=-fno-var-tracking-assignments
|
|
Export CXXFLAGS=-fno-var-tracking-assignments
|
|
```
|
|
```
|
|
|
|
|
... | @@ -486,48 +484,47 @@ Note: you have to have the exported variable each time you do a “waf configure |
... | @@ -486,48 +484,47 @@ Note: you have to have the exported variable each time you do a “waf configure |
|
|
|
|
|
If you want it to be inside the project then put the flags fixed inside your project, so in the top level wscript (where you define the project) add this configure section before the project declaration:
|
|
If you want it to be inside the project then put the flags fixed inside your project, so in the top level wscript (where you define the project) add this configure section before the project declaration:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
def configure(cnf):
|
|
def configure(cnf):
|
|
|
|
|
|
cnf.env.append_value('CXXFLAGS', \['-fno-var-tracking-assignments'\])
|
|
cnf.env.append_value('CXXFLAGS', \['-fno-var-tracking-assignments'\])
|
|
```
|
|
```
|
|
|
|
|
|
|
|
### ------------------------------------------------------
|
|
|
|
|
|
|
|
### \[MAL\]
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
### Avoid ephemeral ports \[MAL\]
|
|
|
|
|
|
### ------------------------------------------------------
|
|
|
|
### [MAL]
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Avoid ephemeral ports [MAL]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
When you leave a client running for a while (say 20 minutes) without server available, you start getting errors:
|
|
When you leave a client running for a while (say 20 minutes) without server available, you start getting errors:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
Message=Malformed message received, missing frames.
|
|
Message=Malformed message received, missing frames.
|
|
```
|
|
```
|
|
|
|
|
|
Starting the server does not fix the situation, and gives this error:
|
|
Starting the server does not fix the situation, and gives this error:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
Errno 48 : Address already in use
|
|
Errno 48 : Address already in use
|
|
```
|
|
```
|
|
|
|
|
|
**Solution**
|
|
**Solution**
|
|
|
|
|
|
The solution is to not use ports from the ephemeral range (aka local port range). The port numbers in the ephemeral range can be found with `cat /proc/sys/net/ipv4/ip_local_port_range`. For DevEnv 3.x with CentOS 8 they are:
|
|
The solution is to not use ports from the ephemeral range (aka local port range). The port numbers in the ephemeral range can be found with `cat /proc/sys/net/ipv4/ip_local_port_range`. For DevEnv 3.x with CentOS 8 they are:
|
|
|
|
|
|
| Port Range | Usable for MAL |
|
|
| Port Range | Usable for MAL |
|
|
| ---- | ---- |
|
|
|------------|----------------|
|
|
| 1 -1023 | 🟠 No |
|
|
| 1 -1023 | 🟠 No |
|
|
| 1024 - 32767 | 🟢 Yes |
|
|
| 1024 - 32767 | 🟢 Yes |
|
|
| 32768 - 60999 | 🟠 No |
|
|
| 32768 - 60999 | 🟠 No |
|
|
| 61000 - 65535 | 🟢 Yes |
|
|
| 61000 - 65535 | 🟢 Yes |
|
|
|
|
|
|
With the implementation of ECII-402, the MAL library will write a warning log (and can also be configured to throw an exception) if an application runs a MAL instance on one of the ephemeral ports.
|
|
With the implementation of ECII-402, the MAL library will write a warning log (and can also be configured to throw an exception) if an application runs a MAL instance on one of the ephemeral ports.
|
|
|
|
|
... | @@ -539,11 +536,13 @@ After a while of (re-)connection attempts, the client will manage to connect... |
... | @@ -539,11 +536,13 @@ After a while of (re-)connection attempts, the client will manage to connect... |
|
|
|
|
|
This happens because TCP design allows for a 'simultaneous connect feature': if a client is trying to connect to local port and if the port is from the ephemeral range, it can occasionally connect to itself. The client thinks it is connected to a server, however it is actually connected to itself. Moreover, the server can not bind to its server port anymore.
|
|
This happens because TCP design allows for a 'simultaneous connect feature': if a client is trying to connect to local port and if the port is from the ephemeral range, it can occasionally connect to itself. The client thinks it is connected to a server, however it is actually connected to itself. Moreover, the server can not bind to its server port anymore.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
### Req/Rep Connection Listeners \[MAL Python\]
|
|
### Req/Rep Connection Listeners [MAL Python]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
... | @@ -554,7 +553,8 @@ This is done with the method `registerConnectionListener()`. |
... | @@ -554,7 +553,8 @@ This is done with the method `registerConnectionListener()`. |
|
Given the example below, this does not work, and the `listenerMethod()` is never called.
|
|
Given the example below, this does not work, and the `listenerMethod()` is never called.
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
```plaintext
|
|
import sys
|
|
import sys
|
|
import datetime
|
|
import datetime
|
|
import signal
|
|
import signal
|
... | @@ -593,14 +593,14 @@ rtn = stdcmds.Status() |
... | @@ -593,14 +593,14 @@ rtn = stdcmds.Status() |
|
rtn.wait()
|
|
rtn.wait()
|
|
print( str(rtn.get() ))
|
|
print( str(rtn.get() ))
|
|
```
|
|
```
|
|
|
|
|
|
*From \<<https://jira.eso.org/browse/ECII-212>\>*
|
|
_From <_[_https://jira.eso.org/browse/ECII-212_](https://jira.eso.org/browse/ECII-212)_>_
|
|
|
|
|
|
**Solution**
|
|
**Solution**
|
|
|
|
|
|
The developer must keep a reference to the returned Object from the `registerConnectionListener()` invocation.
|
|
The developer must keep a reference to the returned Object from the `registerConnectionListener()` invocation.
|
|
|
|
|
|
```
|
|
```plaintext
|
|
stdcmds = factory.getClient(uri, StdCmdsAsync, qos=mal.rr.qos.ReplyTime(THREE_SECONDS))
|
|
stdcmds = factory.getClient(uri, StdCmdsAsync, qos=mal.rr.qos.ReplyTime(THREE_SECONDS))
|
|
listenerRegistration = stdcmds.registerConnectionListener(listenerMethod)
|
|
listenerRegistration = stdcmds.registerConnectionListener(listenerMethod)
|
|
```
|
|
```
|
... | @@ -611,14 +611,15 @@ The documentation states a Return value, but is the responsibility of the develo |
... | @@ -611,14 +611,15 @@ The documentation states a Return value, but is the responsibility of the develo |
|
|
|
|
|
Remember to delete (assign None), to this object when closing the connection to the MAL service.
|
|
Remember to delete (assign None), to this object when closing the connection to the MAL service.
|
|
|
|
|
|
*From \<<https://jira.eso.org/browse/ECII-212>\>*
|
|
_From <_[_https://jira.eso.org/browse/ECII-212_](https://jira.eso.org/browse/ECII-212)_>_
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
### Latency on Pub/Sub \[MAL ZMQ\]
|
|
### Latency on Pub/Sub [MAL ZMQ]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
... | @@ -634,7 +635,7 @@ From MAL 1.0.4 on, |
... | @@ -634,7 +635,7 @@ From MAL 1.0.4 on, |
|
|
|
|
|
MAL supports the below MAL specific property to limit queue size for large message publishers.
|
|
MAL supports the below MAL specific property to limit queue size for large message publishers.
|
|
|
|
|
|
```
|
|
```plaintext
|
|
mal::Mal::Properties m_malProperties1;
|
|
mal::Mal::Properties m_malProperties1;
|
|
m_malProperties1["zpb.ps.zmq.sndhwm"] = "1";
|
|
m_malProperties1["zpb.ps.zmq.sndhwm"] = "1";
|
|
|
|
|
... | @@ -653,23 +654,23 @@ The issue has been first reported in [ECII-159](https://jira.eso.org/browse/ECII |
... | @@ -653,23 +654,23 @@ The issue has been first reported in [ECII-159](https://jira.eso.org/browse/ECII |
|
|
|
|
|
The problem lies in the ZMQ send queues. Default size is 1000 and with 144MB per message (in this case) this means 144GB. Limiting this to 1 (for a test) a publisher can handle 20 subscribers (tested) without any problems. The solution is to reconfigure the send-queue size appropriately.
|
|
The problem lies in the ZMQ send queues. Default size is 1000 and with 144MB per message (in this case) this means 144GB. Limiting this to 1 (for a test) a publisher can handle 20 subscribers (tested) without any problems. The solution is to reconfigure the send-queue size appropriately.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### Sending an array of unions \[MAL CPP\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Sending an array of unions [MAL CPP]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
Trying to send a msg, I get the following error message from CII:
|
|
Trying to send a msg, I get the following error message from CII:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
[libprotobuf ERROR google/protobuf/message_lite.cc:121] Can't parse message of type "generated.zpb.fcfif.StdCmds_Request" because it is missing required fields: data.Setup.payload[0].piezoData.input
|
|
[libprotobuf ERROR google/protobuf/message_lite.cc:121] Can't parse message of type "generated.zpb.fcfif.StdCmds_Request" because it is missing required fields: data.Setup.payload[0].piezoData.input
|
|
```
|
|
```
|
|
|
|
|
|
My ICD definition looks like this
|
|
My ICD definition looks like this
|
|
|
|
|
|
```xml
|
|
```xml
|
|
<enum name="PiezoInput">
|
|
<enum name="PiezoInput">
|
... | @@ -717,7 +718,7 @@ My ICD definition looks like this |
... | @@ -717,7 +718,7 @@ My ICD definition looks like this |
|
|
|
|
|
My code looks like this
|
|
My code looks like this
|
|
|
|
|
|
```
|
|
```plaintext
|
|
[...]
|
|
[...]
|
|
auto piezo = mal->createDataEntity<::fcfif::Piezo>();
|
|
auto piezo = mal->createDataEntity<::fcfif::Piezo>();
|
|
piezo->setId("foo");
|
|
piezo->setId("foo");
|
... | @@ -731,10 +732,10 @@ union->setPiezoData(piezo); |
... | @@ -731,10 +732,10 @@ union->setPiezoData(piezo); |
|
|
|
|
|
[...]
|
|
[...]
|
|
```
|
|
```
|
|
|
|
|
|
**Solution**
|
|
|
|
|
|
|
|
```
|
|
**Solution**
|
|
|
|
|
|
|
|
```plaintext
|
|
auto p = factory.getClient<::fcfif::PiezoTestSync>(uri,
|
|
auto p = factory.getClient<::fcfif::PiezoTestSync>(uri,
|
|
{std::make_shared<mal::rr::qos::ReplyTime>
|
|
{std::make_shared<mal::rr::qos::ReplyTime>
|
|
(std::chrono::seconds(3))},
|
|
(std::chrono::seconds(3))},
|
... | @@ -769,17 +770,19 @@ Your code does not work since you do not use union instance provided by the pare |
... | @@ -769,17 +770,19 @@ Your code does not work since you do not use union instance provided by the pare |
|
|
|
|
|
This issue was first described in [ECII-154](https://jira.eso.org/browse/ECII-154)
|
|
This issue was first described in [ECII-154](https://jira.eso.org/browse/ECII-154)
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
### Failed to send request, send queue full [MAL]
|
|
|
|
|
|
### Failed to send request, send queue full \[MAL\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
You are intending to update a config, but you get an IllegalStateException where the last line is
|
|
You are intending to update a config, but you get an IllegalStateException where the last line is
|
|
|
|
|
|
```
|
|
```plaintext
|
|
elt.mal.zpb.rr.ClientAsyncImpl:183
|
|
elt.mal.zpb.rr.ClientAsyncImpl:183
|
|
```
|
|
```
|
|
|
|
|
... | @@ -789,13 +792,13 @@ throw `new MalException("Failed to send request, send queue full");` |
... | @@ -789,13 +792,13 @@ throw `new MalException("Failed to send request, send queue full");` |
|
|
|
|
|
Probably you have called close() on the CiiConfigClient instance somewhere, maybe also implicitly during a try-with-resource block.
|
|
Probably you have called close() on the CiiConfigClient instance somewhere, maybe also implicitly during a try-with-resource block.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### Getting More Logs \[MAL Log\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Getting More Logs [MAL Log]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
... | @@ -807,7 +810,7 @@ The MAL seems to misbehave. How can I get more log messages from the MAL used in |
... | @@ -807,7 +810,7 @@ The MAL seems to misbehave. How can I get more log messages from the MAL used in |
|
|
|
|
|
From MAL 1.1.0, edit the MAL log4j config xml and specify the MAL log levels:
|
|
From MAL 1.1.0, edit the MAL log4j config xml and specify the MAL log levels:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
<Logger name="elt.mal" level="TRACE" />
|
|
<Logger name="elt.mal" level="TRACE" />
|
|
```
|
|
```
|
|
|
|
|
... | @@ -817,7 +820,7 @@ Example for **Zpb.** For other middlewares, see below |
... | @@ -817,7 +820,7 @@ Example for **Zpb.** For other middlewares, see below |
|
|
|
|
|
1. Put a log-config file into your file system:
|
|
1. Put a log-config file into your file system:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
log4cplus.rootLogger=TRACE, stdout
|
|
log4cplus.rootLogger=TRACE, stdout
|
|
|
|
|
|
log4cplus.logger.malDds=TRACE, MyFileAppender
|
|
log4cplus.logger.malDds=TRACE, MyFileAppender
|
... | @@ -895,14 +898,13 @@ log4cplus.appender.MyFileAppender.layout=log4cplus::PatternLayout |
... | @@ -895,14 +898,13 @@ log4cplus.appender.MyFileAppender.layout=log4cplus::PatternLayout |
|
log4cplus.appender.MyFileAppender.layout.ConversionPattern=[%-5p][%D{%Y/%m/%d %H:%M:%S:%q}][%-l][%t] %m%n
|
|
log4cplus.appender.MyFileAppender.layout.ConversionPattern=[%-5p][%D{%Y/%m/%d %H:%M:%S:%q}][%-l][%t] %m%n
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
2. Pass the path to the log-config to MAL:
|
|
2. Pass the path to the log-config to MAL:
|
|
|
|
|
|
MAL logging is initialized from a configuration file, the path of which is read from mal properties with key mal::PROP_LOG_CONFIG_FILENAME. When loading mal, use set mal::PROP_LOG_CONFIG_FILENAME in mal properties.
|
|
MAL logging is initialized from a configuration file, the path of which is read from mal properties with key mal::PROP_LOG_CONFIG_FILENAME. When loading mal, use set mal::PROP_LOG_CONFIG_FILENAME in mal properties.
|
|
|
|
|
|
For example:
|
|
For example:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
auto zpbMal = mal::loadMal("zpb",
|
|
auto zpbMal = mal::loadMal("zpb",
|
|
mal::Mal::Properties{{mal::PROP_LOG_CONFIG_FILENAME,"/path/to/mal-log4cplus.conf"}}
|
|
mal::Mal::Properties{{mal::PROP_LOG_CONFIG_FILENAME,"/path/to/mal-log4cplus.conf"}}
|
|
);
|
|
);
|
... | @@ -910,7 +912,7 @@ auto zpbMal = mal::loadMal("zpb", |
... | @@ -910,7 +912,7 @@ auto zpbMal = mal::loadMal("zpb", |
|
|
|
|
|
or in **python:**
|
|
or in **python:**
|
|
|
|
|
|
```
|
|
```plaintext
|
|
import elt.pymal as mal
|
|
import elt.pymal as mal
|
|
zpbMal = mal.loadMal ("zpb", {"zpb.log4cplus.filename":"/path/to/mal-log4cplus.conf"})
|
|
zpbMal = mal.loadMal ("zpb", {"zpb.log4cplus.filename":"/path/to/mal-log4cplus.conf"})
|
|
```
|
|
```
|
... | @@ -919,9 +921,10 @@ zpbMal = mal.loadMal ("zpb", {"zpb.log4cplus.filename":"/path/to/mal-log4cplus.c |
... | @@ -919,9 +921,10 @@ zpbMal = mal.loadMal ("zpb", {"zpb.log4cplus.filename":"/path/to/mal-log4cplus.c |
|
|
|
|
|
With [ECII-246](https://jira.eso.org/browse/ECII-246), it is possible to change the log levels of the MAL loggers at run-time via a method call:
|
|
With [ECII-246](https://jira.eso.org/browse/ECII-246), it is possible to change the log levels of the MAL loggers at run-time via a method call:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
::elt::mal::util::logging::setLogLevelForLoggers( ... )
|
|
::elt::mal::util::logging::setLogLevelForLoggers( ... )
|
|
```
|
|
```
|
|
|
|
|
|
The allowed logger names are listed below.
|
|
The allowed logger names are listed below.
|
|
|
|
|
|
**Background**
|
|
**Background**
|
... | @@ -931,6 +934,7 @@ MAL does not use the Cii Logging System (CiiLogManager etc.) directly. Instead, |
... | @@ -931,6 +934,7 @@ MAL does not use the Cii Logging System (CiiLogManager etc.) directly. Instead, |
|
List of logger names available in the **Cpp MAL / Python MAL:**
|
|
List of logger names available in the **Cpp MAL / Python MAL:**
|
|
|
|
|
|
Loggers for **mal-zpb**
|
|
Loggers for **mal-zpb**
|
|
|
|
|
|
- malZpbInstancePublisher
|
|
- malZpbInstancePublisher
|
|
- malZpbPublisher
|
|
- malZpbPublisher
|
|
- malZpbClientAsyncImpl
|
|
- malZpbClientAsyncImpl
|
... | @@ -941,6 +945,7 @@ Loggers for **mal-zpb** |
... | @@ -941,6 +945,7 @@ Loggers for **mal-zpb** |
|
- malZpbBasePubSub
|
|
- malZpbBasePubSub
|
|
|
|
|
|
Loggers for **mal-dds**
|
|
Loggers for **mal-dds**
|
|
|
|
|
|
- malDds
|
|
- malDds
|
|
- malDdsSubscriptionManager
|
|
- malDdsSubscriptionManager
|
|
- malDdsSubscriptionReaderListener
|
|
- malDdsSubscriptionReaderListener
|
... | @@ -952,6 +957,7 @@ Loggers for **mal-dds** |
... | @@ -952,6 +957,7 @@ Loggers for **mal-dds** |
|
- malDdsInstancePublisher
|
|
- malDdsInstancePublisher
|
|
|
|
|
|
Loggers for **mal-opcua**
|
|
Loggers for **mal-opcua**
|
|
|
|
|
|
- malOpcua
|
|
- malOpcua
|
|
- malOpcuaBasePubSub
|
|
- malOpcuaBasePubSub
|
|
- malOpcuaMrvSubscriber
|
|
- malOpcuaMrvSubscriber
|
... | @@ -964,19 +970,19 @@ Loggers for **mal-opcua** |
... | @@ -964,19 +970,19 @@ Loggers for **mal-opcua** |
|
- malOpcuaClient
|
|
- malOpcuaClient
|
|
- malOpcuaClientEventLoop
|
|
- malOpcuaClientEventLoop
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### More Frames expected \[MAL ZMQ\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### More Frames expected [MAL ZMQ]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
In your application you get errors like this:
|
|
In your application you get errors like this:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
Oct 16, 2019 11:26:21 AM elt.mal.zpb.ps.ZpbSubscriber events
|
|
Oct 16, 2019 11:26:21 AM elt.mal.zpb.ps.ZpbSubscriber events
|
|
|
|
|
|
WARNING: Remote data entity type hash does not match (1040672065 != 1708154137).
|
|
WARNING: Remote data entity type hash does not match (1040672065 != 1708154137).
|
... | @@ -1020,7 +1026,6 @@ The first warning message indicates that your client has received a piece of dat |
... | @@ -1020,7 +1026,6 @@ The first warning message indicates that your client has received a piece of dat |
|
<zpb />
|
|
<zpb />
|
|
</mal>
|
|
</mal>
|
|
</pubsub_topic>
|
|
</pubsub_topic>
|
|
|
|
|
|
```
|
|
```
|
|
|
|
|
|
The second warning and the error trace are just a consequence of the first warning.
|
|
The second warning and the error trace are just a consequence of the first warning.
|
... | @@ -1031,27 +1036,29 @@ Check your topics.xml file, and make sure each channel has its own exclusive top |
... | @@ -1031,27 +1036,29 @@ Check your topics.xml file, and make sure each channel has its own exclusive top |
|
|
|
|
|
In the above example, e.g.:
|
|
In the above example, e.g.:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
zpb.ps://134.171.2.220:57110/test1
|
|
zpb.ps://134.171.2.220:57110/test1
|
|
```
|
|
```
|
|
|
|
|
|
and
|
|
and
|
|
```
|
|
|
|
|
|
```plaintext
|
|
zpb.ps://134.171.2.220:57110/test2
|
|
zpb.ps://134.171.2.220:57110/test2
|
|
```
|
|
```
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### Address in use \[MAL ZMQ\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Address in use [MAL ZMQ]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
Running your application, you see this error message:
|
|
Running your application, you see this error message:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
ZMQException: Errno 48 : Address already in use
|
|
ZMQException: Errno 48 : Address already in use
|
|
```
|
|
```
|
|
|
|
|
... | @@ -1073,14 +1080,13 @@ The error message is in fact misleading. |
... | @@ -1073,14 +1080,13 @@ The error message is in fact misleading. |
|
|
|
|
|
**Example**
|
|
**Example**
|
|
|
|
|
|
```
|
|
```plaintext
|
|
eltcii33 [09:38:27] eeltdev:~/mschilli > mal-esotests-testclient1 pub sAddr=zpb://eltcii28:12333/Sample tSlow=100 nSamp=100
|
|
eltcii33 [09:38:27] eeltdev:~/mschilli > mal-esotests-testclient1 pub sAddr=zpb://eltcii28:12333/Sample tSlow=100 nSamp=100
|
|
pub:sys: Available MAL Flavours loaded: [dds, opc, zpb]
|
|
pub:sys: Available MAL Flavours loaded: [dds, opc, zpb]
|
|
pub:config: sAddr=zpb://eltcii28:12333/Sample
|
|
pub:config: sAddr=zpb://eltcii28:12333/Sample
|
|
pub:config: nSamp=100
|
|
pub:config: nSamp=100
|
|
pub:config: tSlow=100
|
|
pub:config: tSlow=100
|
|
Internal Error: org.eso.elt.mal.MalException: org.zeromq.ZMQException: Errno 48 : Address already in use
|
|
Internal Error: org.eso.elt.mal.MalException: org.zeromq.ZMQException: Errno 48 : Address already in use
|
|
|
|
|
|
```
|
|
```
|
|
|
|
|
|
**Reason**
|
|
**Reason**
|
... | @@ -1091,23 +1097,23 @@ The above code is trying, on host eltcii33, to publish with an endpoint eltcii28 |
... | @@ -1091,23 +1097,23 @@ The above code is trying, on host eltcii33, to publish with an endpoint eltcii28 |
|
|
|
|
|
On eltcii33, the endpoint must be eltcii33.
|
|
On eltcii33, the endpoint must be eltcii33.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### Scheme not supported \[MAL\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Scheme not supported [MAL]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
Running your application, you get this error message:
|
|
Running your application, you get this error message:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
elt.mal.SchemeNotSupportedException: middleware not supported
|
|
elt.mal.SchemeNotSupportedException: middleware not supported
|
|
```
|
|
```
|
|
|
|
|
|
**Solution A**
|
|
**Solution A**
|
|
|
|
|
|
In your code, you've misspelled the middleware name, e.g. "opc" instead of "opcua"
|
|
In your code, you've misspelled the middleware name, e.g. "opc" instead of "opcua"
|
|
|
|
|
... | @@ -1117,13 +1123,13 @@ The middleware is supported in fact, but failed to load. |
... | @@ -1117,13 +1123,13 @@ The middleware is supported in fact, but failed to load. |
|
|
|
|
|
- E.g. in DDS, you are using a Qos profile xml file which has some illegal syntax inside.
|
|
- E.g. in DDS, you are using a Qos profile xml file which has some illegal syntax inside.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### Choosing a NIC \[MAL DDS\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Choosing a NIC [MAL DDS]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
... | @@ -1137,21 +1143,24 @@ The multicast middlewares (DDS and MUDPI) supported by the MAL allow you to spec |
... | @@ -1137,21 +1143,24 @@ The multicast middlewares (DDS and MUDPI) supported by the MAL allow you to spec |
|
|
|
|
|
**Solution (DDS)**
|
|
**Solution (DDS)**
|
|
|
|
|
|
Get the XML file shown in Solution #1 on this page: <https://community.rti.com/howto/control-or-restrict-network-interfaces-nics-used-discovery-and-data-distribution>, and continue with this article:
|
|
Get the XML file shown in Solution #1 on this page: <https://community.rti.com/howto/control-or-restrict-network-interfaces-nics-used-discovery-and-data-distribution>, and continue with this article: [KB: Configuring DDS](https://gitlab.eso.org/ecs/eltsw-docs/-/wikis/KnowledgeBase/CII#configuring-dds-mal-dds)
|
|
[KB: Configuring DDS](https://gitlab.eso.org/ecs/eltsw-docs/-/wikis/KnowledgeBase/CII#configuring-dds-mal-dds)
|
|
|
|
|
|
|
|
**Solution (MUDPI)**
|
|
**Solution (MUDPI)**
|
|
|
|
|
|
Set the "mudpi.ps.interfaceName" mal property when creating the MAL:
|
|
Set the "mudpi.ps.interfaceName" mal property when creating the MAL:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
auto &factory = ::elt::mal::loadMalForUri("mudpi.ps://",
|
|
auto &factory = ::elt::mal::loadMalForUri("mudpi.ps://",
|
|
{ {"mudpi.ps.interfaceName","192.168.100.165"} } );
|
|
{ {"mudpi.ps.interfaceName","192.168.100.165"} } );
|
|
```
|
|
```
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
### Configuring DDS [MAL DDS]
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
### Configuring DDS \[MAL DDS\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
... | @@ -1164,15 +1173,13 @@ This article explains how to define and use configuration for the DDS middleware |
... | @@ -1164,15 +1173,13 @@ This article explains how to define and use configuration for the DDS middleware |
|
To configure DDS, 3 things are necessary:
|
|
To configure DDS, 3 things are necessary:
|
|
|
|
|
|
- put the desired config into an external XML file (see Fast DDS documentation/examples)
|
|
- put the desired config into an external XML file (see Fast DDS documentation/examples)
|
|
|
|
|
|
- set the FASTRTPS_DEFAULT_PROFILES_FILE (Connext: NDDS_QOS_PROFILES) environment variable, so DDS finds the XML file
|
|
- set the FASTRTPS_DEFAULT_PROFILES_FILE (Connext: NDDS_QOS_PROFILES) environment variable, so DDS finds the XML file
|
|
|
|
|
|
- pass 2 properties to the MAL factory, so DDS finds the right profile in the XML file
|
|
- pass 2 properties to the MAL factory, so DDS finds the right profile in the XML file
|
|
|
|
|
|
|
|
|
|
**Example: How to restrict DDS traffic to your own host**
|
|
**Example: How to restrict DDS traffic to your own host**
|
|
|
|
|
|
XML file (see https://fast-dds.docs.eprosima.com/en/latest/fastdds/discovery/general_disc_settings.html)
|
|
XML file (see <https://fast-dds.docs.eprosima.com/en/latest/fastdds/discovery/general_disc_settings.html>)
|
|
|
|
|
|
```xml
|
|
```xml
|
|
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<dds>
|
|
<dds>
|
... | @@ -1191,6 +1198,7 @@ XML file (see https://fast-dds.docs.eprosima.com/en/latest/fastdds/discovery/gen |
... | @@ -1191,6 +1198,7 @@ XML file (see https://fast-dds.docs.eprosima.com/en/latest/fastdds/discovery/gen |
|
```
|
|
```
|
|
|
|
|
|
Code (C++)
|
|
Code (C++)
|
|
|
|
|
|
```cpp
|
|
```cpp
|
|
// Create DDS-MAL with custom mal properties
|
|
// Create DDS-MAL with custom mal properties
|
|
|
|
|
... | @@ -1206,14 +1214,58 @@ auto malpub = factory.getPublisher<AltAz> (pubsuburi, qos, {}); |
... | @@ -1206,14 +1214,58 @@ auto malpub = factory.getPublisher<AltAz> (pubsuburi, qos, {}); |
|
```
|
|
```
|
|
|
|
|
|
Before running your code:
|
|
Before running your code:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
export FASTRTPS_DEFAULT_PROFILES_FILE=<path of XML file>
|
|
export FASTRTPS_DEFAULT_PROFILES_FILE=<path of XML file>
|
|
```
|
|
```
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
### Discovery over multiple NICs \[MAL DDS\]
|
|
|
|
|
|
|
|
**Problem**
|
|
|
|
|
|
|
|
How do DataReaders connect over multiple NICs
|
|
|
|
|
|
|
|
**Explanantion**
|
|
|
|
Let's say we have 3 hosts:
|
|
|
|
- A: one NIC on 192.168.1.10 and another NIC on 10.10.10.10
|
|
|
|
- B: one NIC on 192.168.1.11
|
|
|
|
- C: one NIC on 10.10.10.12
|
|
|
|
|
|
|
|
On host A we have a participant with FASTDDS_STATISTICS="PUBLICATION_THROUGHPUT_TOPIC" and a DataWriter on topic _important_high_frequency_data_.
|
|
|
|
|
|
|
|
On host B we have a participant with FASTDDS_STATISTICS="SUBSCRIPTION_THROUGHPUT_TOPIC" and a DataReader on topic _important_high_frequency_data_
|
|
|
|
|
|
|
|
On host C we have the Fast DDS monitor.
|
|
|
|
|
|
|
|
Participants B and C will **not** discover each other, since they are on different LANs.
|
|
|
|
|
|
|
|
Participant A discovery will announce:
|
|
|
|
"I have a DataWriter for topic _important_high_frequency_data_ communicating through any of 192.168.1.10, 10.10.10.10.
|
|
|
|
I also have a DataWriter for topic _fastdds_statistics_publication_throughput_ communicating through any of 192.168.1.10, 10.10.10.10."
|
|
|
|
|
|
|
|
Participant B discovery will announce:
|
|
|
|
"I have a DataReader for topic _important_high_frequency_data_ listening on 192.168.1.11.
|
|
|
|
I also have a DataWriter for topic _fastdds_statistics_subscription_throughput_ communicating through any of 192.168.1.11."
|
|
|
|
|
|
|
|
The DataWriter on participant A will then send data for topic _important_high_frequency_data_ listening to 192.168.1.11 (through NIC 192.168.1.10)
|
|
|
|
|
|
|
|
Participant C discovery will announce:
|
|
|
|
"I have a DataReader for topic _fastdds_statistics_publication_throughput_ listening on 10.10.10.12.
|
|
|
|
I also have a DataReader for topic _fastdds_statistics_subscription_throughput_ listening on 10.10.10.12."
|
|
|
|
|
|
|
|
The statistics DataWriter on participant A will then send data for topic _fastdds_statistics_publication_throughput_ to 10.10.10.12 (through NIC 10.10.10.10) and be visible on DDS Monitor.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
\--------------------------------------------------------------------------
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Summary of OPC/UA MAL in C++
|
|
### Summary of OPC/UA MAL in C++
|
|
|
|
|
|
This article covers integration of OPC/UA in CII MAL specifically for OPC/UA Data Access and Subscription profiles. OPC/UA method invocation is also supported in CII MAL but is not described in this article, likewise details of the Python (and Java) support are not provided. Only C++ is considered here.
|
|
This article covers integration of OPC/UA in CII MAL specifically for OPC/UA Data Access and Subscription profiles. OPC/UA method invocation is also supported in CII MAL but is not described in this article, likewise details of the Python (and Java) support are not provided. Only C++ is considered here.
|
... | @@ -1224,20 +1276,18 @@ The XML ICD definition of types in CII is used to map sets of data points togeth |
... | @@ -1224,20 +1276,18 @@ The XML ICD definition of types in CII is used to map sets of data points togeth |
|
|
|
|
|
Each attribute in the defined type is connected to a corresponding data point in the OPC/UA data space via a URI. Thus the CII URI for a complex type will contain specific addresses of multiple nodes in the OPC/UA data space.
|
|
Each attribute in the defined type is connected to a corresponding data point in the OPC/UA data space via a URI. Thus the CII URI for a complex type will contain specific addresses of multiple nodes in the OPC/UA data space.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
#### Pub/Sub API for OPC/UA Clients:
|
|
#### Pub/Sub API for OPC/UA Clients:
|
|
|
|
|
|
The CII MAL Pub/Sub API utilizes OPC/UA Data Access Reads and Writes, as well OPC/UA subscription. A Publisher will directly trigger an OPC DA write, while a Subscriber will work in one of two ways, depending on the type associated with the subscriber:
|
|
The CII MAL Pub/Sub API utilizes OPC/UA Data Access Reads and Writes, as well OPC/UA subscription. A Publisher will directly trigger an OPC DA write, while a Subscriber will work in one of two ways, depending on the type associated with the subscriber:
|
|
|
|
|
|
- If the subscribers CII URI contains only a single node (i.e. the XML ICD type contained only a single attribute) then the Subscriber will create an OPC/UA subscription on that data point. The subscription will trigger notification of updates to the data point node, which will then be queued for notification via the CII Subscriber API.
|
|
- If the subscribers CII URI contains only a single node (i.e. the XML ICD type contained only a single attribute) then the Subscriber will create an OPC/UA subscription on that data point. The subscription will trigger notification of updates to the data point node, which will then be queued for notification via the CII Subscriber API.
|
|
|
|
|
|
- If the Subscriber is using subscription, the opc.ps.outstandingPublishRequests property should not be zero (e.g. set it to 5), see the example code below. The reason is that the publish queue is used to store and send subscription notification events, and if the queue is small the even notifications may simply be dropped.
|
|
- If the Subscriber is using subscription, the opc.ps.outstandingPublishRequests property should not be zero (e.g. set it to 5), see the example code below. The reason is that the publish queue is used to store and send subscription notification events, and if the queue is small the even notifications may simply be dropped.
|
|
|
|
|
|
- If the subscriber CII URI contains multiple nodes (i.e. the XML ICD type contains multiple attributes) then the Subscriber launches a thread to perform periodic polling of data from the OPC/UA server. The rate is based on the properties passed in creating the subscriber. e.g.
|
|
- If the subscriber CII URI contains multiple nodes (i.e. the XML ICD type contains multiple attributes) then the Subscriber launches a thread to perform periodic polling of data from the OPC/UA server. The rate is based on the properties passed in creating the subscriber. e.g.
|
|
|
|
|
|
```cpp
|
|
```cpp
|
... | @@ -1254,11 +1304,12 @@ try{ |
... | @@ -1254,11 +1304,12 @@ try{ |
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
#### Request/Reply API for OPC/UA Clients:
|
|
#### Request/Reply API for OPC/UA Clients:
|
|
|
|
|
|
As OPC/UA Data Access read and write essentially follow a synchronous request/reply pattern, CII MAL also provides this interface for OPC/UA clients.
|
|
As OPC/UA Data Access read and write essentially follow a synchronous request/reply pattern, CII MAL also provides this interface for OPC/UA clients.
|
... | @@ -1286,22 +1337,21 @@ class DataAccess : public ::elt::mal::rr::RrEntity { |
... | @@ -1286,22 +1337,21 @@ class DataAccess : public ::elt::mal::rr::RrEntity { |
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
A test application showing its use is here:
|
|
A test application showing its use is here:
|
|
|
|
|
|
<https://gitlab.eso.org/cosylab/elt-cii/mal/mal-test/-/blob/develop/cpp/mal-test-performance/opcua/mal-opcua-da-speed/src/common.cpp>
|
|
<https://gitlab.eso.org/cosylab/elt-cii/mal/mal-test/-/blob/develop/cpp/mal-test-performance/opcua/mal-opcua-da-speed/src/common.cpp>
|
|
|
|
|
|
|
|
### ------------------------------------------------------
|
|
|
|
|
|
|
|
### \[OLDB\]
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
### ------------------------------------------------------
|
|
---
|
|
### [OLDB]
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### Less or More Logs \[OLDB Log\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Less or More Logs [OLDB Log]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
... | @@ -1311,9 +1361,9 @@ or, the OLDB API seems to be misbehaving, and you want more logs. |
... | @@ -1311,9 +1361,9 @@ or, the OLDB API seems to be misbehaving, and you want more logs. |
|
|
|
|
|
**Solution**
|
|
**Solution**
|
|
|
|
|
|
Please read the article "[Adjust CII Log Levels [Log]](#user-content-adjust-cii-log-levels-log)" in the Log section of this Knowledge Base. The relevant logger names for the OLDB API are:
|
|
Please read the article "[Adjust CII Log Levels \[Log\]](#user-content-adjust-cii-log-levels-log)" in the Log section of this Knowledge Base. The relevant logger names for the OLDB API are:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
CiiOldb
|
|
CiiOldb
|
|
CiiOldbDirectoryTreeProvider
|
|
CiiOldbDirectoryTreeProvider
|
|
CiiOldbFactory
|
|
CiiOldbFactory
|
... | @@ -1323,40 +1373,48 @@ CiiOldbRemoteFileProvider |
... | @@ -1323,40 +1373,48 @@ CiiOldbRemoteFileProvider |
|
```
|
|
```
|
|
|
|
|
|
Example: to turn off ERROR logs for testing the existence of non-existing datapoints, use:
|
|
Example: to turn off ERROR logs for testing the existence of non-existing datapoints, use:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
log4cplus.logger.CiiOldbRemoteDataPointProvider=FATAL
|
|
log4cplus.logger.CiiOldbRemoteDataPointProvider=FATAL
|
|
```
|
|
```
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
### Cannot create Datapoints [OLDB]
|
|
|
|
|
|
### Cannot create Datapoints \[OLDB\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
Trying to create a datapoint, you get this error:
|
|
Trying to create a datapoint, you get this error:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
Cannot save to zpb.rr://ciiconfservicehost:9116/configuration/service/clientApi
|
|
Cannot save to zpb.rr://ciiconfservicehost:9116/configuration/service/clientApi
|
|
```
|
|
```
|
|
|
|
|
|
resp. you get this error:
|
|
resp. you get this error:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
[ERROR][CiiOldb] Unknown error occurred ::elt::error::icd::CiiSerializableException
|
|
[ERROR][CiiOldb] Unknown error occurred ::elt::error::icd::CiiSerializableException
|
|
```
|
|
```
|
|
|
|
|
|
and in the IntCfg-logs (as root: journalctl -u srv-config) you see:
|
|
and in the IntCfg-logs (as root: journalctl -u srv-config) you see:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
Cannot save to zpb.rr://ciiconfservicehost:9116/configuration/service/clientApi
|
|
Cannot save to zpb.rr://ciiconfservicehost:9116/configuration/service/clientApi
|
|
```
|
|
```
|
|
|
|
|
|
This can be caused by low disk space (< 5%) available for the oldb permanent store:
|
|
This can be caused by low disk space (< 5%) available for the oldb permanent store:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
df -h /var/lib/elasticsearch
|
|
df -h /var/lib/elasticsearch
|
|
```
|
|
```
|
|
|
|
|
|
**Solution**
|
|
**Solution**
|
|
|
|
|
|
```
|
|
```plaintext
|
|
# Remove old log files:
|
|
# Remove old log files:
|
|
find /var/log/elasticsearch -type f -mtime +30 -delete
|
|
find /var/log/elasticsearch -type f -mtime +30 -delete
|
|
|
|
|
... | @@ -1373,33 +1431,33 @@ df -h /var/lib/elasticsearch |
... | @@ -1373,33 +1431,33 @@ df -h /var/lib/elasticsearch |
|
|
|
|
|
If disk usage is above 95%, elasticsearch goes into read-only mode, and creating new datapoints is not possible any more. To remove old content from the database, it is first necessary to create some free space on the disk (since the database needs space to perform deletetion-operations), then unlock the database, and then remove unnecessary old content from it.
|
|
If disk usage is above 95%, elasticsearch goes into read-only mode, and creating new datapoints is not possible any more. To remove old content from the database, it is first necessary to create some free space on the disk (since the database needs space to perform deletetion-operations), then unlock the database, and then remove unnecessary old content from it.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Exception while connecting to OLDB service
|
|
### Exception while connecting to OLDB service
|
|
|
|
|
|
When starting an application using the OLDB API, the following exception is received:
|
|
When starting an application using the OLDB API, the following exception is received:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
<date/time>, ERROR, CiiOldbFactory/140635105143296, Unexpected config exception occurred while retrieving configuration for cii.config://remote/oldb/configurations/oldbClientConfig What:Path oldb/configurations/oldbClientConfig, version -1 not found
|
|
<date/time>, ERROR, CiiOldbFactory/140635105143296, Unexpected config exception occurred while retrieving configuration for cii.config://remote/oldb/configurations/oldbClientConfig What:Path oldb/configurations/oldbClientConfig, version -1 not found
|
|
terminate called after throwing an instance of 'elt::oldb::CiiOldbException'
|
|
terminate called after throwing an instance of 'elt::oldb::CiiOldbException'
|
|
what(): Unexpected config exception occurred while retrieving configuration for cii.config://remote/oldb/configurations/oldbClientConfig What:Path oldb/configurations/oldbClientConfig, version -1 not found
|
|
what(): Unexpected config exception occurred while retrieving configuration for cii.config://remote/oldb/configurations/oldbClientConfig What:Path oldb/configurations/oldbClientConfig, version -1 not found
|
|
```
|
|
```
|
|
|
|
|
|
**Solution**
|
|
**Solution** This can indicate that elasticSearch on the config/oldb server is not running, or has crashed. Use cii-services command to check the status on the server where the (cii-internal) config is running.
|
|
This can indicate that elasticSearch on the config/oldb server is not running, or has crashed.
|
|
|
|
Use cii-services command to check the status on the server where the (cii-internal) config is running.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Connecting to OLDB takes long, then fails \[cpp OLDB\]
|
|
### Connecting to OLDB takes long, then fails \[cpp OLDB\]
|
|
|
|
|
|
**Question**
|
|
**Question** My application blocks a long time on first OLDB access, and eventually fails with a timeout.
|
|
My application blocks a long time on first OLDB access, and eventually fails with a timeout.
|
|
|
|
|
|
|
|
**Answer**
|
|
**Answer**
|
|
|
|
|
... | @@ -1407,7 +1465,7 @@ Reconfigure the communication timeout (default: 60 seconds) |
... | @@ -1407,7 +1465,7 @@ Reconfigure the communication timeout (default: 60 seconds) |
|
|
|
|
|
a) through an environment variable and a properties file
|
|
a) through an environment variable and a properties file
|
|
|
|
|
|
```
|
|
```plaintext
|
|
$ cat <<EOF >/tmp/cii_client.ini
|
|
$ cat <<EOF >/tmp/cii_client.ini
|
|
connection_timeout = 5
|
|
connection_timeout = 5
|
|
EOF
|
|
EOF
|
... | @@ -1416,7 +1474,7 @@ $ export CONFIG_CLIENT_INI = /tmp/cii_client.ini |
... | @@ -1416,7 +1474,7 @@ $ export CONFIG_CLIENT_INI = /tmp/cii_client.ini |
|
|
|
|
|
b) programmatically (available since CII 2.0/DevEnv 3.9)
|
|
b) programmatically (available since CII 2.0/DevEnv 3.9)
|
|
|
|
|
|
```
|
|
```plaintext
|
|
CiiClientConfiguration config_client_ini = { .connection_timeout = 5, };
|
|
CiiClientConfiguration config_client_ini = { .connection_timeout = 5, };
|
|
elt::config::CiiConfigClient::SetDevClientConfig (config_client_ini);
|
|
elt::config::CiiConfigClient::SetDevClientConfig (config_client_ini);
|
|
```
|
|
```
|
... | @@ -1425,9 +1483,12 @@ elt::config::CiiConfigClient::SetDevClientConfig (config_client_ini); |
... | @@ -1425,9 +1483,12 @@ elt::config::CiiConfigClient::SetDevClientConfig (config_client_ini); |
|
|
|
|
|
The actual stalling comes from a failed MAL-communication with the CII Internal Configuration System, which likely is not running. Setting the timeout for the CiiConfigClient is therefore the thing to do. Note that the properties file (aka. "deployment config") takes precedence and will, if they overlap, overrule the programmatic (aka. "developer config") settings.
|
|
The actual stalling comes from a failed MAL-communication with the CII Internal Configuration System, which likely is not running. Setting the timeout for the CiiConfigClient is therefore the thing to do. Note that the properties file (aka. "deployment config") takes precedence and will, if they overlap, overrule the programmatic (aka. "developer config") settings.
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
### Mock OLDB for unit tests \[OLDB cpp python\]
|
|
### Mock OLDB for unit tests \[OLDB cpp python\]
|
|
|
|
|
|
**Question**
|
|
**Question**
|
... | @@ -1443,18 +1504,14 @@ You can create an in-memory OLDB providing a cached config oldb implementation a |
... | @@ -1443,18 +1504,14 @@ You can create an in-memory OLDB providing a cached config oldb implementation a |
|
The oldb-client cpp module is providing a
|
|
The oldb-client cpp module is providing a
|
|
|
|
|
|
- pure (virtual = 0) interface elt::oldb::CiiOldbDataPointProvider<sup>\[1\]</sup>, and two implementations:
|
|
- pure (virtual = 0) interface elt::oldb::CiiOldbDataPointProvider<sup>\[1\]</sup>, and two implementations:
|
|
|
|
|
|
- in-memory data point provider storing data points to the memory
|
|
- in-memory data point provider storing data points to the memory
|
|
|
|
|
|
(this is an empty implementation which provides a minimal operational fake oldb)
|
|
(this is an empty implementation which provides a minimal operational fake oldb)
|
|
|
|
|
|
- a redis data point provider storing data points to redis.
|
|
- a redis data point provider storing data points to redis.
|
|
|
|
|
|
- a remote filesystem interface elt::oldb:impl::ciiOldbRemoteFileProvider.hpp<sup>\[2\]</sup>, and two implementations:
|
|
- a remote filesystem interface elt::oldb:impl::ciiOldbRemoteFileProvider.hpp<sup>\[2\]</sup>, and two implementations:
|
|
|
|
|
|
- S3 implementation
|
|
- S3 implementation
|
|
|
|
- local file system implementation: ciiOldbLocalFileProvider<sup>\[3\]</sup> _\[Note: not before DevEnv 3.4\]_
|
|
- local file system implementation: ciiOldbLocalFileProvider<sup>\[3\]</sup> *\[Note: not before DevEnv 3.4\]*
|
|
|
|
|
|
|
|
Here are complete examples of unit tests showing the main use cases how to use oldb (with subscriptions) and metadata creation:
|
|
Here are complete examples of unit tests showing the main use cases how to use oldb (with subscriptions) and metadata creation:
|
|
|
|
|
... | @@ -1464,19 +1521,20 @@ The same exists in python: |
... | @@ -1464,19 +1521,20 @@ The same exists in python: |
|
|
|
|
|
Example in <https://gitlab.eso.org/ahoffsta/cii-srv/-/blob/oldb-in-memory-missing-python-binding/oldb-client/python/oldb/test/oldbInMemoryTest.py>
|
|
Example in <https://gitlab.eso.org/ahoffsta/cii-srv/-/blob/oldb-in-memory-missing-python-binding/oldb-client/python/oldb/test/oldbInMemoryTest.py>
|
|
|
|
|
|
|
|
|
|
References
|
|
References
|
|
|
|
|
|
\[1\] <https://gitlab.eso.org/cii/srv/cii-srv/-/blob/master/oldb-client/cpp/oldb/src/include/ciiOldbDataPointProvider.hpp>
|
|
\[1\] <https://gitlab.eso.org/cii/srv/cii-srv/-/blob/master/oldb-client/cpp/oldb/src/include/ciiOldbDataPointProvider.hpp>
|
|
|
|
|
|
\[2\] <https://gitlab.eso.org/cii/srv/cii-srv/-/blob/master/oldb-client/cpp/oldb/src/include/provider/ciiOldbRemoteFileProvider.hpp>
|
|
\[2\] <https://gitlab.eso.org/cii/srv/cii-srv/-/blob/master/oldb-client/cpp/oldb/src/include/provider/ciiOldbRemoteFileProvider.hpp>
|
|
|
|
|
|
\[3\] <https://gitlab.eso.org/cii/srv/cii-srv/-/blob/master/oldb-client/cpp/oldb/src/provider/ciiOldbLocalFileProvider.hpp> *\[Note: not before DevEnv 3.4\]*
|
|
\[3\] <https://gitlab.eso.org/cii/srv/cii-srv/-/blob/master/oldb-client/cpp/oldb/src/provider/ciiOldbLocalFileProvider.hpp> _\[Note: not before DevEnv 3.4\]_
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### access_key empty (DevEnv 3.2.0) \[OLDB\]
|
|
### access_key empty (DevEnv 3.2.0) \[OLDB\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
... | @@ -1489,7 +1547,7 @@ Unexpected exception occurred. What:Configuration invalid: access_key empty |
... | @@ -1489,7 +1547,7 @@ Unexpected exception occurred. What:Configuration invalid: access_key empty |
|
|
|
|
|
Run the following commands (you will be asked for the root pw):
|
|
Run the following commands (you will be asked for the root pw):
|
|
|
|
|
|
```
|
|
```plaintext
|
|
wget -q www.eso.org/~mschilli/download/cii/postinstall/cii-postinstall-20210610
|
|
wget -q www.eso.org/~mschilli/download/cii/postinstall/cii-postinstall-20210610
|
|
|
|
|
|
cii-services stop config
|
|
cii-services stop config
|
... | @@ -1520,12 +1578,12 @@ The CII post-install procedure is able to hotfix the settings (ECII397). |
... | @@ -1520,12 +1578,12 @@ The CII post-install procedure is able to hotfix the settings (ECII397). |
|
|
|
|
|
The problem will be fixed in DevEnv 3.4.
|
|
The problem will be fixed in DevEnv 3.4.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Datapoint already exists \[OLDB\]
|
|
### Datapoint already exists \[OLDB\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
... | @@ -1534,7 +1592,7 @@ My application tries to create an OLDB datapoint. |
... | @@ -1534,7 +1592,7 @@ My application tries to create an OLDB datapoint. |
|
|
|
|
|
This fails because the datapoint "already exists":
|
|
This fails because the datapoint "already exists":
|
|
|
|
|
|
```
|
|
```plaintext
|
|
ERROR, CiiOldbRedisDataPointProvider/140709706681216, Data point uri: cii.oldb:/tcs/hb/tempser3 in Redis already exists.
|
|
ERROR, CiiOldbRedisDataPointProvider/140709706681216, Data point uri: cii.oldb:/tcs/hb/tempser3 in Redis already exists.
|
|
```
|
|
```
|
|
|
|
|
... | @@ -1542,7 +1600,7 @@ In response, my application skips the creation step, and wants to use the report |
... | @@ -1542,7 +1600,7 @@ In response, my application skips the creation step, and wants to use the report |
|
|
|
|
|
However, when doing this, I get the error "datapoint doesn't exist":
|
|
However, when doing this, I get the error "datapoint doesn't exist":
|
|
|
|
|
|
```
|
|
```plaintext
|
|
Dynamic exception type: elt::oldb::CiiOldbDpUndefinedException
|
|
Dynamic exception type: elt::oldb::CiiOldbDpUndefinedException
|
|
std::exception::what: The data point cii.oldb:///tcs/hb/tempser3 with this name does not exist.
|
|
std::exception::what: The data point cii.oldb:///tcs/hb/tempser3 with this name does not exist.
|
|
```
|
|
```
|
... | @@ -1553,7 +1611,7 @@ Likewise, when I run the oldb-gui database browser, it does not show this data p |
... | @@ -1553,7 +1611,7 @@ Likewise, when I run the oldb-gui database browser, it does not show this data p |
|
|
|
|
|
I try to access an OLDB datapoint, and I see two errors like this:
|
|
I try to access an OLDB datapoint, and I see two errors like this:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
Target configuration does not exist: Failed to retrieve configuration from elastic search: Configuration
|
|
Target configuration does not exist: Failed to retrieve configuration from elastic search: Configuration
|
|
[…]
|
|
[…]
|
|
elt.oldb.exceptions.CiiOldbDpExistsException: Data point cii.oldb:/alarm/alarm/device/motor/input_int_dp_alarm already exisits.
|
|
elt.oldb.exceptions.CiiOldbDpExistsException: Data point cii.oldb:/alarm/alarm/device/motor/input_int_dp_alarm already exisits.
|
... | @@ -1565,7 +1623,7 @@ Go directly to Solution 2 below. |
... | @@ -1565,7 +1623,7 @@ Go directly to Solution 2 below. |
|
|
|
|
|
I try to delete an OLDB datapoint and I see an error like this:
|
|
I try to delete an OLDB datapoint and I see an error like this:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
CiiOldbPyB.CiiOldbException: De-serialization error:sizeof(T)\*count is greater then remaining
|
|
CiiOldbPyB.CiiOldbException: De-serialization error:sizeof(T)\*count is greater then remaining
|
|
```
|
|
```
|
|
|
|
|
... | @@ -1581,7 +1639,7 @@ Datapoints are stored in two databases: a document-database (permanent store) fo |
... | @@ -1581,7 +1639,7 @@ Datapoints are stored in two databases: a document-database (permanent store) fo |
|
|
|
|
|
With DevEnv 4, which contains [ECII-500](https://jira.eso.org/browse/ECII-500), you can probably delete the datapoint to clean up the situation:
|
|
With DevEnv 4, which contains [ECII-500](https://jira.eso.org/browse/ECII-500), you can probably delete the datapoint to clean up the situation:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
#!/usr/bin/env python
|
|
#!/usr/bin/env python
|
|
import elt.config
|
|
import elt.config
|
|
import elt.oldb
|
|
import elt.oldb
|
... | @@ -1599,11 +1657,11 @@ oldb_client.delete_data_point(uri) |
... | @@ -1599,11 +1657,11 @@ oldb_client.delete_data_point(uri) |
|
If the above didn't help, find out which "half" of the datapoint exists.
|
|
If the above didn't help, find out which "half" of the datapoint exists.
|
|
|
|
|
|
1. The current value exists, and the metadata is missing. This is the case when upgrading DevEnv/CII without deleting the Redis cache.
|
|
1. The current value exists, and the metadata is missing. This is the case when upgrading DevEnv/CII without deleting the Redis cache.
|
|
|
|
|
|
2. The metadata exists, and the current value is missing
|
|
2. The metadata exists, and the current value is missing
|
|
|
|
|
|
Define the following shell functions (note: not applicable to redis-clusters):
|
|
Define the following shell functions (note: not applicable to redis-clusters):
|
|
```
|
|
|
|
|
|
```plaintext
|
|
function oldb_ela_list { curl -s -X GET localhost:9200/configuration_instance/_search?size=2000\&q=data.uri.value:\"$1\" | jq -r '.hits.hits[]._id' | sort ; }
|
|
function oldb_ela_list { curl -s -X GET localhost:9200/configuration_instance/_search?size=2000\&q=data.uri.value:\"$1\" | jq -r '.hits.hits[]._id' | sort ; }
|
|
|
|
|
|
function oldb_ela_del { curl -s -X POST localhost:9200/configuration_instance/_delete_by_query?q=data.uri.value:\"$1\" | jq -r '.deleted' ; }
|
|
function oldb_ela_del { curl -s -X POST localhost:9200/configuration_instance/_delete_by_query?q=data.uri.value:\"$1\" | jq -r '.deleted' ; }
|
... | @@ -1615,7 +1673,7 @@ function oldb_red_del { redis-cli --scan --pattern "*$1*" | xargs redis-cli del |
... | @@ -1615,7 +1673,7 @@ function oldb_red_del { redis-cli --scan --pattern "*$1*" | xargs redis-cli del |
|
|
|
|
|
Then check if the problematic key is in the volatile store:
|
|
Then check if the problematic key is in the volatile store:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
# Search for path component of dp-uri (here: "device")
|
|
# Search for path component of dp-uri (here: "device")
|
|
$ oldb_red_list device
|
|
$ oldb_red_list device
|
|
... output will be e.g.:
|
|
... output will be e.g.:
|
... | @@ -1630,7 +1688,7 @@ $ oldb_red_del device/doubledp444 |
... | @@ -1630,7 +1688,7 @@ $ oldb_red_del device/doubledp444 |
|
|
|
|
|
Otherwise, check if the problematic key is in the permanent store:
|
|
Otherwise, check if the problematic key is in the permanent store:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
# Search for path component of dp-uri (whole-word search, e.g. "dev" would not match)
|
|
# Search for path component of dp-uri (whole-word search, e.g. "dev" would not match)
|
|
$ oldb_ela_list device
|
|
$ oldb_ela_list device
|
|
... output e.g.:
|
|
... output e.g.:
|
... | @@ -1643,14 +1701,13 @@ $ oldb_ela_del doubbledp446 |
... | @@ -1643,14 +1701,13 @@ $ oldb_ela_del doubbledp446 |
|
$ sudo cii-services stop config ; sudo cii-services start config
|
|
$ sudo cii-services stop config ; sudo cii-services start config
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
**Solution 3**
|
|
**Solution 3**
|
|
|
|
|
|
If none of the above helped, another possibility is to clean up the metadata.
|
|
If none of the above helped, another possibility is to clean up the metadata.
|
|
|
|
|
|
WARNING: This is an invasive operation. It deletes all datapoints in the OLDB.
|
|
WARNING: This is an invasive operation. It deletes all datapoints in the OLDB.
|
|
|
|
|
|
```
|
|
```plaintext
|
|
# Clean up the OLDB databases
|
|
# Clean up the OLDB databases
|
|
config-initEs.sh
|
|
config-initEs.sh
|
|
oldb-initEs
|
|
oldb-initEs
|
... | @@ -1660,17 +1717,19 @@ WARNING: This is an invasive operation. It deletes all datapoints in the OLDB. |
... | @@ -1660,17 +1717,19 @@ WARNING: This is an invasive operation. It deletes all datapoints in the OLDB. |
|
```
|
|
```
|
|
|
|
|
|
If you are dealing with a multi-user oldb ("role_groupserver", meaning it serves an OLDB to a team of developers), after executing the above commands you need to additionally execute (with privileges):
|
|
If you are dealing with a multi-user oldb ("role_groupserver", meaning it serves an OLDB to a team of developers), after executing the above commands you need to additionally execute (with privileges):
|
|
```
|
|
|
|
|
|
```plaintext
|
|
/elt/ciisrv/postinstall/cii-postinstall role_groupserver
|
|
/elt/ciisrv/postinstall/cii-postinstall role_groupserver
|
|
```
|
|
```
|
|
|
|
|
|
If you have doubts, please contact us.
|
|
If you have doubts, please contact us.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Command Line Tools and Python snippets \[OLDB\]
|
|
### Command Line Tools and Python snippets \[OLDB\]
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
... | @@ -1681,7 +1740,7 @@ I need to inspect or modify the content of the OLDB from the command line or a s |
... | @@ -1681,7 +1740,7 @@ I need to inspect or modify the content of the OLDB from the command line or a s |
|
|
|
|
|
**cii-oldb-traversal-tool** for searching through the OLDB
|
|
**cii-oldb-traversal-tool** for searching through the OLDB
|
|
|
|
|
|
```
|
|
```plaintext
|
|
$ cii-oldb-traversal-tool --file output --quality OK
|
|
$ cii-oldb-traversal-tool --file output --quality OK
|
|
$ cat output
|
|
$ cat output
|
|
cii.oldb:///root/trklsv/cfg/log/level|OK|WARNING|2020-09-11T15:25:08Z
|
|
cii.oldb:///root/trklsv/cfg/log/level|OK|WARNING|2020-09-11T15:25:08Z
|
... | @@ -1701,7 +1760,7 @@ cii.oldb:///root/trklsv/ctr/target/radec/ra|OK|0.000000|2020-09-11T15:24:26Z |
... | @@ -1701,7 +1760,7 @@ cii.oldb:///root/trklsv/ctr/target/radec/ra|OK|0.000000|2020-09-11T15:24:26Z |
|
|
|
|
|
**oldb-cli** for reading, writing, subscribing to an OLDB-datapoint
|
|
**oldb-cli** for reading, writing, subscribing to an OLDB-datapoint
|
|
|
|
|
|
```
|
|
```plaintext
|
|
$ oldb-cli read cii.oldb:///root/trklsv/cfg/req/endpoint
|
|
$ oldb-cli read cii.oldb:///root/trklsv/cfg/req/endpoint
|
|
SLF4J: Class path contains multiple SLF4J bindings.
|
|
SLF4J: Class path contains multiple SLF4J bindings.
|
|
SLF4J: Found binding in [jar:file:/eelt/ciisrv/1.0-RC3-20201030/lib/srv-support-libs/slf4j-nop-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
|
|
SLF4J: Found binding in [jar:file:/eelt/ciisrv/1.0-RC3-20201030/lib/srv-support-libs/slf4j-nop-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
|
... | @@ -1713,12 +1772,11 @@ log4j:WARN Please initialize the log4j system properly. |
... | @@ -1713,12 +1772,11 @@ log4j:WARN Please initialize the log4j system properly. |
|
Timestamp: 2020-09-11T15:25:08.648Z
|
|
Timestamp: 2020-09-11T15:25:08.648Z
|
|
Quality: OK
|
|
Quality: OK
|
|
Value: zpb.rr://localhost:44444/m1/TrkLsvServer
|
|
Value: zpb.rr://localhost:44444/m1/TrkLsvServer
|
|
|
|
|
|
```
|
|
```
|
|
|
|
|
|
**oldb Python API** for creating, deleting an OLDB-datapoint
|
|
**oldb Python API** for creating, deleting an OLDB-datapoint
|
|
|
|
|
|
```
|
|
```plaintext
|
|
$ python
|
|
$ python
|
|
Python 3.7.6 (default, Jan 8 2020, 19:59:22)
|
|
Python 3.7.6 (default, Jan 8 2020, 19:59:22)
|
|
[GCC 7.3.0] :: Anaconda, Inc. on linux
|
|
[GCC 7.3.0] :: Anaconda, Inc. on linux
|
... | @@ -1731,21 +1789,21 @@ Type "help", "copyright", "credits" or "license" for more information. |
... | @@ -1731,21 +1789,21 @@ Type "help", "copyright", "credits" or "license" for more information. |
|
|
|
|
|
… and, to create a datapoint:
|
|
… and, to create a datapoint:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
>>> elt.oldb.CiiOldbGlobal.set_write_enabled(True)
|
|
>>> elt.oldb.CiiOldbGlobal.set_write_enabled(True)
|
|
>>> oldb.create_data_point_by_value (Uri("cii.oldb:/ccs/tst/tmp1"), "my text")
|
|
>>> oldb.create_data_point_by_value (Uri("cii.oldb:/ccs/tst/tmp1"), "my text")
|
|
```
|
|
```
|
|
|
|
|
|
… and, to read a datapoint:
|
|
… and, to read a datapoint:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
>>> oldb.get_data_point(Uri("cii.oldb:/ccs/tst/tmp1")).read_value().get_value()
|
|
>>> oldb.get_data_point(Uri("cii.oldb:/ccs/tst/tmp1")).read_value().get_value()
|
|
'my text'
|
|
'my text'
|
|
```
|
|
```
|
|
|
|
|
|
… and, to subscribe to a datapoint:
|
|
… and, to subscribe to a datapoint:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
>>> class CB:
|
|
>>> class CB:
|
|
>>> def new_value(self,value,uri):
|
|
>>> def new_value(self,value,uri):
|
|
>>> print ("value:", value.get_value())
|
|
>>> print ("value:", value.get_value())
|
... | @@ -1755,23 +1813,22 @@ Type "help", "copyright", "credits" or "license" for more information. |
... | @@ -1755,23 +1813,22 @@ Type "help", "copyright", "credits" or "license" for more information. |
|
|
|
|
|
… and, to delete a datapoint:
|
|
… and, to delete a datapoint:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
>>> elt.oldb.CiiOldbGlobal.set_write_enabled(True)
|
|
>>> elt.oldb.CiiOldbGlobal.set_write_enabled(True)
|
|
>>> oldb.delete_data_point (Uri("cii.oldb:/ccs/tst/tmp1"))
|
|
>>> oldb.delete_data_point (Uri("cii.oldb:/ccs/tst/tmp1"))
|
|
```
|
|
```
|
|
|
|
|
|
|
|
### ------------------------------------------------------
|
|
|
|
|
|
|
|
### \[Log\]
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
### ------------------------------------------------------
|
|
---
|
|
### [Log]
|
|
|
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### Change Log Levels at Run-time \[Log\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Change Log Levels at Run-time [Log]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
... | @@ -1783,14 +1840,14 @@ With [ECII-282](https://jira.eso.org/browse/ECII-282), the CiiLogManager was ext |
... | @@ -1783,14 +1840,14 @@ With [ECII-282](https://jira.eso.org/browse/ECII-282), the CiiLogManager was ext |
|
|
|
|
|
**C++** added methods:
|
|
**C++** added methods:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
void elt::log::CiiLogManager::SetLogLevel(const std::string logger_name, log4cplus::LogLevel level)
|
|
void elt::log::CiiLogManager::SetLogLevel(const std::string logger_name, log4cplus::LogLevel level)
|
|
void elt::log::CiiLogManager::SetLogLevel(log4cplus::Logger logger, log4cplus::LogLevel level)
|
|
void elt::log::CiiLogManager::SetLogLevel(log4cplus::Logger logger, log4cplus::LogLevel level)
|
|
```
|
|
```
|
|
|
|
|
|
**Java** added methods:
|
|
**Java** added methods:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
void elt.log.CiiLogManager.setLogLevel(
|
|
void elt.log.CiiLogManager.setLogLevel(
|
|
final String loggerName, final org.apache.logging.log4j.Level level);
|
|
final String loggerName, final org.apache.logging.log4j.Level level);
|
|
void elt.log.CiiLogManager.setLogLevel(
|
|
void elt.log.CiiLogManager.setLogLevel(
|
... | @@ -1799,19 +1856,21 @@ org.apache.logging.log4j.Logger logger, final org.apache.logging.log4j.Level lev |
... | @@ -1799,19 +1856,21 @@ org.apache.logging.log4j.Logger logger, final org.apache.logging.log4j.Level lev |
|
|
|
|
|
**Python** added methods:
|
|
**Python** added methods:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
elt.log.CiiLogManager.set_log_level(name_or_logger: Union\[str, logging.Logger\], level: logging.Level)
|
|
elt.log.CiiLogManager.set_log_level(name_or_logger: Union\[str, logging.Logger\], level: logging.Level)
|
|
```
|
|
```
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
### Adjust CII Log Levels [Log]
|
|
|
|
|
|
### Adjust CII Log Levels \[Log\]
|
|
|
|
|
|
With plain CII (no application frameworks on top), you define a log config file (myapp.logconfig):
|
|
With plain CII (no application frameworks on top), you define a log config file (myapp.logconfig):
|
|
|
|
|
|
```
|
|
```plaintext
|
|
log4cplus.rootLogger=INFO, STDOUT
|
|
log4cplus.rootLogger=INFO, STDOUT
|
|
log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
|
|
log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
|
|
log4cplus.appender.STDOUT.layout=elt::log::layout::CiiSimpleLayout
|
|
log4cplus.appender.STDOUT.layout=elt::log::layout::CiiSimpleLayout
|
... | @@ -1821,7 +1880,8 @@ log4cplus.logger.CiiOldb=FATAL |
... | @@ -1821,7 +1880,8 @@ log4cplus.logger.CiiOldb=FATAL |
|
```
|
|
```
|
|
|
|
|
|
The name of the log config is your choice, but to comply with the rules of "waf install", best use such a project structure:
|
|
The name of the log config is your choice, but to comply with the rules of "waf install", best use such a project structure:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
myapp/
|
|
myapp/
|
|
├── resource
|
|
├── resource
|
|
│ └── config
|
|
│ └── config
|
... | @@ -1831,9 +1891,9 @@ myapp/ |
... | @@ -1831,9 +1891,9 @@ myapp/ |
|
└── wscript
|
|
└── wscript
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
Then apply the log config from your application (myapp.cpp):
|
|
Then apply the log config from your application (myapp.cpp):
|
|
```
|
|
|
|
|
|
```plaintext
|
|
#include <ciiLogManager.hpp>
|
|
#include <ciiLogManager.hpp>
|
|
int main(int ac, char *av[]) {
|
|
int main(int ac, char *av[]) {
|
|
::elt::log::CiiLogManager::Configure("resource/config/myapp.logconfig");
|
|
::elt::log::CiiLogManager::Configure("resource/config/myapp.logconfig");
|
... | @@ -1843,12 +1903,9 @@ int main(int ac, char *av[]) { |
... | @@ -1843,12 +1903,9 @@ int main(int ac, char *av[]) { |
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
|
|
|
|
**List of Loggers** Generally, to learn about all loggers that are active in your application, add this (temporarily) to your application:
|
|
|
|
|
|
|
|
```plaintext
|
|
**List of Loggers**
|
|
|
|
Generally, to learn about all loggers that are active in your application, add this (temporarily) to your application:
|
|
|
|
|
|
|
|
```
|
|
|
|
#include <ciiLogManager.hpp>
|
|
#include <ciiLogManager.hpp>
|
|
[...]
|
|
[...]
|
|
std::cout << "Current loggers (in addition to root logger):" << std::endl;
|
|
std::cout << "Current loggers (in addition to root logger):" << std::endl;
|
... | @@ -1861,26 +1918,25 @@ for (int i=0,n=list.size(); i<n; i++) { |
... | @@ -1861,26 +1918,25 @@ for (int i=0,n=list.size(); i<n; i++) { |
|
|
|
|
|
Note: With the next version of CII, the logger name will be included in log messages by default.
|
|
Note: With the next version of CII, the logger name will be included in log messages by default.
|
|
|
|
|
|
|
|
**Log Format** To use a different log format (which CII allows, but the Control System guidelines do not), you can modify the above config like this:
|
|
|
|
|
|
**Log Format**
|
|
```plaintext
|
|
To use a different log format (which CII allows, but the Control System guidelines do not), you can modify the above config like this:
|
|
|
|
|
|
|
|
```
|
|
|
|
#log4cplus.appender.STDOUT.layout=elt::log::layout::CiiSimpleLayout
|
|
#log4cplus.appender.STDOUT.layout=elt::log::layout::CiiSimpleLayout
|
|
log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
|
|
log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
|
|
log4cplus.appender.STDOUT.layout.ConversionPattern=[%-5p][%D{%Y/%m/%d %H:%M:%S:%q}][%-l][%t] %m%n
|
|
log4cplus.appender.STDOUT.layout.ConversionPattern=[%-5p][%D{%Y/%m/%d %H:%M:%S:%q}][%-l][%t] %m%n
|
|
```
|
|
```
|
|
|
|
|
|
|
|
### ------------------------------------------------------
|
|
|
|
|
|
|
|
### \[Lang\]
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
### ------------------------------------------------------
|
|
---
|
|
### [Lang]
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
### Catching API Exceptions \[Lang Python\]
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Catching API Exceptions [Lang Python]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
... | @@ -1888,7 +1944,7 @@ My application contains a call to the CII Python API. |
... | @@ -1888,7 +1944,7 @@ My application contains a call to the CII Python API. |
|
|
|
|
|
When I ran it, it threw an exception with the following backtrace:
|
|
When I ran it, it threw an exception with the following backtrace:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
Top Level Unexpected exception:
|
|
Top Level Unexpected exception:
|
|
Traceback (most recent call last):
|
|
Traceback (most recent call last):
|
|
File "/home/eltdev/MODULES/test/app.py", line 91, in instantiateDP
|
|
File "/home/eltdev/MODULES/test/app.py", line 91, in instantiateDP
|
... | @@ -1898,7 +1954,7 @@ CiiOldbPyB.CiiOldbDpExistsException: The Data point cii.oldb:/root/test/xxxdp al |
... | @@ -1898,7 +1954,7 @@ CiiOldbPyB.CiiOldbDpExistsException: The Data point cii.oldb:/root/test/xxxdp al |
|
|
|
|
|
Therefore, I added a corresponding try-catch around my call:
|
|
Therefore, I added a corresponding try-catch around my call:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
try:
|
|
try:
|
|
...
|
|
...
|
|
except CiiOldbPyB.CiiOldbDpExistsException as e:
|
|
except CiiOldbPyB.CiiOldbDpExistsException as e:
|
... | @@ -1908,7 +1964,7 @@ When I run it, the try-catch doesn't work. |
... | @@ -1908,7 +1964,7 @@ When I run it, the try-catch doesn't work. |
|
|
|
|
|
Moreover, I now get two backtraces:
|
|
Moreover, I now get two backtraces:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
Top Level Unexpected exception:
|
|
Top Level Unexpected exception:
|
|
Traceback (most recent call last):
|
|
Traceback (most recent call last):
|
|
File "/home/eltdev/MODULES/test/app.py", line 91, in instantiateDP
|
|
File "/home/eltdev/MODULES/test/app.py", line 91, in instantiateDP
|
... | @@ -1932,7 +1988,7 @@ You were mislead by the first backtrace: the exception name in the backtrace is |
... | @@ -1932,7 +1988,7 @@ You were mislead by the first backtrace: the exception name in the backtrace is |
|
|
|
|
|
In your code, replace "**CiiOldbPyB**" with "**elt.oldb**":
|
|
In your code, replace "**CiiOldbPyB**" with "**elt.oldb**":
|
|
|
|
|
|
```
|
|
```plaintext
|
|
try:
|
|
try:
|
|
....
|
|
....
|
|
except elt.oldb.CiiOldbDpExistsException as e:
|
|
except elt.oldb.CiiOldbDpExistsException as e:
|
... | @@ -1940,7 +1996,7 @@ except elt.oldb.CiiOldbDpExistsException as e: |
... | @@ -1940,7 +1996,7 @@ except elt.oldb.CiiOldbDpExistsException as e: |
|
|
|
|
|
For completeness - do no forget this statement:
|
|
For completeness - do no forget this statement:
|
|
|
|
|
|
```
|
|
```plaintext
|
|
import elt.oldb
|
|
import elt.oldb
|
|
```
|
|
```
|
|
|
|
|
... | @@ -1960,57 +2016,61 @@ Unfortunately, in the backtraces you will always see the original name instead o |
... | @@ -1960,57 +2016,61 @@ Unfortunately, in the backtraces you will always see the original name instead o |
|
|
|
|
|
This question was originally asked in [ECII-422](https://jira.eso.org/browse/ECII-422).
|
|
This question was originally asked in [ECII-422](https://jira.eso.org/browse/ECII-422).
|
|
|
|
|
|
|
|
### ------------------------------------------------------
|
|
|
|
|
|
|
|
### \[IntCfg\]
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
### ------------------------------------------------------
|
|
### Elasticsearch disk usage and house-keeping \[IntCfg\]
|
|
### [IntCfg]
|
|
|
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
### Elasticsearch disk usage and house-keeping [IntCfg]
|
|
|
|
|
|
|
|
The Elasticsearch database is used by many CII services, e.g. to store CII log messages, tracing data, and Oldb metadata. If you run a local elasticsearch database on your host (i.e. you have set up a "role_ownserver" during post-install), it is advisable to do some house-keeping on this database from time to time.
|
|
The Elasticsearch database is used by many CII services, e.g. to store CII log messages, tracing data, and Oldb metadata. If you run a local elasticsearch database on your host (i.e. you have set up a "role_ownserver" during post-install), it is advisable to do some house-keeping on this database from time to time.
|
|
|
|
|
|
Some house-keeping is automated (e.g. ".monitoring-es" indices are automatically rolled over every few days), others may be automated in the future, but currently are not. Instead you should perform the tasks below at your own discretion.
|
|
Some house-keeping is automated (e.g. ".monitoring-es" indices are automatically rolled over every few days), others may be automated in the future, but currently are not. Instead you should perform the tasks below at your own discretion.
|
|
|
|
|
|
1. Check which indices you have and how much memory they consume:
|
|
1. Check which indices you have and how much memory they consume:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
curl localhost:9200/_cat/indices/_all?v\&s=store.size
|
|
curl localhost:9200/_cat/indices/_all?v\&s=store.size
|
|
```
|
|
```
|
|
|
|
|
|
2. To delete diagnostic indices that are older than X days:
|
|
2. To delete diagnostic indices that are older than X days:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
function ela_purge_idx { name=$1; age=$2; limit=$(date -d "$age days ago" +"%Y%m%d") ; for a in `curl -s localhost:9200/_aliases | jq -r 'keys | .[]'` ; do [[ $a == *$name* ]] && [[ "${a//[!0-9]/}" -lt $limit ]] && curl -X DELETE localhost:9200/$a ; done }
|
|
function ela_purge_idx { name=$1; age=$2; limit=$(date -d "$age days ago" +"%Y%m%d") ; for a in `curl -s localhost:9200/_aliases | jq -r 'keys | .[]'` ; do [[ $a == *$name* ]] && [[ "${a//[!0-9]/}" -lt $limit ]] && curl -X DELETE localhost:9200/$a ; done }
|
|
|
|
|
|
ela_purge_idx jaeger 10 # delete *jaeger* indices older than 10 days
|
|
ela_purge_idx jaeger 10 # delete *jaeger* indices older than 10 days
|
|
```
|
|
```
|
|
|
|
|
|
3. To delete CII log messages that are older than 30 days:
|
|
3. To delete CII log messages that are older than 30 days:
|
|
```
|
|
|
|
|
|
```plaintext
|
|
curl -X POST "localhost:9200/cii_log_default_index/_delete_by_query?pretty" -H 'Content-Type: application/json' -d' {"query": {"range" : {"@timestamp" : {"lte": "now-30d/d" } } } } '
|
|
curl -X POST "localhost:9200/cii_log_default_index/_delete_by_query?pretty" -H 'Content-Type: application/json' -d' {"query": {"range" : {"@timestamp" : {"lte": "now-30d/d" } } } } '
|
|
```
|
|
```
|
|
|
|
|
|
4. To free your disk from diagnostic logs older than 10 days, do (as root):
|
|
4. To free your disk from diagnostic logs older than 10 days, do (as root):
|
|
```
|
|
|
|
|
|
```plaintext
|
|
find /var/log/elasticsearch -type f -mtime +10 -delete
|
|
find /var/log/elasticsearch -type f -mtime +10 -delete
|
|
```
|
|
```
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
--------------------------------------------------------------------------
|
|
---
|
|
--------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------
|
|
### config not found on remote db \[IntCfg\]
|
|
### config not found on remote db [IntCfg]
|
|
|
|
|
|
|
|
**Problem**
|
|
**Problem**
|
|
|
|
|
|
You are intending to read a config from the local config database ("localdb"), but you see an error message like this.
|
|
You are intending to read a config from the local config database ("localdb"), but you see an error message like this.
|
|
|
|
|
|
```
|
|
```plaintext
|
|
elt.config.exceptions.CiiConfigNoTcException: Target configuration does not exist: Failed to retrieve configuration from elastic search: Configuration cii.config://*/supervisoryapp/TrkLsvDeploy on the remote db was not found
|
|
elt.config.exceptions.CiiConfigNoTcException: Target configuration does not exist: Failed to retrieve configuration from elastic search: Configuration cii.config://*/supervisoryapp/TrkLsvDeploy on the remote db was not found
|
|
at elt.config.client.ConfigRemoteDatabase.retrieveConfig(ConfigRemoteDatabase.java:191)
|
|
at elt.config.client.ConfigRemoteDatabase.retrieveConfig(ConfigRemoteDatabase.java:191)
|
|
at elt.config.client.CiiConfigClient.retrieveConfig(CiiConfigClient.java:354)
|
|
at elt.config.client.CiiConfigClient.retrieveConfig(CiiConfigClient.java:354)
|
... | @@ -2036,19 +2096,18 @@ Your local file may be invalid (e.g. illegal format, or doesn't match the config |
... | @@ -2036,19 +2096,18 @@ Your local file may be invalid (e.g. illegal format, or doesn't match the config |
|
|
|
|
|
Look at the content of your local config database, e.g. with
|
|
Look at the content of your local config database, e.g. with
|
|
|
|
|
|
```
|
|
```plaintext
|
|
$ find $INTROOT/localdb
|
|
$ find $INTROOT/localdb
|
|
```
|
|
```
|
|
|
|
|
|
and correct the file in place, or fix the source yaml and then redeploy it from source to the localdb.
|
|
and correct the file in place, or fix the source yaml and then redeploy it from source to the localdb.
|
|
|
|
|
|
**Background**
|
|
**Background**
|
|
|
|
|
|
You may have a malformed json file in your local db, which the config service failed to read.
|
|
You may have a malformed json file in your local db, which the config service failed to read.
|
|
|
|
|
|
Because of the use the location wildcard "\*" in your code (in "cii.config://\*/supervisoryapp/TrkLsvDeploy"),
|
|
Because of the use the location wildcard "\*" in your code (in "[cii.config://\*/supervisoryapp/TrkLsvDeploy"](cii.config://\*/supervisoryapp/TrkLsvDeploy%22)),
|
|
|
|
|
|
the config service has consequently tried to load the config from the remote config database, where no such config exists.
|
|
the config service has consequently tried to load the config from the remote config database, where no such config exists.
|
|
|
|
|
|
To that end, the error message is misleading, and should be improved (ticket [ECII-208](https://jira.eso.org/browse/ECII-208)). |
|
To that end, the error message is misleading, and should be improved (ticket [ECII-208](https://jira.eso.org/browse/ECII-208)). |
|
|
|
\ No newline at end of file |
|
|
|
|
|
|
|
|