Пример #1
0
        public void TraceLineDiscovered(CLogDecodedTraceLine decodedTraceLine, StringBuilder results)
        {
            Dictionary <int, string> map = new Dictionary <int, string>();
            int idx = 1;

            if (skip)
            {
                results.Append(decodedTraceLine.match.MatchedRegEx.ToString());
                return;
            }

            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, decodedTraceLine.match.MatchedRegEx.ToString());
            int c = -1;

            try
            {
                for (; ;)
                {
                    foreach (var m in decodedTraceLine.configFile.AllKnownMacros())
                    {
                        map[idx] = m.MacroName;
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"{idx}. {m.MacroName}");
                        ++idx;
                    }

                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"{idx}. <skip the reset in this file and save");

                    string choice = Console.ReadLine();
                    c = Convert.ToInt32(choice);

                    if (c == idx)
                    {
                        skip = true;
                        results.Append(decodedTraceLine.match.MatchedRegEx.ToString());
                        return;
                    }

                    break;
                }
            }
            catch (Exception)
            {
                CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "ERROR : invalid input");
            }


            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "UNIQUE ID");
            string id = Console.ReadLine().Trim().ToUpper();

            results.Append($"{map[c]}(");
            results.Append("" + id);
            results.Append($", \"{decodedTraceLine.TraceString}\"");

            foreach (var arg in decodedTraceLine.splitArgs)
            {
                results.Append($", {arg.VariableInfo.UserSpecifiedUnModified}");
            }
            results.Append(");");
        }
Пример #2
0
 public static void PrintMatchDiagnostic(CLogLineMatch traceLineMatch)
 {
     if (null == traceLineMatch)
     {
         return;
     }
     CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"Failing Line : {traceLineMatch.MatchedRegExX.Value}");
 }
Пример #3
0
        public void LoadCustomCSharp(string customTypeClogCSharpFile, CLogConfigurationFile configFile)
        {
            if (!File.Exists(customTypeClogCSharpFile))
            {
                CLogConsoleTrace.TraceLine(TraceType.Err, $"Custom C# file for custom decoder is missing.  Please create the file, or remove its reference from the config file");
                CLogConsoleTrace.TraceLine(TraceType.Err, $"                Missing File: {customTypeClogCSharpFile}");
                CLogConsoleTrace.TraceLine(TraceType.Err, $"      Defined In Config File: {configFile.FilePath}");
                throw new CLogEnterReadOnlyModeException("CustomCSharpFileMissing: " + customTypeClogCSharpFile, CLogHandledException.ExceptionType.UnableToOpenCustomDecoder, null);
            }

            string sourceCode = File.ReadAllText(customTypeClogCSharpFile);
            string sourceHash = Path.GetFileName(configFile.FilePath);

            _traceEmittorX.SetSourceCode(sourceCode);
        }
Пример #4
0
        private static int PerformInstall(string outputDir)
        {
            if (File.Exists(outputDir))
            {
                CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Output file for install cannot be a file. It either must not exist, or be a directory");
                return(-11);
            }
            Directory.CreateDirectory(outputDir);

            Assembly utilsAssembly = typeof(CLogConsoleTrace).Assembly;
            string   baseName      = utilsAssembly.GetName().Name;

            void ExtractFile(string name)
            {
                using Stream embeddedStream = utilsAssembly.GetManifestResourceStream($"{baseName}.{name}");
                using StreamReader reader   = new StreamReader(embeddedStream);
                string contents = reader.ReadToEnd();
                string fileName = Path.Combine(outputDir, name);

                if (File.Exists(fileName))
                {
                    string existingContents = File.ReadAllText(fileName);
                    if (existingContents == contents)
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"Skipping file {name} as its up to date");
                        return;
                    }
                }
                File.WriteAllText(fileName, contents);
                CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"Installed file {name}");
            }

            ExtractFile("clog.h");
            ExtractFile("CLog.cmake");

            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "--installDirectory overrides all arguments. Dependencies successfully installed!");

            return(0);
        }
