diff --git a/manifest.json b/manifest.json index 3c13cf4..2345af1 100644 --- a/manifest.json +++ b/manifest.json @@ -59,7 +59,7 @@ "output": { ".html": { "relative_path": "reference/TcLog/Logger/TcLog.html", - "hash": "Hsc16PcssUpB0u4qogyTc29JAf9SO/YR3Duf59hq4qM=" + "hash": "CdJguhizAKF5XVzsToP0inyHBZ40/jM63YGhdnSgu/A=" } }, "is_incremental": false, @@ -275,7 +275,7 @@ "output": { ".html": { "relative_path": "userguide/configuration.html", - "hash": "cpNQnS2lXJlrcsrazfwQgD0b8sDpixxCFSFFMefLGaM=" + "hash": "pwbbiewwLNtLH0c1S2luuNBPnoQ/sfx5rH+EiVdoaHk=" } }, "is_incremental": false, @@ -287,7 +287,7 @@ "output": { ".html": { "relative_path": "userguide/customization.html", - "hash": "BcJLLPCsqBOwuTUds8cQmaNq1byPhU2+iLBWIuSxOZg=" + "hash": "ppkAz36PQhyT6ghKthQVOxsWePw9IQu3gYFJtp9CYbA=" } }, "is_incremental": false, @@ -299,7 +299,7 @@ "output": { ".html": { "relative_path": "userguide/getting_started.html", - "hash": "hLJaQkOwPFGV7o6GnaFN0FK9F6ln9pyFyPSZQQMURYg=" + "hash": "9f2lJnz+DDYo8cA0+EjiZrnyY7L9TUO2p2TWXRwF3GA=" } }, "is_incremental": false, @@ -311,7 +311,7 @@ "output": { ".html": { "relative_path": "userguide/installation.html", - "hash": "jPLwm2fAVOXD3HjvpohdTOYFHpcMY+JVOF9sKIlpI+g=" + "hash": "1tPJ5P2a5rEO+mCNcVUMYdxdI/V2zYSAvxj18D2KAVQ=" } }, "is_incremental": false, @@ -323,7 +323,7 @@ "output": { ".html": { "relative_path": "userguide/introduction.html", - "hash": "8wUWv5iFtBORench9D50I8aU9PwOsbDdVUu+OSXNHs4=" + "hash": "cVuaDDhWJG1mT6kXQy1TX+gz1U9quS8bBIwGZrTLeK0=" } }, "is_incremental": false, @@ -335,7 +335,7 @@ "output": { ".html": { "relative_path": "userguide/license.html", - "hash": "9HFud/U9euuZFjY4txBca6rKLTwtBl8JbxRbnNkhmHs=" + "hash": "Kou359aQXJIGJ5PVnQ87jzJp4eEDWpWzeoish7JYCVw=" } }, "is_incremental": false, @@ -347,7 +347,7 @@ "output": { ".html": { "relative_path": "userguide/logging.html", - "hash": "OvRiz4d0BT1+OivK9zyUDLSrFXmwYlb//49JSS9aQhk=" + "hash": "mNdTcAyJ1O4crj/ScIMnDQmKzTz0wkbQI8uC3KCuIDQ=" } }, "is_incremental": false, @@ -359,7 +359,7 @@ "output": { ".html": { "relative_path": "userguide/performance.html", - "hash": "nuiR10dxBIEYdp8xzdg5Q6CAb6VlQGXzDw04sZ9bjoA=" + "hash": "FC0URvWJjHoUHyWTkTQruVbBeXyvzFOUCi5OuC36dPE=" } }, "is_incremental": false, diff --git a/reference/TcLog/Logger/TcLog.html b/reference/TcLog/Logger/TcLog.html index 3cc0a69..8cac45a 100644 --- a/reference/TcLog/Logger/TcLog.html +++ b/reference/TcLog/Logger/TcLog.html @@ -276,7 +276,7 @@

Append Example:

VAR
   Logger: TcLog;
-	 myInt : INT := 10;
+   myInt : INT := 10;
   myVarInfo : __SYSTEM.VAR_INFO := __VARINFO(myInt);
 END_VAR
 Logger.AppendVariable(myVarInfo, myInt);
