找回密码
 立即注册
首页 业界区 安全 程序日志优化:精准捕获与日志分级,践行数字低碳 ...

程序日志优化:精准捕获与日志分级,践行数字低碳

赖琳芳 3 天前
面对系统每日产生的海量日志,我们的一次小小技术优化,不仅是提升效率,更是一次实实在在的“低碳”实践。本文将以一条具体的 org.apache.http.conn.ConnectTimeoutException 异常日志为例,展示如何通过技术手段,在保障系统可观测性的同时,为节能减碳贡献力量。

先贴出来这个timeout异常log,看看你需要几次下滑屏幕?
点击查看代码
  1. 2025-10-22 11:00:05.191 [TID:d2faa69abf014567ad1b23fcd34f8967.844.17611020000360091] [DubboServerHandler-10.*.1.110:20890-thread-197] ERROR c.e.c.p.m.l.levyimpl.own.LevySignProviderApiByOWN:? - *****【自有服务商】 签约调服务商查询接口,异常:{}java.lang.RuntimeException: org.apache.http.conn.ConnectTimeoutException: Connect to 47.*.99.98:8280 [/47.*.99.98] failed: connect timed out
  2.     at com.emax.channel.provider.modules.levyprovider.util.HttpClientHelper.httpClientPost(HttpClientHelper.java:403)
  3.     at com.emax.channel.provider.modules.levyprovider.util.HttpClientHelper.httpClientPost(HttpClientHelper.java:435)
  4.     at com.emax.channel.provider.modules.levyprovider.levyimpl.own.LevySignProviderApiByOWN.querySign(LevySignProviderApiByOWN.java:224)
  5.     at com.emax.channel.provider.modules.levyprovider.levyimpl.own.LevyServiceProviderApiByOWN.querySign(LevyServiceProviderApiByOWN.java:691)
  6.     at com.emax.channel.provider.modules.levyprovider.levyimpl.own.LevyServiceProviderApiByOWN$$FastClassBySpringCGLIB$$1465a46f.invoke(<generated>)
  7.     at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
  8.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
  9.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
  10.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
  11.     at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
  12.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  13.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
  14.     at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
  15.     at com.emax.channel.provider.modules.levyprovider.levyimpl.own.LevyServiceProviderApiByOWN$$EnhancerBySpringCGLIB$$cc086de3.querySign(<generated>)
  16.     at com.emax.channel.provider.modules.levyprovider.levyimpl._route.LevyChannelRouteServiceImpl.querySign(LevyChannelRouteServiceImpl.java:330)
  17.     at com.emax.channel.provider.modules.levyprovider.levyimpl._route.LevyChannelRouteServiceImpl$$FastClassBySpringCGLIB$$c67fd737.invoke(<generated>)
  18.     at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
  19.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
  20.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
  21.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
  22.     at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
  23.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  24.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
  25.     at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
  26.     at com.emax.channel.provider.modules.levyprovider.levyimpl._route.LevyChannelRouteServiceImpl$$EnhancerBySpringCGLIB$$4b092e13.querySign(<generated>)
  27.     at com.emax.channel.provider.modules.levySign.service.LevySignBizService.queryLevySignStatus(LevySignBizService.java:121)
  28.     at com.emax.channel.provider.modules.levySign.provider.LevySignServiceImpl.querySign(LevySignServiceImpl.java:158)
  29.     at com.emax.channel.provider.modules.levySign.provider.LevySignServiceImpl$$FastClassBySpringCGLIB$$f64e351d.invoke(<generated>)
  30.     at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
  31.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
  32.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
  33.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
  34.     at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
  35.     at com.emax.zhenghe.common.aspect.LogExecutionInterceptor.logExecution(LogExecutionInterceptor.java:55)
  36.     at sun.reflect.GeneratedMethodAccessor797.invoke(Unknown Source)
  37.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  38.     at java.lang.reflect.Method.invoke(Method.java:498)
  39.     at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
  40.     at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
  41.     at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
  42.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
  43.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
  44.     at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
  45.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  46.     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
  47.     at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
  48.     at com.emax.channel.provider.modules.levySign.provider.LevySignServiceImpl$$EnhancerBySpringCGLIB$$b352fcad.querySign(<generated>)
  49.     at com.emax.channel.rpcapi.levySign.service.LevySignServiceDubboWrap130.invokeMethod(LevySignServiceDubboWrap130.java)
  50.     at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:73)
  51.     at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:100)
  52.     at org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:55)
  53.     at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56)
  54.     at org.apache.dubbo.rpc.filter.ClassLoaderCallbackFilter.invoke(ClassLoaderCallbackFilter.java:38)
  55.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  56.     at com.emax.zhenghe.common.filters.ProviderExceptionFilter.invoke(ProviderExceptionFilter.java:32)
  57.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  58.     at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:79)
  59.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  60.     at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:44)
  61.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  62.     at com.alibaba.csp.sentinel.adapter.dubbo3.SentinelDubboProviderFilter.invoke(SentinelDubboProviderFilter.java:85)
  63.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  64.     at com.emax.zhenghe.common.filters.ProviderRequestLogFilter.invoke(ProviderRequestLogFilter.java:60)
  65.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  66.     at com.serviceshare.principal.dubbo.filter.ProviderPrincipalFilter.invoke(ProviderPrincipalFilter.java:50)
  67.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  68.     at org.apache.dubbo.monitor.support.MonitorFilter.$sw$original$invoke$1vamrv0(MonitorFilter.java:100)
  69.     at org.apache.dubbo.monitor.support.MonitorFilter.$sw$original$invoke$1vamrv0$accessor$$sw$p4vq621(MonitorFilter.java)
  70.     at org.apache.dubbo.monitor.support.MonitorFilter$$sw$auxiliary$61t58p2.call(Unknown Source)
  71.     at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86)
  72.     at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java)
  73.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  74.     at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:54)
  75.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  76.     at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:192)
  77.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  78.     at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:54)
  79.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  80.     at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41)
  81.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  82.     at org.apache.dubbo.rpc.filter.ProfilerServerFilter.invoke(ProfilerServerFilter.java:58)
  83.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  84.     at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:133)
  85.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
  86.     at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CallbackRegistrationInvoker.invoke(FilterChainBuilder.java:194)
  87.     at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:156)
  88.     at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:102)
  89.     at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:177)
  90.     at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:53)
  91.     at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:62)
  92.     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  93.     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  94.     at org.apache.dubbo.common.threadlocal.InternalRunnable.run(InternalRunnable.java:41)
  95.     at java.lang.Thread.run(Thread.java:750)
  96. Caused by: org.apache.http.conn.ConnectTimeoutException: Connect to 47.*.99.98:8280 [/47.*.99.98] failed: connect timed out
  97.     at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:151)
  98.     at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
  99.     at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
  100.     at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
  101.     at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
  102.     at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
  103.     at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
  104.     at org.apache.http.impl.client.InternalHttpClient.$sw$original$doExecute$7gb7dq1(InternalHttpClient.java:185)
  105.     at org.apache.http.impl.client.InternalHttpClient.$sw$original$doExecute$7gb7dq1$accessor$$sw$l56slt2(InternalHttpClient.java)
  106.     at org.apache.http.impl.client.InternalHttpClient$$sw$auxiliary$67oq2v1.call(Unknown Source)
  107.     at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86)
  108.     at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java)
  109.     at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
  110.     at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
  111.     at com.emax.channel.provider.modules.levyprovider.util.HttpClientHelper.httpClientPost(HttpClientHelper.java:393)
  112.     ... 93 common frames omitted
  113. Caused by: java.net.SocketTimeoutException: connect timed out
  114.     at java.net.PlainSocketImpl.socketConnect(Native Method)
  115.     at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
  116.     at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
  117.     at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
  118.     at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
  119.     at java.net.Socket.connect(Socket.java:607)
  120.     at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75)
  121.     at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
  122.     ... 107 common frames omitted
