Imports System
Imports System.Threading
Imports Plumtree.Remote.Logging

' <summary>
' Demonstrates IDK logging API.
' </summary>
Public Class LoggingCommandLineExample

    Private Shared ReadOnly INSTANCES_COMPONENT_NAME As String = "Instances"
    Private Shared ReadOnly MAIN_LOOP_COMPONENT_NAME As String = "Main Loop"

    ' characters legal for logging application names: ASCII alphanumerics and space plus . - and _.
    Public Shared ReadOnly LOGGING_APPLICATION_NAME As String = "Logging_API_Example-1"

    ' set to true to multicast log messages to local network
    ' set to false to send message only listeners on local machine
    Public Shared ReadOnly LOG_TO_NETWORK As Boolean = True

    Private logger As ILogger              ' instance logging class
    Private Shared mainLogger As ILogger   ' main component logging class

    Private _thread As Thread    ' thread for each instance of LoggingCommandLineExample

    ' Suggested initialization for non-web applications is in a static block
    ' in your application's main class or a logging utility class.
    Shared Sub New()
        ' Don't attempt to re-initialize in case logging was already
        ' initialized (for example, as part of an EDK-based web application).

        If Not LogFactory.IsInitialized Then
            LogFactory.Initialize(LOGGING_APPLICATION_NAME, LOG_TO_NETWORK)
        End If
        Console.Out.WriteLine("Set your logging receiver to the ""server"" or ""application name"" ")
        Console.Out.WriteLine(LogFactory.GetApplicationName)
        Console.Out.WriteLine("The logging component names are ""EDK"", """ & MAIN_LOOP_COMPONENT_NAME & """ and """ & INSTANCES_COMPONENT_NAME & " "".")

        mainLogger = LogFactory.GetLogger(MAIN_LOOP_COMPONENT_NAME, GetType(LoggingCommandLineExample))
    End Sub

    ' <summary>
    ' Constructor for LoggingCommandLineExample.
    ' </summary>
    ' <param name="instanceName"></param>
    Public Sub New(ByVal instanceName As String)
        _thread = New Thread(New ThreadStart(AddressOf Run))
        _thread.Name = instanceName
        Me.logger = LogFactory.GetLogger(INSTANCES_COMPONENT_NAME, GetType(LoggingCommandLineExample))
        mainLogger.Info("Created new instance named {0}", instanceName)
    End Sub

    ' <summary>
    ' The main entry point for the logging example.
    ' </summary>
    <STAThread()> _
    Public Shared Sub Main(ByVal args As String())

        Dim methodName As String = "main"
        mainLogger.FunctionBegin(methodName)

        ' get a timestamp to measure performance of this function
        Dim performanceStartTicks As Long = mainLogger.PerformanceBegin

        mainLogger.Action("Creating and starting instances")

        Dim example1 As New LoggingCommandLineExample("Bill")
        example1.Thread.Start()
        Dim example2 As New LoggingCommandLineExample("Larry")
        example2.Thread.Start()

        mainLogger.Action("Done creating instances")

        ' send log message with time since performanceBegin
        mainLogger.PerformanceEnd(methodName, performanceStartTicks)
        mainLogger.FunctionEnd(methodName)
    End Sub

    ' <summary>
    ' Each thread runs through a small test of logging messages and
    ' interleaves work to the other by calling Thread.Sleep(1).
    ' </summary>
    Private Sub Run()
        Dim methodName As String = "run"

        ' send log message that function is starting
        logger.FunctionBegin(methodName)

        ' get a timestamp to measure performance of this function
        Dim performanceStartTicks As Long = LoggingCommandLineExample.mainLogger.PerformanceBegin

        Thread.Sleep(1)  ' interleaves work to the other thread

        ' demonstrates the available logging levels and shows use of token
        ' substitution in format strings to construct messages.
        Dim levelDescriptionFormat As String = "{0} level messages are {1} by default in the log receiver."

        ' debug() through fatal() are increasingly serious warning messages.
        '   By comparison, the message types action, function, and performance
        '   are generally "info" or "debug" level, with Action perhaps representing
        '   a message more important than "Info".  Function and performance messages
        '   are off by default.
        logger.Debug(levelDescriptionFormat, "Debug", "off")
        logger.Info(levelDescriptionFormat, "Info", "off")
        logger.Warn(levelDescriptionFormat, "Warn", "on")
        logger.Error(levelDescriptionFormat, "Error", "on")
        logger.Fatal(levelDescriptionFormat, "Fatal", "on")

        Thread.Sleep(1)   ' interleaves work to the other thread

        ' Exceptions may also be caught and logged, and may use token substitution.
        Try
            Throw New ThreadInterruptedException((_thread.Name & " was interrupted."))
        Catch eCaught As Exception
            logger.Warn(eCaught, "Caught an exception from {0}. ", eCaught.GetType.Name)
        End Try

        Thread.Sleep(1)   ' interleaves work to the other thread

        ' send log message with time since performanceBegin
        mainLogger.PerformanceEnd(methodName, performanceStartTicks)

        ' send log message that function is ending
        logger.FunctionEnd(methodName)
    End Sub

    ' <summary>
    ' Returns the thread for this instance.
    ' </summary>
    Public ReadOnly Property Thread() As Thread
        Get
            Return _thread
        End Get
    End Property

End Class
