用C语言+HTML(Bootstrap、JS)编写一套工具

天台道人 发布于 2016/03/12 14:38
阅读 21
收藏 1

概述

这是一个轻量级日志系统,分C-API、接收和展示共三个部分。C代码要求跨平台——Linux、Windows、OSX,验收在Ubuntu下进行,WebUI只要支持Chrome。代码清晰整洁、简单好懂,C代码能做成可重用的全做成可重用放util,模块要实现完整把业务代码凝练得很清晰流畅。头文件定义请参考附件,确定好util头文件接口后请和我沟通。需求写得很细,请耐心看完。


背景

日志格式示例

{

"type":"log",

"host":"",

"dir":"", //程序所在目录

"app":"", //程序可执行文件名

"param":"-config sample.xml", //程序执行参数

"pid":, //程序进程Id

"body":"", //日志正文

"ts":, //unix时间戳,单位秒

"level":number, //日志等级,0~7, DBG, INF, NOTICE, WARN, ERR, CRIT, ALERT, EMERG

"line":, //log接口所在代码文件的行号

"file":"trans.c", //log接口所在代码文件的文件名

"job_id":"",

"task_id":"",

// "history":true //存在该字段且为true时,表示这是一条补发数据,WebUI上的过滤条件为实时时,无需显示带history属性的log,因为它已经不实时了

}

host/app/body/level/job_id/task_id由用户通过C接口输入, dir/param/pid/ts/line/file由api自动获取

心跳格式示例

{"type":"heartbeat", "host":"", "dir":"", "app":"", "param":"", "pid":***}

消息队列

http://nats.io

https://github.com/nats-io/cnats

Util中的模块

线程、互斥等跨平台的模块已经写好放在附件中,其他模块的头文件部分示例也在附件。每个模块由sample.h/sample.c和sample_test.c组成,测试C文件要测试通过所有接口

http_server(基于https://github.com/h2o/h2o,支持WebSocket,建议使用html+javascript编写测试代码,更简单)、unqlite(接口我没写,参照mongodb实现)、mongodb、zip、json、queue


工具A —— 日志输出编程库log.h/.c

提供两个编程接口,在stdout打印日志,同时,通过消息队列发送日志给后台程序,如果断网则存入磁盘。代码风格为ANSI-C风格,或linux内核的风格。

API

/* 程序初始化时调用,host对应日志的host字段,mq_addr是nats的地址 */

int log_init(const char *host, const char *mq_addr, int mq_port);

/* 生成日志,使用类似与C语言中sprintf的可变参,job_id和task_id为空时json中也不写对应字段 */

void log(enum log_level level, const char *job_id, const char *task_id, const char *fmt, ...);

工作流程

1、字符界面输出格式示例 [ERROR] Can't find (or read) directory to add to classloader

2、log接口在格式化可变参数时,要求不限制输出结果长度,可采用循环snprintf+判断返回值的方式

3、log接口把可变参格式化成日志正文后,组装json,gzip压缩,加入队列,后台有个线程(不在log接口中同步发送或写磁盘是处于保证log接口尽快返回,不影响调用者性能),以消息队列方式将日志发送给叫"log"的主题,如果发送失败则保存在缓存目录。

4、log接口每10秒写入一个新日志文件,路径为"进程所在目录/log/pid-unixtime.log"(需要自动建立log目录),独占方式写磁盘文件

5、log接口保存在磁盘的日志是去除了回车换行的json,两条json间以换行符分割,以便读取时区分起止

6、30秒定时发送心跳给log主题

7、网络畅通时检查日志缓存目录,当日志程序文件名对应的时间比当前系统时间大10秒以上时则打开该文件,把日志读取后增加history属性且置true,gzip压缩,然后放发送队列,发出去后删除磁盘文件


工具B —— 日志处理程序logd

这是一个日志后台处理程序,通过消息队列监听(订阅叫log的主题)接收日志,以json数据库Unqlite和MongoDB保存日志,以WebUI展示日志,WebUI尽可能打包进可执行文件,以浏览器访问程序的http监听地址即可访问WebUI

1、和WebUI传输时直接使用json

2、减少数据库读写,比如100ms进行一次批量读写,或者通过事务实现(若用事务则用代码自动实现,避免人工设置数据库的麻烦),减少性能影响

3、根据logKeepDays参数定时清理数据库

4、自动建库建表,每天一个集合,比如20160301

5、WebUI可多开且同时相互独立工作

6、程序可独立运行,也易于嵌入其他c项目

7、统计host、app、dir、pid时,可以在数据库中单独建表管理

8、logd和WebUI间使用Websocket通信时要制定简单的应用层协议,请自行制定,keep it simple

配置文件

{

"db":"unqlite/mongodb" // 数据库的种类,二选一,

"dbAddr":"ip:port"

"dbUsr":"",

"dbPwd":"",

"httpListenPort": //webUI的访问端口

"wsListenPort":13 //webUI的websocket通信端口,如果可以省略此人工配置更好

"logKeepDays":100 //日志超出这个天数时,删除过时的日志,<=0表示无限

"showJobId":true //是否显示JobId选项,这个选项允许隐藏

}


工具C —— WebUI for logd

草图

IMG.jpg

文字补充:

1、仅一个页面,采用bootstrap,Klavika-Regular字体;每条日志由自定义内容(默认为日志中的ts,多个字段时以空格隔开,有背景色,颜色和日志等级关联)和日志正文(日志中的body)组成

2、用http获取页面,用websocket获取实时日志

3、倒序显示,最新的在最前,日志一行不够显示时自动换行,每页显示的日志条数自适应,不要水平垂直滚动条,以iframe嵌入其他页面时也尽可能保持此特性,,鼠标悬浮于各行时,以悬浮div显示对应的日志json全文

4、Host/App/Pid的值是与logd连接建立和数据需刷新时给前端的,表示当前条件(实时或历史)下所有可能的值,默认为"All",历史条件下Host可多达上百,请注意显示空间。“Realtime”下拉框的值有2个可能:Realtime/History,默认为前者。Level的值有8个可能值:Dbg+ / Info+ / Notice+ / Warn+ / Err+ / Crit+ / Alert+ / Emerg+,+表示大于等于,默认为Dbg+。”Job Id“、”Body key words“、”Extern filter“、”Show filter“由人工填写,Show filter默认值为"ts",其余的默认空。”Start“按钮文字在”Start“和"Stop"之间切换,表示执行和停止操作,执行操作前清空日志结果区

5、Pid字段仅在选“Realtime”时有效,否则禁用;“Start time”、“End time”和翻页按钮仅在选“History”时才有效,否则禁用断网后所有选项禁用或给提示,并自动不限次重连

6、"Body key words"表示logd需检查日志的body字段的文本中是否有关键字,有才发送;”Extern filter“可输入一个json,后台以该json指定的key-value匹配,符合的才返回前端;"Show filter"无需给后台,仅前端用,表示自定义显示需显示哪些字段,输入和显示时以空格隔开多个字段

加载中
0
小帅帅丶
小帅帅丶
好像我上家公司的行业
返回顶部
顶部