Join 34,000+ subscribers and receive articles from our
blog about software quality, testing, QA and security.

Async Logging / Enter/Leave message calls


#1

Hi I have two questions:

  1. How do you setup Async logging to a file or console?

  2. If each thread has its only log object and I call their respective enter/leave message calls, it screws up the other object’s enter/leave indentation. Is there away around this?

Thanks!


#2

Hello!

You can enable asynchronous logging for a connection by setting the “async.enabled” option in the connection string to true:

This is independent from the used protocol, so it will work for both file logging and logging directly to the Console (via TCP or named pipes). There are a few other async options such the buffer size etc. that are explained thoroughly in the SmartInspect manual (press F1 in the console, then go to “Working with SmartInspect | Connection and Protocols | Common Options”).

Please note that asynchronous logging involves a certain overhead and we usually recommend asynchronous logging only for TCP connections (to make it a non-blocking connection). File logging, for instance, is so fast (and practically non-blocking, especially when you use the “buffer” option for setting the I/O buffer) that asynchronous logging would slow it down a bit.

This is the normal behavior for a multi-threaded application. If you are using the default configuration of the Console, there’s only one view (“All Log Entries”) that displays the log entries of all threads (which run and generate log messages in parallel). To view the threads independently from each other, you can either create a view for each thread (Edit | Apply Builtin Autoview Rule | Thread Rule) or let the Console automatically create new thread views (with Edit | AutoView Rules).

Hope that helps, just let me know if you have any further questions!


#3

Awesome! Thanks!


#4

Heya,

we are trying to evaluate using SmartInspect for our company. We have multithreaded, multicored application, where i want to use SmartInspect for monitoring of it. So maybe i missunderstood your system. But for me at this time i cant get it rid to have nice view in the console. The problem is that a thread (which is usually some wrap of functionallity) isnt really only one physically thread. That happens because we have to do some functionallity in parallel. We have such an high traffic that we have to use that. So here is an example of an short test app i use to try to understand it:


    public class Worker1
    {

        public void Run1()
        {
            const int LOOPS = 3;

            string processName = "Run1()";
            List<Task> taskList = new List<Task>();
            SiAuto.Main.EnterProcess(processName);
            for (int i = 0, l = LOOPS; i < l; i++)
            {
                int index = i;
                Task newTask = new Task(() =>
                                {
                                    string threadName = String.Format("Thread_1#{0}", index);
                                    SiAuto.Main.EnterThread(threadName);
                                    Session ses = SiAuto.Main;
                                    //ses.EnterThread(threadName);
                                    ses.LogMessage(String.Format("Do_1#{0}", index));
                                    Thread.Sleep(1500);
                                    SiAuto.Main.LeaveThread(threadName);
                                });
                taskList.Add(newTask);
                newTask.Start();
            }
            Task.WaitAll(taskList.ToArray());
            SiAuto.Main.LeaveProcess(processName);
            SiAuto.Main.LogSystem("Run1() leaving");
        }

        public void Run2()
        {
            const int LOOPS = 3;

            string processName = "Run2()";
            List<Task> taskList = new List<Task>();
            SiAuto.Main.EnterProcess(processName);
            for (int i = 0, l = LOOPS; i < l; i++)
            {
                int index = i;
                Task newTask = new Task(() =>
                {
                    string threadName = String.Format("Thread_2#{0}", index);
                    SiAuto.Main.EnterThread(threadName);
                    Session ses = SiAuto.Main;
                    //ses.EnterThread(threadName);
                    ses.LogMessage(String.Format("Do#_2{0}", index));
                    Thread.Sleep(1500);
                    SiAuto.Main.LeaveThread(threadName);
                });
                taskList.Add(newTask);
                newTask.Start();
            }
            Task.WaitAll(taskList.ToArray());
            SiAuto.Main.LeaveProcess(processName);
            SiAuto.Main.LogSystem("Run2() leaving");
        }
        
    }
    class Program
    {
        static void Main(string[] args)
        {
            Framework frame = new Framework();
            frame.Init();
            SiAuto.Main.EnterMethod(frame, "MAIN");

            new Task(() =>
            {
                Worker1 worker = new Worker1();
                worker.Run1();
                worker.Run2();
            }).Start();

            Console.WriteLine("Press <ENTER>");
            Console.ReadLine();
            SiAuto.Main.LeaveMethod(frame, "MAIN");
            frame.Dispose();
        }
    }