Пример #5
0
        public bool IsValid()
        {
            if (!string.IsNullOrWhiteSpace(this.InstallDependencies))
            {
                return(true);
            }

            if (!string.IsNullOrEmpty(this.OutputDirectory))
            {
                if (string.IsNullOrEmpty(this.InputFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "OutputDirectory specified, and InputFile is empty");
                    return(false);
                }

                if (!string.IsNullOrEmpty(this.OutputFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "OutputDirectory specified, but OutputFile is not empty");
                    return(false);
                }
                this.OutputFile  = Path.Combine(this.OutputDirectory, Path.GetFileName(this.InputFile));
                this.OutputFile += ".clog.h";
                CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, "Setting Output file to : " + this.OutputFile);
            }

            //
            // If either input or output is empty, require that we're linting or upgrading
            //
            if (string.IsNullOrEmpty(this.InputFile) || string.IsNullOrEmpty(this.OutputFile))
            {
                if (!LintConfig && !UpgradeConfigFile && !RefreshCustomTypeProcessor)
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "input file and output file are required if not linting or upgrading config file");
                    return(false);
                }
            }
            else
            {
                if (string.IsNullOrEmpty(this.InputFile) || string.IsNullOrEmpty(this.OutputFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "please specify both an input and and output file");
                    return(false);
                }

                if (string.IsNullOrEmpty(ScopePrefix))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "please specify scope prefix");
                    return(false);
                }

                if (string.IsNullOrEmpty(SidecarFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "please specify sidecar file");
                    return(false);
                }
            }

            if (LintConfig || UpgradeConfigFile)
            {
                if (!string.IsNullOrEmpty(this.InputFile) || !string.IsNullOrEmpty(this.OutputFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "do not specify input or output files if you're linting or upgrading the config file");
                    return(false);
                }
            }

            if (RefreshCustomTypeProcessor)
            {
                if (string.IsNullOrEmpty(this.SidecarFile) || string.IsNullOrEmpty(this.ConfigurationFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Please specify both the side car to update, and the configuration file that contains a reference to the new type processor");
                    return(false);
                }
            }

            //
            // Makesure ConfigurationProfile is specified for all but those who do not need it
            //
            if (!RefreshCustomTypeProcessor)
            {
                if (string.IsNullOrEmpty(this.ConfigurationProfile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Please specify both the side car to update, and the configuration file that contains a reference to the new type processor");
                    return(false);
                }
            }

            return(true);
        }
Пример #6
0
        private static int Main(string[] cmdLineArgs)
        {
            ParserResult <CommandLineArguments> o = Parser.Default.ParseArguments <CommandLineArguments>(cmdLineArgs);

            return(o.MapResult(
                       options =>
            {
                string sidecarJson = File.ReadAllText(options.SideCarFile);
                CLogSidecar sidecar = CLogSidecar.FromJson(sidecarJson);


                TextReader file = Console.In;

                if (!File.Exists(options.ETLFile))
                {
                    TraceLine(TraceType.Err, $"ETL File {options.ETLFile} doesnt exist");
                    return -1;
                }

                StreamWriter outputfile = null;
                if (!String.IsNullOrEmpty(options.OutputFile))
                {
                    outputfile = new StreamWriter(new FileStream(options.OutputFile, FileMode.Create));
                }

                try
                {
                    TraceProcessorSettings traceSettings = new TraceProcessorSettings {
                        AllowLostEvents = true, AllowTimeInversion = true
                    };

                    using (ITraceProcessor etwfile = TraceProcessor.Create(options.ETLFile, traceSettings))
                    {
                        HashSet <Guid> ids = new HashSet <Guid>();

                        foreach (var m in sidecar.EventBundlesV2)
                        {
                            foreach (var prop in m.Value.ModuleProperites)
                            {
                                if (prop.Key.Equals("MANIFESTED_ETW"))
                                {
                                    ids.Add(new Guid(prop.Value["ETW_Provider"]));
                                }
                                else if (prop.Key.Equals("TRACELOGGING"))
                                {
                                    ids.Add(new Guid(prop.Value["ETW_Provider"]));
                                }
                            }
                        }

                        var events = etwfile.UseGenericEvents(ids.ToArray());
                        etwfile.Process();

                        foreach (var e in events.Result.Events)
                        {
                            string line = "";

                            try
                            {
                                Dictionary <string, IClogEventArg> fixedUpArgs = new Dictionary <string, IClogEventArg>();
                                string errorString = "ERROR";

                                if (null == e.Fields)
                                {
                                    continue;
                                }

                                Dictionary <string, IClogEventArg> args = new Dictionary <string, IClogEventArg>();

                                foreach (var f in e.Fields)
                                {
                                    args[f.Name] = new ManifestedETWEvent(f);
                                }

                                CLogDecodedTraceLine bundle = null;
                                int eidAsInt = -1;

                                foreach (var b in sidecar.EventBundlesV2)
                                {
                                    Dictionary <string, string> keys;

                                    if (!e.IsTraceLogging)
                                    {
                                        if (!b.Value.ModuleProperites.TryGetValue("MANIFESTED_ETW", out keys))
                                        {
                                            continue;
                                        }

                                        string eid;

                                        if (!keys.TryGetValue("EventID", out eid))
                                        {
                                            continue;
                                        }

                                        eidAsInt = Convert.ToInt32(eid);

                                        if (eidAsInt == e.Id)
                                        {
                                            bundle = b.Value;
                                            errorString = "ERROR:" + eidAsInt;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (e.ActivityName.Equals(b.Key))
                                        {
                                            bundle = b.Value;
                                            errorString = "ERROR:" + b.Key;
                                            break;
                                        }
                                    }
                                }

                                if (null == bundle)
                                {
                                    continue;
                                }

                                Dictionary <string, string> argMap;

                                if (e.IsTraceLogging)
                                {
                                    argMap = new Dictionary <string, string>();
                                    foreach (var arg in args)
                                    {
                                        argMap[arg.Key] = arg.Key;
                                    }
                                }
                                else
                                {
                                    argMap = sidecar.GetTracelineMetadata(bundle, "MANIFESTED_ETW");
                                }

                                var types = CLogFileProcessor.BuildTypes(sidecar.ConfigFile, null, bundle.TraceString, null, out string clean);

                                if (0 == types.Length)
                                {
                                    errorString = bundle.TraceString;
                                    goto toPrint;
                                }

                                int argIndex = 0;

                                foreach (var type in types)
                                {
                                    var arg = bundle.splitArgs[argIndex];
                                    CLogEncodingCLogTypeSearch node = sidecar.ConfigFile.FindType(arg);

                                    switch (node.EncodingType)
                                    {
                                    case CLogEncodingType.Synthesized:
                                        continue;

                                    case CLogEncodingType.Skip:
                                        continue;
                                    }

                                    string lookupArgName = argMap[arg.VariableInfo.SuggestedTelemetryName];

                                    if (!args.ContainsKey(lookupArgName))
                                    {
                                        Console.WriteLine($"Argmap missing {lookupArgName}");
                                        throw new Exception("InvalidType : " + node.DefinationEncoding);
                                    }

                                    if (0 != node.DefinationEncoding.CompareTo(type.TypeNode.DefinationEncoding))
                                    {
                                        Console.WriteLine("Invalid Types in Traceline");
                                        throw new Exception("InvalidType : " + node.DefinationEncoding);
                                    }

                                    fixedUpArgs[arg.VariableInfo.SuggestedTelemetryName] = args[lookupArgName];
                                    ++argIndex;
                                }

                                toPrint:

                                EventInformation ei = new EventInformation();
                                ei.Timestamp = e.Timestamp.DateTimeOffset;
                                ei.ProcessId = e.ProcessId.ToString("x");
                                ei.ThreadId = e.ThreadId.ToString("x");
                                DecodeAndTraceToConsole(outputfile, bundle, errorString, sidecar.ConfigFile, fixedUpArgs, ei, options.ShowTimestamps, options.ShowCPUInfo);
                            }
                            catch (Exception)
                            {
                                Console.WriteLine($"Invalid TraceLine : {line}");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    CLogConsoleTrace.TraceLine(TraceType.Err, "ERROR : " + e);
                    if (null != outputfile)
                    {
                        outputfile.WriteLine("ERROR : " + e);
                    }
                }
                finally
                {
                    if (null != outputfile)
                    {
                        outputfile.Flush();
                        outputfile.Close();
                    }
                }
                return 0;
            }, err =>
            {
                Console.WriteLine("Bad Args : " + err);
                return -1;
            }));
        }
Пример #7
0
        public bool IsValid()
        {
            //
            // If either input or output is empty, require that we're linting or upgrading
            //
            if (string.IsNullOrEmpty(this.InputFile) || string.IsNullOrEmpty(this.OutputFile))
            {
                if (!LintConfig && !UpgradeConfigFile && !RefreshCustomTypeProcessor)
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "input file and output file are required if not linting or upgrading config file");
                    return(false);
                }
            }
            else
            {
                if (string.IsNullOrEmpty(this.InputFile) || string.IsNullOrEmpty(this.OutputFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "please specify both an input and and output file");
                    return(false);
                }

                if (string.IsNullOrEmpty(ScopePrefix))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "please specify scope prefix");
                    return(false);
                }

                if (string.IsNullOrEmpty(SidecarFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "please specify sidecar file");
                    return(false);
                }
            }

            if (LintConfig || UpgradeConfigFile)
            {
                if (!string.IsNullOrEmpty(this.InputFile) || !string.IsNullOrEmpty(this.OutputFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "do not specify input or output files if you're linting or upgrading the config file");
                    return(false);
                }
            }

            if (RefreshCustomTypeProcessor)
            {
                if (string.IsNullOrEmpty(this.SidecarFile) || string.IsNullOrEmpty(this.ConfigurationFile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Please specify both the side car to update, and the configuration file that contains a reference to the new type processor");
                    return(false);
                }
            }

            //
            // Makesure ConfigurationProfile is specified for all but those who do not need it
            //
            if (!RefreshCustomTypeProcessor)
            {
                if (string.IsNullOrEmpty(this.ConfigurationProfile))
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Please specify both the side car to update, and the configuration file that contains a reference to the new type processor");
                    return(false);
                }
            }

            return(true);
        }
Пример #8
0
        private static int Main(string[] args)
        {
            ParserResult <CommandLineArguments> o = Parser.Default.ParseArguments <CommandLineArguments>(args);

            return(o.MapResult(
                       options =>
            {
                try
                {
                    //
                    // The CommandLineArguments library validates most input arguments for us,  there are few ones that are complicated
                    //    this secondary check looks for those and errors out if present
                    //
                    if (!options.IsValid())
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Invalid args");
                        return -1;
                    }

                    CLogConfigurationFile configFile = CLogConfigurationFile.FromFile(options.ConfigurationFile);
                    configFile.ProfileName = options.ConfigurationProfile;

                    CLogSidecar sidecar;
                    if (!Directory.Exists(Path.GetDirectoryName(options.SidecarFile)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(options.SidecarFile));
                    }

                    if (!File.Exists(options.SidecarFile))
                    {
                        sidecar = new CLogSidecar();
                    }
                    else
                    {
                        string json = File.ReadAllText(options.SidecarFile);
                        sidecar = CLogSidecar.FromJson(json);
                        if (null == sidecar)
                        {
                            sidecar = new CLogSidecar();
                        }
                    }
                    sidecar.SetConfigFile(configFile);


                    string outputCFile = Path.Combine(Path.GetDirectoryName(options.OutputFile),
                                                      options.ScopePrefix + "_" + Path.GetFileName(options.OutputFile)) + ".c";

                    configFile.ScopePrefix = options.ScopePrefix;
                    configFile.FilePath = Path.GetFullPath(options.ConfigurationFile);
                    configFile.OverwriteHashCollisions = options.OverwriteHashCollisions;

                    CLogTraceMacroDefination syslog = new CLogTraceMacroDefination();
                    syslog.EncodedArgNumber = 1;
                    syslog.MacroName = "syslog";
                    syslog.MacroConfiguration = new System.Collections.Generic.Dictionary <string, string>();
                    syslog.MacroConfiguration[options.ConfigurationProfile] = options.ConfigurationProfile;

                    configFile.SourceCodeMacros.Add(syslog);


                    CLogFileProcessor processor = new CLogFileProcessor(configFile);
                    SysLogToClog converter = new SysLogToClog();

                    string content = File.ReadAllText(options.InputFile);
                    string output = processor.ConvertFile(configFile, null, converter, content, options.InputFile, true);

                    if (!Directory.Exists(Path.GetDirectoryName(options.OutputFile)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(options.OutputFile));
                    }


                    File.WriteAllText(options.InputFile, output);
                }
                catch (CLogHandledException e)
                {
                    e.PrintDiagnostics();
                    return -2;
                }

                return 0;
            }, err =>
            {
                Console.WriteLine("Bad Args : " + err);
                return -1;
            }));
        }
