コード例 #1
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            var    stateValues      = state as IEnumerable <KeyValuePair <string, object> >;
            string formattedMessage = formatter?.Invoke(state, exception);

            // If we don't have a message, there's nothing to log.
            if (string.IsNullOrEmpty(formattedMessage))
            {
                return;
            }

            bool isSystemTrace = Utility.GetStateBoolValue(stateValues, ScriptConstants.LogPropertyIsSystemLogKey);

            if (isSystemTrace)
            {
                // System traces are not logged to files.
                return;
            }

            bool isPrimaryHostTrace = Utility.GetStateBoolValue(stateValues, ScriptConstants.LogPropertyPrimaryHostKey);

            if (isPrimaryHostTrace && !_isPrimary())
            {
                return;
            }

            if (exception != null)
            {
                if (exception is FunctionInvocationException ||
                    exception is AggregateException)
                {
                    // we want to minimize the stack traces for function invocation
                    // failures, so we drill into the very inner exception, which will
                    // be the script error
                    Exception actualException = exception;
                    while (actualException.InnerException != null)
                    {
                        actualException = actualException.InnerException;
                    }

                    formattedMessage += $"{Environment.NewLine}{actualException.Message}";
                }
                else
                {
                    formattedMessage += $"{Environment.NewLine}{exception.ToFormattedString()}";
                }
            }

            formattedMessage = FormatLine(stateValues, logLevel, formattedMessage);

            try
            {
                _fileWriter.AppendLine(formattedMessage);

                // flush errors immediately
                if (logLevel == LogLevel.Error || exception != null)
                {
                    _fileWriter.Flush();
                }
            }
            catch (Exception)
            {
                // Make sure the Logger doesn't throw if there are Exceptions (disk full, etc).
            }
        }