OPC Studio User's Guide and Reference
Component Event Logging
View with Navigation Tools
Concepts > Development Concepts > Development Advanced Topics > Configuration and Instrumentation > Component Event Logging
In This Topic

QuickOPC does not log events on itself, but allows you to implement such functionality. It generates notifications with log entries that contain the necessary data. You can receive these notifications, and implement any kind of event logging with them in your code.

Note that you should not programmatically use the logging event notifications for any kind of direct actions on the OPC subsystem. For example, the notifications that inform you about the connections and disconnections to/from OPC servers have no direct relation to your OPC method calls, because the component internally merges the requests from multiple objects, and also makes optimizations to prevent unnecessary disconnections etc. The purpose of event logging is different from OPC communication.

The data generated by event logging can contain security sensitive information. Make sure that when consuming and processing such data, it is properly secured.

Event Logging for OPC UA Client-Server

The EasyUAClient component has a static LogEntry event. This event is raised for loggable entries originating in the OPC-UA client engine and the EasyUAClient component. Each event notification carries a LogEntryEventArgs object, which contains information such as the source of the event, the event message, event type, timestamp, etc.

The EasyUAServer component works analogically.

 

In COM, you cannot access static members of the EasyUAClient object, and therefore you cannot directly use its LogEntry event. To get around this, create an instance of the EasyUAClientManagement object instead, and use its (non-static) LogEntry event to achieve the same result.

Example - QuickOPC

.NET

// This example demonstrates the loggable entries originating in the OPC-UA client engine and the EasyUAClient component.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.BaseLib.Instrumentation;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._EasyUAClient
{
    class LogEntry
    {
        public static void Main1()
        {
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            // Hook static events
            EasyUAClient.LogEntry += EasyUAClientOnLogEntry;

            try
            {
                // Do something - invoke an OPC read, to trigger some loggable entries.
                var client = new EasyUAClient();
                try
                {
                    client.ReadValue(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853");
                }
                catch (UAException uaException)
                {
                    Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                    return;
                }

                Console.WriteLine("Processing log entry events for 1 minute...");
                System.Threading.Thread.Sleep(60 * 1000);

                Console.WriteLine("Finished.");
            }
            finally
            {
                // Unhook static events
                EasyUAClient.LogEntry -= EasyUAClientOnLogEntry;
            }
        }

        // Event handler for the LogEntry event. It simply prints out the event.
        private static void EasyUAClientOnLogEntry(object sender, LogEntryEventArgs logEntryEventArgs)
        {
            Console.WriteLine(logEntryEventArgs);
        }
    }
}

COM

// This example demonstrates the loggable entries originating in the OPC-UA client engine and the EasyUAClient component.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

#include "stdafx.h"    // Includes "QuickOpc.h", and other commonly used files
#include <atlcom.h>
#include "LogEntry.h"

namespace _EasyUAClientManagement
{
    // CEasyUAClientManagementEvents

    class CEasyUAClientManagementEvents : public IDispEventImpl<1, CEasyUAClientManagementEvents>
    {
    public:
    BEGIN_SINK_MAP(CEasyUAClientManagementEvents)
        // Event handlers must have the __stdcall calling convention
        SINK_ENTRY(1, 1 /*DISPID_EASYUACLIENTManagementEVENTS_LOGENTRY*/, &CEasyUAClientManagementEvents::LogEntry)
    END_SINK_MAP()

    public:
        // Event handler for the LogEntry event. It simply prints out the event.
        STDMETHOD(LogEntry)(VARIANT varSender, _LogEntryEventArgs* pEventArgs)
        {
            _tprintf(_T("%s\n"), (LPCTSTR)CW2CT(pEventArgs->ToString));
            return S_OK;
        }
    };



    void LogEntry::Main()
    {
        // Initialize the COM library
        CoInitializeEx(NULL, COINIT_MULTITHREADED);
        {
            // The management object allows access to static behavior - here, the shared LogEntry event.
            _EasyUAClientManagementPtr ClientManagementPtr(__uuidof(EasyUAClientManagement));

            // Hook events
            CEasyUAClientManagementEvents* pClientManagementEvents = new CEasyUAClientManagementEvents();
            AtlGetObjectSourceInterface(ClientManagementPtr, &pClientManagementEvents->m_libid, 
                &pClientManagementEvents->m_iid, 
                &pClientManagementEvents->m_wMajorVerNum, &pClientManagementEvents->m_wMinorVerNum);
            pClientManagementEvents->m_iid = _uuidof(DEasyUAClientManagementEvents);
            pClientManagementEvents->DispEventAdvise(ClientManagementPtr, &pClientManagementEvents->m_iid);

            // Do something - invoke an OPC read, to trigger some loggable entries.
            _EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));
            ClientPtr->ReadValue(
                //L"http://opcua.demo-this.com:51211/UA/SampleServer", 
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer",
                L"nsu=http://test.org/UA/Data/ ;i=10853");

            _tprintf(_T("Processing log entry events for 1 minute...\n"));
            Sleep(60*1000);

            // Unhook events
            pClientManagementEvents->DispEventUnadvise(ClientManagementPtr, &pClientManagementEvents->m_iid);
        }
         // Release all interface pointers BEFORE calling CoUninitialize()
        CoUninitialize();
    }
}