This runs very nice and all its fine. But when i dont do Task.WaitAll(taskList.ToArray()); in Run1(), the log flow is completely broken, in process flow and in the log entries of the console. The object Task() is from microsoft’s reactive framework which simplyfies using of parallel programming. So if i want to have a nice view, which parameter i have to use for separating the views? On which parameter SmartInspect assigned the log while using the SiAuto methods? Or maybe split it own session? The last point i dont really want, because there are a hugh development overhead and and the code will blow.

Maybe its not much which helps me understand, let me know please :slight_smile:


#5

Hi,

If would be great if you could provide me with some additional details here. What do you mean with broken? If you are viewing the log messages in the standard view (‘All Log Entries’), they will naturally interleave in a multi-threaded application (as they are coming in in parallel and the standard view shows all available threads by default). To view the threads independently from each other, you would need to create thread specific views (please see above for how to set this up).

Regards,
Tobias


#6

Hey,

yeah i know thatz normally because SmartInspect will assign the log calls to e thread. And thatz the problem at all because the functionally flow isnt realy on one thread. As you can see i startup some tasks in Run1(). This tasks will be

  1. not run in the same thread
  2. not run on the same cpu
    To have more than one thread is essential for using parallelity! We have high traffic systems and we have to use more than one core parallel. The functional flow (EnterMethod, LeaveMethod, EnterProcess, LeaveProcess, i dont take EnterThread and LeaveThread here because you view of thread doesnt really match our physically threads) is not running at the same thread. So SmartInspect cant assign the correct log flow. The threads that where taken for the work by using parallel development is really not linear, its choosen really randomly and will be provided to threads. The count of the threads depending on the count of the cpu’s of the machine. I have spent a lot of time now to get smartinspect understand it, but until now i cant find a way. SmartInspect is a very great product and after seen it i really want to use it because of the console. We have many servers where are running a hughe count of applications and i need a flexible way for monitoring and logging that at all. SmartInspect is really that what ive searching for, so i think you may have an idea how to get my monitoring clean like SmartInspect may work at the most scenarios.

Michael


#7

I have to get an meaning about future logging of new applications this week, so its a little bit critical. How i said i really want to use SI. So i reviewed you completely framework much more closer. I found out thatz possible to send custom packages manually to the framework. So i can have internally log stacks for one logically process. But this really a hughe overhead on development. Maybe i have to take that overhead? It will be i think 1 month work for me more to integrate it.


#8

Hello Michael,

If you need more flexibility of how SmartInspect groups log entries in the views, I suggest taking a look at using different sessions for your threads and/or ‘tasks’ (and by tasks I mean the group of threads you might want to see in the same view in the Console).

So for example, if you want see specific log entries in the same view (be it from different threads or even processes), you can just create a new session and use that session to send the log entries. You can even do this across different processes, as SmartInspect just uses the name of the session as criteria. E.g., to create new sessions:

[code]// Create a new session for client 982
Session blue = SiAuto.Si.AddSession(“Blue”);
blue.Color = System.Drawing.Color.LightBlue;
blue.LogMessage(“Logged In”);

// And another one for client 289
Session yellow = SiAuto.Si.AddSession(“Yellow”);
yellow.Color = System.Drawing.Color.LightYellow;
yellow.LogMessage(“Logged In”);[/code]

You can then create a new view in the Console and filter for the particular sessions you are interested in. You can even create an AutoView rule (Edit | AutoView Rules) that spawns new views for you automatically.

About the Process Flow toolbar: processes and threads in the toolbar are detected by the different thread and process IDs. So if you are using a task framework or thread pooling, you will naturally see varies threads and processes in the list. Could you email me a screenshot/log of the issue you are seeing? I believe this would be the easiest way to figure out the problem. You can directly email me at dg@gurock.com (either in English or German) and I’m happy to help (I’m available the entire day so I can respond quickly).

Thanks,
Dennis