/// <summary> /// Annotates the specified span with the given labels. /// </summary> private void AnnotateSpan(TraceSpan span, Dictionary <string, string> labels) { foreach (var l in labels) { span.Labels.Add(l.Key, l.Value); } }
public void OnActionExecuted(ActionExecutedContext context) { traceSpan = TraceContext.Get(); traceSpan.duration = DateTime.Now.ToUnixTimestamp() - traceSpan.timestamp; //运行时间 traceSpan.tags.Add("status", "200"); if (context.Exception != null) { Result result = null; if (context.Exception is ChecksException ce) //验证异常(业务) { result = Result.Fail(ce.Code, ce.Message); traceSpan.tags.Add("checks", context.Exception.ToString()); } else if (context.Exception is QueueException qe) //消息队列异常(业务) { result = Result.Fail(qe.Code, qe.Message); traceSpan.tags.Add("queues", context.Exception.ToString()); traceSpan.tags["status"] = "500"; } else { result = Result.Fail(500, "服务器连接错误"); traceSpan.tags.Add("error", context.Exception.ToString()); traceSpan.tags["status"] = "500"; } context.ExceptionHandled = true; context.Result = new ObjectResult(result); } Log.Info(traceSpan.ToJson()); }
/// <summary> /// Verifies that the span contains the set of expected labels. /// The span can have other labels. /// </list> /// </summary> /// <param name="span">The span to check.</param> /// <param name="expectedLabels">The set of labels expected to be present on the span.</param> public static void AssertSpanLabelsContains(TraceSpan span, IDictionary <string, string> expectedLabels) { foreach (var keyValue in expectedLabels) { Assert.Equal(keyValue.Value, span.Labels[keyValue.Key]); } }
public void Span_EnsureVisibleDuration_LongSpan(int startSeconds, int startNanos, int endSeconds, int endNanos) { var tracer = SimpleManagedTracer.Create(new NoOpConsumer(), ProjectId, TraceId); var traceSpan = new TraceSpan { StartTime = new Timestamp { Seconds = startSeconds, Nanos = startNanos }, EndTime = new Timestamp { Seconds = endSeconds, Nanos = endNanos } }; var span = new SimpleManagedTracer.Span(tracer, traceSpan); span.EnsureVisibleDuration(); Assert.Equal(startSeconds, traceSpan.StartTime.Seconds); Assert.Equal(startNanos, traceSpan.StartTime.Nanos); Assert.Equal(endSeconds, traceSpan.EndTime.Seconds); Assert.Equal(endNanos, traceSpan.EndTime.Nanos); }
/// <summary> /// Constructor /// </summary> /// <param name="Name">Event name</param> /// <param name="StartTime">Time of the event</param> /// <param name="FinishTime">Finish time for the event. May be null.</param> public Event(string Name, TimeSpan StartTime, TimeSpan?FinishTime) { this.Name = Name; this.StartTime = StartTime; this.FinishTime = FinishTime; this.Span = TraceSpan.Create(Name); }
public void Span_EnsureVisibleDuration_ShortSpan(int startSeconds, int startNanos, int endSeconds, int endNanos) { var tracer = SimpleManagedTracer.Create(new NoOpConsumer(), ProjectId, TraceId); var traceSpan = new TraceSpan { StartTime = new Timestamp { Seconds = startSeconds, Nanos = startNanos }, EndTime = new Timestamp { Seconds = endSeconds, Nanos = endNanos } }; var span = new SimpleManagedTracer.Span(tracer, traceSpan); span.EnsureVisibleDuration(); Assert.True(IsNormalized(span.TraceSpan.StartTime)); Assert.True(IsNormalized(span.TraceSpan.EndTime)); Assert.True(IsAtLeast1MsSpan(span.TraceSpan)); }
/// <inheritdoc /> public IDisposable StartSpan(string name, StartSpanOptions options = null) { GaxPreconditions.CheckNotNull(name, nameof(name)); options = options ?? StartSpanOptions.Create(); TraceSpan span = new TraceSpan(); span.SpanId = _spanIdFactory.NextId(); span.Kind = options.SpanKind.Convert(); span.Name = name; span.StartTime = Timestamp.FromDateTime(DateTime.Now.ToUniversalTime()); lock (_stackLock) { if (_traceStack.Count != 0) { span.ParentSpanId = _traceStack.Peek().SpanId; } else if (_rootSpanParentId != null) { span.ParentSpanId = (ulong)_rootSpanParentId; } _traceStack.Push(span); AnnotateSpan(options.Labels); } return(new Span(this)); }
public void Trace_MultipleSpans() { string rootSpanName = EntryData.GetMessage(nameof(Trace_MultipleSpans), _testId); var labels = new Dictionary <string, string> { { "annotation-key", "annotation-value" } }; var tracer = CreateSimpleManagedTracer(_grpcConsumer); using (tracer.StartSpan(rootSpanName)) { BlockUntilClockTick(); using (tracer.StartSpan("child-one")) { tracer.SetStackTrace(TraceEntryData.CreateStackTrace()); BlockUntilClockTick(); } using (tracer.StartSpan("child-two")) { BlockUntilClockTick(); using (tracer.StartSpan("grandchild-one", StartSpanOptions.Create(SpanKind.RpcClient))) { BlockUntilClockTick(); } using (tracer.StartSpan("grandchild-two")) { BlockUntilClockTick(); tracer.AnnotateSpan(labels); } } } TraceProto trace = TraceEntryPolling.Default.GetTrace(rootSpanName, _startTime); Assert.NotNull(trace); Assert.Equal(5, trace.Spans.Count); TraceSpan root = trace.Spans.First(s => s.Name.Equals(rootSpanName)); TraceSpan childOne = trace.Spans.First(s => s.Name.Equals("child-one")); TraceSpan childTwo = trace.Spans.First(s => s.Name.Equals("child-two")); TraceSpan grandchildOne = trace.Spans.First(s => s.Name.Equals("grandchild-one")); TraceSpan grandchildTwo = trace.Spans.First(s => s.Name.Equals("grandchild-two")); Assert.Equal(root.SpanId, childOne.ParentSpanId); TraceEntryVerifiers.AssertContainsStackTrace(childOne, nameof(TraceEntryData.CreateStackTrace), nameof(SimpleManagedTracerTest)); Assert.Equal(root.SpanId, childTwo.ParentSpanId); Assert.Equal(childTwo.SpanId, grandchildOne.ParentSpanId); Assert.Equal(TraceSpan.Types.SpanKind.RpcClient, grandchildOne.Kind); Assert.Equal(childTwo.SpanId, grandchildTwo.ParentSpanId); Assert.Equal(TraceSpan.Types.SpanKind.Unspecified, grandchildTwo.Kind); TraceEntryVerifiers.AssertSpanLabelsExact(grandchildTwo, labels); }
/// <summary> /// Used to ensure a <see cref="TraceSpan"/>'s that starts ends immediately /// has a total run time of 1ms. /// /// This is needed as we set the length to 1ms for spans that do not have /// a difference of 1ms between start and end. If we do not the Trace /// API will not record the span. /// </summary> private static bool IsAtLeast1MsSpan(TraceSpan span) { var duration = span.EndTime - span.StartTime; return(duration.Seconds >= 1 || // Checking Seconds again to avoid returning true for cases // in which StartTime is greater than EndTime. (duration.Seconds == 0 && duration.Nanos >= 1_000_000)); }
public void Trace_MultipleSpans() { string rootSpanName = CreateRootSpanName(nameof(Trace_MultipleSpans)); var consumer = CreateGrpcTraceConsumer(); var tracer = CreateSimpleManagedTracer(consumer); var annotation = new Dictionary <string, string> { { "annotation-key", "annotation-value" } }; tracer.StartSpan(rootSpanName); BlockUntilClockTick(); tracer.StartSpan("child-one"); tracer.SetStackTrace(new StackTrace(CreateException(), true)); BlockUntilClockTick(); tracer.EndSpan(); tracer.StartSpan("child-two"); BlockUntilClockTick(); tracer.StartSpan("grandchild-one", StartSpanOptions.Create(SpanKind.RpcClient)); BlockUntilClockTick(); tracer.EndSpan(); tracer.StartSpan("grandchild-two"); BlockUntilClockTick(); tracer.AnnotateSpan(annotation); tracer.EndSpan(); tracer.EndSpan(); tracer.EndSpan(); TraceProto trace = _polling.GetTrace(rootSpanName, _startTime); Assert.NotNull(trace); Assert.Equal(5, trace.Spans.Count); TraceSpan root = trace.Spans.First(s => s.Name.Equals(rootSpanName)); TraceSpan childOne = trace.Spans.First(s => s.Name.Equals("child-one")); TraceSpan childTwo = trace.Spans.First(s => s.Name.Equals("child-two")); TraceSpan grandchildOne = trace.Spans.First(s => s.Name.Equals("grandchild-one")); TraceSpan grandchildTwo = trace.Spans.First(s => s.Name.Equals("grandchild-two")); Assert.Equal(root.SpanId, childOne.ParentSpanId); var labels = childOne.Labels; Assert.True(labels.ContainsKey(TraceLabels.StackTrace)); Assert.Contains(nameof(CreateException), labels[TraceLabels.StackTrace]); Assert.Contains(nameof(SimpleManagedTracerTest), labels[TraceLabels.StackTrace]); Assert.Equal(root.SpanId, childTwo.ParentSpanId); Assert.Equal(childTwo.SpanId, grandchildOne.ParentSpanId); Assert.Equal(TraceSpan.Types.SpanKind.RpcClient, grandchildOne.Kind); Assert.Equal(childTwo.SpanId, grandchildTwo.ParentSpanId); Assert.Equal(TraceSpan.Types.SpanKind.Unspecified, grandchildTwo.Kind); Assert.True(TraceUtils.IsValidAnnotation(grandchildTwo, annotation)); }
/// <summary> /// Verifies that a span contains a StackTrace label whose value contains /// the specified texts. /// </summary> public static void AssertContainsStackTrace(TraceSpan span, params string[] textContained) { var labelValue = span.Labels[TraceLabels.StackTrace]; Assert.False(string.IsNullOrWhiteSpace(labelValue)); foreach (var text in textContained) { labelValue.Contains(text); } }
private static bool IsValidSpan(TraceSpan span, string name, ulong parentId, SpanKind kind) { return(span.SpanId != 0 && kind.Convert() == span.Kind && name.Equals(span.Name) && span.StartTime != null && parentId == span.ParentSpanId && span.EndTime != null && span.StartTime.ToDateTime() <= span.EndTime.ToDateTime()); }
/// <inheritdoc /> public void AnnotateSpan(Dictionary <string, string> labels) { GaxPreconditions.CheckNotNull(labels, nameof(labels)); lock (_stackLock) { CheckStackNotEmpty(); TraceSpan span = _traceStack.Peek(); foreach (var l in labels) { span.Labels.Add(l.Key, l.Value); } } }
/// <inheritdoc /> public void EndSpan() { lock (_stackLock) { CheckStackNotEmpty(); TraceSpan span = _traceStack.Pop(); span.EndTime = Timestamp.FromDateTime(DateTime.Now.ToUniversalTime()); _trace.Spans.Add(span); if (_traceStack.Count == 0) { Flush(); } } }
/// <summary> /// Checks if a span's labels are are equal to a dictionary strings. /// </summary> internal static bool IsValidAnnotation(TraceSpan span, Dictionary <string, string> annotation) { var labels = span.Labels; if (labels.Count != annotation.Count) { return(false); } foreach (KeyValuePair <string, string> label in labels) { if (String.Compare(label.Value, annotation[label.Key]) != 0) { return(false); } } return(true); }
/// <inheritdoc /> public IDisposable StartSpan(string name, StartSpanOptions options = null) { GaxPreconditions.CheckNotNull(name, nameof(name)); options = options ?? StartSpanOptions.Create(); var currentStack = TraceStack; var span = new TraceSpan { SpanId = _spanIdFactory.NextId(), Kind = options.SpanKind.Convert(), Name = name, StartTime = Timestamp.FromDateTime(DateTime.UtcNow), ParentSpanId = GetCurrentSpanId(currentStack).GetValueOrDefault() }; AnnotateSpan(span, options.Labels); TraceStack = currentStack.Push(span); Interlocked.Increment(ref _openSpanCount); return(new Span(this)); }
public void OnActionExecuting(ActionExecutingContext context) { //初始化日志 TraceSpan traceSpan = TraceContext.CreateTrace(); traceSpan.parentId = context.HttpContext.Request.Headers[ZipkinTraceConstants.HeaderSpanId]; var traceId = context.HttpContext.Request.Headers[ZipkinTraceConstants.HseaderTraceId].ToString(); if (!traceId.IsNullOrEmpty()) { traceSpan.traceId = traceId; } traceSpan.timestamp = DateTime.Now.ToUnixTimestamp(); traceSpan.timestamp_millis = DateTime.Now.ToTimestamp(); traceSpan.name = context.HttpContext.Request.Path; traceSpan.kind = "SERVER"; traceSpan.localEndpoint.serviceName = "pay"; #region 日志信息 traceSpan.tags.Add("http.url", $"{context.HttpContext.Request.Host.Value}"); traceSpan.tags.Add("http.path", $"{context.HttpContext.Request.Host.Value}{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString}"); #endregion traceSpan.tags.Add("request.body", context.HttpContext.Request.ToReadAsyncJson()); traceSpan.tags.Add("group", $"http"); }
/// <summary> /// Build all the tasks for this node /// </summary> /// <param name="Job">Information about the current job</param> /// <param name="TagNameToFileSet">Mapping from tag names to the set of files they include. Should be set to contain the node inputs on entry.</param> /// <returns>Whether the task succeeded or not. Exiting with an exception will be caught and treated as a failure.</returns> public bool Build(JobContext Job, Dictionary <string, HashSet <FileReference> > TagNameToFileSet) { // Run each of the tasks in order HashSet <FileReference> BuildProducts = TagNameToFileSet[DefaultOutput.TagName]; for (int Idx = 0; Idx < Tasks.Count; Idx++) { using (ITraceSpan Span = TraceSpan.Create("Task", Tasks[Idx].GetTraceName())) { ITaskExecutor Executor = Tasks[Idx].GetExecutor(); if (Executor == null) { // Execute this task directly try { Tasks[Idx].GetTraceMetadata(Span, ""); Tasks[Idx].Execute(Job, BuildProducts, TagNameToFileSet); } catch (Exception Ex) { ExceptionUtils.AddContext(Ex, "while executing task {0}", Tasks[Idx].GetTraceString()); if (Tasks[Idx].SourceLocation != null) { ExceptionUtils.AddContext(Ex, "at {0}({1})", GetReadablePathForDiagnostics(Tasks[Idx].SourceLocation.Item1), Tasks[Idx].SourceLocation.Item2); } throw; } } else { Tasks[Idx].GetTraceMetadata(Span, "1."); // The task has a custom executor, which may be able to execute several tasks simultaneously. Try to add the following tasks. int FirstIdx = Idx; while (Idx + 1 < Tasks.Count && Executor.Add(Tasks[Idx + 1])) { Idx++; Tasks[Idx].GetTraceMetadata(Span, string.Format("{0}.", 1 + Idx - FirstIdx)); } try { Executor.Execute(Job, BuildProducts, TagNameToFileSet); } catch (Exception Ex) { for (int TaskIdx = FirstIdx; TaskIdx <= Idx; TaskIdx++) { ExceptionUtils.AddContext(Ex, "while executing {0}", Tasks[TaskIdx].GetTraceString()); } if (Tasks[FirstIdx].SourceLocation != null) { ExceptionUtils.AddContext(Ex, "at {0}({1})", GetReadablePathForDiagnostics(Tasks[FirstIdx].SourceLocation.Item1), Tasks[FirstIdx].SourceLocation.Item2); } throw; } } } } // Remove anything that doesn't exist, since these files weren't explicitly tagged BuildProducts.RemoveWhere(x => !FileReference.Exists(x)); return(true); }
public async Task SendAsync(TraceSpan traceSpan) { await _eventBus.PublishAsync(new TracerEvent(traceSpan)); }
/// <summary> /// Main entry point. Parses any global options and initializes the logging system, then invokes the appropriate command. /// </summary> /// <param name="ArgumentsArray">Command line arguments</param> /// <returns>Zero on success, non-zero on error</returns> private static int Main(string[] ArgumentsArray) { SingleInstanceMutex Mutex = null; try { // Start capturing performance info Timeline.Start(); // Parse the command line arguments CommandLineArguments Arguments = new CommandLineArguments(ArgumentsArray); // Parse the global options GlobalOptions Options = new GlobalOptions(Arguments); // Configure the log system Log.OutputLevel = Options.LogOutputLevel; Log.IncludeTimestamps = Options.bLogTimestamps; Log.IncludeProgramNameWithSeverityPrefix = Options.bLogFromMsBuild; // Configure the progress writer ProgressWriter.bWriteMarkup = Options.bWriteProgressMarkup; // Add the log writer if requested. When building a target, we'll create the writer for the default log file later. if (Options.LogFileName != null) { Log.AddFileWriter("LogTraceListener", Options.LogFileName); } // Ensure we can resolve any external assemblies that are not in the same folder as our assembly. AssemblyUtils.InstallAssemblyResolver(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation())); // Change the working directory to be the Engine/Source folder. We are likely running from Engine/Binaries/DotNET // This is critical to be done early so any code that relies on the current directory being Engine/Source will work. DirectoryReference.SetCurrentDirectory(UnrealBuildTool.EngineSourceDirectory); // Get the type of the mode to execute, using a fast-path for the build mode. Type ModeType = typeof(BuildMode); if (Options.Mode != null) { // Find all the valid modes Dictionary <string, Type> ModeNameToType = new Dictionary <string, Type>(StringComparer.OrdinalIgnoreCase); foreach (Type Type in Assembly.GetExecutingAssembly().GetTypes()) { if (Type.IsClass && !Type.IsAbstract && Type.IsSubclassOf(typeof(ToolMode))) { ToolModeAttribute Attribute = Type.GetCustomAttribute <ToolModeAttribute>(); if (Attribute == null) { throw new BuildException("Class '{0}' should have a ToolModeAttribute", Type.Name); } ModeNameToType.Add(Attribute.Name, Type); } } // Try to get the correct mode if (!ModeNameToType.TryGetValue(Options.Mode, out ModeType)) { Log.TraceError("No mode named '{0}'. Available modes are:\n {1}", Options.Mode, String.Join("\n ", ModeNameToType.Keys)); return(1); } } // Get the options for which systems have to be initialized for this mode ToolModeOptions ModeOptions = ModeType.GetCustomAttribute <ToolModeAttribute>().Options; // Start prefetching the contents of the engine folder if ((ModeOptions & ToolModeOptions.StartPrefetchingEngine) != 0) { using (Timeline.ScopeEvent("FileMetadataPrefetch.QueueEngineDirectory()")) { FileMetadataPrefetch.QueueEngineDirectory(); } } // Read the XML configuration files if ((ModeOptions & ToolModeOptions.XmlConfig) != 0) { using (Timeline.ScopeEvent("XmlConfig.ReadConfigFiles()")) { string XmlConfigMutexName = SingleInstanceMutex.GetUniqueMutexForPath("UnrealBuildTool_Mutex_XmlConfig", Assembly.GetExecutingAssembly().CodeBase); using (SingleInstanceMutex XmlConfigMutex = new SingleInstanceMutex(XmlConfigMutexName, true)) { FileReference XmlConfigCache = Arguments.GetFileReferenceOrDefault("-XmlConfigCache=", null); XmlConfig.ReadConfigFiles(XmlConfigCache); } } } // Acquire a lock for this branch if ((ModeOptions & ToolModeOptions.SingleInstance) != 0 && !Options.bNoMutex) { using (Timeline.ScopeEvent("SingleInstanceMutex.Acquire()")) { string MutexName = SingleInstanceMutex.GetUniqueMutexForPath("UnrealBuildTool_Mutex", Assembly.GetExecutingAssembly().CodeBase); Mutex = new SingleInstanceMutex(MutexName, Options.bWaitMutex); } } // Register all the build platforms if ((ModeOptions & ToolModeOptions.BuildPlatforms) != 0) { using (Timeline.ScopeEvent("UEBuildPlatform.RegisterPlatforms()")) { UEBuildPlatform.RegisterPlatforms(false, false); } } if ((ModeOptions & ToolModeOptions.BuildPlatformsHostOnly) != 0) { using (Timeline.ScopeEvent("UEBuildPlatform.RegisterPlatforms()")) { UEBuildPlatform.RegisterPlatforms(false, true); } } if ((ModeOptions & ToolModeOptions.BuildPlatformsForValidation) != 0) { using (Timeline.ScopeEvent("UEBuildPlatform.RegisterPlatforms()")) { UEBuildPlatform.RegisterPlatforms(true, false); } } // Create the appropriate handler ToolMode Mode = (ToolMode)Activator.CreateInstance(ModeType); // Execute the mode int Result = Mode.Execute(Arguments); if ((ModeOptions & ToolModeOptions.ShowExecutionTime) != 0) { Log.TraceInformation("Total execution time: {0:0.00} seconds", Timeline.Elapsed.TotalSeconds); } return(Result); } catch (CompilationResultException Ex) { // Used to return a propagate a specific exit code after an error has occurred. Does not log any message. Log.TraceLog(ExceptionUtils.FormatExceptionDetails(Ex)); return((int)Ex.Result); } catch (BuildException Ex) { // BuildExceptions should have nicely formatted messages. We can log these directly. Log.TraceError(ExceptionUtils.FormatException(Ex)); Log.TraceLog(ExceptionUtils.FormatExceptionDetails(Ex)); return((int)CompilationResult.OtherCompilationError); } catch (Exception Ex) { // Unhandled exception. Log.TraceError("Unhandled exception: {0}", ExceptionUtils.FormatException(Ex)); Log.TraceLog(ExceptionUtils.FormatExceptionDetails(Ex)); return((int)CompilationResult.OtherCompilationError); } finally { // Cancel the prefetcher using (Timeline.ScopeEvent("FileMetadataPrefetch.Stop()")) { FileMetadataPrefetch.Stop(); } // Print out all the performance info Timeline.Print(TimeSpan.FromMilliseconds(20.0), LogEventType.Log); // Make sure we flush the logs however we exit Trace.Close(); // Write any trace logs TraceSpan.Flush(); // Dispose of the mutex. Must be done last to ensure that another process does not startup and start trying to write to the same log file. if (Mutex != null) { Mutex.Dispose(); } } }
public TracerEvent(TraceSpan traceSpan) { this.Id = Guid.NewGuid(); this.Timestamp = DateTime.UtcNow; this.TraceSpan = traceSpan; }
/// <summary> /// Verifies that the span has the exact set of expected labels. /// </list> /// </summary> /// <param name="span">The spna to check.</param> /// <param name="expectedLabels">The set of labels expected to be present on the span.</param> public static void AssertSpanLabelsExact(TraceSpan span, IDictionary <string, string> expectedLabels) { Assert.Equal(expectedLabels.Count, span.Labels.Count); AssertSpanLabelsContains(span, expectedLabels); }
/// <summary> /// Main method. /// </summary> /// <param name="Arguments">Command line</param> public static ExitCode Process(string[] Arguments, StartupTraceListener StartupListener) { // Initial check for local or build machine runs BEFORE we parse the command line (We need this value set // in case something throws the exception while parsing the command line) IsBuildMachine = Arguments.Any(x => x.Equals("-BuildMachine", StringComparison.InvariantCultureIgnoreCase)); if (!IsBuildMachine) { int Value; if (int.TryParse(Environment.GetEnvironmentVariable("IsBuildMachine"), out Value) && Value != 0) { IsBuildMachine = true; } } Log.TraceVerbose("IsBuildMachine={0}", IsBuildMachine); Environment.SetEnvironmentVariable("IsBuildMachine", IsBuildMachine ? "1" : "0"); // Scan the command line for commands to execute. var CommandsToExecute = new List <CommandInfo>(); string OutScriptsForProjectFileName; var AdditionalScriptsFolders = new List <string>(); ParseCommandLine(Arguments, CommandsToExecute, out OutScriptsForProjectFileName, AdditionalScriptsFolders); // Get the path to the telemetry file, if present string TelemetryFile = CommandUtils.ParseParamValue(Arguments, "-Telemetry"); // should we kill processes on exit ShouldKillProcesses = !GlobalCommandLine.NoKill; Log.TraceVerbose("ShouldKillProcesses={0}", ShouldKillProcesses); if (CommandsToExecute.Count == 0 && GlobalCommandLine.Help) { DisplayHelp(); return(ExitCode.Success); } // Disable AutoSDKs if specified on the command line if (GlobalCommandLine.NoAutoSDK) { PlatformExports.PreventAutoSDKSwitching(); } // Setup environment Log.TraceLog("Setting up command environment."); CommandUtils.InitCommandEnvironment(); // Create the log file, and flush the startup listener to it TraceListener LogTraceListener = LogUtils.AddLogFileListener(CommandUtils.CmdEnv.LogFolder, CommandUtils.CmdEnv.FinalLogFolder); StartupListener.CopyTo(LogTraceListener); Trace.Listeners.Remove(StartupListener); // Initialize UBT if (!UnrealBuildTool.PlatformExports.Initialize()) { Log.TraceInformation("Failed to initialize UBT"); return(ExitCode.Error_Unknown); } // Clean rules folders up ProjectUtils.CleanupFolders(); // Compile scripts. using (TelemetryStopwatch ScriptCompileStopwatch = new TelemetryStopwatch("ScriptCompile")) { ScriptCompiler.FindAndCompileAllScripts(OutScriptsForProjectFileName, AdditionalScriptsFolders); } if (GlobalCommandLine.CompileOnly) { Log.TraceInformation("Compilation successful, exiting (CompileOnly)"); return(ExitCode.Success); } if (GlobalCommandLine.List) { ListAvailableCommands(ScriptCompiler.Commands); return(ExitCode.Success); } if (GlobalCommandLine.Help) { DisplayHelp(CommandsToExecute, ScriptCompiler.Commands); return(ExitCode.Success); } // Enable or disable P4 support CommandUtils.InitP4Support(CommandsToExecute, ScriptCompiler.Commands); if (CommandUtils.P4Enabled) { Log.TraceLog("Setting up Perforce environment."); CommandUtils.InitP4Environment(); CommandUtils.InitDefaultP4Connection(); } try { // Find and execute commands. ExitCode Result = Execute(CommandsToExecute, ScriptCompiler.Commands); if (TelemetryFile != null) { Directory.CreateDirectory(Path.GetDirectoryName(TelemetryFile)); CommandUtils.Telemetry.Write(TelemetryFile); } return(Result); } finally { // Flush any timing data TraceSpan.Flush(); } }
private static bool IsValidSpan(TraceSpan span, string name) => IsValidSpan(span, name, 0);
private static bool IsValidSpan(TraceSpan span, string name, ulong parentId) => IsValidSpan(span, name, parentId, SpanKind.Unspecified);
internal Span(SimpleManagedTracer tracer, TraceSpan traceSpan) { _tracer = GaxPreconditions.CheckNotNull(tracer, nameof(tracer)); TraceSpan = GaxPreconditions.CheckNotNull(traceSpan, nameof(traceSpan)); }
/// <summary> /// Used to ensure a <see cref="TraceSpan"/>'s that starts ends immediately /// has a total run time of 1ms. /// /// This is needed as we set the length to 1ms for spans that do not have /// a difference of 1ms between start and end. If we do not the Trace /// API will not record the span. /// </summary> private static bool Is1MsSpan(TraceSpan span) { var duration = span.EndTime - span.StartTime; return(duration.Seconds == 0 && duration.Nanos == 1_000_000); }