SvcPerf provides a query engine which can be used to compile the manifest and execute a query. The query can use constructs from reactive and Tx to consume ETL traces.

namespace SvcPerf
{
    public class QueryEngine
    {
        public static void CompileManifest(string manifest);
            
        public static IDisposable Dump(
            IList<string> etlfiles, 
            Action<type> onStart, 
            Action<object> onNext, 
            Action<Exception> onError, 
            string query);
    }
}

The Dump(…) method returns a context object that can be disposed on completion or provide a mode for cancellation.

The following example shows how to dump out CSV of objects returned from a query. The OnNext handler for the Dump is invoked for every event and hence to iterate over large files we need to make sure that the onNext is fast. The onStart allows to query type returned by the Dump extension in the query.

Note: Only a SINGLE dump clause is supported in InProc query model for now.

Here is the complete example of an in-proc CSV dumper.

namespace Inproc
{
    using SvcPerf;
    using System;
    using System.IO;
    using System.Linq;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {

            const string query =
            @"
var all = playback.GetObservable<SystemEvent>();
var allevents  = from e in playback.BufferOutput(all)
                 select new  
                 { 
                    Timestamp = e.Header.Timestamp,
                    Name = e.GetType().Name,
                   Provider = e.Header.ProviderId, 
                   Version = e.Header.Version,
                   Id = e.Header.EventId, 
                   Opcode = e.Header.Opcode, 
                   Task = e.Header.Task, 
                   Pid = e.Header.ProcessId,
                   Tid = e.Header.ThreadId, 
                   Activity = e.Header.ActivityId,
                   RelatedActividy = e.Header.RelatedActivityId,
                   Message = e.ToString(),                        
                 };                 

playback.Run();
allevents.Dump();
";
            QueryEngine.CompileManifest(@"C:\dd\SvcPerf\test\TestResources\http.man");
            PropertyInfo[] properties = null;
            QueryEngine.Dump(
                new string[] { @"C:\dd\SvcPerf\test\TestResources\HTTP_Server.etl" }.ToList(),
                (t) => properties = PrintHeader(t,Console.Out),
                (o) => WriteLine(o, Console.Out, properties),
                (e) => Console.WriteLine(e),
                query);
        }


        public static PropertyInfo[]  PrintHeader(Type type, TextWriter writer)
        {
            string s = string.Empty;
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                if (s.Length > 0)
                    s = String.Join(",", new string[] { s, propertyInfo.Name });
                else
                    s = propertyInfo.Name;
            }

            writer.WriteLine(s);
            return type.GetProperties();
        }

        static void WriteLine(object obj, TextWriter writer, PropertyInfo[] properties)
        {

            string s = string.Empty;
            for (int idx = 0; idx < properties.Length; idx++)
            {
                var value = properties[idx].GetValue(obj, null);
                var formattedValue = value == null ? String.Empty : value.ToString();

                if (value != null)
                {
                    if (value.GetType() == typeof(string))
                        formattedValue = "\"" + formattedValue + "\"";
                }

                if (s.Length > 0)
                    s = String.Join(",", new string[] { s, formattedValue });
                else
                    s = formattedValue;

            }

            writer.WriteLine(s);
            writer.Flush();
        }
    }
}

Last edited Jan 20, 2013 at 1:50 AM by sajay, version 5

Comments

No comments yet.