复制代码
海量的日志,尤其是冗长的异常堆栈,不仅占据大量存储空间,其写入过程也持续消耗着计算和电力资源。每一次磁盘I/O操作,都关联着数据中心的能耗。据研究,即便是线上办公工具的使用,其碳减排贡献也相当可观,一次线上会议相比线下出行就能减少可观的碳排放。我们的系统日志优化,也正是遵循类似的“低碳”逻辑——减少不必要的数据输出,就是减少能源消耗
优化前的代码对所有的异常“一视同仁”,打印完整的堆栈轨迹,导致单次异常日志就可能超过100行。若此类异常每日发生数百次,其累积的日志量及其背后的存储与处理能耗不容小觑。
  1. } catch (Exception e) {
  2.     log.error("*****{} 签约调服务商查询接口,异常:{}", BUSI_NAME, e); // 无论何种异常,均打印完整错误堆栈
  3.     signResultVo.setResultMsg("签约查询异常");
  4. }
复制代码
优化后的代码则对连接超时这类已知的、相对常见的异常进行了“低碳”化处理:降低日志级别为 WARN,并仅记录关键信息,避免输出冗长的堆栈轨迹。
  1. } catch (Exception e) {
  2.     // 单独处理连接超时异常,践行日志“低碳”化:减少不必要的信息输出,降低存储与处理能耗
  3.     if (e instanceof ConnectTimeoutException || e.getCause() instanceof org.apache.http.conn.ConnectTimeoutException) {
  4.         log.warn("*****{} 签约调服务商查询接口超时,levy={}-{} : {}", BUSI_NAME,
  5.                 channelConfig.getLevyCode(), channelConfig.getLevyName(),
  6.                 ExceptionUtils.getMessage(e)); // 关键信息一目了然,摒弃冗余堆栈
  7.     } else {
  8.         log.error("*****{} 签约调服务商查询接口,异常:{}", BUSI_NAME, e); // 其他异常仍按错误级别完整记录
  9.     }
  10.     signResultVo.setResultMsg("签约查询异常");
  11. }