Пример #9
0
        public void TraceLineDiscovered(CLogDecodedTraceLine decodedTraceLine, CLogOutputInfo outputInfo, StringBuilder results)
        {
            Dictionary <int, string> map = new Dictionary <int, string>();
            int idx = 1;

            if (skip)
            {
                results.Append(decodedTraceLine.match.MatchedRegExX.ToString());
                return;
            }

            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, decodedTraceLine.match.MatchedRegExX.ToString());
            int c = -1;

            try
            {
                for (; ;)
                {
                    foreach (var m in decodedTraceLine.configFile.AllKnownMacros())
                    {
                        map[idx] = m.MacroName;
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"{idx}. {m.MacroName}");
                        ++idx;
                    }

                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"{idx}. <skip the rest in this file and save>");

                    string choice = null;
                    while (String.IsNullOrEmpty(choice))
                    {
                        try
                        {
                            choice = Console.ReadLine();
                            c      = Convert.ToInt32(choice);
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("try again please");
                        }
                    }

                    if (c == idx)
                    {
                        skip = true;
                        results.Append(decodedTraceLine.match.MatchedRegExX.ToString());
                        return;
                    }

                    break;
                }
            }
            catch (Exception)
            {
                CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "ERROR : invalid input");
            }


            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "UNIQUE ID");
            string id = Console.ReadLine().Trim().ToUpper();

            while (takenIds.Contains(id))
            {
                Console.WriteLine("ID is taken please use a unique ID");
                id = Console.ReadLine().Trim().ToUpper();
            }
            takenIds.Add(id);

            results.Append($"{map[c]}(");
            results.Append("" + id);
            results.Append($", \"{decodedTraceLine.TraceString}\"");

            for (int i = 2; i < decodedTraceLine.splitArgs.Length; ++i)
            {
                var arg = decodedTraceLine.splitArgs[i];
                results.Append($", {arg.VariableInfo.UserSuppliedTrimmed}");
            }
            results.Append(");");
        }
