/// <summary>
 /// Initializes a new instance of the <see cref="ApiTraceLogPiece"/> class.
 /// </summary>
 /// <param name="parent">The parent.</param>
 /// <param name="methodFullName">Full name of the method.</param>
 /// <param name="entryStamp">The entry stamp.</param>
 internal ApiTraceLogPiece(ApiTraceLogPiece parent, string methodFullName = null, DateTime? entryStamp = null)
     : this()
 {
     this.Parent = parent;
     this.MethodFullName = methodFullName;
     this.EntryStamp = entryStamp ?? DateTime.UtcNow;
 }
 /// <summary>
 /// Fills the inner trace log.
 /// </summary>
 /// <param name="container">The container.</param>
 /// <param name="log">The log.</param>
 private static void FillInnerTraceLog(List<ApiTraceLogPiece> container, ApiTraceLogPiece log)
 {
     if (log.InnerTraces != null)
     {
         foreach (var one in log.InnerTraces)
         {
             container.Add(one);
             FillInnerTraceLog(container, one);
         }
     }
 }
        /// <summary>
        /// Converts the API trace log piece.
        /// </summary>
        /// <param name="apiTraceLog">The API trace log.</param>
        /// <returns>ApiTraceLogPiece.</returns>
        private static ApiTraceLogPiece ConvertApiTraceLogPiece(RuntimeApiTraceLog apiTraceLog)
        {
            if (apiTraceLog != null)
            {
                var result = new ApiTraceLogPiece
                {
                    EntryStamp = apiTraceLog.EntryStamp,
                    Exception = apiTraceLog.Exception,
                    ExitStamp = apiTraceLog.ExitStamp,
                    MethodFullName = apiTraceLog.MethodFullName,
                    MethodParameters = apiTraceLog.MethodParameters
                };

                foreach (var one in apiTraceLog.Children)
                {
                    result.InnerTraces.Add(ConvertApiTraceLog(one));
                }

                return result;
            }

            return null;
        }
 /// <summary>
 /// Disposes this instance.
 /// </summary>
 public static void Dispose()
 {
     _current = null;
     _root = null;
 }
        /// <summary>
        /// Fills the exit information.
        /// </summary>
        /// <param name="piece">The piece.</param>
        /// <param name="exceptionKey">The exception key.</param>
        /// <param name="exitStamp">The exit stamp.</param>
        private static void Exit(ApiTraceLogPiece piece, Guid? exceptionKey, DateTime? exitStamp = null)
        {
            if (piece != null)
            {
                piece.ExceptionKey = exceptionKey;
                piece.ExitStamp = exitStamp ?? DateTime.UtcNow;
                _current = piece.Parent;
            }

            if (_root != null && !_root.ExceptionKey.HasValue)
            {
                _root.ExceptionKey = exceptionKey;
            }
        }
        /// <summary>
        /// Enters the specified trace log.
        /// </summary>
        /// <param name="traceLog">The trace log.</param>
        /// <param name="setNameAsMajor">The set name as major.</param>
        internal static void Enter(ApiTraceLogPiece traceLog, bool setNameAsMajor = false)
        {
            if (traceLog != null)
            {
                if (_root != null)
                {
                    traceLog.Parent = _current;
                    _current.InnerTraces.Add(traceLog);
                    _current = traceLog;

                    if (setNameAsMajor && !string.IsNullOrWhiteSpace(_current.MethodFullName))
                    {
                        _root.MethodFullName = _current.MethodFullName;
                    }
                }
            }
        }
 /// <summary>
 /// Initializes the specified trace identifier.
 /// </summary>
 /// <param name="traceId">The trace identifier.</param>
 /// <param name="traceSequence">The trace sequence.</param>
 /// <param name="entryStamp">The entry stamp.</param>
 /// <param name="methodName">Name of the method.</param>
 public static void Initialize(string traceId, int? traceSequence, DateTime? entryStamp = null, [CallerMemberName] string methodName = null)
 {
     if (!string.IsNullOrWhiteSpace(traceId))
     {
         _root = new ApiTraceLog(entryStamp: entryStamp)
         {
             TraceId = traceId,
             TraceSequence = traceSequence.HasValue ? (traceSequence.Value + 1) : 0
         };
         var current = new ApiTraceLogPiece(_root, methodName, entryStamp);
         _root.InnerTraces.Add(current);
         _current = current;
     }
 }
        /// <summary>
        /// APIs the trace log to string.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="log">The log.</param>
        /// <param name="level">The level.</param>
        /// <returns>System.String.</returns>
        private static void ApiTraceLogToString(StringBuilder builder, ApiTraceLogPiece log, int level)
        {
            if (builder != null && log != null)
            {
                builder.AppendIndent(' ', 2 * (level + 1));
                builder.AppendLineWithFormat("Entry: {0}", log.EntryStamp.ToFullDateTimeString());
                builder.AppendIndent(' ', 2 * (level + 1));
                builder.AppendLineWithFormat("Exit: {0}", log.ExitStamp.ToFullDateTimeString());
                builder.AppendIndent(' ', 2 * (level + 1));
                builder.AppendLineWithFormat("Exception Key: {0}", log.ExceptionKey);
                builder.AppendIndent(' ', 2 * (level + 1));

                foreach (var one in log.InnerTraces)
                {
                    builder.AppendLineWithFormat("Inner trace: ");
                    ApiTraceLogToString(builder, one, level + 1);
                }
            }
        }
        /// <summary>
        /// APIs the trace log to string.
        /// </summary>
        /// <param name="log">The log.</param>
        /// <param name="level">The level.</param>
        /// <returns>System.String.</returns>
        private static string ApiTraceLogToString(ApiTraceLogPiece log, int level)
        {
            StringBuilder builder = new StringBuilder();

            if (log != null)
            {
                builder.AppendIndent(' ', 2 * (level + 1));
                builder.AppendLineWithFormat("Entry: {0}", log.EntryStamp.ToFullDateTimeString());
                builder.AppendIndent(' ', 2 * (level + 1));
                builder.AppendLineWithFormat("Exit: {0}", log.ExitStamp.ToFullDateTimeString());
                builder.AppendIndent(' ', 2 * (level + 1));
                builder.AppendLineWithFormat("Parameters: {0}", log.MethodParameters.ToJson());
                builder.AppendIndent(' ', 2 * (level + 1));
                builder.AppendLineWithFormat("Exception: {0}", log.Exception == null ? "NA" : log.Exception.ToJson());
                builder.AppendIndent(' ', 2 * (level + 1));
                foreach (var one in log.InnerTraces)
                {
                    builder.AppendLineWithFormat("Inner trace: {0}", ApiTraceLogToString(one, level + 1));
                }
            }

            return builder.ToString();
        }
 /// <summary>
 /// To the trace log.
 /// </summary>
 /// <param name="methodCallMessage">The method call message.</param>
 /// <param name="parent">The parent.</param>
 /// <param name="entryStamp">The entry stamp.</param>
 /// <returns>Beyova.ApiTracking.ApiTraceLogPiece.</returns>
 internal static ApiTraceLogPiece ToTraceLog(this IMethodCallMessage methodCallMessage, ApiTraceLogPiece parent, DateTime? entryStamp = null)
 {
     return methodCallMessage != null ? new ApiTraceLogPiece(parent, methodCallMessage.MethodBase.GetFullName()) : null;
 }
 /// <summary>
 /// To the trace log.
 /// </summary>
 /// <param name="methodInfo">The method information.</param>
 /// <param name="parent">The parent.</param>
 /// <param name="entryStamp">The entry stamp.</param>
 /// <returns>Beyova.ApiTracking.ApiTraceLogPiece.</returns>
 internal static ApiTraceLogPiece ToTraceLog(this MethodInfo methodInfo, ApiTraceLogPiece parent, DateTime? entryStamp = null)
 {
     return methodInfo != null ? new ApiTraceLogPiece(parent, methodInfo.GetFullName(), entryStamp) : null;
 }
 /// <summary>
 /// To the trace log.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="parent">The parent.</param>
 /// <param name="entryStamp">The entry stamp.</param>
 /// <returns>Beyova.ApiTracking.ApiTraceLogPiece.</returns>
 internal static ApiTraceLogPiece ToTraceLog(this RuntimeContext context, ApiTraceLogPiece parent, DateTime? entryStamp = null)
 {
     return context != null ? new ApiTraceLogPiece(parent, context.ApiMethod?.GetFullName(), entryStamp) : null;
 }