diff --git a/userguide/configuration.html b/userguide/configuration.html
index 02b0c63..1f2975e 100644
--- a/userguide/configuration.html
+++ b/userguide/configuration.html
@@ -84,9 +84,6 @@
                     
  • Installation
  • -
  • - User Guide -
  • User guide @@ -126,11 +123,11 @@

    Delimiter

    Including the instance path in the log message

    TcLog offers with .IncludeInstancePath() the possibility to include the location where the message was triggered into the message text:

    _coreLogger
    -	.WriteToAds()
    -	.IncludeInstancePath()
    -	.MinimumLevel(LogLevels.Warning)
    -	.RunLogger();
    -	
    +  .WriteToAds()
    +  .IncludeInstancePath()
    +  .MinimumLevel(LogLevels.Warning)
    +  .RunLogger();
    +  
     _logger.Error('This is an error message.');
     

    Including the instance path

    @@ -143,14 +140,14 @@

    Log to ADS output

    Log to file system

    TcLog brings the option to store logs in the file system in the form of text files. This option can be applied to TcLogCore via the method .WriteToFile(path, filename):

    _coreLogger
    -	.IncludeInstancePath()
    -	.MinimumLevel(LogLevels.Warning)
    -	.WriteToFile('c:\logs\', 'test.txt')
    -	.RunLogger();
    -	
    +  .IncludeInstancePath()
    +  .MinimumLevel(LogLevels.Warning)
    +  .WriteToFile('c:\logs\', 'test.txt')
    +  .RunLogger();
    +  
     _loggerTrig
    -	.OnRisingEdge(_log)
    -	.Error('rTrig Test');
    +  .OnRisingEdge(_log)
    +  .Error('rTrig Test');
     

    Logging to the file system

    Timestamp

    diff --git a/userguide/customization.html b/userguide/customization.html index 34bee7f..a140fa0 100644 --- a/userguide/customization.html +++ b/userguide/customization.html @@ -84,9 +84,6 @@
  • Installation
  • -
  • - User Guide -
  • User guide @@ -130,32 +127,32 @@

    Wrapper around TcLog

    As wrapper we use an function block that encapsulates TcLog and enforces the data input with the help of the inputs. Furthermore it implements the interface ILog which establishes the link between logger and base logger.

    FUNCTION_BLOCK UserLog IMPLEMENTS ILog
     VAR_INPUT
    -	Condition: BOOL;
    -	Identification: STRING;
    -	Value: REAL;
    -	Unit: STRING;
    +  Condition: BOOL;
    +  Identification: STRING;
    +  Value: REAL;
    +  Unit: STRING;
     END_VAR
     VAR
    -	_getTimeData: DateTime;
    -	_timestamp: STRING;
    +  _getTimeData: DateTime;
    +  _timestamp: STRING;
     END_VAR
     VAR_STAT
    -	_logger: TcLog;	
    +  _logger: TcLog; 
     END_VAR
     
     _getTimeData();
     _timestamp := _getTimeData.ToString('hh:mm:ss');
     
     _logger
    -	.OnCondition(Condition)
    -	.AppendString(_timestamp)
    -	.AppendString(';')
    -	.AppendString(Identification)
    -	.AppendString(';')
    -	.AppendAny(Value)
    -	.AppendString(';')
    -	.AppendString(Unit)
    -	.ToCustomFormat('');
    +  .OnCondition(Condition)
    +  .AppendString(_timestamp)
    +  .AppendString(';')
    +  .AppendString(Identification)
    +  .AppendString(';')
    +  .AppendAny(Value)
    +  .AppendString(';')
    +  .AppendString(Unit)
    +  .ToCustomFormat('');
     

    We can use the helper function GenerateTimeData, which returns the current date and time formatted via the .ToString(Format) method. With its help we generate the timestamp of the sensor data.

    The .ToCustomFormat('') method at the end of the chain causes the message to be logged unchanged. No additional information like further timestamps or instance path will be appended.

    @@ -163,7 +160,7 @@

    The interface ILog

    The interface is implemented by passing the logger reference to the TcLog instance:

    METHOD SetLogger : BOOL
     VAR_INPUT
    -	ref2Core : REFERENCE TO TcLogCore;
    +  ref2Core : REFERENCE TO TcLogCore;
     END_VAR
     
     _logger.SetLogger(ref2Core);
    @@ -171,35 +168,35 @@ 

    The interface ILog

    Calling the wrapper

    Somewhere in our program TcLogCore is called cyclically. If there is more than one instance of it, we can tell our logger which instance we want via .SetLogger(Instance). Otherwise the configuration of the logger singleton is used.

    VAR
    -	_newLogger: TcLogCore;
    -	_rTrigLog : R_TRIG;
    -	_log : BOOL;
    -	_myLog : UserLog;
    -	_myValue: REAL := 1.0;
    -	_myValue2: REAL := 2.0;
    +  _newLogger: TcLogCore;
    +  _rTrigLog : R_TRIG;
    +  _log : BOOL;
    +  _myLog : UserLog;
    +  _myValue: REAL := 1.0;
    +  _myValue2: REAL := 2.0;
     END_VAR
     
     _newLogger
    -	.MinimumLevel(LogLevels.Information)
    -	.SetRollingInterval(RollingIntervals.Hourly)
    -	.WriteToFile('c:\logs\', 'sensor.csv')
    -	.DeleteLogFilesAfterDays(1)
    -	.RunLogger();
    -	
    +  .MinimumLevel(LogLevels.Information)
    +  .SetRollingInterval(RollingIntervals.Hourly)
    +  .WriteToFile('c:\logs\', 'sensor.csv')
    +  .DeleteLogFilesAfterDays(1)
    +  .RunLogger();
    +  
     _myLog.SetLogger(_newLogger);
     _rTrigLog(CLK := _log);
     
     _myLog(
    -	Condition := _rTrigLog.Q,
    +  Condition := _rTrigLog.Q,
         Identification := '+CC1-B31',
    -	Value := _myValue,
    -	Unit := '°C');
    -	
    +  Value := _myValue,
    +  Unit := '°C');
    +  
     _myLog(
    -	Condition := _rTrigLog.Q,
    -	Identification := '+CC1-B32',
    -	Value := _myValue2,
    -	Unit := '°C');
    +  Condition := _rTrigLog.Q,
    +  Identification := '+CC1-B32',
    +  Value := _myValue2,
    +  Unit := '°C');
     

    As soon as logging is triggered via _log, the csv file and the entries in it are created:

    Custom logging

    diff --git a/userguide/getting_started.html b/userguide/getting_started.html index 576e1ba..aa84e6c 100644 --- a/userguide/getting_started.html +++ b/userguide/getting_started.html @@ -84,9 +84,6 @@
  • Installation
  • -
  • - User Guide -
  • User guide @@ -127,22 +124,22 @@

    Getting started

    Example usage

    Configure the core logger in your project:

    VAR
    -	_coreLogger : TcLogCore(bufferSize := 100 * SIZEOF(BYTE) * MAX_STRINGLENGTH);
    +  _coreLogger : TcLogCore(bufferSize := 100 * SIZEOF(BYTE) * MAX_STRINGLENGTH);
     END_VAR
     
     _coreLogger
    -	.WriteToAds()
    +  .WriteToAds()
         .WriteToFile('c:\logs\', 'sensor_data.txt')
    -	.MinimumLevel(LogLevels.Debug)
    -	.RunLogger();
    +  .MinimumLevel(LogLevels.Debug)
    +  .RunLogger();
     

    Then, maybe in a different POU, use TcLog to log messages:

    VAR
    -	_logger : TcLog;
    +  _logger : TcLog;
     END_VAR
     
    -_logger.Debug('This is a debug message.');	
    -_logger.Error('This is an error message.');		
    +_logger.Debug('This is a debug message.');  
    +_logger.Error('This is an error message.');   
     

    This will log both messages to both the ADS output and the file system.

    Next, see how to configure TcLog and how to use TcLog in detail.

    diff --git a/userguide/installation.html b/userguide/installation.html index 2022c47..0559a57 100644 --- a/userguide/installation.html +++ b/userguide/installation.html @@ -84,9 +84,6 @@
  • Installation
  • -
  • - User Guide -
  • User guide diff --git a/userguide/introduction.html b/userguide/introduction.html index ab7148a..d1d54d5 100644 --- a/userguide/introduction.html +++ b/userguide/introduction.html @@ -84,9 +84,6 @@
  • Installation
  • -
  • - User Guide -
  • User guide diff --git a/userguide/license.html b/userguide/license.html index 2bf067a..d80d319 100644 --- a/userguide/license.html +++ b/userguide/license.html @@ -84,9 +84,6 @@
  • Installation
  • -
  • - User Guide -
  • User guide diff --git a/userguide/logging.html b/userguide/logging.html index cd953d5..fb96f45 100644 --- a/userguide/logging.html +++ b/userguide/logging.html @@ -84,9 +84,6 @@
  • Installation
  • -
  • - User Guide -
  • User guide @@ -122,16 +119,16 @@

    Flexible logging

    TcLog implements a StringBuilder which makes it easy to build your own message text:

    VAR
         _logger: TcLog;
    -	_myInt : INT := 10;
    -	_myVarInfo : __SYSTEM.VAR_INFO := __VARINFO(_myInt);
    +  _myInt : INT := 10;
    +  _myVarInfo : __SYSTEM.VAR_INFO := __VARINFO(_myInt);
     END_VAR
     
     _logger
    -	.AppendString('Let´s log some values: ')
    -	.AppendAny(_myInt)
    -	.AppendString(' - or some symbols: ')
    -	.AppendVariable(_myVarInfo, _myInt)
    -	.Error('');	
    +  .AppendString('Let´s log some values: ')
    +  .AppendAny(_myInt)
    +  .AppendString(' - or some symbols: ')
    +  .AppendVariable(_myVarInfo, _myInt)
    +  .Error(''); 
     

    Using a StringBuilder to generate the message text

    Thus any amount of information can be appended to the message without having to implement TcLog with a large number of input parameters, since TwinCAT (at least in version before build 4026.0) does not allow optional input parameters.

    @@ -141,48 +138,48 @@

    Conditional logging

    The most common use of logging will be in the form IF ... THEN log() END_IF. Therefore this query is already integrated in TcLog:

    VAR
         _logger: TcLog;
    -	_triggerLogging : R_TRIG;
    -	_log : BOOL;
    +  _triggerLogging : R_TRIG;
    +  _log : BOOL;
     END_VAR
     
     _triggerLogging(CLK := _log);
     _logger
    -	.OnCondition(_triggerLogging.Q)
    -	.Error('Only logs when OnCondition evaluates to TRUE.');	
    +  .OnCondition(_triggerLogging.Q)
    +  .Error('Only logs when OnCondition evaluates to TRUE.');  
     

    Logging on rising/falling edges

    Since a log message is usually to be sent once in the event of a status change, TcLog also provides a block for this purpose: TcLogTrig. In contrast to TcLog, a separate instance must be created for each use of this block, since the edge state is stored internally. The conditional execution can thus be further simplified:

    VAR
    -	_loggerTrig : TcLogTRIG;
    +  _loggerTrig : TcLogTRIG;
         _log : BOOL;
     END_VAR
     
     _loggerTrig
    -	.OnRisingEdge(_log)
    -	.Error('rTrig Test');
    +  .OnRisingEdge(_log)
    +  .Error('rTrig Test');
     

    Likewise, logging can be triggered on falling edges with OnFallingEdge(cond).

    Use of multiple loggers

    Even though the logger was primarily designed as a singleton, it is possible to use multiple loggers. For example, sensor data can be collected cyclically and stored in a separate log file. To add another logger, an instance of TcLogCore must be created. This is then bound to the desired TcLog instance:

    VAR
    -	_newLogger: TcLogCore;
    -	_logger: TcLog;
    -	_myInt : INT := 10;
    +  _newLogger: TcLogCore;
    +  _logger: TcLog;
    +  _myInt : INT := 10;
     END_VAR
     
     _newLogger
    -	.MinimumLevel(LogLevels.Information)
    -	.SetRollingInterval(RollingIntervals.Hourly)
    -	.WriteToFile('c:\logs\', 'sensor_data.txt')
    -	.DeleteLogFilesAfterDays(7)
    -	.RunLogger();
    -	
    +  .MinimumLevel(LogLevels.Information)
    +  .SetRollingInterval(RollingIntervals.Hourly)
    +  .WriteToFile('c:\logs\', 'sensor_data.txt')
    +  .DeleteLogFilesAfterDays(7)
    +  .RunLogger();
    +  
     // Bind the new logger to the TcLog instance
     _logger.SetLogger(_newLogger);
     
     _logger.AppendString('Sensor xy: ')
    -	.AppendAny(_myInt)
    -	.Information('');	
    +  .AppendAny(_myInt)
    +  .Information(''); 
     

    From now on _logger considers the configuration of _newLogger.

    diff --git a/userguide/performance.html b/userguide/performance.html index 473a16e..ecae261 100644 --- a/userguide/performance.html +++ b/userguide/performance.html @@ -84,9 +84,6 @@
  • Installation
  • -
  • - User Guide -
  • User guide