经验教训-先明确需求

最近工作中遇到一个问题,完成一个工作后发现自己的实现方式不够精简,主要是当初没有分析好需求的原因。

需求来了

最近要做一个linux下brasero刻录工具的刻录审计的功能。审计内容包括:刻录文件名称、大小、刻录机类型、刻录时间、刻录结果。

解决方法

通过了解,brasero在刻录光盘的时候会在/tmp目录下产生临时刻录日志文件,日志文件中记录有刻录文件的名称和绝对路径,通过分析日志文件就能获取刻录文件名称、刻录时间、刻录结果,根据文件名称可以计算文件大小信息,所以文件的大小也可以获取到。

另外刻录机的类型通过demsg获取系统启动时和启动后刻录机的加载信息,通过获取最近加载的刻录机信息来判断最近刻录时使用的刻录机类型。

这是在纯应用角度考虑的问题解决办法,我不知道能不能从linux内核角度通过某些特殊操作能够监控刻录相关驱动函数的调用来判断刻录操作,这里我就以我的解决方案为基础,谈一下我没有很好理解需求所犯的开发错误。

我的问题

由于考虑到开始监控刻录机操作前可能刻录机已经刻录了其他文件,也就是说/tmp目录下已经记录有其他刻录操作生成的日志文件,所以我就想把他们的刻录操作也获取到,这是我犯的错误,因为根本没必要获取,我们只需要监控从我们的审计程序启动后的刻录操作就可以了。

因为这个错误,我在代码中引入了链表,链表内又加入了两个指针数组,其中一个用于存放当前刻录操作中的文件名称,另外一个用于存放文件的大小,考虑到文件大小也是以直观方式展现,直接存成了char *filesize[128]。
我的结构体大概是这个样子的:

1
2
3
4
5
6
7
struct FileInfo{
char *file_name[128]; //存放文件名称
char *file_size[128]; //存放文件大小
char *record_time[32]; //存放刻录时间
int record_result; //存放刻录结果
char *record_machine[32]; //存放刻录机类型
}fileinfo, *p_fileinfo;

考虑到加入链表是想把所有的刻录日志文件都读取出来,每个日志文件中读取的信息存放到一个链表节点,这样就可以存放所有的日志信息了,等把所有的日志信息都读取完毕后,直接从链表头节点依次读取出这些刻录审计信息放到一个缓冲区,由日志上报进程上报到服务端。

但是事实上根本不需要这样做,实际情况下,刻录机不可能同时进行两个刻录操作,刻录操作都是一次只能进行一个,也就是说不会同时产生两个刻录日志文件,我上面考虑的多个刻录日志文件的情况是这种情况:我的审计程序没有启动前已经有刻录操作被执行了,所以/tmpo目录下有刻录日志文件。

我应该每次只获取最新的刻录日志文件,读取并上报它的信息就行了。但是如果我两个读取日志文件的时间间隔很大,中间发生了多次刻录操作的情况下,怎么处理?那就缩短刻录审计间隔吧,设置为5s的时间间隔,一般的刻录操作不会低于5s时间,所以这样可以保证不会两次审计之间存在多次刻录操作的情况。

如果每次都是读取一个日志文件,那就完全没有必要使用链表了,只需要把结构体内的数据全部放到头文件就行,每次读取完后直接将这次信息放到缓冲区内调用日志上报功能,进行审计日志上报就可以了。

当然为了数据的好看和整齐,可以保留这个数据结构,直接往这个结构体内存放数据就行,最后上报的时候再从这个结构体内读取信息就可以了。

总结

因为自己没有认真思考需求,导致做了很多无用工,其实是完全可以避免的。无用的设计导致代码逻辑变得复杂,更容易出现问题和不利于代码的可读性和维护,这是我应该吸取的教训,先读懂需求,再跟别人确认实现方案,这样才是最优的工作方式。

关于这个需求的解决方案,我觉得我的方法可能是有问题的,或许应该从内核方向着手更加稳妥一点,再研究一下,有新发现的话再更新这篇文章。

2018.06.03 北京 晴