2014-01-13 165 views
4

我在網絡上搜索記錄器配置Jboss 7。如何使用日期和大小一起配置記錄器。如何在JBoss 7中配置PeriodicSizeRotatingFileHandler?

文件記錄儀1 size-rotating-file-handler

<size-rotating-file-handler name="FILE"> 
    <formatter> 
     <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> 
    </formatter> 
    <file relative-to="jboss.server.log.dir" path="server.log"/> 
    <rotate-size value="1000k"/> 
    <max-backup-index value="20"/> 
    <append value="true"/> 
</size-rotating-file-handler> 

Out Put Files are : 
    server.log.1 
    server.log.2 
    server.log.3 
    .. 

文件記錄儀2 periodic-rotating-file-handler

<periodic-rotating-file-handler name="FILE"> 
    <formatter> 
     <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> 
    </formatter> 
    <file relative-to="jboss.server.log.dir" path="server.log"/> 
    <suffix value=".yyyy-MM-dd"/> 
    <append value="true"/> 
</periodic-rotating-file-handler> 

Out Put Files are : 
    server.log.2013-12-12 
    server.log.2013-12-13 
    server.log.2013-12-14 
    .. 

我預期的文件

server.log.2013-12-12.1 
server.log.2013-12-12.2 
server.log.2013-12-12.3 
server.log.2013-12-13.1 
server.log.2013-12-13.2 
server.log.2013-12-13.3   

回答

4

根據您的JBoss版本7有一個org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler可以用作custom-handler。我相信它是在jboss-logmanager 1.3.0.Final中引入的。我不記得它在哪個版本的JBoss AS/WildFly中。

下面是CLI命令示例。

/subsystem=logging/custom-handler=example:add(class=org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler, module=org.jboss.logmanager, formatter="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n", properties={rotateSize=1024000,maxBackupIndex=20,suffix=".yyyy-MM-dd",fileName="${jboss.server.log.dir}/example.log"}) 
+0

感謝您的支持。我會爲此進行研究。 – CycDemo

+0

我明白了你的觀點。我也更新了我的答案。請檢查並檢查它。 – CycDemo

1

Jboss 7 (AS)必須是週期性的旋轉文件處理程序支持或大小旋轉文件處理程序,但不是兩者。

我得到一些參考(JBoss 7 Custom File Handler)支持週期性和大小旋轉。它正在編寫Custom File HandlerJBoss 7 Custom File Handler用於創建每日旋轉大小限制日誌。

但是,我根據我的要求更新了原始PeriodicSizeHandler.java的一部分源代碼。

我的更新源:

PeriodicSizeHandler.java

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.PrintWriter; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.logging.ErrorManager; 
import java.util.logging.Handler; 
import java.util.logging.Level; 
import java.util.logging.LogRecord; 

public class PeriodicSizeHandler extends Handler { 
    private int count = 1; 
    protected static Long calculatedBytes; 
    private String maxBytes = "2g"; 
    private String logFileName = "server.log"; 
    private static String logDirPath; 
    private File logFile; 
    private FileOutputStream outputStream; 

    static { 
     logDirPath = System.getenv("JBOSS_HOME") + "\\standalone\\log"; 
    } 

    public enum Bytes { 
     Byte("b", 1l), KiloBytes("k", (Byte.bytes * 1024)), MegaBytes("m", 
       (KiloBytes.bytes * 1024)), GigaBytes("g", 
       (MegaBytes.bytes * 1024)), ; 

     private Bytes(String byteAcronym, Long bytes) { 
      this.byteAcronym = byteAcronym; 
      this.bytes = bytes; 
     } 

     private String byteAcronym; 
     private Long bytes; 