复制代码
低碳成效速览

下表清晰展示了本次优化在“低碳”维度上的直接收益:
对比项优化前 (单次异常)优化后 (单次异常)低碳收益分析日志行数约 100+ 行1行日志体积减少超过99%,直接降低了存储空间占用和后续处理所需的计算资源。存储占用巨大极小每日可节省大量磁盘空间,意味着数据中心硬盘阵列的能耗得以降低。I/O 负载高(写入大量数据)极低显著减少磁盘写入操作,降低系统I/O压力,间接节约了电力。核心信息淹没在堆栈细节中聚焦于异常原因与服务商保持了关键信息(何种异常、哪个服务商),满足了监控与排查的基本需求。通过单元测试验证,优化后,原本冗长的错误日志被精简为一行清晰的警告信息:
  1. // 优化前:超过100行的堆栈跟踪
  2. // 优化后:
  3. 2025-10-22 14:29:58,754 WARN ... - *****【自有服务商】 签约调服务商查询接口超时,levy=XXX-XXX : ConnectTimeoutException: Connect to ... timed out
复制代码
总结:代码优化亦是环保行动

本次优化巧妙地将“低碳”理念融入技术实践:

  • 精准:对超时异常进行差异化处理,避免信息冗余。
  • 高效:用最少的日志承载最关键的信息,提升运维效率。
  • 绿色:通过大幅削减日志量,直接降低了系统的存储成本能源消耗
这正印证了“低碳”并非遥不可及的口号,它同样体现在我们编写的每一行代码、每一次针对性的技术优化中。当数百次的异常日志从每天占用数MB空间锐减至几KB时,我们为减少数字世界的“碳足迹”做出了实实在在的努力。
希望这个案例能启发大家,在追求系统稳定高效的同时,积极发现并践行更多的技术“低碳”可能性。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册