很多人不愿意做伸手党,但有时候,我们却因为能力有限最终还是做了伸手党,怎么办?
最终的解决方案只有一个:提高能力,下次自己解决问题。
今天我们就一起提高一下能力:在寻找程序日志这件事上,再也不做伸手党。
一个尴尬
很多开发 web 服务的程序员都经历过这样一个尴尬:
登录了服务器,却找不到日志在哪
尤其是,自己明明有 superuser 权限[1],却连这么基本的信息都查不出来,只能张口问别人,是不是挺不好意思的?
而我在写这篇博客之前,也不知道怎么解决这个问题;但在一个 ubuntu 服务器上探索了一下之后(其实是几天之后),发现只要 10 分钟的功夫,所有人都可以借助 linux 类操作系统的特点[2],找到你想要的日志。
最简单的情况
如果想找日志,最简单的情况就是:日志写在一个编程框架约定的地址。
如果你的团队使用 Ruby on Rails 框架,那么日志很有可能写在 log/
目录下;如果是 Django 框架,那么在 settings.py
文件中可以找到日志的位置。我们所要做的,就是找到程序(进程)的工作目录,然后看看日志是否真的在那里。
至于怎么找进程的工作目录,pwdx ${your_pid}
这个命令你值得拥有。如果继续问,怎么找到进程号(pid),方法就很多了,比如通过一个服务的端口号,通过进程的名称,更多的方法请 google how to get pid of a process。这里只提醒一点,因为某些进程可能不是当前用户运行的,如果试用了各种方法之后却查不到某个进程,那么就可以试试加上 sudo 权限了。
没有默认的地址可以找
有时候,你要研究的服务使用的是一个陌生的框架,或者干脆就没用什么框架,再或者运维小哥哥在部署时改动了日志的位置但没有在项目代码中留下任何痕迹。这个时候,你要怎么找日志?
在 linux 家族的操作系统中,有关进程的信息,很多都被写在了 proc 文件系统中。你可以把 proc 文件系统理解为一个目录,他的地址就在 /proc
。这个目录下有很多的子目录,其中一个子目录就是以你要调查的进程的 pid 命名的。然后 cd /proc/${your_pid}
,你会看到这个进程的很多信息:
这里面可以探索的东西很多,你可以参照文档来探索一下这些“文件”都代表什么。但我们现在主要调查一下 fd 这个目录。
fd 的意思是 file descriptor,即文件描述符。我们每在程序中打开一个文件,这里都会多一个文件描述符。所以,可以想象,既然程序要写日志,那么他必然会有一个关于日志文件的文件描述符,我们只需要在这里 fd 这个目录下找到他就可以了。所以:
cd fd
ls -l # or ls -gG (not showing owner and group)
你会发现 1 和 2 这两个文件描述符就指向日志文件。
--> 符号前面的编号就是 fd 的数字编号事实上,每个进程都至少有 0,1,2 这三个文件描述符,其中 1 和 2 分别代表 stdout 和 stderr,这两个文件就是大多数程序默认的输出日志的地方。
其实,即使是我们上面提到的简单情况,也必然符合这里提到的规则。只不过因为惯例的帮助,我们不用来 /proc
目录下这样查找而已。
到这里,我们已经能够找到一些不出现在常规地址到日志了。如果你发现自己因为权限不够而无法进入fd
这个子目录,那么请使用 superuser 权限:sudo su
。
日志写在了 pts 中
上一节提到的规则是非常通用的,因为 linux 家族的操作系统都遵守这样的标准。但有一些程序还是比较特殊的,因为他们的日志会写入一个 pts 文件:
imagepts 叫做 pseudoterminal slave,并不是一个真正的文件;他只是在模拟一个输入输出设备。对于我们「找日志」的需求来说,一个有实践意义的关键点是,这个伪文件,可以像正常的文件一样读取:cat /dev/pts/1
,之后如果程序有新增(and only 新增)的日志,你就可以在终端中看到了。
但这样的处理无法让你看到过去的日志。如果你确定这些日志一定被收集在某个特定的文件中了,那么也是有办法通过当前的 pts 文件,找到那个最终的日志文件的。这个我们以后再讲(因为我现在也不知道)。
这里顺带说一下,如果一个服务是通过系统的service启动的,那么他的日志默认会被写在一个 pts 文件中,而这些写入 pts 文件的日志最终又会被收集一个叫做upstart 的程序收集到 /var/log/upstart
目录下面。
另外,如果你在/proc/${your_pid}/environ
文件中(这个文件会显示程序的环境变量)看到一些类似于 UPSTART_*
的环境变量,那么更有可能说明这个进程的文件在用 upstart 进行收集,所以更可以去/var/log/upstart
下去查看一番。
通过日志收集器收集的日志
有时候,我们会想办法用日志收集器收集日志,比如要集合多个服务器上的请求日志时。
如果你想要看这些日志,可能就要看一下程序中的代码了:
- 了解一下日志被发送到了那个ip地址
- 登录对应的服务器,查看日志收集器的配置,看看日志被转发到了哪里
- 去日志的最终目的地查看
当然,如果日志最终的目的地是一个可视化的整理工具(比如 Elasticsearch),你可就有福了。
网友评论