     public static long getBytes(String maxBytesRep) throws Exception { 
      if (maxBytesRep == null && "".equals(maxBytesRep)) { 
       throw new Exception(
         "The max bytes representation cannot be empty or null"); 
      } 
      String uByteRepresentation = maxBytesRep.toLowerCase(); 
      for (Bytes b : values()) { 
       if (uByteRepresentation.endsWith(b.byteAcronym)) { 
        String strNumVal = uByteRepresentation.substring(0, 
          uByteRepresentation.indexOf(b.byteAcronym)); 
        try { 
         return getBytes(Double.valueOf(strNumVal), b); 
        } catch (Exception e) { 
         throw new Exception(
           "The max bytes representation: " 
             + maxBytesRep 
             + ", is not valid. Shoubl be of the form XXX..(B or b)/M or m /G or g). Ex: '1000b', '100m', '1g'"); 
        } 
       } 
      } 
      // If no acronym is mentioned consider it as Byte representation Ex. 
      // maxBytes = 1000 
      try { 
       return getBytes(Double.valueOf(uByteRepresentation), Bytes.Byte); 
      } catch (Exception e) { 
       throw new Exception(
         "The max bytes representation: " 
           + maxBytesRep 
           + ", is not valid. Shoubl  be of the form XXX../(B or b)/M or m /G or g). Ex: '1000', '1000b', '100m', '1g'"); 
      } 
     } 

     public String getByteAcronym() { 
      return this.byteAcronym; 
     } 

     public Long getBytes() { 
      return this.bytes; 
     } 

     public static long getBytes(double multiple, Bytes bytes) { 
      return Math.round(multiple * bytes.bytes); 
     } 
    } 

    public PeriodicSizeHandler() { 
    } 

    @Override 
    public void flush() { 
     try { 
      if (outputStream != null) { 
       outputStream.flush(); 
      } 
     } catch (IOException e) { 
      reportError(e.getMessage(), e, ErrorManager.FLUSH_FAILURE); 
     } 
    } 

    @Override 
    public void close() { 
     if (outputStream != null) { 
      try { 
       outputStream.close(); 
      } catch (IOException e) { 
       reportError(e.getMessage(), e, ErrorManager.CLOSE_FAILURE); 
      } 

     } 
    } 

    @Override 
    public void publish(LogRecord record) { 
     init(); 
     if (rollOver(record)) { 
      archiveFile(); 
      createLogChannel(); 
     } 
     logToFile(record); 
    } 

    // Initialize 
    public synchronized void init() { 
     if (outputStream == null) { 
      try { 
       logFile = new File(getFilePath()); 
       if (logFile.exists()) { 
        outputStream = new FileOutputStream(logFile, true); 
       } else { 
        createLogChannel(); 
       } 
      } catch (FileNotFoundException e) { 
       reportError(e.getMessage(), e, ErrorManager.OPEN_FAILURE); 
      } 
     } 
    } 

    private String getFilePath() { 
     return getLogDirPath() + File.separator + logFileName; 
    } 

    // check the file size 
    private boolean rollOver(LogRecord record) { 
     try { 
      StringBuilder logMessage = new StringBuilder(getFormatter().format(record)); 
      if ((outputStream.getChannel().size() + logMessage.length()) > getByteValue(getMaxBytes())) { 
       return true; 
      } 
     } catch (IOException e) { 
      reportError(e.getMessage(), e, ErrorManager.GENERIC_FAILURE); 
     } 
     return false; 
    } 

