NIOログファイルの読み込み

4457 ワード

分散開発におけるログ処理の簡単な考え方
一.ログのフォーマットと生成ルール
1.約定ログの出力フォーマット
2.ログの生成を約束するディレクトリ
3.ログ生成を約束する期間は、1日に1つのログ・ファイルを生成するか、時間に1つのログ・ファイルを生成するか
 
二.ログ抽出
1.ログ抽出の応用ログ情報をmysqlライブラリに抽出する
2.各アプリケーションが統計する内容をタイミングで統計する(srping+quarz)
3.統計分析(HightChar)を表示できるweb端末を提供する
 
ファイルの収集整理、ログのIO読み取りに簡単なテスト方法を書きました.
 
 
@Test
	public  void test() throws Exception{
		
        long time = System.currentTimeMillis();
        System.out.println("    "+time);
        
	RandomAccessFile fin = new RandomAccessFile("D:\\logs\\catalina.out", "r");
	RandomAccessFile fout = new RandomAccessFile("D:\\logs\\catalina.out1", "rw");
        FileChannel fcin = fin.getChannel();  
        FileChannel fcout = fout.getChannel();  
        ByteBuffer buffer = ByteBuffer.allocate(15360);  
        int byteRead = 0;
        while((byteRead=fcin.read(buffer))>0){
        	buffer.flip();
        	while(buffer.hasRemaining()){
        		 fcout.write(buffer);
	   		}
           buffer.clear();
        }
        fcin.close();  
        fcout.close();  
        fin.close();  
        fout.close();  
        System.out.println("    "+System.currentTimeMillis());
        System.out.println("    " +(System.currentTimeMillis() - time));
	}

 
 
本機の構成はwin 7 4 Gメモリ64がシステム32がjdkである
 
以上のByteBufferを用いる読み取り処理を、2.57 GB(2764091431バイト)のNIOで行う.allocate(15360); 得られた値は
 
    1419939751750
    1419939811927
    60177

この値の設定は自分のパソコンの実際の構成テストに基づいて得ることができ、この値は私のパソコンでcpuの変動をほとんど感じず、これは複数のスレッドを開いて処理することも可能である.
 
ファイルが収集された後、それはファイルの読み取りであり、データベースに組み込まれ、採用されたテスト方法は:
	@Test
	public  void testRead() throws Exception{
        long time = System.currentTimeMillis();
        System.out.println("    "+time);
	RandomAccessFile fin = new RandomAccessFile("D:\\logs\\logger.log", "r");
	long pos = 0;
        fin.seek(pos);
		String line = null;
		while((line=fin.readLine())!=null){
			pos = fin.getFilePointer();
			System.out.println(line + "-----" + fin.getFilePointer());
			if(pos==232){
				break;
			}
		}
		fin.seek(pos);
		while((line=fin.readLine())!=null){
			System.out.println(line + "-----" + fin.getFilePointer());
		}
        System.out.println("    "+System.currentTimeMillis());
        System.out.println("    " +(System.currentTimeMillis() - time));
	}

 
このクラスは既読位置を設定ことができ、次回は設定位置からpos=finを読み出す.getFilePointer()は、解析入庫を行単位で読み込みます
 
NIOの別のファイル書き込み方式もあります
	@Test
	public void testTransTo(){
	try{
		
        long time = System.currentTimeMillis();
        System.out.println("    "+time);
		
	RandomAccessFile fromFile = new RandomAccessFile("D:\\logs\\catalina.out", "r");
	FileChannel      fromChannel = fromFile.getChannel(); 
		
	RandomAccessFile toFile = new RandomAccessFile("D:\\logs\\catalina.out1", "rw"); 
	FileChannel      toChannel = toFile.getChannel(); 
		
	long position = 0;
	long persize = fromChannel.size(); 
	long maxSize = persize;
		
	//FileChannel transferFrom()              FileChannel 
	//toChannel.transferFrom(fromChannel, position, count);
		
	//transferTo()      FileChannel      channel 。          :           1G  30      ,        cpu  ,             
		
	fromChannel.transferTo(position, persize, toChannel);
		
	fromFile.close();
	fromChannel.close();
	toFile.close();
	toChannel.close();
        
        System.out.println("    "+System.currentTimeMillis());
        System.out.println("    " +(System.currentTimeMillis() - time)/1000);
		
	}catch(Exception e){
	    e.printStackTrace();
	}
}

 
このように2.5個のログを読み取る私のcpuは瞬間的に90%以上になるが、読み取り時間は47で、元の1/2に縮小するには24が必要であるが、cpuも瞬間的に90%以上になり、元の1/3に縮小する読み取り時間は17 cpuの方が安定しているので、1 G以下のログを読むときに速度が少し高くなるのではないかと考えた.