使用 tail 结合 grep 查找日志关键字并高亮及显示所在行上下文

介绍了如何使用 tail 结合 grep 查找日志关键字并高亮及显示所在行上下文, 最后还附带介绍了如何使用脚本文件对整个过程进行抽象化.

对于一个开发或运维人员而言, 当系统出现故障时, 第一步常常就是查看日志. 查看日志经常碰到的一个需求就是按关键字去搜索, 在日常开发机子上的 IDE 上, 都集成了强大的搜索功能, 但因为系统通常部署在 Linux 系统上, 一般只有命令行界面, 在其上应该怎么去搜索呢? 恐怕有些同学就不是那么清楚了.

有些人会用 ftp 之类的把日志下载下来本地再搜索, 如果是小一点的文件还好, 但日志文件往往都比较大, 因此这样的方式无疑是极为低效的.

下面就介绍一种相对快捷的方式, 也不需要用到特别高级的命令, 仅需要 tailgrep 两个命令结合起来即可, 能达到这样一个效果:

  1. 能按关键字搜索;
  2. 在显示关键字所在行时还能高亮关键字;
  3. 能把关键字所在行的上下文, 比如上下 10 行的内容也一起显示出来.

继续阅读

使用 lombok @Slf4j 注解简化日志功能的引入

介绍了如何使用 lombok @Slf4j 注解简化日志功能的引入, 兼谈了重复性管理的问题.

在开发过程中, 打印必要的日志是必不可少的一环, 而要打印日志, 在相关的类中就要引入日志相关属性, 在传统上, 一般是通过 LoggerFactory.getLogger 去实现的:

package net.xiaogd.demo.mybatis.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LogDemoController {

    // 自行声明
    private static final Logger log = LoggerFactory.getLogger((LogDemoController.class));

    //...
}

尽管这已经很简洁, 但如果有大量的类要做类似的操作, 还是略显重复, 从 重复性管理 的角度, 我们怎么才能尽量减少这些重复的样板代码呢?

答案就是利用 lombok@Slf4j 注解.

继续阅读

使用 .editorconfig 文件来统一编程风格

介绍了 .editorconfig 文件及如何使用它来统一项目的编程风格, 兼谈了一些项目管理的心得.

做过长期开发的程序员都知道保持编程风格统一的重要性, 统一的风格能够降低各种成本.

有一句名言是咋说的来着? 代码主要是给人看的, 其次才是给电脑去运行.

但另一方面, 大家又普遍是偷懒的, 对于这些长期会受益, 但短期收益不明显甚至带来麻烦的事, 许多团队中的成员不能说抵制吧, 但至少是积极性不高的.

此时, 假如你是一个团队的领导者, 怎么才能有效地保持项目中编程风格的统一呢? 下面介绍的这个 .editorconfig 文件的方式将能有效地帮助我们.

继续阅读

引入 lombok 简化代码及相关 IDE 设置

简要介绍了 lombok 的特性, 以及如何在 maven 引入和 IDE 中的设置(包括Eclipse 及 Intellij IDEA)

使用 lombok 可以简化一些样板代码的编写, 下面说说如何启用它, 包括了 maven 及 IDE 中的设置(Eclipse 及 Intellij IDEA)

具体例子

开发中经常会遇到一些纯粹作为记录的类, 如 VO, DTO 之类的, 在以往, 需要给它们一一生成所谓的 getter 和 setter. 虽然有 IDE 可以辅助快速生成这样方法, 可大量的这种简单的 get 和 set 方法的存在也是挺碍眼的, 可否简化呢?

答案是可以的, 方式就是借助 lombok 这个代理工具.

继续阅读

重复性管理--抽象的重要性(下)

什么是抽象及它在重复性管理中的作用

接着 上一篇的谈论, 继续谈论抽象在重复性管理中的重要作用.

好的抽象与糟糕的抽象?

通过前面的一些例子, 你可能形成了一个印象: 所谓抽象很多时候就是把一些代码封装到一个方法中.

不过事实上并不是这么简单的. 抽象的结果确实很多时候产生了一个方法, 但不是说我把一堆代码整在一块就是一个抽象, 又或者说, 即便它是一个抽象, 但可能却不是一个好的抽象, 而是一个糟糕的抽象.

假如你看到一段代码很长, 然后你"啪"的一声把它从中间拦腰截断, 划分出两个方法来, 一个叫 firstPart(), 一个叫 secondPart(), 那么这算是怎样的一个抽象呢?

继续阅读