网络那端

2009年3月18日星期三

关于Log4J日志丢失的疑问和解决

首先说,这不是个问题,只是我的不慎,导致它成了一个问题,并困扰了我很久. 故事是这样的:

我用spring + strut2 + hibernate 开发了一个系统, 日志是使用log4j 实现的,并在log4j.xml 中配置. 本来一切工作都很正常, 突然有一天,我发现有很多的debug日志没有输出, 导致我调试非常的困难. 在log4j.xml 中我确认打开了我的包的debug级输出, 并把其他包都设置为warn级.

配置并没有错误. 但事情发生了, pak 包中有个 action包,它下面全部都是继承xwork2.ActionSupport来的Action类,例如:

pak.action.BaseAction
pak.action.UserAction
pak.action.RoleAction
pak.action......OtherAction ...
pak.utils.StrUtil
pak.utils.DateUtil

其中BaseAction是所有其他Action类的父类. pak.utils包是另外一个包. 我发现pak.utils包及其他包中的日志都能输出, 而pak.action中无法输出,只有在 warn以上的才能输出.

为什么会这样? Log4j 不稳定? 不能吧. 那这些类有什么和其他包中有什么区别呢?

仔细研究发现: 在pak.utils包和其他包中的每个类都使用下面的方法来定义log对象.
private final Log log = LogFactory.getLog(this.getClass());

而在BaseAction中则为了简化代码, 直接使用了xwork2.ActionSupport中定义的LOG:
private final Log log = ActionSupport.LOG;

明白了, 因为我在log4j.xml 中把com.opensymphony 设置为warn级,导致ActionSupport的子类中都无法输出info/debug级日志.

总结:

不知道为什么log4j是这样的, 想来应该是因为在继承中使用父类的对象,而父类又被限制所致.

解决的办法, 当然是又使用了 private final Log log = LogFactory.getLog(this.getClass()); 这个方式.肯定不能把xwork2的日志级别改为debug, 否则就死定了.

在这之前, 我也曾经考虑过让其他包分别继承并使用spring, hibernate, org.apache.commons 中已经定义的log对象, 以便让系统可以统一的控制日志输出. 现在看来,这个方法不可取. 否则你将无法控制只输出你自己的包里的日志.

2009年3月13日星期五

Ubuntu 的网络配置

Ubuntu的网卡配置信息,在文件 /etc/network/interfaces 中。

例如:

auto lo
iface lo inet loopback

#virtual interface
#
#auto eth0:1
#iface eth0:1 inet static
#address 10.1.1.1
#netmask 255.255.255.0
#network 10.1.1.0
#broadcast 10.1.1.255

打开后里面可设置每个网卡的DHCP或静态ip,及各项网络参数。前面auto eth0,让网卡开机自动挂载.修改该文件后,通过重新启动网络,可以立刻生效,命令:
sudo /etc/init.d/networking restart

Ubuntu 的 DHCP 客户端功能,是由/sbin/dhclient 实现的,其配置文件在/etc/dhcp3/dhclient.conf 中。

通过图形界面 系统-首选项 - Network Configuration 可以设置各个网卡。

1. 以DHCP方式配置网卡

编辑文件/etc/network/interfaces:
sudo vi /etc/network/interfaces

并用下面的行来替换有关eth0的行:
auto eth0
iface eth0 inet dhcp

然后,用下面的命令使网络设置生效:
sudo /etc/init.d/networking restart


也可以在命令行下直接输入下面的命令来获取地址
sudo dhclient eth0


2. 为网卡配置静态IP地址

编辑文件:
sudo vi /etc/network/interfaces

对eth0 配置如下:
#开机自动加载,并指定ip、网关、子网等
auto eth0
iface eth0 inet static
address 192.168.1.101
gateway 192.168.1.1
netmask 255.255.255.0
#network 192.168.1.0
#broadcast 192.168.1.255

用下面的命令使网络设置生效:
sudo /etc/init.d/networking restart


3. 设定第二个IP地址(虚拟网卡)

编辑文件
sudo vi /etc/network/interfaces

在该文件中添加如下的行:
auto eth0:1
iface eth0:1 inet static
address 192.168.2.201
netmask 255.255.255.0
#network x.x.x.x
#broadcast x.x.x.x
#gateway x.x.x.x


用下面的命令使网络设置生效:
sudo /etc/init.d/networking restart


4. 设置主机名称(hostname)

使用下面的命令来查看当前主机的主机名称
sudo /bin/hostname

或设置当前主机的主机名称:
sudo /bin/hostname name2

这个名称可以是全名,如:dog.mydomain.com, 也可以只是简称dog.

但该名称name2并没有被写入/etc/hostname文件,reboot之后,它会从该文件来读取主机的旧名称。所以如果要永久改变主机名,需要在/etc/hostname 文件中直接写入新的名称。

此外使用 sudo domainname 可以查看和设置域名。例如:
sudo domainname mydomain.com
(如果这个命令不存在,你需要安装nis包,实际上nis和portmap包多用在服务器上,个人用机不需要安装,用hostname命令就可以了)

我觉得hostname命令只是设置了当前的系统变量kernel.hostname, 可以通过sysctl命令来做相同的事情:
sysctl kernel.hostname 用来查看当前主机名和域名 sysctl kernel.hostname=NEW_NAME 用来设置主机名 sysctl kernel.domainname=NEW_DOMAIN


关于设置主机名称的更多信息,请访问这里


5. 配置DNS

简单的设置静态解析,在/etc/hosts文件中,加入一些主机名称和这些主机名称对应的IP地址,就可以直接使用。

要访问DNS 服务器来进行查询,需要设置/etc/resolv.conf文件.
假设DNS服务器的IP地址是192.168.1.2, 那么/etc/resolv.conf文件的内容应为:

search mydomain.com
nameserver 192.168.1.2

另外参考其他文章:
http://www.itkhl.com/Article/data/itkhl-62546.html
http://my.donews.com/wucr/2008/02/15/post-080215-095538-676/