Пример #10
0
        public void TraceLineDiscovered(string sourceFile, CLogDecodedTraceLine decodedTraceLine, CLogSidecar sidecar, StringBuilder macroPrefix, StringBuilder inline, StringBuilder function)
        {
            string hash = decodedTraceLine.UniqueId;
            CLogExportModuleDefination moduleSettings = decodedTraceLine.GetMacroConfigurationProfile().FindExportModule(_ModuleName);

            if (!_inited)
            {
                if (!moduleSettings.CustomSettings.ContainsKey("ETWManifestFile"))
                {
                    throw new CLogEnterReadOnlyModeException("ETWManifestFileNotSpecified", CLogHandledException.ExceptionType.MustSpecifiyETWManifest, decodedTraceLine.match);
                }

                xmlFileName = moduleSettings.CustomSettings["ETWManifestFile"];
                xmlFileName = Path.Combine(Path.GetDirectoryName(decodedTraceLine.macro.ConfigFileWithMacroDefination), xmlFileName);

                Init();
            }

            if (!moduleSettings.CustomSettings.ContainsKey("ETW_Provider"))
            {
                Console.WriteLine($"The 'CustomSettings' dictionary for macro {decodedTraceLine.macro.MacroName} does not contain a GUID for the EtwProvider");
                Console.WriteLine("    Please add an entry and rerun");
                Console.WriteLine("");
                Console.WriteLine($"Configuration File  : {decodedTraceLine.configFile.FilePath}");
                Console.WriteLine("");
                Console.WriteLine("");
                Console.WriteLine("");
                throw new CLogEnterReadOnlyModeException("ETW_Provider:NotSpecified", CLogHandledException.ExceptionType.MustSpecifyETWProvider, decodedTraceLine.match);
            }

            Guid providerId = new Guid(moduleSettings.CustomSettings["ETW_Provider"]);

            ManifestInformation manifest = FindProviderCache(providerId);
            string eventNamePrefix;

            if (!moduleSettings.CustomSettings.TryGetValue("EventNamePrefix", out eventNamePrefix))
            {
                eventNamePrefix = string.Empty;
            }

            if (null == manifest)
            {
                Console.WriteLine($"Unable to locate ETW provider {providerId} in CLOG macro {decodedTraceLine.macro.MacroName}");
                Console.WriteLine("    CLOG will not create this provider within the manifest;  it will only add to an existing provider");
                Console.WriteLine("    please consult the MSDN documentation for an ETW manifest for instructions");
                Console.WriteLine("");

                Console.WriteLine($"Macro:  {providerId} is defined in {decodedTraceLine.configFile.FilePath}");
                Console.WriteLine($"ETW Manifest : is set as {xmlFileName}");
                Console.WriteLine("");
                Console.WriteLine("");
                Console.WriteLine("");
                throw new CLogEnterReadOnlyModeException("ManifestedETWProviderNotFoundInManifest", CLogHandledException.ExceptionType.ManifestedETWProviderNotFound, decodedTraceLine.match);
            }

            //
            // Only allow a hash one time for now....
            //
            if (manifest.knownHashes.Contains(hash))
            {
                return;
            }

            manifest.knownHashes.Add(hash);

            //
            //  See if our event already exists - if it does we do not want to add it a second time
            //
            List <XmlElement> toRemove = new List <XmlElement>();
            XmlElement        newEvent = null;

            foreach (var p in manifest.events.ChildNodes)
            {
                if (!(p is XmlElement))
                {
                    continue;
                }

                XmlElement pe = (XmlElement)p;

                if (pe.Name == "event")
                {
                    if (!pe.HasAttribute("symbol"))
                    {
                        continue;
                    }

                    string symbol = pe.GetAttribute("symbol");

                    if (0 == symbol.CompareTo(eventNamePrefix + hash))
                    {
                        toRemove.Add(pe);
                        newEvent = pe;
                        break;
                    }
                }
            }

            //
            //  Add the event if it doesnt already exist
            //
            if (null == newEvent)
            {
                newEvent = doc.CreateElement("event", manifest.events.NamespaceURI);
                manifest.events.AppendChild(newEvent);
                _dirty = true;
                CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, $"Adding event {eventNamePrefix + hash} to ETW manifest {xmlFileName}");
            }

            int    hashUInt;
            string eventAsString;

            decodedTraceLine.macro.DecodeUniqueId(decodedTraceLine.match, hash, out eventAsString, out hashUInt);

            uint eventId;

            if (!newEvent.HasAttribute("value"))
            {
                eventId = FindUnusedEventId(providerId, decodedTraceLine.match);
                SetAttribute(newEvent, "value", eventId.ToString());
            }
            else
            {
                eventId = Convert.ToUInt32(newEvent.GetAttribute("value"));
            }

            //
            // Store the eventID for future decode as well as every configuration setting attached to this module
            //
            decodedTraceLine.AddConfigFileProperty(ModuleName, "EventID", eventId.ToString());
            foreach (var setting in moduleSettings.CustomSettings)
            {
                decodedTraceLine.AddConfigFileProperty(ModuleName, setting.Key, setting.Value);
            }


            SetAttribute(newEvent, "symbol", eventNamePrefix + hash);

            string oldTemplate = null;

            if (newEvent.HasAttribute("template"))
            {
                oldTemplate = newEvent.GetAttribute("template");
            }
            string templateId = DiscoverOrCreateTemplate(decodedTraceLine, sidecar, providerId, oldTemplate, eventId);

            SetAttribute(newEvent, "template", templateId);

            if (moduleSettings.CustomSettings.ContainsKey("Level"))
            {
                SetAttribute(newEvent, "level", moduleSettings.CustomSettings["Level"]);
            }
            else
            {
                CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, $"Manifested ETW Level not specified;  if you desire a Level, add 'Level' to CustomSettings in {decodedTraceLine.configFile.FilePath}");
            }

            if (moduleSettings.CustomSettings.ContainsKey("Keywords"))
            {
                SetAttribute(newEvent, "keywords", moduleSettings.CustomSettings["Keywords"]);
            }
            else
            {
                CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, $"Manifested ETW Keywords not specified;  if you desire a Keyword, add 'Keywords' to CustomSettings in {decodedTraceLine.configFile.FilePath}");
            }


            //
            // Construct the function signature
            //
            string traceLine        = $"EventWrite{eventNamePrefix + hash}(";
            bool   haveMultipleArgs = false;

            foreach (var a in decodedTraceLine.splitArgs)
            {
                CLogFileProcessor.CLogVariableBundle arg  = a;
                CLogEncodingCLogTypeSearch           node = decodedTraceLine.configFile.FindType(arg, decodedTraceLine);

                switch (node.EncodingType)
                {
                case CLogEncodingType.Synthesized:
                    continue;

                case CLogEncodingType.Skip:
                    continue;
                }

                if (haveMultipleArgs)
                {
                    traceLine += ", ";
                }

                haveMultipleArgs = true;

                switch (node.EncodingType)
                {
                case CLogEncodingType.ByteArray:
                    traceLine += $"{arg.MacroVariableName}_len, {arg.MacroVariableName}";
                    continue;

                default:
                    traceLine += $"{arg.MacroVariableName}";
                    break;
                }
            }

            traceLine += "); \\";
            inline.AppendLine(traceLine);
            Save(decodedTraceLine.match);
        }
