草庐IT

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

buguge - Keep it simple,stupid 2023-03-28 原文

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

这里的运维可不是指运维同学,而是说,我们的系统在生产运行过程中的维护(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;

}

有关面向“运维”编程,不考虑运营成本的编码都是耍流氓!的更多相关文章

  1. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  2. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  3. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  4. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  5. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  6. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  7. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  8. c - Ruby - 源代码 - 编码风格 - 2

    查看Ruby代码,它具有以下proc_arity:staticVALUEproc_arity(VALUEself){intarity=rb_proc_arity(self);returnINT2FIX(arity);}更多的是C编码风格问题,但为什么staticVALUE在单独的一行而不是像这样的:staticVALUEproc_arity(VALUEself) 最佳答案 它来自UNIX世界,因为它有助于轻松grep函数的定义:$grep-n'^proc_arity'*.c或使用vim:/^proc_arity

  9. ruby - 如何以编程方式删除实例上的 "singleton information"以使其编码(marshal)? - 2

    我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。

  10. Ruby 元编程问题 - 2

    我正在查看Ruby日志记录库Logging.logger方法并从sourceatgithub提出问题与这段代码有关:logger=::Logging::Logger.new(name)logger.add_appendersappenderlogger.additive=falseclass我知道类 最佳答案 这实际上删除了方法(当它实际被执行时)。这是确保close不会被调用两次的保障措施。看起来好像有嵌套的“class 关于Ruby元编程问题,我们在StackOverflow上找到一

随机推荐