У меня в последней версии SCADA:

## Код:
```
MODULE KrlJournaling;
   IMPORT Lf := KrlLife, Var := KrlVariants;

   TYPE
      Writer* = POINTER TO ABSTRACT RECORD (Lf.Object) END;

   PROCEDURE (w: Writer) Write* (rec: Var.Record), NEW, ABSTRACT;
   PROCEDURE (w: Writer) Transect*, NEW, ABSTRACT;
   PROCEDURE (w: Writer) Flush* (hard: BOOLEAN), NEW, ABSTRACT;

END KrlJournaling.
```


Write - сформировать запись из произвольного сочетания полей в журнале.
Transect - разделяет циклы журналирования (показывая реализации, где, например, можно разделить старый и новый файл журнала).
Flush - понятно.

Где:

## Код:
```
MODULE KrlVariants;

      Record = ARRAY OF Value;

      ValueData = ARRAY 16 OF BYTE;

      Value = RECORD 
         field-: KrlTokens.FieldT; (* токен, что за поле *)
         data-: ValueData; (* значение поля *)
         (IN v: Value) Bool (): BOOLEAN, NEW;
         (IN v: Value) Byte (): BYTE, NEW;
         (IN v: Value) Int (): INTEGER, NEW;
...
         (VAR v: Value) PutBool (field: KrlTokens.BoolT; x: BOOLEAN), NEW;
         (VAR v: Value) PutByte (field: KrlTokens.ByteT; x: BYTE), NEW;
         (VAR v: Value) PutInt (field: KrlTokens.IntT; x: INTEGER), NEW;
         (VAR v: Value) PutRec (field: KrlTokens.RecT; lim: INTEGER; IN s: ARRAY OF Value), NEW;
      END;
```


Пример записи о событии включения узла в журнал:

## Код:
```
VAR rec: ARRAY 16 OF Var.Value;
   BEGIN
      rec[0].PutTok(Var.recType, switchOnEv); (* поле с токеном recType хранит другой токен - токен типа записи журнала *)
      rec[1].PutLInt(ErcJrn.timestampSec, KrlDates.UnixT()); (* время *)
      rec[2].PutTok(ErcJrn.nodeSign, node); (* токен узла, к которому относится событие *)
      wr.Write(rec)
```