Пример #11
0
        private string DiscoverOrCreateTemplate(CLogDecodedTraceLine traceLine, CLogSidecar sidecar, Guid providerId, string existingTemplateName, uint eventId)
        {
            string hash = "";

            //
            // Construct a list of the desired types - we'll use this to see if we can find a preexisting suitable template
            //
            List <TemplateNode> listofArgsAsSpecifiedBySourceFile = ConstructTemplateArgs(traceLine);
            string templateId = existingTemplateName;

            if (string.IsNullOrEmpty(existingTemplateName))
            {
                templateId = "template_" + hash;

                foreach (TemplateNode arg in listofArgsAsSpecifiedBySourceFile)
                {
                    templateId += arg.Hash;
                }
            }

            //
            // See if the template already exists;  for example from a different file
            //
            ManifestInformation manifest = FindProviderCache(providerId);
            XmlElement          template = null;

            foreach (var p in manifest.templates.ChildNodes)
            {
                if (!(p is XmlElement))
                {
                    continue;
                }

                XmlElement pe = (XmlElement)p;

                if (pe.Name == "template")
                {
                    if (!pe.HasAttribute("tid"))
                    {
                        continue;
                    }

                    string tid = pe.GetAttribute("tid");

                    if (0 == tid.CompareTo(templateId))
                    {
                        template = pe;
                        break;
                    }
                }
            }

            //
            // If we dont have an existing template, add one
            //
            if (null == template)
            {
                template = doc.CreateElement("template", manifest.events.NamespaceURI);

                foreach (var arg in listofArgsAsSpecifiedBySourceFile)
                {
                    var dataNode = doc.CreateElement("data", manifest.events.NamespaceURI);
                    dataNode.SetAttribute("name", arg.Name);

                    if (!string.IsNullOrEmpty(arg.LengthOfSelf))
                    {
                        dataNode.SetAttribute("length", arg.LengthOfSelf);
                    }
                    dataNode.SetAttribute("inType", arg.Type);

                    template.AppendChild(dataNode);
                }

                // Only apply a template ID if it's not empty - otherwise choose the default
                if (!templateId.Equals("templateId_"))
                {
                    template.SetAttribute("tid", templateId);
                }

                manifest.templates.AppendChild(template);
            }

            //
            //
            int argIdx = 0;
            Dictionary <string, string> argLookup = sidecar.GetTracelineMetadata(traceLine, ModuleName);

            if (null == argLookup)
            {
                argLookup = new Dictionary <string, string>();
            }


            foreach (var a in template.ChildNodes)
            {
                if (!(a is XmlElement))
                {
                    continue;
                }

                XmlElement pe = (XmlElement)a;

                if (pe.Name != "data")
                {
                    continue;
                }

                string inType = pe.GetAttribute("inType");
                string name   = pe.GetAttribute("name");

                if (listofArgsAsSpecifiedBySourceFile.Count <= argIdx)
                {
                    if (traceLine.configFile.DeveloperMode)
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Template Argument Type Mismatch - overwriting due to developer mode");
                        _dirty = true;
                        return(DiscoverOrCreateTemplate(traceLine, sidecar, providerId, null, eventId));
                    }

                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Template Argument Type Mismatch - manifested ETW template and CLOG string differ");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"         Event ID : {eventId}");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"   Event Provider : {providerId}");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"        Event UID : {traceLine.UniqueId}");

                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, "Recommended Course of action:");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, $"  1. (best) from within the manifest, delete the template ({templateId}) from your event ({eventId})");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, $"  2. cleanup your template to be in this format");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, $"  3. set the environment variable CLOG_DEVELOPMENT_MODE=1  ($env:CLOG_DEVELOPMENT_MODE=1)");

                    throw new CLogEnterReadOnlyModeException("ETWManifestTypeMismatch", CLogHandledException.ExceptionType.ETWTypeMismatch, traceLine.match);
                }

                TemplateNode templateReference = listofArgsAsSpecifiedBySourceFile[argIdx];

                argLookup[templateReference.ArgBundle.MacroVariableName] = name;

                if (templateReference.Type != inType)
                {
                    if (traceLine.configFile.DeveloperMode)
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Template Argument Type Mismatch - overwriting due to developer mode");
                        _dirty = true;
                        return(DiscoverOrCreateTemplate(traceLine, sidecar, providerId, null, eventId));
                    }

                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Template Argument Type Mismatch: ");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"               Event ID : {eventId}");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"         Event Provider : {providerId}");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"              Event UID : {traceLine.UniqueId}");

                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"      Mismatch Arg Name : {name}");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"    CLOG specified Type : {templateReference.Type}");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"      ETW Manifest Type : {inType}");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Source Line:");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, CLogConsoleTrace.GetFileLine(traceLine.match));
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, traceLine.match.MatchedRegEx.ToString());

                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");

                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, "Recommended Course of action:");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, $"  1. (best) from within the manifest, delete the template ({templateId}) from your event ({eventId})");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, $"  2. cleanup your template to be in this format");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, $"  3. set the environment variable CLOG_DEVELOPMENT_MODE=1  ($env:CLOG_DEVELOPMENT_MODE=1)");

                    foreach (var t in listofArgsAsSpecifiedBySourceFile)
                    {
                        if (string.IsNullOrEmpty(t.LengthOfSelf))
                        {
                            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, $"          name={t.Name} inType={t.Type}");
                        }
                        else
                        {
                            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Tip, $"          name={t.Name} inType={t.Type}  length={t.LengthOfSelf}");
                        }
                    }

                    throw new CLogEnterReadOnlyModeException("ETWManifestTypeMismatch", CLogHandledException.ExceptionType.ETWTypeMismatch, traceLine.match);
                }
                ++argIdx;
            }


            //
            // Store our metadata into the side car
            //
            sidecar.SetTracelineMetadata(traceLine, ModuleName, argLookup);
            return(templateId);
        }
