private static async Task <HttpResponseMessage> InvokeWithNewScope(
            Func <Task <HttpResponseMessage> > continuation,
            string correlationScopeName, string correlationId)
        {
            using (var scope = ActivityScope.Create(correlationScopeName, correlationId))
            {
                var actionResult = await continuation();

                actionResult.Headers.Add(CorrelationIdHttpHeader, scope.Id);

                return(actionResult);
            }
        }
        private static async Task <HttpResponseMessage> InvokeWithParentScope(
            Func <Task <HttpResponseMessage> > continuation,
            string correlationScopeName, string correlationId, string parentCorrelationId)
        {
            using (var parent = ActivityScope.Create(null, parentCorrelationId))
                using (var child = ActivityScope.Child(correlationScopeName, correlationId))
                {
                    var actionResult = await continuation();

                    actionResult.Headers.Add(CorrelationParentIdHttpHeader, parent.Id);
                    actionResult.Headers.Add(CorrelationIdHttpHeader, child.Id);

                    return(actionResult);
                }
        }
        private static void OpenScope(HttpContextBase context)
        {
            if (context == null)
            {
                return;
            }

            string correlationScopeName = null;
            string correlationId        = null;
            string parentCorrelationId  = null;

            var headers = context.Request?.Headers;

            if (headers != null)
            {
                var correlationIds = headers.GetValues(CorrelationIdHttpHeader);
                if (correlationIds?.Any() ?? false)
                {
                    correlationId = correlationIds.First();
                }

                var correlationIdParents = headers.GetValues(CorrelationParentIdHttpHeader);
                if (correlationIdParents?.Any() ?? false)
                {
                    parentCorrelationId = correlationIdParents.First();
                }

                var correlationScopeNames = headers.GetValues(CorrelationNameHttpHeader);
                if (correlationScopeNames?.Any() ?? false)
                {
                    correlationScopeName = correlationScopeNames.First();
                }
            }

            if (string.IsNullOrWhiteSpace(correlationId))
            {
                correlationId = Guid.NewGuid().ToString();
            }

            if (string.IsNullOrWhiteSpace(parentCorrelationId) == false)
            {
                ActivityScope.Create(null, parentCorrelationId);
                context.Items[ITEM_KEY] = ActivityScope.Child(correlationScopeName, correlationId);
                return;
            }

            context.Items[ITEM_KEY] = ActivityScope.Create(null, correlationId);
        }
        static async Task Main(string[] args)
        {
            var log4NetConfig = new XmlDocument();

            log4NetConfig.Load(File.OpenRead("log4net.config"));

            var repo = log4net.LogManager.CreateRepository(Assembly.GetExecutingAssembly(), typeof(Hierarchy));

            XmlConfigurator.Configure(repo, log4NetConfig["log4net"]);

            LoggingConfiguration.Current.UseLog4Net(repo);

            var logger = LogManager.GetLogger("Sample");

            using (ActivityScope.Create("Logging sample"))
            {
                logger.LogTrace("Trace Level log");
                logger.LogDebug("Debug Level log");
                logger.LogInfo("Info Level log");
                logger.LogWarn("Warn Level log");
                logger.LogError("Error Level log");
                logger.LogFatal("Fatal Level log");
            }

            using (ActivityScope.Create("Logging sample"))
            {
                await Task.WhenAll(
                    Task.Run(() => logger.LogTrace("Trace Level log")),
                    Task.Run(() => logger.LogDebug("Debug Level log")),
                    Task.Run(() =>
                {
                    using (ActivityScope.Child("Child scope 1"))
                        logger.LogInfo("Info Level log");
                }),
                    Task.Run(() => logger.LogWarn("Warn Level log")),
                    Task.Run(() =>
                {
                    using (ActivityScope.Child("Child scope 2"))
                        logger.LogInfo("Error Level log");
                }),
                    Task.Run(() => logger.LogFatal("Fatal Level log"))
                    );
            }

            Console.ReadLine();
        }
        private static async Task InvokeWithNewScope(Func <HttpContext, Task> next, HttpContext context, string correlationScopeName, string correlationId)
        {
            using (var scope = ActivityScope.Create(correlationScopeName, correlationId))
            {
                context.Response.OnStarting(state =>
                {
                    if (state is ActivityScope activity)
                    {
                        context.Response.Headers.Add(CorrelationParentIdHttpHeader, activity.ParentId);
                        context.Response.Headers.Add(CorrelationIdHttpHeader, activity.Id);
                    }

                    return(Task.CompletedTask);
                }, scope);

                await next.Invoke(context);
            }
        }