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

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

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

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

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

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

下面是一个效果示意图:

tail grep log

在这里, 我用我云主机的 nginx access log 做了个示范, 我搜索一篇文章 url 的关键字 "a-port", 然后显示出搜索的结果及上下文, 可以看到关键字被标红显示, 上下文也有显示, 多个搜索结果间以蓝色的短横间隔开来.

下面具体说说怎么实现这样的搜索, 先具体讲讲各个命令及参数, 再说说怎么结合起来, 最后还给出一个脚本化的高级用法.

继续阅读

使用 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 文件的方式将能有效地帮助我们.

.editorconfig 文件及作用

其实它就是一个类似于 ini 之类的配置文件, 而它的名字 editor config 显然也暗示了它是用于配置(config)编辑器(editor)的.

至于前面开头的那个点".", 这个在 windows 系统下将不会有什么作用;

在 linux 之类的系统上, 这个表示隐藏文件, 因为这些配置文件通常而言不需要普通成员了解及改动, 所以设置为一般情况下不显示.

具体而言它的作用是: 帮助工作在同一个项目的使用不同的编辑器和 IDE 的众多开发者维持统一的编程风格.

EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs.

下面是一个在 IDEA IDE 中项目里该文件的截图:

.editorconfig file demo in Intellij IDEA

通常, 你至少需要在项目的根文件下放置一个.

具体配置项及含义

虽然这个文件没有后缀名(或者说只有后缀名), 但它其实就是一个普通的文本文件, 任何的文本文件编辑器都可以直接打开它.

.editorconfig file content demo

我们直接看下它的内容:

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

就是一行一行的配置项, 关于编码, 缩进, 换行等等的规定.

比如上述的 charset = utf-8 的就配置了工程的文本编码缺省都用 utf-8;

又如 indent_style = space 则规定了整个工程使用空格来缩进, 而 indent_size = 4 则规定具体缩进 4 个空格;

end_of_line = lf 则规定了使用 unix(linux) 风格的换行符(lf), 而不是 windows 回车+换行风格的 crlf;

等等...

更多的配置项及高级用法, 请参考其官网 https://editorconfig.org/.

比如, 除了在项目的根目录下放置此文件外, 你还可以在子文件夹内放置它, 以进行更细微的控制, 规则将综合起作用;

又如, 除了将缩进风格统一为 4 空格的粗暴方式外, 你还可以控制根据文件后缀名进行细微控制, 比如 js 才用 2 空格, 而 java 用 4 空格;

还支持各种通配符的设置等等, 这里不一一介绍

作用机制

当然, 你可能会好奇, 为什么在这个文件设置了这些, 它就能起作用呢?

自然, 这离不开 IDE(编辑器)本身对这些文件的支持(可能是直接集成或是通过插件的方式).

比如 Intellij IDEA 就直接集成了对它的支持, Visual Studio 也是如此;

而 Eclipse 和 Visual Studio Code 则可能需要安装插件, 在其插件库中搜 editorconfig 关键字即能找到相关插件.

后续的版本也许可能直接支持, 但目前据我所知是没有直接支持.

另: 除了重量级的 IDE, 很多轻量级的编辑器也是有插件支持的, 具体见官网介绍, 如 Atom, Sublime 之类的.

对于 IDE 而言, 一个很好的观察角度是看这个文件上的图标, 如果该文件上有特殊的图标(以及打开时有代码高亮之类的), 则说明是有相关支持的.

而如果是普通文本图标, 而打开也只是一个普通文本显示, 则说明没有得到支持, 则可能需要安装相关插件.

另一方面, 许多 IDE 本身会有这些代码风格的设置, 对于支持 .editorconfig 文件的(或是安装了插件后支持的) IDE, .editorconfig 文件配置的规则就会作用到这些设置上.

这就带来了一个好处, 无需让团队成员一一去设置, 也避免了一些成员由于犯懒或规范意识不高而不去做这些设置的问题.

引入时机及版本管理要求

显然, 通过了解 .editorconfig 文件的作用, 我们不能猜测到, 引入这个配置文件的最佳时机显然就是在项目的创建之初, 有了它, 各类规则就有了落地的具体载体, 团队成员有机会明确知道项目有哪些具体代码风格上的规范.

另一方面, 成员后续创建并提交的各类源代码文件也会受到它所配置规则的约束, 从而形成统一的风格.

