若业务中涉及到需要记录日志的同时又需要满足日志按时切分功能的话,推荐使用管道pipe+cronolog,而落日志的媒介使用nginx或apache甚至自己写服务来实现也是可以的,paperen推荐nginx

http://paperen.com/file/201

本文按以下节奏进行:

认识管道(pipe)

对于日志的写入这个操作使用管道与不使用管道的区别,在一段时间内确实困扰着paperen,一位老java同事将原来使用管道落日志的操作改为用java来实现,原因是他不懂配置cronolog与管道...同时他觉得使用管道也是IO操作,PS:至今他仍坚守着通过java来写入日志的操作 关于管道,paperen先引用别人的一段说明

管道是进程间通信的主要手段之一。一个管道实际上就是个只存在于内存中的文件,

对这个文件的操作要通过两个已经打开文件进行,它们分别代表管道的两端。

管道是一种特殊的文件,它不属于某一种文件系统,而是一种独立的文件系统,有其自己的数据结构。

根据管道的适用范围将其分为:无名管道和命名管道。

截自:Linux 管道pipe的实现原理

  • 存在于内存中
  • 不属于某一种文件系统
  • 命名管道 FIFO文件

也就是说管道操作实际是操作内存并非IO,在认识管道后又搜索了一下其缺点,找到一篇文章

消息队列和管道的区别以及和共享内存相比效率低的原因

命名管道可在同一台计算机的不同进程之间或在跨越一个网络的不同计算机的不同进程之间,支持可靠的、单向或双向的数据通信。

不同于匿名管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾

共享内存比管道和消息队列效率高的原因:共享内存区是最快的可用IPC形式,一旦这样的内存区映射到共享它的进程的地址空间,这些进程间数据的传递就不再通过执行任何进入内核的系统调用来传递彼此的数据,节省了时间

概括来说,管道FIFO,比IO好,更效率高的话要使用共享内存

安装与使用cronolog

github地址:https://github.com/fordmason/cronolog 安装是很简单的,也可以编译安装

yum install cronolog

下面配置cronolog切分日志的一个例子

mkdir -p -m a+x  /data/logs/
 mkfifo -m a+x /data/logs/log

mkdir:创建目录 结合p参数代表创建上子目录 mkfifo:创建实名管道 -m:设置模式 a+x:追加与可执行

nohup cat /data/logs/log | nohup /usr/sbin/cronolog /data/logs/%y_%m_%d_%H.log >> /dev/null &

结合nginx实现日志切分

有上面的基础后,对于实现nginx日志的切分那很简单就是将nginx的access_log指向咱们配置的管道文件即可

  • nginx.conf中增加一个logformat(report)
  • 添加/修改nginx vhosts的配置(当然一般是新建一个vhost来处理)
  • 编写一个脚本来执行cronolog读取管道文件的数据
  • 重启nginx

以下直接放出相关脚本,相关路径按照自己实际情况调整

nginx.conf

log_format  report  '[$time_local] $remote_addr $request_uri';

domain.conf

server {
  listen   8282;
  server_name ip;

  access_log /data/logs/ip/access.log report;

  location /
  {
    root /usr/local/nginx/html;
  }
 }

report.sh

nohup cat /data/logs/ip/access.log | nohup /usr/sbin/cronolog /data/logs/%y_%m_%d_%H.log &

先执行report.sh后才重启nginx

如果看不懂也没关系,paperen这里提供一个部署脚本方便大家部署(内附安装nginx),下载脚本,你可以直接在联网的服务器直接执行以下命令

wget http://paperen.com/demo/cronolog-deploy/deploy.sh | chmod +x deploy.sh | ./deploy.sh

不过有些人不建议这样nginx+cronolog的切分日志方案,具体可以看这篇文章 Nginx and Cronolog