Logging and Diagnosing
In this tutorial we will learn
- how to use the Zeugwerk Logger
- how to use tools to observe a logfile of a currently running application/machine
- how to enter new log messages
To be ready to start, please make sure all necessary tools are installed as mentioned here and its a good advice to take the quickstart tutorial first to know how to use the visualization and start this tutorial by creating a PLC from the Quickstart Template.
Logging
The Zeugwerk Logger comes with no extra tool, the logging is simply be done by the PLC itself. Potentially various sinks can be implemented, the default sink, which is also demonstrated here, is a textfile. Messages are buffered and therefore a lot of messages can be logged in each PLC cycle. For a technology deep dive of the logger please follow the docs here.
In this tutorial we will first add a simple info message each time the automatic sequence finishes and then add another message which outputs the actual sequence cycle count.
Start by creating a Zeugwerk Application using the Quickstart Template. Then open the automatic-sequence implementation, which can be found in PLC -> Tutorial Quickstart -> ZApp -> Unit -> Quickstart -> _States -> QuickstartSequenceAutomatic
To enter a log message at the end of the sequence, signaling that it has finished, lets scroll down to the very bottom and look for a step called AutomaticCylinderUp2 or if you have finished the Quickstart tutorial AutomaticWait3Secs as seen here and add a call to _logger.info. Since the new call is added inside the IF _step.OnEntry() statement, the message is only written once.
(* ------------------------------------------------------------- *)
UselessBoxStep.AutomaticCylinderUp2:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_actuator.CylinderY.UpAsync(THIS^);
_io.MagnetOn.Enable(FALSE);
_logger.info('Automatic sequence finished, now restart!'); // < Add this line
END_IF
Await(obj1:=_actuator.CylinderY, nextStep:=UselessBoxStep.AutomaticWait3Secs);
(* ------------------------------------------------------------- *)
UselessBoxStep.AutomaticWait3Secs:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_timer.WaitAsync(3.0);
END_IF
Await(obj1:=_timer, nextStep:=UselessBoxStep.AutomaticBegin);
If we make this log message outside the IF-statement, it will be entered every PLC cycle until we leave this state. This will lead to a lot log messages. So a good advice is, always try to log on edges of booleans or state changes but never cyclically inside a state - this keeps the log file much more comfortable to read.
Now activate this solution and connect the 3D Visualization. To be able to observe live whats happening with our solution we now connect a log-viewer tool which acts like tail -f in linux to the logfile.
The default location of the logfile is on the local disk of the PLC-target (so remember, if the target is your local PC/Notebook its C:, otherwise if it is a PLC-controller somewhere on your network it is on the hard disk there). To see which path is initialized open PLC -> Tutorial Quickstart -> ZApp -> ZModuleProgram and scroll down until you see the _logger line in the declaration part of your editor.
Depending on where you write your log file you will have to open it. Start LogExpert and click on Open File. Now navigate to the location of the logfile and double click on it, it should be opened without locking so we can now observe live whats happening. After booting of the application there are only a few messages entered here.
Lets move on and click on the GoHome button in the 3D Visualization to start the homing sequence of the PLC application. Now the logfile should get a live. All steps which are done during homing are automatically logged here. This includes all steps done by the actuators, ios and axis. It should look like this:
Now lets click on Start. The automatic sequence should now start as we know from the Quickstart Tutorial and at the end our log message should appear in the log viewer.
Perfect! the automatic sequence reached its last step and the logger writes our log message. Isnt that cool, no external tool needed, just the PLC and our powerfull logging tool. In fact there are a lot of optimizations running in background of this logger in order not to have a bad influence on the PLC performance. To get more information on that read our deep dive documentation here.
Now lets make a more sophisticated log-message and learn how to use the Zeugwerk StringBuilder. The StringBuilder is a small Class which makes concatenating strings more easier and it has a lot of nice functions to integrate for example the value of a Boolean or floating point numbers.
We now will count how often the automatic sequence runs through its whole steps. First lets declare a new variable _count in the declaration section of the function block
FUNCTION_BLOCK UselessBoxSequenceAutomatic EXTENDS UselessBoxSequence IMPLEMENTS ZCore.ISequence
VAR
_step : ZCore.Step(UselessBoxStep.AutomaticBegin, UselessBoxStep.AutomaticEnd);
_timer : ZAux.Timer;
_count : INT; // < Add this line
END_VAR
Now we go again to the end of this sequence and we want to increment count every cycle the sequence steps into the AutomaticCylinderUp2 step. Additionally we use the StringBuilder to concatenate a new String which gets then logged into the log file.
(* ------------------------------------------------------------- *)
UselessBoxStep.AutomaticCylinderUp2:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_actuator.CylinderY.UpAsync(THIS^);
_io.MagnetOn.Enable(FALSE);
// Add the next two lines
_count := _count + 1;
_logger.Info(_stringBuilder.Append('Sequence ended #').AppendInt(_count).Append(' times!').ToString());
END_IF
Await(obj1:=_actuator.CylinderY, nextStep:=UselessBoxStep.AutomaticWait3Secs);
Activate the solution, connect the 3D Visualization and start the homing procedure. After that click on Start and watch the sequence going. In parallel open the log file in LogExpert and find the newly added log message.
Thats it, i hope you learned a little on how to use the Zeugwerk Logger and the StringBuilder.