如果没有一开始引入, 后期也是可以引入的, 自然, 越早越好.

而这个配置文件自然也是需要纳入版本管理(git 或 svn), 直接提交到代码仓库中的. 这样一来, 项目成员只要拉取了代码, 就能获取到这些配置了.

同时, 后续的新规则补充或旧规则调整都能很方便同步到各个成员中.

延伸思考: 如何做好项目管理

最后, 想借此机会谈谈如何去做好项目的管理. 比如你现在是一个项目的负责人, 自然, 你自己首先要有规范化的意识, 然后才能去推动整个项目朝着规范化方向前进.

可是, 任何一个有经验的管理者都知道, 事情没有那么简单, 你可能开了好几次会议, 形成了很多决议, 大家也似乎意识到了统一规范的重要, 但在后续的实际运行中, 你也还是可能发现大家慢慢又不遵循规范了.

甚至在一开始就没有遵循!

好的管理者一定是深谙人性的, 而人就是无时不刻想犯懒想省事的, 这或许是最大的人性.

很多时候, 甚至不需要去说别人, 我们想想我们自己是不是这样的?

因此, 很多事情如果你只是靠嘴去说说, 到最后你已经说到厌烦不想再说的时候, 事情最终就又还是回到老样子.

当你不想再说时, 你也犯懒了!

真要把事情做好, 你是需要一些技巧的, 这通常就表现为借助一些工具而非依赖于人的觉悟, 而这里介绍的 .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 这个代理工具.

继续阅读

重复性管理——抽象的重要性(上)

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

Haskell 语言的设计者之一 Paul Hudak 曾说过一句略带夸张的话(overstatement):编程中最重要的三件事是:抽象,抽象,抽象

abstraction, abstraction, abstraction”are the three most important things in programming。

如果你去问一些资深开发者,程序员最重要的的能力之一有哪些?那么“抽象的能力”是绝对能排得上号的。

继续阅读

重复性管理——从泛值到泛型以及泛函(下)

在前面我们谈论了重复性管理上的一些具体做法,重点探讨了泛型范式泛函范式在解决重复性问题上的应用。因为前面的篇幅有很多被具体的代码例子占据了,所以留到现在这篇做一个归纳总结。

与数学的渊源

应该说,编程与数学还是颇有渊源的,或者说它们之间有很多相通的地方。数学的一个突出特点,那就是数学家总是在不断寻求更加一般化的表述,更为抽象的表达。我们来看一个具体的例子。

数学上有所谓的勾股数,最知名的就是我们所熟知的“勾三股四玄五”了。具体而言就是 3^2 + 4^2 = 5^2.

继续阅读

重复性管理——从泛值到泛型以及泛函(中)

在前面,我们探讨了泛型范式在解决重复性问题上的应用,在这里,将继续探讨泛函范式在解决重复性问题上的作用。

注:关于“泛函(functional)”这一名称,前面说了,泛型的本质是“参数化类型”,那么,按照这一思路,泛函的意思也可以理解为“函数的参数化”或者现在时髦的所谓“函数式编程(functional programming)”吧!

当然,你可以有自己的看法,这里用这种比较概括性的说法可以使得标题等比较简短,我也承认,很多时候,想取一个简短又准确的名字是不容易的。

继续阅读

重复性管理——从泛值到泛型以及泛函(上)

为什么用泛型以及它到底解决了什么问题?文中用大量例子介绍了重复性管理的一些具体做法,重点分析了泛型范式在解决重复性问题上的应用。

在之前,我们谈论了计算机科学是什么,我们知道了计算机科学重点在于复杂性的管理,然后在复杂性管理与重复性管理里我们又谈到了复杂性一个重要来源,也就是重复性。软件开发的一个重要主题就是要管理重复性,或者简单说,减少重复。

继续阅读

复杂性管理与重复性管理

探讨了简单重复性所带来的复杂性。

在前面我们说到了所谓的“计算机科学”,重点在于如何控制大型系统的复杂性。

复杂性本身当然也是个很大的话题,而一种常见的复杂性的来源则是重复性,即是由不断的重复所带来的复杂性。

重复性带来的复杂性常被人忽视,大概是因为一开始它是不起眼的,而当人们意识到它的存在时可能已经陷入了泥潭。

继续阅读