Пример #12
0
        private static int Main(string[] args)
        {
            // Manually parse installDirectory, as it interferes with the required configFile
            // The argument still shows up in CommandLineArguments to be shown in help.
            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "--installDirectory")
                {
                    if (i + 1 == args.Length)
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Must pass an argument to --installDirectory");
                        return(-1);
                    }
                    return(PerformInstall(args[i + 1]));
                }
            }

            ParserResult <CommandLineArguments> o = Parser.Default.ParseArguments <CommandLineArguments>(args);

            return(o.MapResult(
                       options =>
            {
                try
                {
                    //
                    // The CommandLineArguments library validates most input arguments for us,  there are few ones that are complicated
                    //    this secondary check looks for those and errors out if present
                    //
                    if (!options.IsValid())
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Invalid args");
                        return -1;
                    }

                    if (!string.IsNullOrWhiteSpace(options.InstallDependencies))
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Internal error, this should have been handled at a previous step");
                        return -1;
                    }

                    CLogConfigurationFile configFile = CLogConfigurationFile.FromFile(options.ConfigurationFile);
                    configFile.ProfileName = options.ConfigurationProfile;

                    if (options.ReadOnly && !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_FORCE_WRITABLE")))
                    {
                        options.ReadOnly = false;
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, "WARNING: CLOG was instructed via --readOnly not to emit changes however this was overridden with CLOG_FORCE_WRITABLE environment variable");
                    }

                    if (options.OverwriteHashCollisions || !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_OVERWRITE_COLLISIONS")))
                    {
                        options.OverwriteHashCollisions = true;
                        options.ReadOnly = false;
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "***********************************************");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Overwriting of sidecare collisions is set by environment variable CLOG_OVERWRITE_COLLISIONS.  This setting is only to be used while making large refactors and should not be included in build environments or standard development environments");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "***********************************************");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                    }

                    if (options.Devmode || !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_DEVELOPMENT_MODE")))
                    {
                        options.ReadOnly = false;
                        options.OverwriteHashCollisions = true;
                        configFile.DeveloperMode = true;
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, "WARNING: CLOG was instructed to enter a developer mode");
                    }

                    if (options.LintConfig)
                    {
                        if (!configFile.MarkPhase)
                        {
                            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Lint operation only works on config files placed into the 'MarkPhase'.  This can be a destricutive action, please read the docs for more information");
                            return -10;
                        }
                        configFile.Lint();
                        configFile.Save(false);
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "Lint operation complete");
                        return 0;
                    }

                    if (options.UpgradeConfigFile)
                    {
                        configFile.UpdateVersion();
                        configFile.Save(false);
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "Config upgrade complete");
                        return 0;
                    }

                    CLogSidecar sidecar;
                    if (!Directory.Exists(Path.GetDirectoryName(options.SidecarFile)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(options.SidecarFile));
                    }

                    if (!File.Exists(options.SidecarFile))
                    {
                        sidecar = new CLogSidecar();
                    }
                    else
                    {
                        string json = File.ReadAllText(options.SidecarFile);
                        sidecar = CLogSidecar.FromJson(json);
                        if (null == sidecar)
                        {
                            sidecar = new CLogSidecar();
                        }
                    }

                    // Check for outdated config file
                    sidecar.UpdateConfigFile(configFile);

                    if (options.RefreshCustomTypeProcessor)
                    {
                        configFile.ForceDecoderCompile();
                        sidecar.Save(options.SidecarFile);
                        return 0;
                    }

                    string outputCFile = Path.Combine(Path.GetDirectoryName(options.OutputFile),
                                                      options.ScopePrefix + "_" + Path.GetFileName(options.OutputFile)) + ".c";

                    configFile.ScopePrefix = options.ScopePrefix;
                    configFile.FilePath = Path.GetFullPath(options.ConfigurationFile);
                    configFile.OverwriteHashCollisions = options.OverwriteHashCollisions;

                    //Delete the output file; we want to encourage build breaks if something goes wrong
                    if (File.Exists(options.OutputFile))
                    {
                        File.Delete(options.OutputFile);
                    }

                    if (File.Exists(outputCFile))
                    {
                        File.Delete(outputCFile);
                    }


                    CLogFileProcessor processor = new CLogFileProcessor(configFile);
                    CLogFullyDecodedMacroEmitter fullyDecodedMacroEmitter = new CLogFullyDecodedMacroEmitter(options.InputFile, sidecar);

                    fullyDecodedMacroEmitter.AddClogModule(sidecar);

                    CLogTraceLoggingOutputModule traceLoggingEmitter = new CLogTraceLoggingOutputModule();
                    fullyDecodedMacroEmitter.AddClogModule(traceLoggingEmitter);

                    CLogDTraceOutputModule dtrace = new CLogDTraceOutputModule();
                    fullyDecodedMacroEmitter.AddClogModule(dtrace);

                    CLogSystemTapModule systemTap = new CLogSystemTapModule();
                    fullyDecodedMacroEmitter.AddClogModule(systemTap);

                    CLogSysLogModule syslog = new CLogSysLogModule();
                    fullyDecodedMacroEmitter.AddClogModule(syslog);

                    CLogSTDOUT stdout = new CLogSTDOUT();
                    fullyDecodedMacroEmitter.AddClogModule(stdout);

                    CLogManifestedETWOutputModule manifestedEtwOutput = new CLogManifestedETWOutputModule(options.ReadOnly);
                    fullyDecodedMacroEmitter.AddClogModule(manifestedEtwOutput);

                    CLogLTTNGOutputModule lttngOutput = new CLogLTTNGOutputModule(options.InputFile, options.OutputFile,
                                                                                  options.OutputFile + ".lttng.h", options.DynamicTracepointProvider);
                    fullyDecodedMacroEmitter.AddClogModule(lttngOutput);

                    if (!File.Exists(options.InputFile))
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"Invalid Input File : {Path.GetFileName(options.InputFile)}");
                        throw new CLogEnterReadOnlyModeException("InvalidInputFile", CLogHandledException.ExceptionType.InvalidInputFile, null);
                    }

                    string content = File.ReadAllText(options.InputFile);
                    string output = processor.ConvertFile(configFile, fullyDecodedMacroEmitter, content, options.InputFile, false);

                    if (!content.Contains(Path.GetFileName(options.OutputFile)))
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"You must #include the clog output file {Path.GetFileName(options.OutputFile)}");
                        throw new CLogEnterReadOnlyModeException("MustIncludeCLogHeader", CLogHandledException.ExceptionType.SourceMustIncludeCLOGHeader, null);
                    }

                    fullyDecodedMacroEmitter.FinishedProcessing();

                    StringBuilder clogFile = new StringBuilder();
                    clogFile.AppendLine("#include <clog.h>");

                    clogFile.Append(fullyDecodedMacroEmitter.HeaderInit);

                    foreach (var macro in processor.MacrosInUse)
                    {
                        clogFile.AppendLine($"#ifndef _clog_MACRO_{macro.MacroName}");
                        clogFile.AppendLine($"#define _clog_MACRO_{macro.MacroName}  1");
                        clogFile.AppendLine(
                            $"#define {macro.MacroName}(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))");
                        clogFile.AppendLine("#endif");
                    }

                    clogFile.AppendLine("#ifdef __cplusplus");
                    clogFile.AppendLine("extern \"C\" {");
                    clogFile.AppendLine("#endif");

                    clogFile.Append(fullyDecodedMacroEmitter.HeaderFile);
                    clogFile.AppendLine("#ifdef __cplusplus");
                    clogFile.AppendLine("}");
                    clogFile.AppendLine("#endif");

                    clogFile.AppendLine("#ifdef CLOG_INLINE_IMPLEMENTATION");
                    clogFile.AppendLine("#include \"" + Path.GetFileName(outputCFile) + "\"");
                    clogFile.AppendLine("#endif");


                    if (!Directory.Exists(Path.GetDirectoryName(options.OutputFile)))
                    {
                        Console.WriteLine("Creating Directory for Output : " + Path.GetDirectoryName(options.OutputFile));
                        Directory.CreateDirectory(Path.GetDirectoryName(options.OutputFile));
                    }

                    if (sidecar.AreDirty || configFile.AreWeDirty())
                    {
                        if (options.ReadOnly)
                        {
                            if (sidecar.AreDirty)
                            {
                                Console.WriteLine("Sidecar is dirty");
                            }
                            if (configFile.AreWeDirty())
                            {
                                Console.WriteLine("ConfigFile is dirty");
                            }

                            sidecar.PrintDirtyReasons();
                            throw new CLogEnterReadOnlyModeException("WontWriteWhileInReadonlyMode:SideCar", CLogHandledException.ExceptionType.WontWriteInReadOnlyMode, null);
                        }
                        configFile.ForceDecoderCompile();
                        sidecar.Save(options.SidecarFile);
                    }

                    if (configFile.AreWeDirty() || configFile.AreWeInMarkPhase())
                    {
                        if (options.ReadOnly)
                        {
                            throw new CLogEnterReadOnlyModeException("WontWriteWhileInReadonlyMode:ConfigFile", CLogHandledException.ExceptionType.WontWriteInReadOnlyMode, null);
                        }
                        Console.WriteLine("Configuration file was updated, saving...");
                        Console.WriteLine($"    {configFile.FilePath}");
                        configFile.Save(false);
                    }

                    File.WriteAllText(options.OutputFile, clogFile.ToString());
                    File.WriteAllText(outputCFile, fullyDecodedMacroEmitter.SourceFile);
                }
                catch (CLogHandledException e)
                {
                    e.PrintDiagnostics();
                    return -2;
                }

                return 0;
            }, err =>
            {
                Console.WriteLine("Bad Args : " + err);
                return -1;
            }));
        }
Пример #13
0
        private static int Main(string[] args)
        {
            ParserResult <CommandLineArguments> o = Parser.Default.ParseArguments <CommandLineArguments>(args);

            return(o.MapResult(
                       options =>
            {
                string sidecarJson = File.ReadAllText(options.SideCarFile);
                CLogSidecar textManifest = CLogSidecar.FromJson(sidecarJson);

                TextReader file = Console.In;

                if (!string.IsNullOrEmpty(options.BabelTrace))
                {
                    file = new StreamReader(options.BabelTrace);
                }


                string line;
                LTTNGEventDecoder lttngDecoder = new LTTNGEventDecoder(textManifest);
                int lines = 0;
                StreamWriter outputfile = null;
                if (!String.IsNullOrEmpty(options.OutputFile))
                {
                    outputfile = new StreamWriter(new FileStream(options.OutputFile, FileMode.Create));
                }

                DateTimeOffset startTime = DateTimeOffset.Now;

                try
                {
                    while (!string.IsNullOrEmpty(line = file.ReadLine()))
                    {
                        ++lines;
                        if (0 == lines % 10000)
                        {
                            Console.WriteLine($"Line : {lines}");
                        }
                        Dictionary <string, IClogEventArg> valueBag;
                        EventInformation ei;
                        CLogDecodedTraceLine bundle = lttngDecoder.DecodedTraceLine(line, out ei, out valueBag);
                        DecodeAndTraceToConsole(outputfile, bundle, line, textManifest.ConfigFile, valueBag, ei, options.ShowTimestamps, options.ShowCPUInfo);
                    }
                }
                catch (Exception e)
                {
                    CLogConsoleTrace.TraceLine(TraceType.Err, "ERROR : " + e);
                    if (null != outputfile)
                    {
                        outputfile.WriteLine("ERROR : " + e);
                    }
                }
                finally
                {
                    if (null != outputfile)
                    {
                        outputfile.Flush();
                        outputfile.Close();
                    }
                }
                Console.WriteLine($"Decoded {lines} in {DateTimeOffset.Now - startTime}");
                return 0;
            }, err =>
            {
                Console.WriteLine("Bad Args : " + err);
                return -1;
            }));
        }
