关于Weblogic Server重启或log rotation导致server.log的i node number变化问2011-01-13 BlogJava 走走停停又三年关于Weblogic Server重启或log rotation导致server.log的i node number变化问题前两天同事问我一个问题,说是客户那边使用Tivoli分析weblogic server日志的时候,每当server重启,Tivoli就出错,说是FileId is changed。当时就怀疑可能跟server log的iNodeNumber有关。因为没怎么仔细看过weblogic server logging的代码,也不是很确认。跟同事说,让客户通过 ls -i 确认一下对应的iNodeNumber。客户反馈说:iNodeNumber没有发生变化,崩溃,文件名没变, iNodeNumber没变,Tivoli说的FileId到底是什么? FileSystem里还有其他标识文件的东西?我有点开始怀疑这个客户了,嘿嘿。 索性,自己做个测试吧。首先看了看weblogic的代码,log rotation的时候,只是调用了File.renameTo(),如下:weblogic.loggin.FileStreamHandler.rotateLog()logFile.renameTo(rotatedFile)见鬼了, rename完了iNodeNumber还有不变的道理?看看JDK代码再说,File.renameTo()1 public boolean renameTo(File dest) { 2 SecurityManager security = System.getSecurityManager(); 3 if (security != null) { 4 security.checkWrite(path); 5 security.checkWrite(dest.path); 6 } 7 return fs.rename(this,dest); 8 }这家伙,还是依赖于FileSystem的,再一看,FileSystem是个抽象类,rename的具体实现肯定跟具体的subclass有关了,只能看看Win32FileSystem吧,Win32FileSystem.java1 public boolean rename(File f1,File f2) { 2 // Keep canonicalization caches in sync after file deletion 3 // and renaming operations. Could be more clever than this 4 // (i.e.,only remove/update affected entries) but probably 5 // not worth it since these entries expire after 30 seconds 6 // anyway. 7 cache.clear(); 8 prefixCache.clear(); 9 return rename0(f1,f2); 10 } 11 private native boolean rename0(File f1,File f2);好了,现在看到了,rename0()是个native 操作,跟共享库(.dll or .so)又扯上关系了。得, 没有本地库代码,也看不到什么实现了(不过个人感觉,本地实现调用应该是系统函数rename: int rename(const char *old,const char *new)),只能自己做实现了。写了个小测试程序, 如下:1 package com.bea.cs.test.file; 2 3 import java.io.File; 4 5 public class FileTest { 6 7 private File src = new File("test"); 8 9 public static void main(String args[]) 10 { 11 FileTest test = new FileTest(); 12 test.run(); 13 } 14 15 public void run() 16 { 17 rename("test1"); 18 } 19 20 private boolean rename(String name) 21 { 22 boolean ret = false; 23 File dest = new File(name); 24 ret = src.renameTo(dest); 25 /* 26 * as src is renamed to dest,dest should hold the iNodeNumber of src 27 */ 28 src = new File("test"); 29 try 30 { 31 /* 32 * As has been renamed to dest,src should not exist again 33 * so we should create a new src file,or it will disappear when 34 * test exits. As a new file,src shuold get a new iNodeNumber 35 * that different from it"s original value 36 */ 37 if(!src.exists()) 38 src.createNewFile(); 39 }catch(Exception e) 40 { 41 e.printStackTrace(); 42 } 43 return ret; 44 } 45 }测试的结果如下:Test Reustlslsol6% ls -il total 8 6033508 drwxr-xr-x 3 fjin staff 4096 Sep 26 23:48 com 6033514 -rw-r--r-- 1 fjin staff 0 Sep 26 23:56 test slsol6% java com.bea.cs.test.file.FileTest slsol6% ls -il total 8 6033508 drwxr-xr-x 3 fjin staff 4096 Sep 26 23:48 com 6033506 -rw-r--r-- 1 fjin staff 0 Sep 27 01:03 test 6033514 -rw-r--r-- 1 fjin staff 0 Sep 26 23:56 test1现在我这能怀疑客户了, Tivoli报错应该是正常的(Work as design),不过比较纳闷的是:Tivoli为什么要引用FileId,而不是FileName? 开始想改改weblogic的代码,调用类似于 copy的操作,而不是rename。结果没有看到File提供类似的API,而且如果这样做的话,清空原先file内容也是个问题,于是作罢。