Polly善用Context来记录异常发生时的参数信息

Polly是一个.NET弹性和瞬态故障处理库,具体用法可以参考:https://github.com/App-vNext/Polly,此处不会细讲如何使用Polly来进行异常处理或重试,就如标题所说,本篇内容主要为异常发生时除了Exception,又如何获取记录发生异常时你可能关心的数据信息

可能你们会觉得这么简单的问题有什么好说的,直接在方法内try catch记录后,再throw不就行了?当然这的确是一个实际的方法,但作为一个有追求的码农,每个Policy执行的方法都写一段try catch来进行日志记录,这么low的行为,实在……

好像废话多了,直奔主题吧,在使用Polly的时候,我们可以注意到所有的Policy都具备一个叫onXXX的委托,以RetryPolicy为例,在其所有重载方法中,一定会有最后一个参数叫onRetry的重载方法,该委托最多参数定义如下Action<Exception, TimeSpan, int, Context>,可见该委托包含了Exception发生的异常,然后还有一个重要参数就是Context,这个上下文在这里非常关键,还是以抽象类Policy的Execute方法为例,其重载方法除了包含带Context的Action外,本身也具备直接的Context参数,所以我们可以在对应Action中将请求参数传入Context,而Execute方法直接自带的Context则可以用来传入基础的参数,下面则是用于演示的demo代码

            //为方便测试,这里定义一个通用的委托,来模拟日志记录行为
            Action<Context,Exception, string> act = (c,e, s) =>
            {
                var color = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("LOG******{0}******LOG", s);
                foreach (var k in c.Keys)
                    Console.WriteLine("Key:{0}  Value:{1}", k, c[k]);
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Exception:{0}", e);
                
                //记录日志,这里日志就可以通过context来记录更精准的方法信息
                Console.ForegroundColor = color;
            };

            var fallBackPolicy = Policy.Handle<Exception>().Fallback((c, ct) => { }, (e, c) =>
            {
                //https://github.com/App-vNext/Polly/wiki/Fallback
                act(c, e, string.Format("FallBack context contains keys:{0}", c.Keys.Count));
            });

            var timeoutPolicy = Policy.Timeout(5, Polly.Timeout.TimeoutStrategy.Pessimistic, (c, ts, t) =>
            {
                //https://github.com/App-vNext/Polly/wiki/Timeout
                //因为此处测试我们并没指定CancellationToken ,所以这里采取悲观策略
                act(c, new TimeoutException(), string.Format("Timeout context contains keys:{0}", c.Keys.Count));//Timeout比较特殊,因为异常不是发生在代码中,所以此处我们直接new了一个异常传入
            });

            fallBackPolicy.Execute(c =>
            {
                //因为timeout会产生异常,所以这里用FallBack包含下,不然后面的retryPolicy就无法执行了
                timeoutPolicy.Execute((ct) =>
                {
                    Thread.Sleep(6000);
                }, new Dictionary<string, object> { { "Action", "timeoutPolicy" } });
            }, new Dictionary<string, object> { { "Action", "fallBackPolicy" } });


            var retryPolicy = Policy.Handle<Exception>().WaitAndRetry(5, (i, c) =>
            {
                //获取timespan的委托中,我们对context进行调整以进行测试
                Console.WriteLine("------------------");
                Console.WriteLine("Add key:{0} into context in sleepDurationProvider action", i);
                c.Add(i.ToString(), i.ToString());
                //c[i.ToString()] = i;//也可以直接这样进行赋值
                return TimeSpan.FromSeconds(5);
            }, (e, t, c) =>
            {
                act(c, e, string.Format("OnRetry context contains keys:{0}", c.Keys.Count));
            });
            retryPolicy.Execute(() =>
            {
                throw new Exception("just test");
            }, new Dictionary<string, object> { { "Action", "retryPolicy" } });

执行截图如下


这样,就可以将所有的异常统一进行log记录,而且log也包含了当前方法的相关参数信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值