Пример #14
0
        private void Init()
        {
            if (_inited)
            {
                return;
            }

            if (!File.Exists(xmlFileName))
            {
                Console.WriteLine($"ETW Manifest {xmlFileName} doesnt exist");
                throw new CLogEnterReadOnlyModeException("Output Manifest Missing", CLogHandledException.ExceptionType.ETWManifestNotFound, null);
            }

            try
            {
                doc.PreserveWhitespace = true;
                doc.Load(xmlFileName);

                XmlElement assembly    = doc["assembly"];
                XmlElement stringTable = null;

                if (null == assembly)
                {
                    assembly = doc["instrumentationManifest"];
                }

                var instrumentation = assembly["instrumentation"];
                var rootEvents      = instrumentation["events"];

                var stringEvents = assembly["localization"];
                foreach (var culture in stringEvents.ChildNodes)
                {
                    if (!(culture is XmlElement))
                    {
                        continue;
                    }

                    XmlElement pe = (XmlElement)culture;
                    if (pe.Name == "resources")
                    {
                        if (!pe.HasAttribute("culture"))
                        {
                            continue;
                        }

                        string attr = pe.GetAttribute("culture");

                        if (!attr.Equals("en-US"))
                        {
                            continue;
                        }

                        stringTable = pe["stringTable"];
                    }
                }

                foreach (var p in rootEvents.ChildNodes)
                {
                    if (!(p is XmlElement))
                    {
                        continue;
                    }

                    XmlElement pe = (XmlElement)p;

                    if (pe.Name == "provider")
                    {
                        if (!pe.HasAttribute("guid"))
                        {
                            continue;
                        }

                        string attr = pe.GetAttribute("guid");
                        Guid   id   = new Guid(attr);

                        if (!_providerCache.ContainsKey(id))
                        {
                            _providerCache[id] = new ManifestInformation(doc, pe, stringTable);
                        }
                    }
                }

                _inited = true;
            }
            catch (Exception)
            {
                CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"Error processing ETW manifest {xmlFileName}");
                throw;
            }
        }
