Beispiel #1
0
        internal async Task <MethodInfo> GetFunctionTargetAsync(bool isInvocation = false)
        {
            try
            {
                return(await _functionLoader.GetFunctionTargetAsync().ConfigureAwait(false));
            }
            catch (CompilationErrorException exc)
            {
                // on the invocation path we want to log detailed logs and all compilation diagnostics
                var properties = isInvocation ? null : PrimaryHostLogProperties;
                FunctionLogger.Log(LogLevel.Error, 0, properties, exc, (state, ex) => "Function compilation error");
                TraceCompilationDiagnostics(exc.Diagnostics, LogTargets.User, isInvocation);
                throw;
            }
            catch (CompilationServiceException)
            {
                const string message = "Compilation service error";
                FunctionLogger.LogError(message);

                // Compiler errors are often sporadic, so we'll attempt to reset the loader here to avoid
                // caching the compiler error and leaving the function hopelessly broken
                if (++_compilerErrorCount < 3)
                {
                    _functionLoader.Reset();

                    const string resetMessage = "Function loader reset. Failed compilation result will not be cached.";
                    FunctionLogger.LogError(resetMessage);
                }
                throw;
            }
        }
Beispiel #2
0
        internal void TraceCompilationDiagnostics(ImmutableArray <Diagnostic> diagnostics, LogTargets logTarget = LogTargets.All, bool isInvocation = false)
        {
            if (logTarget == LogTargets.None)
            {
                return;
            }

            // build the log state based on inputs
            Dictionary <string, object> logState = new Dictionary <string, object>();

            if (!isInvocation)
            {
                // generally we only want to trace compilation diagnostics on the single primary
                // host, to avoid duplicate log statements in the case of file save operations.
                // however if the function is being invoked, we always want to output detailed
                // information.
                logState.Add(ScriptConstants.LogPropertyPrimaryHostKey, true);
            }
            if (!logTarget.HasFlag(LogTargets.User))
            {
                logState.Add(ScriptConstants.LogPropertyIsSystemLogKey, true);
            }
            else if (!logTarget.HasFlag(LogTargets.System))
            {
                logState.Add(ScriptConstants.LogPropertyIsUserLogKey, true);
            }

            // log the diagnostics
            foreach (var diagnostic in diagnostics.Where(d => !d.IsSuppressed))
            {
                FunctionLogger.Log(diagnostic.Severity.ToLogLevel(), 0, logState, null, (s, e) => diagnostic.ToString());
            }

            // log structured logs
            if (Host.InDebugMode && (Host.IsPrimary || isInvocation))
            {
                Host.EventManager.Publish(new StructuredLogEntryEvent(() =>
                {
                    var logEntry = new StructuredLogEntry("codediagnostic");
                    logEntry.AddProperty("functionName", Metadata.Name);
                    logEntry.AddProperty("diagnostics", diagnostics.Select(d =>
                    {
                        FileLinePositionSpan span = d.Location.GetMappedLineSpan();
                        return(new
                        {
                            code = d.Id,
                            message = d.GetMessage(),
                            source = Path.GetFileName(d.Location.SourceTree?.FilePath ?? span.Path ?? string.Empty),
                            severity = d.Severity,
                            startLineNumber = span.StartLinePosition.Line + 1,
                            startColumn = span.StartLinePosition.Character + 1,
                            endLine = span.EndLinePosition.Line + 1,
                            endColumn = span.EndLinePosition.Character + 1,
                        });
                    }));

                    return(logEntry);
                }));
            }
        }
        internal void TraceCompilationDiagnostics(ImmutableArray <Diagnostic> diagnostics, LogTargets logTarget = LogTargets.All)
        {
            if (logTarget == LogTargets.None)
            {
                return;
            }

            IDictionary <string, object> hostTraceProperties = PrimaryHostLogProperties;

            if (!logTarget.HasFlag(LogTargets.User))
            {
                hostTraceProperties = PrimaryHostSystemLogProperties;
            }
            else if (!logTarget.HasFlag(LogTargets.System))
            {
                hostTraceProperties = PrimaryHostUserLogProperties;
            }

            foreach (var diagnostic in diagnostics.Where(d => !d.IsSuppressed))
            {
                FunctionLogger.Log(diagnostic.Severity.ToLogLevel(), 0, hostTraceProperties, null, (s, e) => diagnostic.ToString());
            }

            if (Host.InDebugMode && Host.IsPrimary)
            {
                Host.EventManager.Publish(new StructuredLogEntryEvent(() =>
                {
                    var logEntry = new StructuredLogEntry("codediagnostic");
                    logEntry.AddProperty("functionName", Metadata.Name);
                    logEntry.AddProperty("diagnostics", diagnostics.Select(d =>
                    {
                        FileLinePositionSpan span = d.Location.GetMappedLineSpan();
                        return(new
                        {
                            code = d.Id,
                            message = d.GetMessage(),
                            source = Path.GetFileName(d.Location.SourceTree?.FilePath ?? span.Path ?? string.Empty),
                            severity = d.Severity,
                            startLineNumber = span.StartLinePosition.Line + 1,
                            startColumn = span.StartLinePosition.Character + 1,
                            endLine = span.EndLinePosition.Line + 1,
                            endColumn = span.EndLinePosition.Character + 1,
                        });
                    }));

                    return(logEntry);
                }));
            }
        }
Beispiel #4
0
        protected internal void LogOnPrimaryHost(string message, LogLevel level, Exception exception = null)
        {
            IDictionary <string, object> properties = new Dictionary <string, object>(PrimaryHostLogProperties);

            FunctionLogger.Log(level, 0, properties, exception, (state, ex) => message);
        }