buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

统计

面向“运维”编程,不考虑运营成本的编码都是耍流氓!

面向运维编程?我们小组里的明辉同学做到了,他对面是世伟同学,世伟是我们技术团队的运维大哥,明辉同学每天编程都面对着世伟。

这里的运维可不是指运维同学,而是说,我们的系统在生产运行过程中的维护(System Maintenance)工作,通常理解为代码调优、日志埋点、问题排查等工作。

 

 

 

今天下午,系统运营群里反映问题。我们查看生产日志排查问题时,发现有大文本日志不停在刷屏,严重干扰了我们对问题的定位。

 

大日志刷屏现(wèn)象(tí)由来已久,生产环境每天都在打印海量的log,日志文件动辄10G或20G。这些大文本通常是一些api接口签名串、数据加密串、图片文件base64串/hex串、从db或rpc接口拿到的list序列化串。

我们做任何事情,其实是要考虑成本的。生产排障尤其衡量时间成本。长时间定位不到原因,无法及时反馈和修复,小问题也可能会升(yǎn)级(biàn)为生产事故。

因此,我们在日常编码时,不要忽视这些细节。对于记日志,有必要关注目标对象是否会输出一大段很长很长的文本。如果是,那么,就要做处理。

 

举个例子,下面两段代码,一个是springmvc接口,程序打印获取到的请求参数。一个是程序在调用外部API时,调用前后打印数据报文。这两块的通信报文均涉及到大字段,就要对其做处理。

@RequestMapping(value = "/common.do", method = RequestMethod.POST)
public void doBusiness(@RequestBody String reqJson, HttpServletRequest request, HttpServletResponse response) throws IOException {
    log.info("商户API前置请求,请求参数={}", reqJson);
    ....
}

 

复制代码
logger.info("OCR识别请求地址:{},参数:{}", listAuthUrl , json);

Response response = FastHttpClient.
        post().
        addHeader("Content-Type", "application/json").
        body(json).
        url(listAuthUrl.get(0).getCode()).
        build().
        execute();

String result = response.body().string();
logger.info("OCR识别返回:" + result);
复制代码

小改动,大受益!

上面reqJson和json都是包含了长文本的json串。那么,对于这种情况,怎么处理呢?

简单粗暴的方式,是直接利用subString截取指定长度的子串。弊端是可能会舍掉必要的信息,反而不利于生产排障。

另一种方式,则是将其中特定的大文本进行截取。如下StringUtil方法可供参考。 

复制代码
/**
 * 截取json字符串中的大文本
 * @param jsonStr 含有特长value的JSON字符串
 * @return
 */
public static String cutLongJSONString(String jsonStr) {
    String[] split = jsonStr.split("\"");
    System.out.println(split.length);
    for (int i = 0; i < split.length; i++) {
        if (split[i].length() > 100) {
            split[i] = cutLongString(split[i], 128);
        }
    }
    return String.join("\"", split);
}

/**
 * 截取大文本字符串。
 * 本方法会包含原串的长度。如果不关注,则可直接使用{@link org.apache.commons.lang3.StringUtils#abbreviate(String, int)}或其重载方法
 * @param longString
 * @param length
 * @return
 */
public static String cutLongString(String longString, int length) {
    if(StringUtils.isBlank(longString)){
        return "";
    }
    StringBuilder sb=new StringBuilder();

    if (longString.length()>length){
        sb.append(longString, 0, length).append("...(length=").append(longString.length()).append(")");
        return sb.toString();
    }
    return longString;

}
复制代码

posted on   buguge  阅读(186)  评论(0编辑  收藏  举报

编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
历史上的今天:
2016-11-21 .net(c#)版RSA加密算法,拿走不谢
点击右上角即可分享
微信分享提示