smartinspectpython.smartinspect

Module: smartinspect.py

Revision History

Date Version Description
2023/09/27 3.0.21.0 Updated documentation sample code and examples.
2023/06/09 3.0.8.0 Added InfoEvent event and RaiseInfoEvent method to convey SI informational events to interested parties (e.g. Si Console Server banner, etc).
2023/05/30 3.0.0.0 Initial Version.

@export
class SmartInspect:

The SmartInspect class is the most important class in the SmartInspect Python3 library. An instance of this class is able to write log messages to a file or to send them directly to the SmartInspect Console using TCP. You can control these connections by setting the Connections property.

The SmartInspect class offers several properties for controlling the logging behavior. Besides the Connections property there is the Enabled property which controls if log messages should be sent or not. Furthermore, the AppName property specifies the application name displayed in the SmartInspect Console. And last but not least, we have the Level and DefaultLevel properties which specify the log level of an SmartInspect object and its related sessions.

Additionally, the SmartInspect class acts as parent for sessions, which contain the actual logging methods, like, for example, SISession.LogMessage or SISession.LogObject. It is possible and common that several different sessions have the same parent and thus share the same connections. The SISession class contains dozens of useful methods for logging any kind of data. Sessions can even log variable watches, generate illustrated process and thread information or control the behavior of the SmartInspect Console. It is possible, for example, to clear the entire log in the Console by calling the SISession.ClearLog method.

To accomplish these different tasks the SmartInspect concept uses several different packets. The SmartInspect class manages these packets and logs them to its connections. It is possibility to register event handlers for every packet type which are called after a corresponding packet has been sent.

The error handling in the SmartInspect Python3 library is a little bit different than in other libraries. This library uses an event, the Error event, for reporting errors. We've chosen this way because a logging framework should not alter the behavior of an application by firing exceptions. The only exception you need to handle can be thrown by the Connections property if the supplied SmartInspect.Connections contains errors.

Threadsafety:

This class is fully thread-safe.

SmartInspect(appName: str)

Initializes a new instance of the class.

Arguments:
  • appName (str): The application name used for Log Entries. It is usually set to the name of the application which creates this object.
ErrorEvent

Event raised when an error occurs in SmartInspect processing.

FilterEvent

Event raised to allow packet filtering before a packet is sent to the protocol destination.

InfoEvent

Event raised when an informational event occurs in SmartInspect processing.

LogEntryEvent

Event raised when a Log Entry packet is sent to the protocol destination.

WatchEvent

Event raised when a Watch packet is sent to the protocol destination.

ProcessFlowEvent

Event raised when a Process Flow packet is sent to the protocol destination.

ControlCommandEvent

Event raised when a Control Command packet is sent to the protocol destination.

AppName: str

Gets the AppName property value.

Returns:

The application name used for the Log Entries.

The application name helps you to identify Log Entries from different applications in the SmartInspect Console. If you set this property to null, the application name will be empty when sending Log Entries.

Connections: str

Gets the Connections property value.

Returns:

A connection string that contains all connections used by this SmartInspect instance.

Raises:
  • SIInvalidConnectionsException: Invalid syntax, unknown protocols or inexistent options.

You can set multiple connections by separating the connections with commas. A connection consists of a protocol identifier like "file" plus optional protocol parameters in parentheses. If you, for example, want to log to a file, the Connections property must be set to "file()". You can specify the filename in the parentheses after the protocol identifier like this: "file(filename=\"c:\mylogfile.sil\")". Please note that if the Enabled property is set to true, the connections try to connect to their destinations immediately. By default, no connections are used.

See the SIProtocol class for a list of available protocols and SIProtocolFactory for a way to add your own custom protocols. Furthermore have a look at the LoadConnections and LoadConfiguration methods, which can load a connections string from a file. Also, for a class which assists in building connections strings, please refer to the documentation of the SIConnectionsBuilder class.

To automatically replace placeholders in the given connections string, you can use so called connection variables. Please have a look at the SetVariable method for more information.

Please note that an SIInvalidConnectionsException exception is thrown if an invalid connections string is supplied.

Sample Code

# package imports.
from smartinspectpython.siauto import *

# log messages to default file 'log.sil'.
SIAuto.Si.Connections = 'file()'

# log messages to file 'mylog.sil'.
SIAuto.Si.Connections = "file(filename=""mylog.sil"", append=true)"

# log messages to default file "log.sil", as well as to the SmartInspect 
# Console viewer running on localhost.
SIAuto.Si.Connections = "file(append=true), tcp(host=""localhost"")"

# log messages to default file "log.sil", as well as to file "anotherlog.sil".
SIAuto.Si.Connections = "file(), file(filename=""anotherlog.sil"")"

Gets the DefaultLevel property value.

Returns:

The default log level of this SmartInspect instance and its related sessions.

The DefaultLevel property of this SmartInspect instance represents the default log level used by its corresponding sessions. The default value of this property is SILevel.Message.

Every method in the SISession class which makes use of the parent's Level and does not take a Level argument, uses the default level of its parent as log level.

Enabled: bool

Gets the Enabled property value.

Returns:

The logging Enabled status.

This property allows you to control if anything should be logged at all.

If you set this property to true, all connections will try to connect to their destinations. For example, if the Connections property is set to "file(filename=c:\log.sil)", the file "c:\log.sil" will be opened to write all following packets to it. By setting this property to false, all connections will disconnect.

Additionally, every SISession class method evaluates if its parent is enabled and returns immediately if this is not the case. This guarantees that the performance hit is minimal when logging is disabled. The default value of this property is false. You need to set this property to true before you can use the SmartInspect instance and its related sessions.

Please note: If one or more connections of this SmartInspect object operate in SIProtocol.IsValidOption you must disable this object by setting this property to false before exiting your application to properly exit and cleanup the protocol related threads. Disabling this instance may block until the related protocol threads are finished.

HostName: str

Gets the HostName property value.

Returns:

Returns the hostname of the current machine.

The hostname helps you to identify Log Entries from different machines in the SmartInspect Console. The value of this property is derived from the "socket.gethostname()" module method.

Gets the Level property value.

Returns:

Returns the log level of this SmartInspect instance and its related sessions.

The Level property of this SmartInspect instance represents the log level used by its corresponding sessions to determine if information should be logged or not. The default value of this property is SILevel.Debug.

Every method (except the Clear method family) in the SISession class tests if its log level equals or is greater than the log level of its parent. If this is not the case, the methods return immediately and won't log anything.

The log level for a method in the SISession class can either be specified explicitly by passing a Level argument or implicitly by using the DefaultLevel. Every method in the SISession class which makes use of the parent's log level and does not take a Level argument, uses the DefaultLevel of its parent as log level.

For more information about the default level, please refer to the documentation of the DefaultLevel property.

Gets the SessionDefaults property value.

Returns:

The default property values for new sessions.

This property lets you specify the default property values for new sessions which will be created by or passed to the AddSession method. Please see the AddSession method for more information. For information about the available session properties, please refer to the documentation of the SISession class.

def AddSession( self, sessionName: str, store: bool = False) -> smartinspectpython.sisession.SISession:

Adds and returns a new SISession instance with this SmartInspect object set as parent and optionally saves it for later access.

Arguments:
  • sessionName (str): The name for the new session. Not allowed to be null.
  • store (bool): Indicates if the newly created session should be stored for later access.
Returns:

The new SISession instance or null if the supplied sessionName parameter is null.

Raises:
  • SIArgumentNullException: Thrown if sessionName is null or empty string.

This method allocates a new session with this SmartInspect instance set as parent and the supplied sessionName parameter set as session name. The returned session will be configured with the default session properties as specified by the SessionDefaults property. This default configuration can be overridden on a per-session basis by loading the session configuration with the LoadConfiguration method. Please see the LoadConfiguration documentation for details.

If the 'store' parameter is true, the created and returned session is stored for later access and can be retrieved with the GetSession method. To remove a created session from the internal list, call the DeleteSession method.

If this method is called multiple times with the same session name, then the GetSession method operates on the session which got added last. If the sessionName parameter is null, this method does nothing and returns null as well.

Adds an existing session instance to the internal list of sessions and saves it for later access.

Arguments:
  • session (SISession): The session to store.

This method adds the passed session to the internal list of sessions and saves it for later access. The passed session will be configured with the default session properties as specified by the SessionDefaults property. This default configuration can be overridden on a per-session basis by loading the session configuration with the LoadConfiguration method. Please see the LoadConfiguration documentation for details.

The passed session can later be retrieved with the GetSession method. To remove an added session from the internal list, call the DeleteSession method.

def DeleteSession(self, session: smartinspectpython.sisession.SISession) -> None:

Removes a session from the internal list of sessions.

Arguments:
  • session (SISession): The session to remove from the lookup table of sessions.

This method removes a session which has previously been added with and returned by the AddSession method. After this method returns, the GetSession method returns null when called with the same session name unless a different session with the same name has been added.