Python

# This example demonstrates the loggable entries originating in the OPC-UA client engine and the EasyUAClient component.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Event handler for the LogEntry event. It simply prints out the event.
def onLogEntry(sender, logEntryEventArgs):
    print(logEntryEventArgs)


endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer')
# or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported)
# or 'https://opcua.demo-this.com:51212/UA/SampleServer/'

# Hook static events.
EasyUAClient.LogEntry += onLogEntry

# Instantiate the client object.
client = EasyUAClient()

# Do something - invoke an OPC read, to trigger some loggable entries.
try:
    value = IEasyUAClientExtension.ReadValue(client,
                                             endpointDescriptor,
                                             UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'))
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

print('Processing log entry events for 1 minute...')
time.sleep(60)

print()
print('Finished.')

 

Example - OPC Wizard

.NET

// This example demonstrates the loggable entries originating in the OPC-UA server engine and the EasyUAServer component.
// You can use any OPC UA client, including our Connectivity Explorer and OpcCmd utility, to connect to the server. 
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client, server and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-OPCStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using System.Threading;
using OpcLabs.BaseLib.Instrumentation;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.NodeSpace;

namespace UAServerDocExamples._EasyUAServer
{
    class LogEntry
    {
        public static void Main1()
        {
            // Hook static events.
            EasyUAServer.LogEntry += EasyUAServerOnLogEntry;

            // Instantiate the server object.
            // By default, the server will run on endpoint URL "opc.tcp://localhost:48040/".
            var server = new EasyUAServer();

            // Define a data variable providing random integers.
            var random = new Random();
            server.Add(new UADataVariable("MyDataVariable").ReadValueFunction(() => random.Next()));

            // Start the server.
            Console.WriteLine("The server is starting...");
            server.Start();

            Console.WriteLine("The server is started.");
            Console.WriteLine();

            // Let the user decide when to stop.
            Console.WriteLine("Press Enter to stop the server...");
            Console.ReadLine();

            // Stop the server.
            Console.WriteLine("The server is stopping...");
            server.Stop();

            Console.WriteLine("The server is stopped");

            // Give the remaining events chance to be handled.
            Thread.Sleep(2 * 1000);

            // Unhook static events.
            EasyUAServer.LogEntry -= EasyUAServerOnLogEntry;
        }

        // Event handler for the LogEntry event. It simply prints out the event.
        private static void EasyUAServerOnLogEntry(object sender, LogEntryEventArgs logEntryEventArgs)
        {
            Console.WriteLine(logEntryEventArgs);
        }
    }
}

Event Logging for OPC UA PubSub

Event logging for OPC UA PubSub works similarly to event logging for OPC UA Client-Server (described above), except that you will use the LogEntry Event on the EasyUASubscriber Class

Event Logging for OPC "Classic"

Event logging for OPC “Classic” specifications works similarly to event logging for OPC UA Client-Server (described above), except that you will use the LogEntry Event on the EasyDAClient Class or the EasyAEClient Class.

Currently, only limited contents is provided for OPC Classic: Basically, logged entries only cover callback errors, (some) queue errors, and licensing information.

 

See Also

Fundamentals