bengeisler / TcLog

Flexible logging functionality for TwinCAT 3.
MIT License
54 stars 10 forks source link

Is there a way to check if the logger is time Synced? #17

Closed paulbarron85 closed 10 months ago

paulbarron85 commented 10 months ago

What is the best way to write log messages on the first couple of PLC scans after restarting. I would like to implement something like the following in a POU:

VAR_INPUT
    bInput : BOOL;
    bFirstScan : BOOL;
END_VAR
VAR
    _logger : TcLog;
    _tcLogTrig : TcLogTrig;
END_VAR

_logger
    .OnCondition(bFirstScan)
    .Warning(CONCAT('Initial value is ', BOOL_TO_STRING(bInput)));  

_tcLogTrig
    .OnRisingEdge(bInput)
    .Warning('Signal had a rising edge');   

_tcLogTrig
    .OnFallingEdge(bInput)
    .Warning('Signal had a falling edge');

With the POU being calling like so from MAIN:

VAR
    _coreLogger : TcLogCore(bufferSize := 100 * (Tc2_System.MAX_STRING_LENGTH + Constants.FifoOverhead));
    _logger : TcLog;

    fbTest : FB_Test;
    bInput : BOOL;
    bFirstScan : BOOL := TRUE;
END_VAR

_coreLogger
.WriteToAds()  
.IncludeInstancePath()
.TimestampFormat('YYMMDD')
.SetRollingInterval(RollingIntervals.Daily)
.MinimumLevel(LogLevels.Debug)
.WriteToFile(path, filename)
.RunLogger();

fbTest(bInput := bInput, bFirstScan := bFirstScan);
bFirstScan := FALSE;

However I end up getting two files written as below: image With the contents of the first file being: image

It looks like the time hasn't been updated yet to the local time. Is it possible to expose DateTime._localSystemTime.bValid? Or is there a better way of doing this?

bengeisler commented 10 months ago

The best way would be if the logger buffered these messages until the time is valid and then write them to the file. Since it already has a buffer built-in, this should be easy to implement. It always takes a few cycles until the time information is available.

Meanwhile, as a workaround, you can just use the DateTime function block as dummy because it exposes a Done property and trigger your logging once it becomes true. The same function block is used internally, so I'd expect the done bits to be in sync. See here.

I'll look into the buffering as well this weekend.

bengeisler commented 10 months ago

As a side note, you could simplify the logic of your first logging by leveraging the built-in string builder and any-to-string casts:

_logger
    .OnCondition(bFirstScan)
        .AppendString('Initial value is ')
        .AppendAny(bInput)
    .Warning();
bengeisler commented 10 months ago

This issue has been fixed with the latest release.

It buffers messages so that the timestamp in the filename is always valid. Additionally, it exposes the TimeInfoReady property that can be used to trigger messages only once a valid timestamp is available. See here.

paulbarron85 commented 10 months ago

As a side note, you could simplify the logic of your first logging by leveraging the built-in string builder and any-to-string casts:

_logger
  .OnCondition(bFirstScan)
        .AppendString('Initial value is ')
        .AppendAny(bInput)
  .Warning();

Only problem here is that it prints bool True as 1 and False as 0. I prefer it to print True/False.