This method does nothing if the supplied session argument is null.

def Dispatch(self, caption: str, action: int, state: object) -> None:

Executes a custom protocol action of a connection.

Arguments:
  • caption (str): The identifier of the connection. Not allowed to be null.
  • action (int): The action to execute by the requested connection.
  • state (object): An optional object which encapsulates additional protocol specific information about the custom action. Can be null.

This method dispatches the action and state parameters to the connection identified by the caption argument. If no suitable connection can be found, the Error event is used. The Error event is also used if an exception is thrown in the custom protocol action.

The SmartInspect Python3 library currently implements one custom protocol action in SIMemoryProtocol. The SIMemoryProtocol class is used for writing log packets to memory. On request, it can write its internal queue of packets to a user-supplied stream or SIProtocol object with a custom protocol action.

The request for executing the custom action and writing the queue can be initiated with this Dispatch method.

For more information about custom protocol actions, please refer to the SIProtocol.Dispatch method. Also have a look at the SIProtocol.IsValidOption method which explains how to set the caption of a connection.

Please note that the custom protocol action is executed asynchronously if the requested connection operates in SIProtocol.IsValidOption

If the supplied caption argument is null, this method does nothing and returns immediately.

def Dispose(self, disposing: bool = True) -> None:

Releases all resources of this SmartInspect object.

Arguments:
  • disposing True to dispose of both managed and unmanaged resources.

This method disconnects and removes all internal connections and disables this instance. Moreover, all previously stored sessions will be removed.

def GetSession(self, sessionName: str = None) -> smartinspectpython.sisession.SISession:

Returns a previously added session.

Arguments:
  • sessionName (str): The name of the session to lookup and return. Not allowed to be null.
Raises:
  • SIArgumentNullException: Thrown if sessionName is null.
Returns:

The requested session or null if the supplied sessionName is unknown.

This method returns a session which has previously been added with the AddSession method and can be identified by the supplied sessionName argument. If the requested session is unknown then this method returns null.

Note that the behavior of this method can be unexpected in terms of the result value if multiple sessions with the same name have been added. In this case, this method returns the session which got added last and not necessarily the session which you expect.

Adding multiple sessions with the same name should therefore be avoided.

def GetVariable(self, key: str) -> str:

Returns the value of a connection variable.

Arguments:
  • key (str): The key of the connection variable.
Returns:

The value for the given connection variable or null if the connection variable is unknown.

Please see the SetVariable method for more information about connection variables.

def LoadConfiguration(self, fileName: str) -> None:

Loads the properties and sessions of this SmartInspect instance from a configuration file.

Arguments:
  • fileName (str): The name of the file to load the configuration from.

This method loads the properties and sessions of this SmartInspect object from a file. This file should be a plain text file containing key/value pairs. Each key/value pair is expected to be on its own line. Empty, unrecognized lines and lines beginning with a ';' character are ignored.

The Error event is used to notify the caller if an error occurs while trying to load the configuration from the specified file. Such errors include I/O errors like trying to open a file which does not exist, for example.

The Error event is also used if the specified configuration file contains an invalid connections string. In this case, an instance of the SIInvalidConnectionsException exception type is passed to the Error event.

Calling this method with the fileName parameter set to null has no effect.

This method is useful for loading the properties and sessions of this SmartInspect instance after the deployment of an application. A typical use case for this method is the following scenario: imagine a customer who needs to send a log file to customer service to analyze a software problem. If the software in question uses this LoadConfiguration method, the customer service just needs to send a prepared configuration file to the customer. Now, to load the SmartInspect properties from a file, the customer now just needs to drop this file to the application's installation directory or any other predefined location.

To monitor a SmartInspect configuration file for changes, please have a look at the SIConfigurationTimer class.

To automatically replace placeholders in a loaded connections string, you can use so called connection variables. Please have a look at the SetVariable method for more information.

The following table lists the recognized configuration values, the corresponding SmartInspect properties and their types:

Value Property (Type)
appname AppName (string)
connections Connections (string)
defaultlevel DefaultLevel (SILevel)
enabled Enabled (bool)
level Level (SILevel)

In addition to these properties, this method also configures any stored sessions of this SmartInspect object. Sessions that have been stored or will be added with the AddSession method will be configured with the properties of the related session entry of the passed configuration file. Please see the example section for details on how sessions entries look like.

If no entries can be found in the configuration file for a newly added session, this session will use the default session properties. The default session properties can also be specified in the configuration file. Please note that the session defaults do not apply to the main session SIAuto.Main since this session has already been added before a configuration file can be loaded. The session defaults only apply to newly added sessions and do not affect existing sessions.

The case of the configuration properties doesn't matter. This means, it makes no difference if you specify 'defaultlevel' or 'DefaultLevel' as key, for example.

For a typical configuration file, please see the example below.

To support Unicode strings, both the LoadConnections and LoadConfiguration methods are capable of auto-detecting the string encoding if a BOM (Byte Order Mark) is given at the start of the file. The following table lists the supported encodings and the corresponding BOM identifiers.

Encoding BOM identifier
UTF8 0xEF, 0xBB, 0xBF
Unicode 0xFF, 0xFE
Unicode big-endian 0xFE, 0xFF

If no BOM is given, the text is assumed to be in the ASCII format. If the configuration file has been created or edited with the SmartInspect Configuration Builder, the file always has a UTF8 Byte Order Mark and Unicode strings are therefore handled automatically.

Sample Code

# package imports.
from smartinspectpython.siauto import *

# load SmartInspect settings from a configuration settings file.
siConfigPath:str = "./smartinspect.cfg"
SIAuto.Si.LoadConfiguration(siConfigPath)

# start monitoring the configuration file for changes, and reload it when it changes.
# this will check the file for changes every 60 seconds.
siConfigTask:SIConfigurationTimer = SIConfigurationTimer(SIAuto.Si, siConfigPath, 60)

# get smartinspect logger reference.
logsi:SISession = SIAuto.Main


The following is the configuration settings file contents:

; smartinspect.cfg

; SmartInspect Logging Configuration General settings.
; - "Enabled" parameter to turn logging on (True) or off (False).
; - "Level" parameter to control the logging level (Debug|Verbose|Message|Warning|Error).
; - "AppName" parameter to control the application name.
Enabled = False 
Level = Verbose
DefaultLevel = Debug
AppName = My Application Name

; SmartInspect Logging Configuration Output settings.
; - Log to SmartInspect Console Viewer running on the specified network address.
Connections = tcp(host=localhost, port=4228, timeout=5000, reconnect=true, reconnect.interval=10s, async.enabled=true)
; - Log to a file:
;Connections = "file(filename=\"./tests/logfiles/logfile.log\", rotate=hourly, maxparts=24, append=true)"
; - Log to an encrypted file:
;Connections = "file(filename=\"./tests/logfiles/logfileEncrypted.sil\", encrypt=true, key=""1234567890123456"", rotate=hourly, maxparts=14, append=true)"

; set defaults for new sessions
; note that session defaults do not apply to the SIAuto.Main session, since
; this session was already added before a configuration file can be loaded. 
; session defaults only apply to newly added sessions and do not affect existing sessions.
SessionDefaults.Active = True
SessionDefaults.Level = Message
SessionDefaults.ColorBG = 0xFFFFFF

; configure some individual session properties.
; note that this does not add the session to the sessionmanager; it simply
; sets the property values IF the session name already exists.
Session.Main.Active = True
Session.Main.ColorBG = 0xFFFFFF

def LoadConnections(self, fileName: str, doNotEnable: bool = True) -> None:

Loads the connections string from a file and enables this SmartInspect instance.

Arguments:
  • fileName (str): The name of the file to load the connections string from.
  • doNotEnable (bool): Specifies if this instance should not be enabled automatically. Default value is True.

This method loads the SmartInspect Connections from a file. This file should be a plain text file containing a line like in the following example:

connections=file(filename=c:\log.sil)

Empty, unrecognized lines and lines beginning with a ';' character are ignored. This version of the method enables logging automatically.

The Error event is used to notify the application if the specified file cannot be opened or does not contain a connection string. The Connections and Enabled properties of this instance are not changed if such an error occurs.

The Error event is also used if a connections string could be read but is found to be invalid. In this case, an instance of the SIInvalidConnectionsException exception type is passed to the Error event.

If this doNotEnable parameter is set to true, the Enabled property is not changed. Otherwise this SmartInspect instance will be enabled. Calling this method with the fileName parameter set to null has no effect.

This method is useful for customizing the connections string after the deployment of an application. A typical use case for this method is the following scenario: imagine a customer who needs to send a log file to customer service to analyze a software problem. If the software in question uses this LoadConnections method, the customer service just needs to send a prepared connections file to the customer. To enable the logging, the customer now just needs to drop this file to the application's installation directory or any other predefined location.

