History System: Difference between revisions
Line 279: | Line 279: | ||
password=reader_password ### change this!!! | password=reader_password ### change this!!! | ||
</pre> | </pre> | ||
* test MIDAS connection | |||
<pre> | |||
mh2sql --mysql mysql_writer.txt | |||
(there should be no errors printed) | |||
</pre> | |||
* if desired, import midas history from .hst files: | |||
<pre> | |||
mh2sql --mysql mysql_writer.txt *.hst | |||
Reading 130813.hst | |||
[mh2sql,ERROR] [history_schema.cxx:1165:Mysql::Prepare,ERROR] mysql_query(SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name!='';) error 1146 (Table 'history._history_index' doesn't exist) | |||
[mh2sql,INFO] Adding SQL table "rpcexample", status 311 | |||
[mh2sql,INFO] Adding SQL table "rpcexample_1596127680", status 1 | |||
[mh2sql,INFO] Adding SQL table "_history_index", status 1 | |||
[mh2sql,INFO] Adding column "event_name" to SQL table "_history_index", status 1 | |||
... | |||
[mh2sql,INFO] Adding SQL table "run_transitions", status 311 | |||
[mh2sql,INFO] Adding SQL table "run_transitions_1596127681", status 1 | |||
[mh2sql,INFO] Adding column "state" to SQL table "run_transitions_1596127681", status 1 | |||
[mh2sql,INFO] Adding column "run_number" to SQL table "run_transitions_1596127681", status 1 | |||
Reading 130815.hst | |||
... | |||
</re> | |||
* enable MYSQL history in mlogger: | * enable MYSQL history in mlogger: | ||
** change ODB /Logger/History/MYSQL/Active to "y", "mysql writer" and "mysql reader" to location of these files (leave the default values if these files are in the experiment directory). | ** change ODB /Logger/History/MYSQL/Active to "y", "mysql writer" and "mysql reader" to location of these files (leave the default values if these files are in the experiment directory). |
Revision as of 08:56, 30 July 2020
Links
Introduction
The history system is an add-on capability built into the MIDAS data logger mlogger to record useful information in parallel to the data logging. This information is recorded with a time stamp and saved into a history file (see History drivers) for later retrieval. One set of files is created per day containing all the requested history events. The history data may be displayed in graphical form using the mhttpd MIDAS webserver utility, giving the user an easy way of seeing how experimental variables have changed with time. The history logging will be in action only if the MIDAS data logger is running, but it is not necessary to have any data logging channel enabled.
Since June 2020, it is possible to also use the midas history system to record images (png/jpeg etc) periodically, for example to later produce a timelapse from a webcam - see the Image History page for more details.
MidasHistoryInterface
The new history configuration defines history channels similar to logger channels. Each history channel creates a history interface class (class MidasHistoryInterface). The data logger can use this interface to write data into the history, mhttpd, mhist & co can use this interface to read data from the history. The interface is defined in history.h
History drivers
Presently, the MIDAS distribution contains these drivers:
- MIDAS-History
- this is the traditional history driver, with data stored in the .hst binary files. (format is documented here mhformat, see also mhist and mhdump)
- By default ODB subtree "MIDAS" is set up to write MIDAS-history.
- ODBC-History
- stores history data in SQL database using the ODBC abstraction layer. See ODBC SQL History system.
- By default ODB subtree "ODBC" is set up to write ODBC-history.
- SQLITE-History
- stores data in SQL database as SQLITE3 .sqlite3 files. The SQL table format is similar to ODBC-history, performance is similar, no database server required.
- By default ODB subtree "SQLITE" is set up to write SQLITE-history.
- MYSQL-History
- By default ODB subtree "MYSQL" is set up to write MYSQL-history.
- FILE-History
- stores each variable in its own file, making it much easier to trace the history of a particular variable.
- By default ODB subtree FILE is set up to write FILE-history.
More drivers can be easily added by the user (create history_xxx.cxx, add constructor to hs_get_history(), create the ODB subtree /Logger/History/xxx/channel).
Location of History Files
- MIDAS-history
- By default, the traditional MIDAS-history is enabled, writing history files into the MIDAS data directory path given by the ODB key Data dir.
- If history data is important, it is recommended to write it to a directory that is backed up or archived. (The MIDAS data directory is usually located on a scratch data disk without backups).
- The location of the MIDAS-history data files can be changed by use of the ODB Key History dir.
- ODBC-History
- The location of ODBC-History files is ...
- SQLITE-History
- The location of SQLITE-History files is the directory path given by the ODB key Sqlite dir.
- MYSQL-History
- The location of MYSQL-History files is ...
- FILE-History
- The location of FILE-History files is the directory path given by the ODB key History dir.
Types of History Events
There are two basic types of history events, which are defined in different ways:
- "Frontend" (or "Equipment") History event composed in the frontend. See Frontend History Event for details.
- "Virtual" (or "Links") History event composed within the ODB under the /History/Links subtree. See Virtual History Event for details.
Both these history event definitions take effect when the data logger gets a start run transition. Any modifications made during the run are not applied until the start of the next run.
Virtual History Event
The history of any ODB variable can be recorded in a "virtual" history event by creating a link to that variable in the /History/Links subtree. This is used for ODB variables that are not in an Equipment.
- To enable Virtual History Events
- Create links as desired in /History/Links subtree.
History events are created for each entry under ODB subdirectory /History/Links.
Two types of links are permitted:
- ODB key /history/links/aaa is a link to a subdirectory
- db_watch() is setup to watch this subdirectory
- tags are created for each subdirectory entry (1 tag per entry)
- There is no possibility for naming array elements, so 1 tag per array, regardless of the number of elements.
- ODB key /history/links/bbb is a subdirectory with links to ODB values
-
- db_watch is setup to watch each link target
- tags are created for each link (1 tag per link)
- tag name is the link name (NOT the target name). There is no possibility for naming array elements
Mixing links and subdirectories is not permitted.
The update period of history events created for /history/links is controlled by entries in /history/links periods. Numeric values of periods are same as for a Frontend History event. Numeric value 0 disables the history for a particular event.
See MidasElog#1087 for more information.
Frontend History Event
Each Equipment has the capability to generate "history data".
- To enable Frontend History Events
- Set the Log history ODB key of each equipment to be logged non-zero. (See Log History parameter). (You may need to restart the frontend.)
This causes the event contents to be copied to the ODB /Equipment/<equipment-name>/Variables subtree for the use of the History system. history events are created by parsing the content of /Equipment/<equipment-name>/variables.
For each equipment, history is controlled by the value of
/Equipment/<equipment-name>/common/period as follows:
- 0 = history disabled
- 1 = history is enabled
- >1 = history is enabled, throttled down
The throttling is implemented in log_history()/watch_history() by this algorithm: the very first history event is recorded, then all changed to the data are ignored until "period" seconds has elapsed. Then the next history event will be recorded, and following changes will be ignored until "period" second elapses, and so forth. Period value "1" has special meaning - there is no throttling, all history events are logged.
This information is from MidasElog#1087.
Sequence for frontend History Event
The main steps for the frontend History Event is as follows:
- The user code in the frontend equipment Event Readout routines reads the data, placing it into a MIDAS data bank
- In mfe.c, if the key Log history > 0 (i.e. the history system is enabled for this equipment), this data bank is written into ODB (by update_odb()).
- This ODB write triggers an ODB hot-link into mlogger
- The hot-link calls mlogger.c::log_history(), which calls hs_write() to write the data into the history file. The frequency of the history writes is specified by the number of seconds between writes stored in the ODB key Log history.
- history.c::hs_write() or history_odbc::hs_write_odbc() writes the data into a history file or into an SQL database.
How to Write History events
- Enable desired Frontend and/or Virtual history events
- Select the history driver
- Follow instructions below for selected driver:
Select the history driver
- Select the history driver and therefore the history-logging-channel to use to write the MIDAS-history files.
- set Active ODB key in the selected history-logging-channel to "y". All other logging channels should be disabled.
- set LoggerHistoryChannel ODB key to the selected History channel.
Write MIDAS-History events
- Enable desired Frontend and/or Virtual history events
- Perform steps in Select History Driver with history driver "MIDAS".
- Restart mhttpd and mlogger, start the run.
MIDAS-history files will be saved into the MIDAS-history data directory.
Write ODBC-History events
See MIDAS ODBC SQL History system.
- If necessary, set up a MySQL database.
- Enable desired virtual and frontend history events (see Virtual history events and Frontend history events).
- Perform steps in Select History Driver with history driver "ODBC".
- Check ODB Key Writer_ODBC_DSN is set to "history writer" and Key Reader_ODBC_DSN is set to "history reader" (the default values)
- set Debug to 1 if desired
- restart mlogger in verbose mode (i.e. mlogger -v), and observe how it issues SQL commands to create the tables and columns corresponding to MIDAS-history events and tags.
- restart mhttpd
Notes
- mlogger is programmed to raise alarms if connection to SQL database is interrupted or if some events cannot be written into the database (i.e. data type mismatch, SQL syntax errors, etc). The traditional MIDAS-history never raised alarms because it "never failed" - other than from "disk full" errors, which are immediately obvious.
- With ODBC History enabled, mhttpd will only use history information from the SQL database to make history plots and to extract history variable names for the history plot editor. The ODB
/History subtreesTags and Events are not used.
- variable names presented to the user may change from MIDAS names to SQL names (use the history panel "Label" text fields to create permanent plot labels).
Write SQLITE-history events
No special configuration required.
- Enable desired virtual and frontend history events (see Virtual history events and Frontend history events).
- Perform steps to Select History Driver with history driver "SQLITE".
- Create a directory for storage of sqlite history files
- save its path in the ODB key Sqlite dir
- restart mhttpd and mlogger
In the history data directory (in Sqlite dir) you should see files with name "mh_xxx.sqlite3" corresponding to your equipment and variable names.
Write MYSQL-history events
- Enable desired virtual and frontend history events (see Virtual history events and Frontend history events).
- Perform steps to Select History Driver with history driver "MYSQL".
- setup the MySQL database:
- install mariadb-10.4
macos: sudo port install mariadb-10.4 ln -s ln -fs /opt/local/lib/mariadb-10.4/bin/mysql_config ~/bin/ mysql_config --version 10.4.13
- rebuild midas, check the cmake finds the correct mysql: MIDAS: Found MySQL version 10.4.13
- create $HOME/.my.cnf
[mysqld] #port=3306 socket=/Users/olchansk/mysql/mysql.sock datadir=/Users/olchansk/mysql/db pid-file=/Users/olchansk/mysql/mysqld.pid [client] #port=3306 socket=/Users/olchansk/mysql/mysql.sock
- mkdir $HOME/mysql
- start mysql:
macos: /opt/local/lib/mariadb-10.4/bin/mysqld
- configure the database: start the "mysql" utility (/opt/local/lib/mariadb-10.4/bin/mysql)
NOTE: instructions thanks to Ben S. NOTE: use some other passwords instead of the example "reader_password" and "writer_password" MariaDB [(none)]> CREATE DATABASE IF NOT EXISTS history; Query OK, 1 row affected (0.003 sec) MariaDB [(none)]> CREATE USER history_reader@'localhost' IDENTIFIED BY 'reader_password'; Query OK, 0 rows affected (0.027 sec) MariaDB [(none)]> GRANT SELECT ON history.* TO history_reader@'localhost'; Query OK, 0 rows affected (0.016 sec) MariaDB [(none)]> CREATE USER 'history_writer'@'localhost' IDENTIFIED BY 'writer_password'; Query OK, 0 rows affected (0.014 sec) MariaDB [(none)]> GRANT SELECT,INSERT,CREATE,ALTER,INDEX ON history.* TO 'history_writer'@'localhost'; Query OK, 0 rows affected (0.017 sec) MariaDB [(none)]> flush privileges; Query OK, 0 rows affected (0.001 sec)
- try connecting to both users:
/opt/local/lib/mariadb-10.4/bin/mysql -u history_reader -p ### should ask for reader password /opt/local/lib/mariadb-10.4/bin/mysql -u history_writer -p ### should ask for writer password
- create midas config files:
- mysql_writer.txt
#server=localhost #port=xxx database=history socket=/Users/olchansk/mysql/mysql.sock user=history_writer password=writer_password ### change this!!! #buffer=1000
- mysql_reader.txt
#server=localhost #port=xxx database=history socket=/Users/olchansk/mysql/mysql.sock user=history_reader password=reader_password ### change this!!!
- test MIDAS connection
mh2sql --mysql mysql_writer.txt (there should be no errors printed)
- if desired, import midas history from .hst files:
mh2sql --mysql mysql_writer.txt *.hst Reading 130813.hst [mh2sql,ERROR] [history_schema.cxx:1165:Mysql::Prepare,ERROR] mysql_query(SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name!=;) error 1146 (Table 'history._history_index' doesn't exist) [mh2sql,INFO] Adding SQL table "rpcexample", status 311 [mh2sql,INFO] Adding SQL table "rpcexample_1596127680", status 1 [mh2sql,INFO] Adding SQL table "_history_index", status 1 [mh2sql,INFO] Adding column "event_name" to SQL table "_history_index", status 1 ... [mh2sql,INFO] Adding SQL table "run_transitions", status 311 [mh2sql,INFO] Adding SQL table "run_transitions_1596127681", status 1 [mh2sql,INFO] Adding column "state" to SQL table "run_transitions_1596127681", status 1 [mh2sql,INFO] Adding column "run_number" to SQL table "run_transitions_1596127681", status 1 Reading 130815.hst ... </re> * enable MYSQL history in mlogger: ** change ODB /Logger/History/MYSQL/Active to "y", "mysql writer" and "mysql reader" to location of these files (leave the default values if these files are in the experiment directory). * enable MYSQL history in mhttpd: ** change ODB /History/LoggerHistoryChannel to "MYSQL" * restart mlogger, restart mhttpd ...........Write FILE-history events
* Enable desired virtual and frontend history events (see Virtual history events and Frontend history events). * Perform steps to Select History Driver with history driver "SQLITE". * Assign directory path for saved files using the ODB key History dir. ...........
History Events
The following information is derived from MidasElog#1087. A "history event" is a history atomic unit of data. Associated with each history event is a timestamp (unix time), a name (limited to NAME_LENGTH in the old history) and a list of history tags that describe the individual data values inside the history event. When making history plots in mhttpd (see History Page) for each curve on the plot, one selects a history event (from the list of currently active events, recently active events or the list of all events that ever existed), then from the list of tags inside the history event one selects the particular variable that will be plotted.Old MIDAS history events
In the old MIDAS history, all history events are written into one history file (.hst file + optional .def and .idx event definition and time index files which can be/are regenerated automatically from the .hst file). History events are identified by 16-bit history event IDs, the persistent mapping from history event names and the 16-bit history event IDs is stored in ODB subtree /History/Events. In addition the list of all known history event tags is stored in ODB subtree /History/Tags. For per-equipment history, the 16-bit history event ID is the value of ODB key /Equipment/<equipment-name>/Common/Event ID.SQL history events
In the SQL history (MySQL, SQLITE, etc), each history event is an SQL table. The history event tags are the SQL table columns.FILE history events
In the new FILE history, each history event is written into a separate file, tag definition are recorded in text format in the file header, history event data is appended to the file in binary format (fixed record size). If the history event definition is changed, a new file will be started.History Event Construction
The mlogger creates #Frontend history events in open_history() by parsing the ODB subtree /equipment/<equipment-name>/variables. Each ODB entry under the variables/ subtree is referred to as a "variable". Each variable can be a single ODB value, an array of ODB values, or a subdirectory (corresponding to TID_STRUCT structured data banks). As each variable is processed, one or more tags are created to describe it. Single ODB values will generally produce a single tag, while arrays can produce (depending whether the array is "Named" or not) * multiple tags - one per array element ("Named" array) or * one single tag - describing the whole array The code can generate two types of history:
- "per-equipment" history
- will have the tags for all variables concatenated together into one single history event
- "per-variable" history
- will have one history event defined for each variable. Inside could be one tag (for single odb values and unnamed array) or multiple tags (for named arrays and structured data banks).