Ejemplo n.º 1
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;
            }));
        }
Ejemplo n.º 2
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;
            }));
        }
Ejemplo n.º 3
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;
            }));
        }
Ejemplo n.º 4
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;
            }));
        }
Ejemplo n.º 5
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;
            }));
        }