Пример #15
0
        private static int Main(string[] args)
        {
            ParserResult <CommandLineArguments> o = Parser.Default.ParseArguments <CommandLineArguments>(args);

            return(o.MapResult(
                       options =>
            {
                string currentFile = null;
                try
                {
                    //
                    // The CommandLineArguments library validates most input arguments for us,  there are few ones that are complicated
                    //    this secondary check looks for those and errors out if present
                    //
                    if (!options.IsValid())
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Invalid args");
                        return -1;
                    }


                    CLogConfigurationFile configFile = CLogConfigurationFile.FromFile(options.ConfigurationFile);
                    configFile.ProfileName = options.ConfigurationProfile;

                    if (options.ReadOnly && !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_FORCE_WRITABLE")))
                    {
                        options.ReadOnly = false;
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, "WARNING: CLOG was instructed via --readOnly not to emit changes however this was overridden with CLOG_FORCE_WRITABLE environment variable");
                    }

                    if (options.OverwriteHashCollisions || !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_OVERWRITE_COLLISIONS")))
                    {
                        options.OverwriteHashCollisions = true;
                        options.ReadOnly = false;
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "***********************************************");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Overwriting of sidecare collisions is set by environment variable CLOG_OVERWRITE_COLLISIONS.  This setting is only to be used while making large refactors and should not be included in build environments or standard development environments");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "***********************************************");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "");
                    }

                    if (options.Devmode || !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_DEVELOPMENT_MODE")))
                    {
                        options.ReadOnly = false;
                        options.OverwriteHashCollisions = true;
                        configFile.DeveloperMode = true;
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, "WARNING: CLOG was instructed to enter a developer mode");
                    }

                    if (options.LintConfig)
                    {
                        if (!configFile.MarkPhase)
                        {
                            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Lint operation only works on config files placed into the 'MarkPhase'.  This can be a destricutive action, please read the docs for more information");
                            return -10;
                        }
                        configFile.Lint();
                        configFile.Save(false);
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "Lint operation complete");
                        return 0;
                    }

                    if (options.UpgradeConfigFile)
                    {
                        configFile.UpdateVersion();
                        configFile.Save(false);
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "Config upgrade complete");
                        return 0;
                    }

                    CLogSidecar sidecar;
                    if (!Directory.Exists(Path.GetDirectoryName(options.SidecarFile)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(options.SidecarFile));
                    }

                    if (!File.Exists(options.SidecarFile))
                    {
                        sidecar = new CLogSidecar();
                    }
                    else
                    {
                        string json = File.ReadAllText(options.SidecarFile);
                        sidecar = CLogSidecar.FromJson(json);
                        if (null == sidecar)
                        {
                            sidecar = new CLogSidecar();
                        }
                    }
                    sidecar.SetConfigFile(configFile);


                    if (options.RefreshCustomTypeProcessor)
                    {
                        configFile.ForceDecoderCompile();
                        sidecar.Save(options.SidecarFile);
                        return 0;
                    }

                    //
                    // BUGBUG: refactoring needed for handling batches of input files, expecially
                    //    now that managed languages are coming along.  Leaving this unaddressed
                    //    for now while the best way is still elusive
                    //
                    List <ICLogBatchingModule> batchingModules = new List <ICLogBatchingModule>();

                    Console.WriteLine("Number of files : " + (new List <string>(options.InputFiles)).Count);

                    foreach (string inputFile in options.InputFiles)
                    {
                        Console.WriteLine("Processing: " + inputFile);
                        currentFile = inputFile;

                        string outputFile = options.GetOutputFileName(inputFile);
                        string outputCFile = Path.Combine(Path.GetDirectoryName(outputFile), options.ScopePrefix + "_" + Path.GetFileName(outputFile)) + ".c";

                        configFile.ScopePrefix = options.ScopePrefix;
                        configFile.FilePath = Path.GetFullPath(options.ConfigurationFile);
                        configFile.OverwriteHashCollisions = options.OverwriteHashCollisions;

                        //Delete the output file; we want to encourage build breaks if something goes wrong
                        if (File.Exists(outputFile))
                        {
                            File.Delete(outputFile);
                        }

                        if (File.Exists(outputCFile))
                        {
                            File.Delete(outputCFile);
                        }

                        CLogFileProcessor processor = new CLogFileProcessor(configFile);
                        CLogFullyDecodedMacroEmitter fullyDecodedMacroEmitter = new CLogFullyDecodedMacroEmitter(inputFile, sidecar);

                        fullyDecodedMacroEmitter.AddClogModule(sidecar);

                        CLogTraceLoggingOutputModule traceLoggingEmitter = new CLogTraceLoggingOutputModule();
                        fullyDecodedMacroEmitter.AddClogModule(traceLoggingEmitter);

                        CLogDTraceOutputModule dtrace = new CLogDTraceOutputModule();
                        fullyDecodedMacroEmitter.AddClogModule(dtrace);


                        CLogSysLogModule syslog = new CLogSysLogModule();
                        fullyDecodedMacroEmitter.AddClogModule(syslog);

                        CLogSTDOUT stdout = new CLogSTDOUT();
                        fullyDecodedMacroEmitter.AddClogModule(stdout);

                        CLogManifestedETWOutputModule manifestedEtwOutput = new CLogManifestedETWOutputModule(options.ReadOnly);
                        fullyDecodedMacroEmitter.AddClogModule(manifestedEtwOutput);

                        CLogLTTNGOutputModule lttngOutput = new CLogLTTNGOutputModule(inputFile, outputFile, outputFile + ".lttng.h", options.DynamicTracepointProvider);
                        fullyDecodedMacroEmitter.AddClogModule(lttngOutput);

                        if (!File.Exists(inputFile))
                        {
                            CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"Invalid Input File (file doesnt exist) : {inputFile}");
                            throw new CLogEnterReadOnlyModeException("InvalidInputFile", CLogHandledException.ExceptionType.InvalidInputFile, null);
                        }

                        CLogOutputInfo outputInfo = new CLogOutputInfo();
                        outputInfo.OutputDirectory = options.OutputDirectory;
                        outputInfo.OutputFileName = outputFile;
                        outputInfo.InputFileName = inputFile;

                        string content = File.ReadAllText(inputFile);
                        string output = processor.ConvertFile(configFile, outputInfo, fullyDecodedMacroEmitter, content, inputFile, false);

                        // TODO: BUGBUG - Java won't ever do this
                        //if (!content.Contains(Path.GetFileName(outputFile)))
                        //{
                        //    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"You must #include the clog output file {Path.GetFileName(outputFile)}");
                        //    throw new CLogEnterReadOnlyModeException("MustIncludeCLogHeader", CLogHandledException.ExceptionType.SourceMustIncludeCLOGHeader, null);
                        //}

                        fullyDecodedMacroEmitter.FinishedProcessing(outputInfo);

                        StringBuilder clogFile = new StringBuilder();

                        clogFile.AppendLine($"#ifndef CLOG_DO_NOT_INCLUDE_HEADER");
                        clogFile.AppendLine("#include <clog.h>");
                        clogFile.AppendLine($"#endif");


                        clogFile.Append(fullyDecodedMacroEmitter.HeaderInit);

                        foreach (var macro in processor.MacrosInUse)
                        {
                            clogFile.AppendLine($"#ifndef _clog_MACRO_{macro.MacroName}");
                            clogFile.AppendLine($"#define _clog_MACRO_{macro.MacroName}  1");
                            clogFile.AppendLine(
                                $"#define {macro.MacroName}(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))");
                            clogFile.AppendLine("#endif");
                        }

                        clogFile.AppendLine("#ifdef __cplusplus");
                        clogFile.AppendLine("extern \"C\" {");
                        clogFile.AppendLine("#endif");

                        clogFile.Append(fullyDecodedMacroEmitter.HeaderFile);
                        clogFile.AppendLine("#ifdef __cplusplus");
                        clogFile.AppendLine("}");
                        clogFile.AppendLine("#endif");

                        clogFile.AppendLine("#ifdef CLOG_INLINE_IMPLEMENTATION");
                        clogFile.AppendLine("#include \"" + Path.GetFileName(outputCFile) + "\"");
                        clogFile.AppendLine("#endif");

                        //
                        // BUGBUG : the intent in saving needs to be
                        //    1. delete any output files early - before we start, getting us into a safe state (build breaks)
                        //    2. save sidecars and other items that make assumptions about the emitted code
                        //    3. save emitted code
                        //
                        // the goal of these orderings is to be safe in the event of failure/crash
                        //
                        if (!Directory.Exists(Path.GetDirectoryName(outputFile)))
                        {
                            Console.WriteLine("Creating Directory for Output : " + Path.GetDirectoryName(outputFile));
                            Directory.CreateDirectory(Path.GetDirectoryName(outputFile));
                        }

                        if (sidecar.AreDirty || configFile.AreWeDirty())
                        {
                            if (options.ReadOnly)
                            {
                                if (sidecar.AreDirty)
                                {
                                    Console.WriteLine("Sidecar is dirty");
                                }
                                if (configFile.AreWeDirty())
                                {
                                    Console.WriteLine("ConfigFile is dirty");
                                }

                                sidecar.PrintDirtyReasons();
                                throw new CLogEnterReadOnlyModeException("WontWriteWhileInReadonlyMode:SideCar", CLogHandledException.ExceptionType.WontWriteInReadOnlyMode, null);
                            }
                            configFile.ForceDecoderCompile();
                            sidecar.Save(options.SidecarFile);
                        }

                        if (configFile.AreWeDirty() || configFile.AreWeInMarkPhase())
                        {
                            if (options.ReadOnly)
                            {
                                throw new CLogEnterReadOnlyModeException("WontWriteWhileInReadonlyMode:ConfigFile", CLogHandledException.ExceptionType.WontWriteInReadOnlyMode, null);
                            }
                            Console.WriteLine("Configuration file was updated, saving...");
                            Console.WriteLine($"    {configFile.FilePath}");
                            configFile.Save(false);
                        }

                        File.WriteAllText(outputFile, clogFile.ToString());
                        File.WriteAllText(outputCFile, fullyDecodedMacroEmitter.SourceFile);
                    }
                    currentFile = null;

                    //
                    // Enumerate batching modules, allowing them to save
                    //
                    foreach (var m in batchingModules)
                    {
                        CLogOutputInfo outputInfo = new CLogOutputInfo();
                        outputInfo.OutputDirectory = options.OutputDirectory;
                        m.FinishedBatch(outputInfo);
                    }
                }
                catch (CLogHandledException e)
                {
                    if (null != currentFile)
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"Failure in file : {currentFile}");
                    }
                    e.PrintDiagnostics(options.VerboseErrors);
                    return -2;
                }
                catch (Exception e)
                {
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"---------------------------------------------------------------------------");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"CLOG has crashed processing : {currentFile}.");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"   if you're reading this, we consider seeing this message a bug.  Even if the message");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"   you're about to read is sufficient to diagnose, we'd like to improve the user experience");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"   please consider filing a bug, with repro files and --verboseErrors");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"");
                    CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"Exception:");

                    if (!options.VerboseErrors)
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "    " + e.Message);
                        return -1;
                    }
                    else
                    {
                        CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, e.ToString());
                    }
                }

                return 0;
            }, err =>
            {
                Console.WriteLine("Bad Args : " + err);
                return -1;
            }));
        }