See LoadConfiguration for a method which is not limited to loading the connections string, but is also capable of loading any other property of this object from a file.

The LoadConnections and LoadConfiguration methods are both capable of detecting the string encoding of the connections and configuration files. Please see the LoadConfiguration method for details.

To automatically replace placeholders in a loaded connections string, you can use so called connection variables. Please have a look at the SetVariable method for more information.

def Now(self) -> datetime.datetime:

Gets the current date and time.

Returns:

The current date and time value via the "datetime.now()" module.

def OnControlCommandEvent( self, sender: object, e: smartinspectpython.sicontrolcommandeventargs.SIControlCommandEventArgs) -> None:

Method that will handle the SmartInspect.ControlCommandEvent event. Inheriting classes can override this method to handle the event.

Arguments:
  • sender (object): The object which fired the event.
  • e (SIControlCommandEventArgs): Arguments that contain detailed information related to the event.

This event can be used if custom processing of ControlCommand packets is needed. The event handlers are always called in the context of the thread which causes the event.

If you specified that one or more connections of this SmartInspect object should operate in SIProtocol.IsValidOption, you need to protect the passed packet and its data by calling its SIPacket.Lock and SIPacket.Unlock methods before and after processing.

IMPORTANT: Keep in mind that adding SmartInspect log statements to the event handlers can cause a presumably undesired recursive behavior!

Sample Code

# package imports.
from datetime import datetime
from smartinspectpython.siauto import *