    /** 
    * Rename with date and time stamp 
    */ 
    private void archiveFile() { 
     System.out.println("archiveFile.........."); 
     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); 
//  String logDir = getLogDirPath() + File.separator + simpleDateFormat.format(new Date()); 
     String newFilePath = getLogDirPath() + File.separator + logFileName + "_" + simpleDateFormat.format(new Date()) + "_" + count++; 
     File newFile = new File(newFilePath); 
     try { 
      OutputStream oos = new FileOutputStream(newFile); 
      byte[] buf = new byte[8192]; 
      InputStream is = new FileInputStream(logFile); 
      int c = 0; 
      while ((c = is.read(buf, 0, buf.length)) > 0) { 
       oos.write(buf, 0, c); 
       oos.flush(); 
      } 
      oos.close(); 
      is.close(); 
      PrintWriter writer = new PrintWriter(logFile); 
      writer.print(""); 
      writer.close();   
     } catch(Exception e) { 
      reportError("Unable to rename old file: " + logFile.getName() 
        + " to new file: " + newFile, null, ErrorManager.GENERIC_FAILURE); 
     } 
    } 

    private void createLogChannel() { 
     try { 
      // make directories 
      File logDir = new File(getLogDirPath()); 
      logDir.mkdirs(); 

      // create log file 
      System.out.println("getFilePath(: " + getFilePath()); 
      logFile = new File(getFilePath()); 
      logFile.createNewFile(); 

      // create the channel 
      outputStream = new FileOutputStream(logFile, true); 
     } catch (FileNotFoundException e) { 
      reportError(e.getMessage(), e, ErrorManager.OPEN_FAILURE); 
     } catch (IOException e) { 
      reportError(e.getMessage(), e, ErrorManager.OPEN_FAILURE); 
     } 
    } 

    private synchronized void logToFile(LogRecord record) { 
     StringBuilder logMessage = new StringBuilder(getFormatter().format(record)); 
     try { 
      if (outputStream != null) { 
       outputStream.write(logMessage.toString().getBytes()); 
       outputStream.flush(); 
      } 
     } catch (IOException e) { 
      reportError(e.getMessage(), e, ErrorManager.WRITE_FAILURE); 
     } 
    } 

    protected long getByteValue(String maxBytes) { 
     if (calculatedBytes != null) { 
      return calculatedBytes; 
     } 
     try { 
      calculatedBytes = Bytes.getBytes(maxBytes); 
     } catch (Exception e) { 
      logToFile(new LogRecord(Level.INFO, "Failed to get byte value from maxBytes: " + maxBytes + ", exception: " + e)); 
      calculatedBytes = getDefaultBytes(); 
     } 
     return calculatedBytes; 
    } 

    // Use Default - 2GB 
    protected Long getDefaultBytes() { 
     int multiple = 2; 
     logToFile(new LogRecord(Level.INFO, "Using the default: '" + multiple + Bytes.GigaBytes.byteAcronym + "'")); 
     return Bytes.getBytes(multiple, Bytes.GigaBytes); 
    } 

    public String getMaxBytes() { 
     return maxBytes; 
    } 

    public void setMaxBytes(String maxBytes) { 
     this.maxBytes = maxBytes; 
    } 

    public String getLogFileName() { 
     return logFileName; 
    } 

    public void setLogFileName(String logFileName) { 
     this.logFileName = logFileName; 
    } 

    public File getLogFile() { 
     return logFile; 
    } 

    public void setLogFile(File logFile) { 
     this.logFile = logFile; 
    } 

    public FileOutputStream getOutputStream() { 
     return outputStream; 
    } 

    public void setOutputStream(FileOutputStream outputStream) { 
     this.outputStream = outputStream; 
    } 

    public void setLogDirPath(String logDirPath) { 
     this.logDirPath = logDirPath; 
    } 

    public String getLogDirPath() { 
     return logDirPath; 
    } 
} 

PeriodicSizeHandlerTest.java

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.util.logging.Formatter; 
import java.util.logging.Level; 
import java.util.logging.LogRecord; 

import junit.framework.TestCase; 

import org.junit.Before; 
import org.junit.Test; 

import com.cyc.jboss.logging.PeriodicSizeHandler.Bytes; 

public class PeriodicSizeHandlerTest extends TestCase { 
    @Before 
    public void setUp() { 
     PeriodicSizeHandler.calculatedBytes = null; 
    } 

    Long bytes = Bytes.getBytes(100, Bytes.Byte); 

    @Test 
    public void testPublishRollOverTrue() throws Exception { 
     PeriodicSizeHandler psh = new PeriodicSizeHandler(); 
     psh.setMaxBytes("3k"); 
     setupFormatter(psh); 
     // text.txt file size is `151k` 
     FileReader fr = new FileReader("D:/temp/test.txt"); 
     BufferedReader br = new BufferedReader(fr); 
     String message; 
     while ((message = br.readLine()) != null) { 
      LogRecord logRecord = new LogRecord(Level.INFO, message); 
      psh.publish(logRecord); 
     } 
     fr.close(); 
     assertTrue(psh.getOutputStream() != null); 
    } 

    private void setupFormatter(PeriodicSizeHandler psh) { 
     Formatter formatr = new Formatter() { 
      @Override 
      public String format(LogRecord record) { 
       return record.getLevel() + " :: " + record.getMessage(); 
      } 
     }; 
     psh.setFormatter(formatr); 
    } 

    public static void main(String[] args) { 
     org.junit.runner.JUnitCore 
       .main(PeriodicSizeHandlerTest.class.getName()); 
    } 
} 

我得到了我的預期輸出文件,如下

