internal static void OnFunctionTimeout(System.Timers.Timer timer, MethodInfo method, Guid instanceId, TimeSpan timeout, bool timeoutWhileDebugging, TraceWriter trace, ILogger logger, CancellationTokenSource cancellationTokenSource, Func <bool> isDebuggerAttached) { timer.Stop(); bool shouldTimeout = timeoutWhileDebugging || !isDebuggerAttached(); string message = string.Format(CultureInfo.InvariantCulture, "Timeout value of {0} exceeded by function '{1}.{2}' (Id: '{3}'). {4}", timeout.ToString(), method.DeclaringType.Name, method.Name, instanceId, shouldTimeout ? "Initiating cancellation." : "Function will not be cancelled while debugging."); trace.Error(message, null, TraceSource.Execution); logger?.LogError(message); trace.Flush(); // Only cancel the token if not debugging if (shouldTimeout) { // only cancel the token AFTER we've logged our error, since // the Dashboard function output is also tied to this cancellation // token and we don't want to dispose the logger prematurely. cancellationTokenSource.Cancel(); } }
protected virtual void TraceError(string errorMessage) { TraceWriter.Error(errorMessage); Logger?.LogError(errorMessage); // when any errors occur, we want to flush immediately TraceWriter.Flush(); }
public override void Flush() { if (_text.Length > 0) { // flush any remaining text _traceWriter.Info(_text.ToString()); } _traceWriter.Flush(); }
/// <summary> /// Trace information for an unhandled exception. /// Each request handler should perform its logic within a try block, and call this handler within the catch block. /// </summary> /// <param name="ex">the exception caught at top level</param> /// <param name="tracer">Tracer that will be used to send telemetry on the failure</param> /// <param name="fallbackTracer">Fallback tracer, in case the tracer fails</param> public static void TraceUnhandledException(Exception ex, IExtendedTracer tracer, TraceWriter fallbackTracer) { // Trace the full exception details string errorToTrace = $"Top level exception: {ex}"; try { // Write to trace tracer?.TraceError(errorToTrace); // Report the exception if (ex != null && tracer != null) { AggregateException aggregateException = ex as AggregateException; if (aggregateException != null) { aggregateException.InnerExceptions.ToList().ForEach(tracer.ReportException); } else { tracer.ReportException(ex); } } // Flush all traces tracer?.Flush(); } catch (Exception traceException) { try { // Try to write to the fallback tracer fallbackTracer?.Error($"Tracer failed - using fallback tracer. Tracer error: {traceException}"); fallbackTracer?.Error(errorToTrace); fallbackTracer?.Flush(); } catch (Exception fallbackTraceException) { try { // Try to write to console Console.WriteLine($"Tracer failed - using fallback tracer. Tracer error: {traceException}"); Console.WriteLine($"Fallback tracer failed - using console. Fallback tracer error: {fallbackTraceException}"); Console.WriteLine(errorToTrace); } catch (Exception) { // Just swallow, nothing better to do here.. } } } }
public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log) { log.Info("C# HTTP trigger function processed a request."); log.Flush(); foreach (var item in req.GetQueryNameValuePairs()) { log.Info(item.Key + ": " + item.Value + ", "); } log.Flush(); // parse query parameter string to = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "to", true) == 0) .Value; string status = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "status", true) == 0) .Value; string integrationName = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "integrationName", true) == 0) .Value; // Get request body dynamic data = await req.Content.ReadAsAsync <object>(); // Set name to query string or body data to = to ?? data?.to; status = status ?? data?.status; integrationName = integrationName ?? data?.integrationName; log.Info($"integrationName = {integrationName}, to = {to}, status {status}"); return(to == null || status == null ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a to and status on the query string or in the request body") : req.CreateResponse(HttpStatusCode.OK, "Sent to " + to + " - Status: " + status)); }
private void HandleHostError(Exception exception) { if (exception == null) { throw new ArgumentNullException("exception"); } // First, ensure that we've logged to the host log // Also ensure we flush immediately to ensure any buffered logs // are written TraceWriter.Error("A ScriptHost error has occurred", exception); TraceWriter.Flush(); if (exception is FunctionInvocationException) { // For all function invocation errors, we notify the invoker so it can // log the error as needed to its function specific logs. FunctionInvocationException invocationException = exception as FunctionInvocationException; NotifyInvoker(invocationException.MethodName, invocationException); } else if (exception is FunctionIndexingException) { // For all startup time indexing errors, we accumulate them per function FunctionIndexingException indexingException = exception as FunctionIndexingException; string formattedError = Utility.FlattenException(indexingException); AddFunctionError(indexingException.MethodName, formattedError); // Also notify the invoker so the error can also be written to the function // log file NotifyInvoker(indexingException.MethodName, indexingException); // Mark the error as handled so indexing will continue indexingException.Handled = true; } else { // See if we can identify which function caused the error, and if we can // log the error as needed to its function specific logs. FunctionDescriptor function = null; if (TryGetFunctionFromException(Functions, exception, out function)) { NotifyInvoker(function.Name, exception); } } }
internal static void OnFunctionTimeout(System.Timers.Timer timer, MethodInfo method, Guid instanceId, TimeSpan timeout, TraceWriter trace, CancellationTokenSource cancellationTokenSource) { timer.Stop(); string message = string.Format(CultureInfo.InvariantCulture, "Timeout value of {0} exceeded by function '{1}.{2}' (Id: '{3}'). Initiating cancellation.", timeout.ToString(), method.DeclaringType.Name, method.Name, instanceId); trace.Error(message, null, TraceSource.Execution); trace.Flush(); // only cancel the token AFTER we've logged our error, since // the Dashboard function output is also tied to this cancellation // token and we don't want to dispose the logger prematurely. cancellationTokenSource.Cancel(); }