class SIEventHandlerClass:
    """
    Helper class for SmartInspect class testing.
    """

    # static variables.
    WriteEventPacketsToConsole:bool = False
    ErrorCount:int = 0
    InfoCount:int = 0
    FilterCount:int = 0
    FilterCancelCount:int = 0
    WatchCount:int = 0
    LogEntryCount:int = 0
    ProcessFlowCount:int = 0
    ControlCommandCount:int = 0
    TotalCount:int = 0


    @staticmethod
    def WireEvents(si) -> None:
        # wire up events.
        si.ErrorEvent += SIEventHandlerClass.ErrorEvent
        si.InfoEvent += SIEventHandlerClass.InfoEvent
        si.FilterEvent += SIEventHandlerClass.FilterEvent
        si.WatchEvent += SIEventHandlerClass.WatchEvent
        si.LogEntryEvent += SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent += SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent += SIEventHandlerClass.ControlCommandEvent


    @staticmethod
    def UnWireEvents(si) -> None:
        # unwire events.
        si.ErrorEvent -= SIEventHandlerClass.ErrorEvent
        si.InfoEvent -= SIEventHandlerClass.InfoEvent
        si.FilterEvent -= SIEventHandlerClass.FilterEvent
        si.WatchEvent -= SIEventHandlerClass.WatchEvent
        si.LogEntryEvent -= SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent -= SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent -= SIEventHandlerClass.ControlCommandEvent


    def ErrorEvent(sender:object, e:SIErrorEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.ErrorCount = SIEventHandlerClass.ErrorCount + 1


    def InfoEvent(sender:object, e:SIInfoEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.InfoCount = SIEventHandlerClass.InfoCount + 1
        pass


    def FilterEvent(sender:object, e:SIFilterEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        # ignore all warning level packets.
        #if (e.Packet.Level == SILevel.Warning):
        #    SIEventHandlerClass.FilterCancelCount = SIEventHandlerClass.FilterCancelCount + 1
        #    e.Cancel = True
        SIEventHandlerClass.FilterCount = SIEventHandlerClass.FilterCount + 1
        pass


    def WatchEvent(sender:object, e:SIWatchEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.WatchCount = SIEventHandlerClass.WatchCount + 1
        pass


    def LogEntryEvent(sender:object, e:SILogEntryEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.LogEntryCount = SIEventHandlerClass.LogEntryCount + 1
        pass


    def ProcessFlowEvent(sender:object, e:SIProcessFlowEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ProcessFlowCount = SIEventHandlerClass.ProcessFlowCount + 1
        pass


    def ControlCommandEvent(sender:object, e:SIControlCommandEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ControlCommandCount = SIEventHandlerClass.ControlCommandCount + 1
        pass


    def ResetCounters(si) -> None:
        print("Resetting all SIEventHandlerClass counters to zero.")
        SIEventHandlerClass.ErrorCount:int = 0
        SIEventHandlerClass.InfoCount:int = 0
        SIEventHandlerClass.FilterCount:int = 0
        SIEventHandlerClass.FilterCancelCount:int = 0
        SIEventHandlerClass.WatchCount:int = 0
        SIEventHandlerClass.LogEntryCount:int = 0
        SIEventHandlerClass.ProcessFlowCount:int = 0
        SIEventHandlerClass.ControlCommandCount:int = 0
        SIEventHandlerClass.TotalCount:int = 0

    def PrintResults(si) -> str:
        print("")
        print("SI Protocol Connections string used for this test:\n" + si.Connections)
        print("")
        print("SI Event Handler Results:")
        print("")
        print("- # Watch Events          = " + str(SIEventHandlerClass.WatchCount))
        print("- # LogEntry Events       = " + str(SIEventHandlerClass.LogEntryCount))
        print("- # ProcessFlow Events    = " + str(SIEventHandlerClass.ProcessFlowCount))
        print("- # ControlCommand Events = " + str(SIEventHandlerClass.ControlCommandCount))
        print("")
        print("- # Total Events          = " + str(SIEventHandlerClass.TotalCount))
        print("")
        print("- # Error Events          = " + str(SIEventHandlerClass.ErrorCount))
        print("- # Info Events           = " + str(SIEventHandlerClass.InfoCount))
        print("- # Filter Events         = " + str(SIEventHandlerClass.FilterCount))
        print("- # Filter Cancel Events  = " + str(SIEventHandlerClass.FilterCancelCount))
        print("")


# wire up smartinspect events.
SIEventHandlerClass.WireEvents(SIAuto.Si)

# set smartinspect connections, and enable logging.
SIAuto.Si.Connections = "tcp(host=localhost,port=4228,timeout=30000)"
SIAuto.Si.Enabled = True

# get smartinspect logger reference.
_logsi:SISession = SIAuto.Main

# test some process flow methods.
_logsi.EnterProcess(None,"My Process")
_logsi.LogMessage("This message is in process My Process.")
_logsi.LogWarning("This warning is in process My Process.")
_logsi.LeaveProcess(None,"My Process")

# test some logentry methods.
_logsi.LogDebug("This is a debug message.")
_logsi.LogVerbose("This is a verbose message.")
_logsi.LogMessage("This is a message.")
_logsi.LogWarning("This is a warning message.")
_logsi.LogError("This is a error message in RED.", SIColors.Red)
_logsi.LogFatal("This is a fatal error message in RED.", SIColors.Red)

# test some control command methods.
_logsi.ClearWatches()

# test some watch methods.
_logsi.Watch(None,"string_py", "string1 value")
_logsi.Watch(None,"int_py", int(0))
_logsi.Watch(None,"float_py", float(3.14159))
_logsi.Watch(None,"datetime_py", datetime(2023,5,11,12,30,10))
_logsi.Watch(None,"bool_py", True)
_logsi.Watch(None,"byte_py", 0xff)

# print SI event counts, unwire events, and dispose of SmartInspect.
SIEventHandlerClass.PrintResults(SIAuto.Si)
SIEventHandlerClass.UnWireEvents(SIAuto.Si)
SIAuto.Si.Dispose()

def OnErrorEvent( self, sender: object, e: smartinspectpython.sierroreventargs.SIErrorEventArgs) -> None:

Method that will handle the SmartInspect.ErrorEvent event. Inheriting classes can override this method to handle the event.

Arguments:
  • sender (object): The object which fired the event.
  • e (SIErrorEventArgs): Arguments that contain detailed information related to the event.

This event is fired when an error occurs. An error could be a connection problem or wrong permissions when writing log files, for example. Instead of throwing exceptions, this event is used for error reporting in the SmartInspect Python3 library.

The event handlers are always called in the context of the thread which caused the event. In SIProtocol.IsValidOption, this is not necessarily the thread that initiated the related call.

IMPORTANT: Keep in mind that adding SmartInspect log statements to the event handlers can cause a presumably undesired recursive behavior!

Sample Code

# package imports.
from datetime import datetime
from smartinspectpython.siauto import *

class SIEventHandlerClass:
    """
    Helper class for SmartInspect class testing.
    """

    # static variables.
    WriteEventPacketsToConsole:bool = False
    ErrorCount:int = 0
    InfoCount:int = 0
    FilterCount:int = 0
    FilterCancelCount:int = 0
    WatchCount:int = 0
    LogEntryCount:int = 0
    ProcessFlowCount:int = 0
    ControlCommandCount:int = 0
    TotalCount:int = 0


    @staticmethod
    def WireEvents(si) -> None:
        # wire up events.
        si.ErrorEvent += SIEventHandlerClass.ErrorEvent
        si.InfoEvent += SIEventHandlerClass.InfoEvent
        si.FilterEvent += SIEventHandlerClass.FilterEvent
        si.WatchEvent += SIEventHandlerClass.WatchEvent
        si.LogEntryEvent += SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent += SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent += SIEventHandlerClass.ControlCommandEvent


    @staticmethod
    def UnWireEvents(si) -> None:
        # unwire events.
        si.ErrorEvent -= SIEventHandlerClass.ErrorEvent
        si.InfoEvent -= SIEventHandlerClass.InfoEvent
        si.FilterEvent -= SIEventHandlerClass.FilterEvent
        si.WatchEvent -= SIEventHandlerClass.WatchEvent
        si.LogEntryEvent -= SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent -= SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent -= SIEventHandlerClass.ControlCommandEvent


    def ErrorEvent(sender:object, e:SIErrorEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.ErrorCount = SIEventHandlerClass.ErrorCount + 1


    def InfoEvent(sender:object, e:SIInfoEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.InfoCount = SIEventHandlerClass.InfoCount + 1
        pass


    def FilterEvent(sender:object, e:SIFilterEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        # ignore all warning level packets.
        #if (e.Packet.Level == SILevel.Warning):
        #    SIEventHandlerClass.FilterCancelCount = SIEventHandlerClass.FilterCancelCount + 1
        #    e.Cancel = True
        SIEventHandlerClass.FilterCount = SIEventHandlerClass.FilterCount + 1
        pass


    def WatchEvent(sender:object, e:SIWatchEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.WatchCount = SIEventHandlerClass.WatchCount + 1
        pass


    def LogEntryEvent(sender:object, e:SILogEntryEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.LogEntryCount = SIEventHandlerClass.LogEntryCount + 1
        pass


    def ProcessFlowEvent(sender:object, e:SIProcessFlowEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ProcessFlowCount = SIEventHandlerClass.ProcessFlowCount + 1
        pass


    def ControlCommandEvent(sender:object, e:SIControlCommandEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ControlCommandCount = SIEventHandlerClass.ControlCommandCount + 1
        pass


    def ResetCounters(si) -> None:
        print("Resetting all SIEventHandlerClass counters to zero.")
        SIEventHandlerClass.ErrorCount:int = 0
        SIEventHandlerClass.InfoCount:int = 0
        SIEventHandlerClass.FilterCount:int = 0
        SIEventHandlerClass.FilterCancelCount:int = 0
        SIEventHandlerClass.WatchCount:int = 0
        SIEventHandlerClass.LogEntryCount:int = 0
        SIEventHandlerClass.ProcessFlowCount:int = 0
        SIEventHandlerClass.ControlCommandCount:int = 0
        SIEventHandlerClass.TotalCount:int = 0

    def PrintResults(si) -> str:
        print("")
        print("SI Protocol Connections string used for this test:\n" + si.Connections)
        print("")
        print("SI Event Handler Results:")
        print("")
        print("- # Watch Events          = " + str(SIEventHandlerClass.WatchCount))
        print("- # LogEntry Events       = " + str(SIEventHandlerClass.LogEntryCount))
        print("- # ProcessFlow Events    = " + str(SIEventHandlerClass.ProcessFlowCount))
        print("- # ControlCommand Events = " + str(SIEventHandlerClass.ControlCommandCount))
        print("")
        print("- # Total Events          = " + str(SIEventHandlerClass.TotalCount))
        print("")
        print("- # Error Events          = " + str(SIEventHandlerClass.ErrorCount))
        print("- # Info Events           = " + str(SIEventHandlerClass.InfoCount))
        print("- # Filter Events         = " + str(SIEventHandlerClass.FilterCount))
        print("- # Filter Cancel Events  = " + str(SIEventHandlerClass.FilterCancelCount))
        print("")


# wire up smartinspect events.
SIEventHandlerClass.WireEvents(SIAuto.Si)

# set smartinspect connections, and enable logging.
SIAuto.Si.Connections = "tcp(host=localhost,port=4228,timeout=30000)"
SIAuto.Si.Enabled = True

# get smartinspect logger reference.
_logsi:SISession = SIAuto.Main

# test some process flow methods.
_logsi.EnterProcess(None,"My Process")
_logsi.LogMessage("This message is in process My Process.")
_logsi.LogWarning("This warning is in process My Process.")
_logsi.LeaveProcess(None,"My Process")

# test some logentry methods.
_logsi.LogDebug("This is a debug message.")
_logsi.LogVerbose("This is a verbose message.")
_logsi.LogMessage("This is a message.")
_logsi.LogWarning("This is a warning message.")
_logsi.LogError("This is a error message in RED.", SIColors.Red)
_logsi.LogFatal("This is a fatal error message in RED.", SIColors.Red)

# test some control command methods.
_logsi.ClearWatches()

# test some watch methods.
_logsi.Watch(None,"string_py", "string1 value")
_logsi.Watch(None,"int_py", int(0))
_logsi.Watch(None,"float_py", float(3.14159))
_logsi.Watch(None,"datetime_py", datetime(2023,5,11,12,30,10))
_logsi.Watch(None,"bool_py", True)
_logsi.Watch(None,"byte_py", 0xff)

# print SI event counts, unwire events, and dispose of SmartInspect.
SIEventHandlerClass.PrintResults(SIAuto.Si)
SIEventHandlerClass.UnWireEvents(SIAuto.Si)
SIAuto.Si.Dispose()

def OnFilterEvent( self, sender: object, e: smartinspectpython.sifiltereventargs.SIFilterEventArgs) -> bool:

Method that will handle the SmartInspect.FilterEvent event. Inheriting classes can override this method to handle the event.

Arguments:
  • sender (object): The object which fired the event.
  • e (SIFilterEventArgs): Arguments that contain detailed information related to the event.

Occurs before a packet is processed, and offers the opportunity to filter out packets.

This event can be used if filtering of certain packets is needed. The event handlers are always called in the context of the thread which causes the event.

IMPORTANT: Keep in mind that adding SmartInspect log statements to the event handlers can cause a presumably undesired recursive behavior!

Sample Code

# package imports.
from datetime import datetime
from smartinspectpython.siauto import *

class SIEventHandlerClass:
    """
    Helper class for SmartInspect class testing.
    """

    # static variables.
    WriteEventPacketsToConsole:bool = False
    ErrorCount:int = 0
    InfoCount:int = 0
    FilterCount:int = 0
    FilterCancelCount:int = 0
    WatchCount:int = 0
    LogEntryCount:int = 0
    ProcessFlowCount:int = 0
    ControlCommandCount:int = 0
    TotalCount:int = 0


    @staticmethod
    def WireEvents(si) -> None:
        # wire up events.
        si.ErrorEvent += SIEventHandlerClass.ErrorEvent
        si.InfoEvent += SIEventHandlerClass.InfoEvent
        si.FilterEvent += SIEventHandlerClass.FilterEvent
        si.WatchEvent += SIEventHandlerClass.WatchEvent
        si.LogEntryEvent += SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent += SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent += SIEventHandlerClass.ControlCommandEvent


    @staticmethod
    def UnWireEvents(si) -> None:
        # unwire events.
        si.ErrorEvent -= SIEventHandlerClass.ErrorEvent
        si.InfoEvent -= SIEventHandlerClass.InfoEvent
        si.FilterEvent -= SIEventHandlerClass.FilterEvent
        si.WatchEvent -= SIEventHandlerClass.WatchEvent
        si.LogEntryEvent -= SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent -= SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent -= SIEventHandlerClass.ControlCommandEvent


    def ErrorEvent(sender:object, e:SIErrorEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.ErrorCount = SIEventHandlerClass.ErrorCount + 1


    def InfoEvent(sender:object, e:SIInfoEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.InfoCount = SIEventHandlerClass.InfoCount + 1
        pass


    def FilterEvent(sender:object, e:SIFilterEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        # ignore all warning level packets.
        #if (e.Packet.Level == SILevel.Warning):
        #    SIEventHandlerClass.FilterCancelCount = SIEventHandlerClass.FilterCancelCount + 1
        #    e.Cancel = True
        SIEventHandlerClass.FilterCount = SIEventHandlerClass.FilterCount + 1
        pass


    def WatchEvent(sender:object, e:SIWatchEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.WatchCount = SIEventHandlerClass.WatchCount + 1
        pass


    def LogEntryEvent(sender:object, e:SILogEntryEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.LogEntryCount = SIEventHandlerClass.LogEntryCount + 1
        pass


    def ProcessFlowEvent(sender:object, e:SIProcessFlowEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ProcessFlowCount = SIEventHandlerClass.ProcessFlowCount + 1
        pass


    def ControlCommandEvent(sender:object, e:SIControlCommandEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ControlCommandCount = SIEventHandlerClass.ControlCommandCount + 1
        pass


    def ResetCounters(si) -> None:
        print("Resetting all SIEventHandlerClass counters to zero.")
        SIEventHandlerClass.ErrorCount:int = 0
        SIEventHandlerClass.InfoCount:int = 0
        SIEventHandlerClass.FilterCount:int = 0
        SIEventHandlerClass.FilterCancelCount:int = 0
        SIEventHandlerClass.WatchCount:int = 0
        SIEventHandlerClass.LogEntryCount:int = 0
        SIEventHandlerClass.ProcessFlowCount:int = 0
        SIEventHandlerClass.ControlCommandCount:int = 0
        SIEventHandlerClass.TotalCount:int = 0

    def PrintResults(si) -> str:
        print("")
        print("SI Protocol Connections string used for this test:\n" + si.Connections)
        print("")
        print("SI Event Handler Results:")
        print("")
        print("- # Watch Events          = " + str(SIEventHandlerClass.WatchCount))
        print("- # LogEntry Events       = " + str(SIEventHandlerClass.LogEntryCount))
        print("- # ProcessFlow Events    = " + str(SIEventHandlerClass.ProcessFlowCount))
        print("- # ControlCommand Events = " + str(SIEventHandlerClass.ControlCommandCount))
        print("")
        print("- # Total Events          = " + str(SIEventHandlerClass.TotalCount))
        print("")
        print("- # Error Events          = " + str(SIEventHandlerClass.ErrorCount))
        print("- # Info Events           = " + str(SIEventHandlerClass.InfoCount))
        print("- # Filter Events         = " + str(SIEventHandlerClass.FilterCount))
        print("- # Filter Cancel Events  = " + str(SIEventHandlerClass.FilterCancelCount))
        print("")


# wire up smartinspect events.
SIEventHandlerClass.WireEvents(SIAuto.Si)

# set smartinspect connections, and enable logging.
SIAuto.Si.Connections = "tcp(host=localhost,port=4228,timeout=30000)"
SIAuto.Si.Enabled = True

# get smartinspect logger reference.
_logsi:SISession = SIAuto.Main

# test some process flow methods.
_logsi.EnterProcess(None,"My Process")
_logsi.LogMessage("This message is in process My Process.")
_logsi.LogWarning("This warning is in process My Process.")
_logsi.LeaveProcess(None,"My Process")

# test some logentry methods.
_logsi.LogDebug("This is a debug message.")
_logsi.LogVerbose("This is a verbose message.")
_logsi.LogMessage("This is a message.")
_logsi.LogWarning("This is a warning message.")
_logsi.LogError("This is a error message in RED.", SIColors.Red)
_logsi.LogFatal("This is a fatal error message in RED.", SIColors.Red)

# test some control command methods.
_logsi.ClearWatches()

# test some watch methods.
_logsi.Watch(None,"string_py", "string1 value")
_logsi.Watch(None,"int_py", int(0))
_logsi.Watch(None,"float_py", float(3.14159))
_logsi.Watch(None,"datetime_py", datetime(2023,5,11,12,30,10))
_logsi.Watch(None,"bool_py", True)
_logsi.Watch(None,"byte_py", 0xff)

# print SI event counts, unwire events, and dispose of SmartInspect.
SIEventHandlerClass.PrintResults(SIAuto.Si)
SIEventHandlerClass.UnWireEvents(SIAuto.Si)
SIAuto.Si.Dispose()

def OnInfoEvent( self, sender: object, e: smartinspectpython.siinfoeventargs.SIInfoEventArgs) -> None:

Method that will handle the SmartInspect.InfoEvent event. Inheriting classes can override this method to handle the event.

Arguments:
  • sender (object): The object which fired the event.
  • e (SIInfoEventArgs): Arguments that contain detailed information related to the event.

This event is fired when an informational event occurs. An informational event could be the SI console server version, or a configuration settings file change, etc.

The event handlers are always called in the context of the thread which caused the event; this is not necessarily the thread that initiated the related call.

IMPORTANT: Keep in mind that adding SmartInspect log statements to the event handlers can cause a presumably undesired recursive behavior!

Sample Code

# package imports.
from datetime import datetime
from smartinspectpython.siauto import *

class SIEventHandlerClass:
    """
    Helper class for SmartInspect class testing.
    """

    # static variables.
    WriteEventPacketsToConsole:bool = False
    ErrorCount:int = 0
    InfoCount:int = 0
    FilterCount:int = 0
    FilterCancelCount:int = 0
    WatchCount:int = 0
    LogEntryCount:int = 0
    ProcessFlowCount:int = 0
    ControlCommandCount:int = 0
    TotalCount:int = 0


    @staticmethod
    def WireEvents(si) -> None:
        # wire up events.
        si.ErrorEvent += SIEventHandlerClass.ErrorEvent
        si.InfoEvent += SIEventHandlerClass.InfoEvent
        si.FilterEvent += SIEventHandlerClass.FilterEvent
        si.WatchEvent += SIEventHandlerClass.WatchEvent
        si.LogEntryEvent += SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent += SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent += SIEventHandlerClass.ControlCommandEvent


    @staticmethod
    def UnWireEvents(si) -> None:
        # unwire events.
        si.ErrorEvent -= SIEventHandlerClass.ErrorEvent
        si.InfoEvent -= SIEventHandlerClass.InfoEvent
        si.FilterEvent -= SIEventHandlerClass.FilterEvent
        si.WatchEvent -= SIEventHandlerClass.WatchEvent
        si.LogEntryEvent -= SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent -= SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent -= SIEventHandlerClass.ControlCommandEvent


    def ErrorEvent(sender:object, e:SIErrorEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.ErrorCount = SIEventHandlerClass.ErrorCount + 1


    def InfoEvent(sender:object, e:SIInfoEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.InfoCount = SIEventHandlerClass.InfoCount + 1
        pass


    def FilterEvent(sender:object, e:SIFilterEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        # ignore all warning level packets.
        #if (e.Packet.Level == SILevel.Warning):
        #    SIEventHandlerClass.FilterCancelCount = SIEventHandlerClass.FilterCancelCount + 1
        #    e.Cancel = True
        SIEventHandlerClass.FilterCount = SIEventHandlerClass.FilterCount + 1
        pass


    def WatchEvent(sender:object, e:SIWatchEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.WatchCount = SIEventHandlerClass.WatchCount + 1
        pass


    def LogEntryEvent(sender:object, e:SILogEntryEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.LogEntryCount = SIEventHandlerClass.LogEntryCount + 1
        pass


    def ProcessFlowEvent(sender:object, e:SIProcessFlowEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ProcessFlowCount = SIEventHandlerClass.ProcessFlowCount + 1
        pass


    def ControlCommandEvent(sender:object, e:SIControlCommandEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ControlCommandCount = SIEventHandlerClass.ControlCommandCount + 1
        pass


    def ResetCounters(si) -> None:
        print("Resetting all SIEventHandlerClass counters to zero.")
        SIEventHandlerClass.ErrorCount:int = 0
        SIEventHandlerClass.InfoCount:int = 0
        SIEventHandlerClass.FilterCount:int = 0
        SIEventHandlerClass.FilterCancelCount:int = 0
        SIEventHandlerClass.WatchCount:int = 0
        SIEventHandlerClass.LogEntryCount:int = 0
        SIEventHandlerClass.ProcessFlowCount:int = 0
        SIEventHandlerClass.ControlCommandCount:int = 0
        SIEventHandlerClass.TotalCount:int = 0

    def PrintResults(si) -> str:
        print("")
        print("SI Protocol Connections string used for this test:\n" + si.Connections)
        print("")
        print("SI Event Handler Results:")
        print("")
        print("- # Watch Events          = " + str(SIEventHandlerClass.WatchCount))
        print("- # LogEntry Events       = " + str(SIEventHandlerClass.LogEntryCount))
        print("- # ProcessFlow Events    = " + str(SIEventHandlerClass.ProcessFlowCount))
        print("- # ControlCommand Events = " + str(SIEventHandlerClass.ControlCommandCount))
        print("")
        print("- # Total Events          = " + str(SIEventHandlerClass.TotalCount))
        print("")
        print("- # Error Events          = " + str(SIEventHandlerClass.ErrorCount))
        print("- # Info Events           = " + str(SIEventHandlerClass.InfoCount))
        print("- # Filter Events         = " + str(SIEventHandlerClass.FilterCount))
        print("- # Filter Cancel Events  = " + str(SIEventHandlerClass.FilterCancelCount))
        print("")


# wire up smartinspect events.
SIEventHandlerClass.WireEvents(SIAuto.Si)

# set smartinspect connections, and enable logging.
SIAuto.Si.Connections = "tcp(host=localhost,port=4228,timeout=30000)"
SIAuto.Si.Enabled = True

# get smartinspect logger reference.
_logsi:SISession = SIAuto.Main

# test some process flow methods.
_logsi.EnterProcess(None,"My Process")
_logsi.LogMessage("This message is in process My Process.")
_logsi.LogWarning("This warning is in process My Process.")
_logsi.LeaveProcess(None,"My Process")

# test some logentry methods.
_logsi.LogDebug("This is a debug message.")
_logsi.LogVerbose("This is a verbose message.")
_logsi.LogMessage("This is a message.")
_logsi.LogWarning("This is a warning message.")
_logsi.LogError("This is a error message in RED.", SIColors.Red)
_logsi.LogFatal("This is a fatal error message in RED.", SIColors.Red)

# test some control command methods.
_logsi.ClearWatches()

# test some watch methods.
_logsi.Watch(None,"string_py", "string1 value")
_logsi.Watch(None,"int_py", int(0))
_logsi.Watch(None,"float_py", float(3.14159))
_logsi.Watch(None,"datetime_py", datetime(2023,5,11,12,30,10))
_logsi.Watch(None,"bool_py", True)
_logsi.Watch(None,"byte_py", 0xff)

# print SI event counts, unwire events, and dispose of SmartInspect.
SIEventHandlerClass.PrintResults(SIAuto.Si)
SIEventHandlerClass.UnWireEvents(SIAuto.Si)
SIAuto.Si.Dispose()

def OnLogEntryEvent( self, sender: object, e: smartinspectpython.silogentryeventargs.SILogEntryEventArgs) -> None:

Method that will handle the SmartInspect.LogEntryEvent event. Inheriting classes can override this method to handle the event.

Arguments:
  • sender (object): The object which fired the event.
  • e (SILogEntryEventArgs): Arguments that contain detailed information related to the event.

This event can be used if custom processing of Log Entry packets is needed. The event handlers are always called in the context of the thread which causes the event.

If you specified that one or more connections of this SmartInspect object should operate in SIProtocol.IsValidOption, you need to protect the passed packet and its data by calling its SIPacket.Lock and SIPacket.Unlock methods before and after processing.

IMPORTANT: Keep in mind that adding SmartInspect log statements to the event handlers can cause a presumably undesired recursive behavior!

Sample Code

# package imports.
from datetime import datetime
from smartinspectpython.siauto import *

class SIEventHandlerClass:
    """
    Helper class for SmartInspect class testing.
    """

    # static variables.
    WriteEventPacketsToConsole:bool = False
    ErrorCount:int = 0
    InfoCount:int = 0
    FilterCount:int = 0
    FilterCancelCount:int = 0
    WatchCount:int = 0
    LogEntryCount:int = 0
    ProcessFlowCount:int = 0
    ControlCommandCount:int = 0
    TotalCount:int = 0


    @staticmethod
    def WireEvents(si) -> None:
        # wire up events.
        si.ErrorEvent += SIEventHandlerClass.ErrorEvent
        si.InfoEvent += SIEventHandlerClass.InfoEvent
        si.FilterEvent += SIEventHandlerClass.FilterEvent
        si.WatchEvent += SIEventHandlerClass.WatchEvent
        si.LogEntryEvent += SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent += SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent += SIEventHandlerClass.ControlCommandEvent


    @staticmethod
    def UnWireEvents(si) -> None:
        # unwire events.
        si.ErrorEvent -= SIEventHandlerClass.ErrorEvent
        si.InfoEvent -= SIEventHandlerClass.InfoEvent
        si.FilterEvent -= SIEventHandlerClass.FilterEvent
        si.WatchEvent -= SIEventHandlerClass.WatchEvent
        si.LogEntryEvent -= SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent -= SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent -= SIEventHandlerClass.ControlCommandEvent


    def ErrorEvent(sender:object, e:SIErrorEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.ErrorCount = SIEventHandlerClass.ErrorCount + 1


    def InfoEvent(sender:object, e:SIInfoEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.InfoCount = SIEventHandlerClass.InfoCount + 1
        pass


    def FilterEvent(sender:object, e:SIFilterEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        # ignore all warning level packets.
        #if (e.Packet.Level == SILevel.Warning):
        #    SIEventHandlerClass.FilterCancelCount = SIEventHandlerClass.FilterCancelCount + 1
        #    e.Cancel = True
        SIEventHandlerClass.FilterCount = SIEventHandlerClass.FilterCount + 1
        pass


    def WatchEvent(sender:object, e:SIWatchEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.WatchCount = SIEventHandlerClass.WatchCount + 1
        pass


    def LogEntryEvent(sender:object, e:SILogEntryEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.LogEntryCount = SIEventHandlerClass.LogEntryCount + 1
        pass


    def ProcessFlowEvent(sender:object, e:SIProcessFlowEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ProcessFlowCount = SIEventHandlerClass.ProcessFlowCount + 1
        pass


    def ControlCommandEvent(sender:object, e:SIControlCommandEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ControlCommandCount = SIEventHandlerClass.ControlCommandCount + 1
        pass


    def ResetCounters(si) -> None:
        print("Resetting all SIEventHandlerClass counters to zero.")
        SIEventHandlerClass.ErrorCount:int = 0
        SIEventHandlerClass.InfoCount:int = 0
        SIEventHandlerClass.FilterCount:int = 0
        SIEventHandlerClass.FilterCancelCount:int = 0
        SIEventHandlerClass.WatchCount:int = 0
        SIEventHandlerClass.LogEntryCount:int = 0
        SIEventHandlerClass.ProcessFlowCount:int = 0
        SIEventHandlerClass.ControlCommandCount:int = 0
        SIEventHandlerClass.TotalCount:int = 0

    def PrintResults(si) -> str:
        print("")
        print("SI Protocol Connections string used for this test:\n" + si.Connections)
        print("")
        print("SI Event Handler Results:")
        print("")
        print("- # Watch Events          = " + str(SIEventHandlerClass.WatchCount))
        print("- # LogEntry Events       = " + str(SIEventHandlerClass.LogEntryCount))
        print("- # ProcessFlow Events    = " + str(SIEventHandlerClass.ProcessFlowCount))
        print("- # ControlCommand Events = " + str(SIEventHandlerClass.ControlCommandCount))
        print("")
        print("- # Total Events          = " + str(SIEventHandlerClass.TotalCount))
        print("")
        print("- # Error Events          = " + str(SIEventHandlerClass.ErrorCount))
        print("- # Info Events           = " + str(SIEventHandlerClass.InfoCount))
        print("- # Filter Events         = " + str(SIEventHandlerClass.FilterCount))
        print("- # Filter Cancel Events  = " + str(SIEventHandlerClass.FilterCancelCount))
        print("")


# wire up smartinspect events.
SIEventHandlerClass.WireEvents(SIAuto.Si)

# set smartinspect connections, and enable logging.
SIAuto.Si.Connections = "tcp(host=localhost,port=4228,timeout=30000)"
SIAuto.Si.Enabled = True

# get smartinspect logger reference.
_logsi:SISession = SIAuto.Main

# test some process flow methods.
_logsi.EnterProcess(None,"My Process")
_logsi.LogMessage("This message is in process My Process.")
_logsi.LogWarning("This warning is in process My Process.")
_logsi.LeaveProcess(None,"My Process")

# test some logentry methods.
_logsi.LogDebug("This is a debug message.")
_logsi.LogVerbose("This is a verbose message.")
_logsi.LogMessage("This is a message.")
_logsi.LogWarning("This is a warning message.")
_logsi.LogError("This is a error message in RED.", SIColors.Red)
_logsi.LogFatal("This is a fatal error message in RED.", SIColors.Red)

# test some control command methods.
_logsi.ClearWatches()

# test some watch methods.
_logsi.Watch(None,"string_py", "string1 value")
_logsi.Watch(None,"int_py", int(0))
_logsi.Watch(None,"float_py", float(3.14159))
_logsi.Watch(None,"datetime_py", datetime(2023,5,11,12,30,10))
_logsi.Watch(None,"bool_py", True)
_logsi.Watch(None,"byte_py", 0xff)

# print SI event counts, unwire events, and dispose of SmartInspect.
SIEventHandlerClass.PrintResults(SIAuto.Si)
SIEventHandlerClass.UnWireEvents(SIAuto.Si)
SIAuto.Si.Dispose()

def OnProcessFlowEvent( self, sender: object, e: smartinspectpython.siprocessfloweventargs.SIProcessFlowEventArgs) -> None:

Method that will handle the SmartInspect.ProcessFlowEvent event. Inheriting classes can override this method to handle the event.

Arguments:
  • sender (object): The object which fired the event.
  • e (SIProcessFlowEventArgs): Arguments that contain detailed information related to the event.

This event can be used if custom processing of ProcessFlow packets is needed. The event handlers are always called in the context of the thread which causes the event.

If you specified that one or more connections of this SmartInspect object should operate in SIProtocol.IsValidOption, you need to protect the passed packet and its data by calling its SIPacket.Lock and SIPacket.Unlock methods before and after processing.

IMPORTANT: Keep in mind that adding SmartInspect log statements to the event handlers can cause a presumably undesired recursive behavior!

Sample Code

# package imports.
from datetime import datetime
from smartinspectpython.siauto import *

class SIEventHandlerClass:
    """
    Helper class for SmartInspect class testing.
    """

    # static variables.
    WriteEventPacketsToConsole:bool = False
    ErrorCount:int = 0
    InfoCount:int = 0
    FilterCount:int = 0
    FilterCancelCount:int = 0
    WatchCount:int = 0
    LogEntryCount:int = 0
    ProcessFlowCount:int = 0
    ControlCommandCount:int = 0
    TotalCount:int = 0


    @staticmethod
    def WireEvents(si) -> None:
        # wire up events.
        si.ErrorEvent += SIEventHandlerClass.ErrorEvent
        si.InfoEvent += SIEventHandlerClass.InfoEvent
        si.FilterEvent += SIEventHandlerClass.FilterEvent
        si.WatchEvent += SIEventHandlerClass.WatchEvent
        si.LogEntryEvent += SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent += SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent += SIEventHandlerClass.ControlCommandEvent


    @staticmethod
    def UnWireEvents(si) -> None:
        # unwire events.
        si.ErrorEvent -= SIEventHandlerClass.ErrorEvent
        si.InfoEvent -= SIEventHandlerClass.InfoEvent
        si.FilterEvent -= SIEventHandlerClass.FilterEvent
        si.WatchEvent -= SIEventHandlerClass.WatchEvent
        si.LogEntryEvent -= SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent -= SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent -= SIEventHandlerClass.ControlCommandEvent


    def ErrorEvent(sender:object, e:SIErrorEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.ErrorCount = SIEventHandlerClass.ErrorCount + 1


    def InfoEvent(sender:object, e:SIInfoEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.InfoCount = SIEventHandlerClass.InfoCount + 1
        pass


    def FilterEvent(sender:object, e:SIFilterEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        # ignore all warning level packets.
        #if (e.Packet.Level == SILevel.Warning):
        #    SIEventHandlerClass.FilterCancelCount = SIEventHandlerClass.FilterCancelCount + 1
        #    e.Cancel = True
        SIEventHandlerClass.FilterCount = SIEventHandlerClass.FilterCount + 1
        pass


    def WatchEvent(sender:object, e:SIWatchEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.WatchCount = SIEventHandlerClass.WatchCount + 1
        pass


    def LogEntryEvent(sender:object, e:SILogEntryEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.LogEntryCount = SIEventHandlerClass.LogEntryCount + 1
        pass


    def ProcessFlowEvent(sender:object, e:SIProcessFlowEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ProcessFlowCount = SIEventHandlerClass.ProcessFlowCount + 1
        pass


    def ControlCommandEvent(sender:object, e:SIControlCommandEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ControlCommandCount = SIEventHandlerClass.ControlCommandCount + 1
        pass


    def ResetCounters(si) -> None:
        print("Resetting all SIEventHandlerClass counters to zero.")
        SIEventHandlerClass.ErrorCount:int = 0
        SIEventHandlerClass.InfoCount:int = 0
        SIEventHandlerClass.FilterCount:int = 0
        SIEventHandlerClass.FilterCancelCount:int = 0
        SIEventHandlerClass.WatchCount:int = 0
        SIEventHandlerClass.LogEntryCount:int = 0
        SIEventHandlerClass.ProcessFlowCount:int = 0
        SIEventHandlerClass.ControlCommandCount:int = 0
        SIEventHandlerClass.TotalCount:int = 0

    def PrintResults(si) -> str:
        print("")
        print("SI Protocol Connections string used for this test:\n" + si.Connections)
        print("")
        print("SI Event Handler Results:")
        print("")
        print("- # Watch Events          = " + str(SIEventHandlerClass.WatchCount))
        print("- # LogEntry Events       = " + str(SIEventHandlerClass.LogEntryCount))
        print("- # ProcessFlow Events    = " + str(SIEventHandlerClass.ProcessFlowCount))
        print("- # ControlCommand Events = " + str(SIEventHandlerClass.ControlCommandCount))
        print("")
        print("- # Total Events          = " + str(SIEventHandlerClass.TotalCount))
        print("")
        print("- # Error Events          = " + str(SIEventHandlerClass.ErrorCount))
        print("- # Info Events           = " + str(SIEventHandlerClass.InfoCount))
        print("- # Filter Events         = " + str(SIEventHandlerClass.FilterCount))
        print("- # Filter Cancel Events  = " + str(SIEventHandlerClass.FilterCancelCount))
        print("")


# wire up smartinspect events.
SIEventHandlerClass.WireEvents(SIAuto.Si)

# set smartinspect connections, and enable logging.
SIAuto.Si.Connections = "tcp(host=localhost,port=4228,timeout=30000)"
SIAuto.Si.Enabled = True

# get smartinspect logger reference.
_logsi:SISession = SIAuto.Main

# test some process flow methods.
_logsi.EnterProcess(None,"My Process")
_logsi.LogMessage("This message is in process My Process.")
_logsi.LogWarning("This warning is in process My Process.")
_logsi.LeaveProcess(None,"My Process")

# test some logentry methods.
_logsi.LogDebug("This is a debug message.")
_logsi.LogVerbose("This is a verbose message.")
_logsi.LogMessage("This is a message.")
_logsi.LogWarning("This is a warning message.")
_logsi.LogError("This is a error message in RED.", SIColors.Red)
_logsi.LogFatal("This is a fatal error message in RED.", SIColors.Red)

# test some control command methods.
_logsi.ClearWatches()

# test some watch methods.
_logsi.Watch(None,"string_py", "string1 value")
_logsi.Watch(None,"int_py", int(0))
_logsi.Watch(None,"float_py", float(3.14159))
_logsi.Watch(None,"datetime_py", datetime(2023,5,11,12,30,10))
_logsi.Watch(None,"bool_py", True)
_logsi.Watch(None,"byte_py", 0xff)

# print SI event counts, unwire events, and dispose of SmartInspect.
SIEventHandlerClass.PrintResults(SIAuto.Si)
SIEventHandlerClass.UnWireEvents(SIAuto.Si)
SIAuto.Si.Dispose()

def OnWatchEvent( self, sender: object, e: smartinspectpython.siwatcheventargs.SIWatchEventArgs) -> None:

Method that will handle the SmartInspect.WatchEvent event. Inheriting classes can override this method to handle the event.

Arguments:
  • sender (object): The object which fired the event.
  • e (SIWatchEventArgs): Arguments that contain detailed information related to the event.

This event can be used if custom processing of Watch packets is needed. The event handlers are always called in the context of the thread which causes the event.

If you specified that one or more connections of this SmartInspect object should operate in SIProtocol.IsValidOption, you need to protect the passed packet and its data by calling its SIPacket.Lock and SIPacket.Unlock methods before and after processing.

IMPORTANT: Keep in mind that adding SmartInspect log statements to the event handlers can cause a presumably undesired recursive behavior!

Sample Code

# package imports.
from datetime import datetime
from smartinspectpython.siauto import *

class SIEventHandlerClass:
    """
    Helper class for SmartInspect class testing.
    """

    # static variables.
    WriteEventPacketsToConsole:bool = False
    ErrorCount:int = 0
    InfoCount:int = 0
    FilterCount:int = 0
    FilterCancelCount:int = 0
    WatchCount:int = 0
    LogEntryCount:int = 0
    ProcessFlowCount:int = 0
    ControlCommandCount:int = 0
    TotalCount:int = 0


    @staticmethod
    def WireEvents(si) -> None:
        # wire up events.
        si.ErrorEvent += SIEventHandlerClass.ErrorEvent
        si.InfoEvent += SIEventHandlerClass.InfoEvent
        si.FilterEvent += SIEventHandlerClass.FilterEvent
        si.WatchEvent += SIEventHandlerClass.WatchEvent
        si.LogEntryEvent += SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent += SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent += SIEventHandlerClass.ControlCommandEvent


    @staticmethod
    def UnWireEvents(si) -> None:
        # unwire events.
        si.ErrorEvent -= SIEventHandlerClass.ErrorEvent
        si.InfoEvent -= SIEventHandlerClass.InfoEvent
        si.FilterEvent -= SIEventHandlerClass.FilterEvent
        si.WatchEvent -= SIEventHandlerClass.WatchEvent
        si.LogEntryEvent -= SIEventHandlerClass.LogEntryEvent
        si.ProcessFlowEvent -= SIEventHandlerClass.ProcessFlowEvent
        si.ControlCommandEvent -= SIEventHandlerClass.ControlCommandEvent


    def ErrorEvent(sender:object, e:SIErrorEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.ErrorCount = SIEventHandlerClass.ErrorCount + 1


    def InfoEvent(sender:object, e:SIInfoEventArgs) -> None:
        print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.InfoCount = SIEventHandlerClass.InfoCount + 1
        pass


    def FilterEvent(sender:object, e:SIFilterEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        # ignore all warning level packets.
        #if (e.Packet.Level == SILevel.Warning):
        #    SIEventHandlerClass.FilterCancelCount = SIEventHandlerClass.FilterCancelCount + 1
        #    e.Cancel = True
        SIEventHandlerClass.FilterCount = SIEventHandlerClass.FilterCount + 1
        pass


    def WatchEvent(sender:object, e:SIWatchEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.WatchCount = SIEventHandlerClass.WatchCount + 1
        pass


    def LogEntryEvent(sender:object, e:SILogEntryEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.LogEntryCount = SIEventHandlerClass.LogEntryCount + 1
        pass


    def ProcessFlowEvent(sender:object, e:SIProcessFlowEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ProcessFlowCount = SIEventHandlerClass.ProcessFlowCount + 1
        pass


    def ControlCommandEvent(sender:object, e:SIControlCommandEventArgs) -> None:
        if SIEventHandlerClass.WriteEventPacketsToConsole:
            print("* SIEvent {0}".format(str(e)))
        SIEventHandlerClass.TotalCount = SIEventHandlerClass.TotalCount + 1
        SIEventHandlerClass.ControlCommandCount = SIEventHandlerClass.ControlCommandCount + 1
        pass


    def ResetCounters(si) -> None:
        print("Resetting all SIEventHandlerClass counters to zero.")
        SIEventHandlerClass.ErrorCount:int = 0
        SIEventHandlerClass.InfoCount:int = 0
        SIEventHandlerClass.FilterCount:int = 0
        SIEventHandlerClass.FilterCancelCount:int = 0
        SIEventHandlerClass.WatchCount:int = 0
        SIEventHandlerClass.LogEntryCount:int = 0
        SIEventHandlerClass.ProcessFlowCount:int = 0
        SIEventHandlerClass.ControlCommandCount:int = 0
        SIEventHandlerClass.TotalCount:int = 0

    def PrintResults(si) -> str:
        print("")
        print("SI Protocol Connections string used for this test:\n" + si.Connections)
        print("")
        print("SI Event Handler Results:")
        print("")
        print("- # Watch Events          = " + str(SIEventHandlerClass.WatchCount))
        print("- # LogEntry Events       = " + str(SIEventHandlerClass.LogEntryCount))
        print("- # ProcessFlow Events    = " + str(SIEventHandlerClass.ProcessFlowCount))
        print("- # ControlCommand Events = " + str(SIEventHandlerClass.ControlCommandCount))
        print("")
        print("- # Total Events          = " + str(SIEventHandlerClass.TotalCount))
        print("")
        print("- # Error Events          = " + str(SIEventHandlerClass.ErrorCount))
        print("- # Info Events           = " + str(SIEventHandlerClass.InfoCount))
        print("- # Filter Events         = " + str(SIEventHandlerClass.FilterCount))
        print("- # Filter Cancel Events  = " + str(SIEventHandlerClass.FilterCancelCount))
        print("")


# wire up smartinspect events.
SIEventHandlerClass.WireEvents(SIAuto.Si)

# set smartinspect connections, and enable logging.
SIAuto.Si.Connections = "tcp(host=localhost,port=4228,timeout=30000)"
SIAuto.Si.Enabled = True

# get smartinspect logger reference.
_logsi:SISession = SIAuto.Main

# test some process flow methods.
_logsi.EnterProcess(None,"My Process")
_logsi.LogMessage("This message is in process My Process.")
_logsi.LogWarning("This warning is in process My Process.")
_logsi.LeaveProcess(None,"My Process")

# test some logentry methods.
_logsi.LogDebug("This is a debug message.")
_logsi.LogVerbose("This is a verbose message.")
_logsi.LogMessage("This is a message.")
_logsi.LogWarning("This is a warning message.")
_logsi.LogError("This is a error message in RED.", SIColors.Red)
_logsi.LogFatal("This is a fatal error message in RED.", SIColors.Red)

# test some control command methods.
_logsi.ClearWatches()

# test some watch methods.
_logsi.Watch(None,"string_py", "string1 value")
_logsi.Watch(None,"int_py", int(0))
_logsi.Watch(None,"float_py", float(3.14159))
_logsi.Watch(None,"datetime_py", datetime(2023,5,11,12,30,10))
_logsi.Watch(None,"bool_py", True)
_logsi.Watch(None,"byte_py", 0xff)

# print SI event counts, unwire events, and dispose of SmartInspect.
SIEventHandlerClass.PrintResults(SIAuto.Si)
SIEventHandlerClass.UnWireEvents(SIAuto.Si)
SIAuto.Si.Dispose()

def ProtocolErrorEvent( self, sender: object, e: smartinspectpython.sierroreventargs.SIErrorEventArgs) -> None:

Handles the protocol ErrorEvent.

Arguments:
  • sender (object): The object which fired the event.
  • e (SIErrorEventArgs): Arguments that contain detailed information related to the event.
def ProtocolInfoEvent( self, sender: object, e: smartinspectpython.siinfoeventargs.SIInfoEventArgs) -> None:

Handles the protocol InfoEvent.

Arguments:
  • sender (object): The object which fired the event.
  • e (SIInfoEventArgs): Arguments that contain detailed information related to the event.
def RaiseInfoEvent(self, message: str) -> None:

Raises the Info event with informational message details.

Arguments:
  • message (str): The message that caused the event.

This method is used to inform interested parties that an Informational event has occured.

def SendControlCommand( self, controlCommand: smartinspectpython.sicontrolcommand.SIControlCommand) -> None:

Logs a Control Command.

Arguments:
  • controlCommand (SIControlCommand): The Control Command to log.

At first, this method determines if the Control Command should really be sent by invoking the OnFilter method. If the Control Command passes the filter test, it will be logged and the SmartInspect.ControlCommand event is fired.

def SendLogEntry(self, logEntry: smartinspectpython.silogentry.SILogEntry) -> None:

Logs a Log Entry.

Arguments:
  • logEntry (SILogEntry): The Log Entry to log.

After setting the application name and hostname of the supplied Log Entry, this method determines if the Log Entry should really be sent by invoking the OnFilter method. If the Log Entry passes the filter test, it will be logged and the SmartInspect.LogEntry event is fired.

def SendProcessFlow( self, processFlow: smartinspectpython.siprocessflow.SIProcessFlow) -> None:

Logs a Process Flow entry.

Arguments:
  • processFlow (SIProcessFlow): The Process Flow entry to log.

After setting the hostname of the supplied Process Flow entry, this method determines if the Process Flow entry should really be sent by invoking the OnFilter method. If the Process Flow entry passes the filter test, it will be logged and the SmartInspect.ProcessFlow event is fired.

def SendWatch(self, watch: smartinspectpython.siwatch.SIWatch) -> None:

Logs a Watch.

Arguments:
  • watch (SIWatch): The watch to log.

At first, this method determines if the Watch should really be sent by invoking the OnFilter method. If the Watch passes the filter test, it will be logged and the SmartInspect.Watch event is fired.

def SetVariable(self, key: str, value: str) -> None:

Adds a new or updates an existing connection variable.

Arguments:
  • key (str): The key of the connection variable.
  • value (str): The value of the connection variable.

This method sets the value of a given connection variable. A connection variable is a placeholder for strings in the SmartInspect.Connections property. When setting a connections string (or loading it from a file with LoadConfiguration), any variables which have previously been defined with SetVariable are automatically replaced with their respective values.

The variables in the connections string are expected to have the following form: $variable$.

If a connection variable with the given key already exists, its value is overridden. To delete a connection variable, use UnsetVariable. This method does nothing if the key or value argument is null.

Connection variables are especially useful if you load a connections string from a file and would like to handle some protocol options in your application instead of the configuration file.

For example, if you encrypt log files, you probably do not want to specify the encryption key directly in your configuration file for security reasons. With connection variables, you can define a variable for the encryption key with SetVariable and then reference this variable in your configuration file. The variable is then automatically replaced with the defined value when loading the configuration file.

Another example deals with the directory or path of a log file. If you include a variable in the path of your log file, you can later replace it in your application with the real value. This might come in handy if you want to write a log file to an environment specific value, such as an application data directory, for example.

def UnsetVariable(self, key: str) -> str:

Unset's an existing connection variable.

Arguments:
  • key (str): The key of the connection variable to delete.

This method deletes the connection variable specified by the given key. Nothing happens if the connection variable doesn't exist or if the key argument is null.

@staticmethod
def Version() -> str:

Gets the version number of the SmartInspect Python3 library.

Returns:

The version number of the SmartInspect Python3 library. The returned string always has the form "MAJOR.MINOR.RELEASE.BUILD".