public void BuildCache(string targetDir, string[] traces, string[] metadaFiles) { List <string> extraAssembies = new List <string>(); foreach (string f in metadaFiles.Concat(traces)) { string output = Path.Combine(GetCacheDir(targetDir), Path.ChangeExtension( Path.GetFileName(f), ".dll")); DateTime metadataTimestamp = File.GetLastWriteTimeUtc(f); DateTime outputTimestamp = File.GetLastWriteTimeUtc(output); if (outputTimestamp == metadataTimestamp) { continue; } var sources = new Dictionary <string, string>(); switch (Path.GetExtension(f).ToLower()) { case ".man": case ".manifest": { string manifest = File.ReadAllText(f); Dictionary <string, string> s = ManifestParser.Parse(manifest); foreach (string type in s.Keys) { if (!sources.ContainsKey(type)) { sources.Add(type, s[type]); } } break; } case ".etl": { string[] manifests = ManifestParser.ExtractFromTrace(f); if (manifests.Length == 0) { continue; } foreach (string manifest in manifests) { Dictionary <string, string> s; try { s = ManifestParser.Parse(manifest); } catch (XmlException ex) { // if one manifest is bad, we should still see the other events string err = String.Format( "Malformed manifest found in the file {0}\nThe corresponding events will not be shown in the tree-control. \nHere are the first 1000 characters: \n\n{1}", f, manifest.Substring(0, 1000)); MessageBox.Show(err, "Tx LINQPad Driver"); continue; } foreach (string type in s.Keys) { if (!sources.ContainsKey(type)) { sources.Add(type, s[type]); } } } } break; case ".blg": case ".csv": case ".tsv": { Dictionary <string, string> s = PerfCounterParser.Parse(f); foreach (string type in s.Keys) { if (!sources.ContainsKey(type)) { sources.Add(type, s[type]); } } } break; case ".evtx": break; case ".xel": { extraAssembies.Add(typeof(XEventAttribute).Assembly.Location); extraAssembies.Add(typeof(CallStack).Assembly.Location); Dictionary <string, string> s = XeTypeGenerator.Parse(f); foreach (string type in s.Keys) { if (!sources.ContainsKey(type)) { sources.Add(type, s[type]); } } } break; default: throw new Exception("Unknown metadata format " + f); } AssemblyBuilder.OutputAssembly(sources, extraAssembies, output); File.SetLastWriteTimeUtc(output, metadataTimestamp); } }
private static void Parse(string[] args) { if (args.Length == 0) { Console.WriteLine( @"Usage: EtwEventTypeGen [/o:dir] [/a:name] [/m:file] [/e:file] [/t:file] [/w:path] Switches: /o:dir Directory for the output. If missing, the output is written to the current directory /a:name Generate Assembly. If missing the output is C# files. /m:manifest Input from manifest(s) /e:etl Input from eventsource etl(s) that contain manifests /t:tmf Input from TMF file(s) /p:file.blg Input from performance counter trace The switches /o and /a must occur at most once. The switches /m /t can occur many times. At least one of these switches must be present Examples: EtwEventTypeGen /m:Microsoft-Windows-HttpService.man EtwEventTypeGen /o:c:\Code\EventTypes /m:*.man EtwEventTypeGen /a:MyEventTypes /t:c:\tmfs\*.tmf /m:*.man EtwEventTypeGen /a:WmiTypes /w:root\wmi\EventTrace\MSNT_SystemTrace "); Environment.Exit(0); } foreach (string arg in args) { string name = arg.Substring(0, 3); string value = arg.Substring(3); switch (name) { case "/a:": if (!String.IsNullOrEmpty(assembly)) { Console.WriteLine("The assembly switch /a: occurs more than once."); Environment.Exit(1); } assembly = value; break; case "/o:": if (!String.IsNullOrEmpty(outputDirectory)) { Console.WriteLine("The output directory switch /o: occurs more than once."); Environment.Exit(1); } outputDirectory = value; break; case "/m:": string[] manifests; string manifestDir = Path.GetDirectoryName(value); if (String.IsNullOrEmpty(manifestDir)) { manifests = Directory.GetFiles(".", value); } else { manifests = Directory.GetFiles( manifestDir, Path.GetFileName(value)); } foreach (string manifest in manifests) { string content = File.ReadAllText(manifest); Dictionary <string, string> code = ManifestParser.Parse(content); foreach (string provider in code.Keys) { generated.Add(provider, code[provider]); } } break; case "/e:": string[] etlFiles; string etlDir = Path.GetDirectoryName(value); if (String.IsNullOrEmpty(etlDir)) { etlFiles = Directory.GetFiles(".", value); } else { etlFiles = Directory.GetFiles( etlDir, Path.GetFileName(value)); } foreach (string etlFile in etlFiles) { string[] etlManifests = ManifestParser.ExtractFromTrace(etlFile); if (etlManifests != null && etlManifests.Length > 0) { int i = 0; foreach (string content in etlManifests) { Dictionary <string, string> code = ManifestParser.Parse(content); foreach (string provider in code.Keys) { generated.Add(provider, code[provider]); } // Write the manifest text file using (TextWriter wr = new StreamWriter(Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(etlFile) + "_" + i.ToString() + ".man"))) { wr.Write(content); } } } else { Console.WriteLine("No manifest found in file:{0}", etlFile); } } break; case "/t:": string[] tmfs; string tmfDir = Path.GetDirectoryName(value); if (String.IsNullOrEmpty(tmfDir)) { tmfs = Directory.GetFiles(".", value); } else { tmfs = Directory.GetFiles( tmfDir, Path.GetFileName(value)); } foreach (string tmf in tmfs) { Console.WriteLine(tmf); string provider = Path.GetFileNameWithoutExtension(tmf); string code = TmfParser.Parse(tmf); generated.Add(provider, code); } break; case "/p:": string[] perfTraces; string perfDir = Path.GetDirectoryName(value); if (String.IsNullOrEmpty(perfDir)) { perfTraces = Directory.GetFiles(".", value); } else { perfTraces = Directory.GetFiles( perfDir, Path.GetFileName(value)); } foreach (string perfTrace in perfTraces) { Console.WriteLine(perfTrace); Dictionary <string, string> code = PerfCounterParser.Parse(perfTrace); foreach (string provider in code.Keys) { generated.Add(provider, code[provider]); } } break; case "/w:": Console.WriteLine("The WMI switch /w: is not yet implemented."); Environment.Exit(2); break; default: Console.WriteLine("Unknown switch " + arg); Environment.Exit(1); break; } } }
public void BuildCache(string targetDir, string[] traces, string[] metadaFiles) { List <string> extraAssembies = new List <string>(); foreach (string f in metadaFiles.Concat(traces)) { string output = Path.Combine(GetCacheDir(targetDir), Path.ChangeExtension( Path.GetFileName(f), ".dll")); DateTime metadataTimestamp = File.GetLastWriteTimeUtc(f); DateTime outputTimestamp = File.GetLastWriteTimeUtc(output); if (outputTimestamp == metadataTimestamp) { continue; } var sources = new Dictionary <string, string>(); switch (Path.GetExtension(f).ToLower()) { case ".man": { string manifest = File.ReadAllText(f); Dictionary <string, string> s = ManifestParser.Parse(manifest); foreach (string type in s.Keys) { if (!sources.ContainsKey(type)) { sources.Add(type, s[type]); } } break; } case ".etl": { string[] manifests = ManifestParser.ExtractFromTrace(f); if (manifests.Length == 0) { continue; } foreach (string manifest in manifests) { Dictionary <string, string> s = ManifestParser.Parse(manifest); foreach (string type in s.Keys) { if (!sources.ContainsKey(type)) { sources.Add(type, s[type]); } } } } break; case ".blg": case ".csv": case ".tsv": { Dictionary <string, string> s = PerfCounterParser.Parse(f); foreach (string type in s.Keys) { if (!sources.ContainsKey(type)) { sources.Add(type, s[type]); } } } break; case ".evtx": break; case ".xel": { extraAssembies.Add(typeof(XEventAttribute).Assembly.Location); extraAssembies.Add(typeof(CallStack).Assembly.Location); Dictionary <string, string> s = XeTypeGenerator.Parse(f); foreach (string type in s.Keys) { if (!sources.ContainsKey(type)) { sources.Add(type, s[type]); } } } break; default: throw new Exception("Unknown metadata format " + f); } AssemblyBuilder.OutputAssembly(sources, extraAssembies, output); File.SetLastWriteTimeUtc(output, metadataTimestamp); } }