server.log_2014-01-13_1 
server.log_2014-01-13_2 
server.log_2014-01-13_3 
.... 
server.log_2014-01-13_55 

如果你想使用你的自定義文件格式,你只需要更新archiveFile()方法,我想是的。

Next solutionJames R.Perkins建議。

下載jboss-logmanager-1.5.1.Final.jarhere

替換舊的jboss-logmanger-xxxx.jarjboss-logmanager-1.5.1.Final.jar<JBOSS_HOME>\modules\org\jboss\logmanager\main目錄。

更改module.xml配置如下

<module xmlns="urn:jboss:module:1.1" name="org.jboss.logmanager"> 
    <resources> 
     <resource-root path="jboss-logmanager-1.5.1.Final.jar"/> 
     <!-- Insert resources here --> 
    </resources> 

    <dependencies/> 
</module> 

配置爲standalone.xml

<subsystem xmlns="urn:jboss:domain:logging:1.1"> 
    ..... 
    <custom-handler name="FILE" class="org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler" module="org.jboss.logmanager"> 
     <formatter> 
      <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> 
     </formatter> 
     <properties> 
      <property name="file" value="D:\temp\server.log"/> <--- your log directory   
      <property name="rotateSize" value="50000"/>   <--- 50000 byte 
      <property name="maxBackupIndex" value="50"/>   
      <property name="append " value="true"/> 
      <property name="suffix" value=".yyyy-MM-dd"/> 
      <property name="autoflush" value="true"/> 
     </properties> 
    </custom-handler> 
    .... 
    <root-logger> 
     <level name="INFO"/> 
     <handlers> 
      <handler name="CONSOLE"/> 
      <handler name="FILE"/> 
     </handlers> 
    </root-logger> 
</subsystem>  

輸出:

server.log.2014-01-16.1 
server.log.2014-01-16.2 
server.log.2014-01-16.3 
+0

我希望有任何建議或意見。因爲這只是我的解決方案。 – CycDemo

+0

只是幾個意見。該處理程序不是線程安全的,而是使用reportError()方法,而不是使用另一個創建新記錄並記錄到該文件。 –

+2

可能要使用相對日誌文件位置,如'$ {jboss.server.log.dir}/server.log' – eis

4

下面是我工作(請務必改變rotationSize和maxBackupIndex以任何有意義的,你的數字我在那裏只是用於測試。):

 <custom-handler name="FILESIZEDATE" class="org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler" module="org.jboss.logmanager"> 
      <formatter> 
       <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> 
      </formatter> 
      <properties> 
       <property name="autoFlush" value="true"/> 
       <property name="append" value="true"/> 
       <property name="rotateSize" value="1000"/> 
       <property name="maxBackupIndex" value="20"/> 
       <property name="suffix" value=".yyyy-MM-dd"/> 
       <property name="fileName" value="${jboss.server.log.dir}/server.log"/> 
      </properties> 
     </custom-handler> 

     <root-logger> 
      <level name="INFO"/> 
      <handlers> 
       <handler name="FILESIZEDATE"/> 
       <handler name="CONSOLE"/> 
      </handlers> 
     </root-logger> 
+0

我如何在Jboss AS 6中實現相同? – happy

-1

的例子由生物和CycDemo爲我工作。但是,有一件重要的事情要注意。

  <custom-handler name="FILE" 
      class="org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler" 
      module="org.jboss.logmanager"> 
      <properties> 
       <property name="maxBackupIndex" value="10"/> 
       <property name="rotateSize" value="500000"/> <!-- 500 Kb --> 
       <property name="suffix" value=".yyyy-MM-dd"/> 
       <property name="fileName" value="${jboss.server.log.dir}/server.log"/> 
       <property name="append" value="true"/> 
       <property name="autoFlush" value="true"/> 
      </properties> 
     </custom-handler> 

maxBackupIndex值爲10表示該特定日期可能有10個索引文件。但是,這不會清理超過十天的日誌文件,或者在寫完十個日誌文件之後。這裏沒有任何參數,比如舊log4j.xml TimeAndSizeRollingAppender規範中的舊MaxRollFileCount,它將在寫入一定數量的日誌文件後清理日誌文件。

如果您想要清理舊的JBoss日誌文件,您必須使用cron和帶有+ mtime參數的find命令。

+0

我如何在Jboss AS 6中實現相同? – happy