【问题标题】:Adding logger in log4j2.xml programmatically以编程方式在 log4j2.xml 中添加记录器
【发布时间】:2014-07-20 00:04:06
【问题描述】:

是否可以通过指定记录器名称在log4j2 中添加记录器可编程性? 我厌倦了在网上搜索它,我发现log4j2 不允许这种功能。这是链接:

How to add Log4J2 appenders at runtime programmatically?

有没有办法做到这一点?

【问题讨论】:

    标签: java logging log4j2


    【解决方案1】:

    我最近有机会以编程方式实现 log4j2 记录器,我想分享一下。

    以下是使用 ConfigurationBuider API 在 log4j2 环境中创建/添加记录器的代码 sn-p:

    package com.simple.log4j2.demo.demo;
    
    import org.apache.logging.log4j.core.Appender;
    import org.apache.logging.log4j.core.Logger;
    import org.apache.logging.log4j.core.LoggerContext;
    import org.apache.logging.log4j.core.appender.ConsoleAppender;
    import org.apache.logging.log4j.core.config.Configuration;
    import org.apache.logging.log4j.core.config.Configurator;
    import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
    import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
    import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
    
    public class Log4j2Logger {
    
    int counter = 0;
    
    LoggerContext ctx;
    
    Configuration config;
    
    Logger logger;
    
    String loggerName = "testLogger";
    
    String appenderName = "myAppender";
    
    static String testMessage = "This is a Test Message";
    
    public void log() {
    
        final ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
        config = builder.build();
        ctx = Configurator.initialize(config);
        config = ctx.getConfiguration();
        ctx.start(config);
        ctx.updateLoggers(config);
    
        // To create/add the logger of the configuration specified above we can use the
        // getLogger(..) method
        logger = ctx.getLogger(loggerName);
    
        // Now we need to attach an appender to the logger so that our messages could be
        // logged
        logger.addAppender(addConsoleAppender(ctx.getConfiguration(), appenderName));
        while (counter < 10) {
            logger.error(testMessage + counter);
            counter++;
        }
    
        // We can remove the logger in the context also after use.
        removeLogger();
    }
    
    private Appender addConsoleAppender(Configuration config, String appenderName) {
        Appender consoleAppender = ConsoleAppender.newBuilder().setConfiguration(config).setName(appenderName)
                .withImmediateFlush(true).build();
        consoleAppender.start();
        return consoleAppender;
    }
    
    public void removeLogger() {
    
        config.getLoggerConfig(loggerName).getAppenders().get(appenderName).stop();
        config.getLoggerConfig(loggerName).removeAppender(appenderName);
        config.removeLogger(loggerName);
        ctx.updateLoggers(config);
        }
    }
    

    对于测试,您可以在任何测试类中包含以下内容:

        Log4j2Logger testLogger = new Log4j2Logger();
        testLogger.log();
    

    此 API 可帮助您以强大的方式处理日志。

    你可以:

    • 使用您的配置创建多个记录器
    • 向其中添加多个 Appender。同时配置它们。
    • 使用结束时删除记录器。
    • 同时创建异步记录器。

    PS : 我使用的是 log4j2 版本 2.12.1。

    【讨论】:

      【解决方案2】:

      我想分享一下我是如何使用 log4j2 实现它的。 您可以添加新的记录器并删除现有的记录器。 也可以更改日志级别。

          src/
              main/
                  java/
                     com/foo/bar/
                         LogLevelPM  
                         LogLevelWin  -- Swing UI
      
                  resources/
                      log4j2.xml
      

      log4j2 的配置

      <?xml version="1.0" encoding="UTF-8"?>
          <Configuration status="WARN">
            <Appenders>
              <Console name="Console" target="SYSTEM_OUT">
                <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
              </Console>
            </Appenders>
            <Loggers>
              <Logger name="com.foo.bar.myLogger" level="debug" additivity="false">
                  <appender-ref ref="Console"/>
              </Logger>
              <Root level="trace">
                <AppenderRef ref="Console"/>
              </Root>
            </Loggers>
          </Configuration>
      

      LogLevelPM 进行实际操作,LogLevelWin 只是一个使用它的示例。

      package com.foo.bar;
      
      import java.util.Collection;
      import java.util.Map;
      
      import org.apache.logging.log4j.Level;
      import org.apache.logging.log4j.LogManager;
      import org.apache.logging.log4j.core.Appender;
      import org.apache.logging.log4j.core.LoggerContext;
      import org.apache.logging.log4j.core.config.Configuration;
      import org.apache.logging.log4j.core.config.LoggerConfig;
      
      public class LogLevelPM {
      
          public Object[][] retrieveLoggers() {
              Object[][] result = null;
      
              LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
              Configuration config = ctx.getConfiguration();
      
              Collection<LoggerConfig> loggerConfigs = config.getLoggers().values();
              result = new Object[loggerConfigs.size()][];
              LoggerConfig rootLoggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
              result[0] = new Object[] {"ROOT", rootLoggerConfig.getLevel().toString(), getAppenderNames(rootLoggerConfig.getAppenders())};
      
              int i = 1;
              for (LoggerConfig loggerConfig : loggerConfigs) {
                  if (!loggerConfig.getName().isEmpty()) {
                      result[i++] = new Object[]{loggerConfig.getName(), loggerConfig.getLevel().toString(), getAppenderNames(loggerConfig.getAppenders())};
                  }
              }
      
              return result;
          }
      
          public String[] getAllAppenders() {
              LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
              Configuration config = ctx.getConfiguration();
      
              Map<String, Appender> appenders = config.getAppenders();
      
              String[] appenderNames = (String[]) appenders.keySet().toArray(new String[appenders.size()]);
      
              return appenderNames;
          }
      
          private String getAppenderNames(Map<String, Appender> appenders) {
              Collection<Appender> existingAppenders = appenders.values();
              String result = "";
      
              for (Appender appender : existingAppenders) {
                  if (!result.isEmpty()) {
                      result += ",";
                  }
                  result += appender.getName();
              }
      
              return result;
          }
      
          public void changeLogLevel(String loggerName, Level level) {
              LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
              Configuration config = ctx.getConfiguration();
              LoggerConfig loggerConfig = null;
              if (loggerName.equals("ROOT")) {
                  loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);         
              } else {
                  loggerConfig = config.getLoggerConfig(loggerName);          
              }
              if (loggerConfig != null) {
                  loggerConfig.setLevel(level);
                  ctx.updateLoggers();            
              }
          }
      
          public void changeAppender(String loggerName, Level level, String appenderName) {
              LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
      
              Configuration config = ctx.getConfiguration();
      
              Map<String, Appender> allAppenders = config.getAppenders();
      
              Appender newAppender = allAppenders.get(appenderName);
      
              if (newAppender != null) {
                  LoggerConfig loggerConfig = null;
                  org.apache.logging.log4j.core.Logger coreLogger = null;
                  if (loggerName.equals("ROOT")) {
                      loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME); 
                  } else {
                      loggerConfig = config.getLoggerConfig(loggerName);          
                  }
      
                  Map<String, Appender> appenders = loggerConfig.getAppenders();
                  Collection<Appender> existingAppenders = appenders.values();
      
                  for (Appender appender : existingAppenders) {
                      loggerConfig.removeAppender(appender.getName());
                  }
      
                  loggerConfig.addAppender(newAppender, level, null);
      
                  ctx.updateLoggers();            
              }
          }
      
          public void addLogger(String loggerName, Level level, String appenderName) {
              LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
      
              Configuration config = ctx.getConfiguration();
      
              LoggerConfig loggerConfig = new LoggerConfig(loggerName, level, false);
      
              Map<String, Appender> allAppenders = config.getAppenders();
      
              Appender appender = allAppenders.get(appenderName);
      
              loggerConfig.addAppender(appender, level, null);
      
              config.addLogger(loggerName, loggerConfig);
      
              ctx.updateLoggers();
          }
      
          public void deleteLogger(String loggerName) {
              LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
      
              Configuration config = ctx.getConfiguration();
      
              config.removeLogger(loggerName);
      
              ctx.updateLoggers();        
          }
      }
      

      LogLevelWin 是基于 Swing 使用上述方法的示例。 这是一段日志代码,您可以跳过。

          package com.foo.bar;
      
      import java.awt.Component;
      import java.awt.Dimension;
      import java.awt.EventQueue;
      import java.awt.event.WindowAdapter;
      import java.awt.event.WindowEvent;
      
      import javax.swing.JFrame;
      
      import net.miginfocom.swing.MigLayout;
      
      import javax.swing.DefaultCellEditor;
      import javax.swing.JButton;
      import javax.swing.JComboBox;
      import javax.swing.ListSelectionModel;
      
      import org.apache.logging.log4j.Level;
      import org.apache.logging.log4j.LogManager;
      import org.apache.logging.log4j.core.LoggerContext;
      import org.apache.logging.log4j.core.config.Configuration;
      import org.apache.logging.log4j.core.config.LoggerConfig;
      
      import java.awt.event.ActionListener;
      import java.awt.event.ActionEvent;
      import java.util.Collection;
      
      import javax.swing.JScrollPane;
      import javax.swing.JTable;
      import javax.swing.event.TableModelEvent;
      import javax.swing.event.TableModelListener;
      import javax.swing.table.DefaultTableCellRenderer;
      import javax.swing.table.DefaultTableModel;
      import javax.swing.table.TableColumn;
      import javax.swing.table.TableModel;
      import javax.swing.JPanel;
      
      public class LoglevelWin extends JFrame {
          private static final long serialVersionUID = 1L;
      
          private Component parent;
          private JScrollPane scrollPane_1;
          private JTable tblLoggers;
          private JButton btnRefresh;
          private JPanel panel;
          private JButton btnNewButton;
          private JButton btnDelete;
          private boolean dirty;
      
          private LogLevelPM logLevelPM = new LogLevelPM();
      
          /**
           * Launch the application.
           */
          public static void main(String[] args) {
              EventQueue.invokeLater(new Runnable() {
                  public void run() {
                      try {
                          LoglevelWin frame = new LoglevelWin(null);
                          frame.setVisible(true);
                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                  }
              });
          }
      
          /**
           * Create the frame.
           */
          public LoglevelWin(Component parent) {
              setMinimumSize(new Dimension(800, 400));
              if (parent != null) {
                  this.parent = parent;
                  parent.setEnabled(false);           
              }
      
              initUI();
      
              setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
      
              this.addWindowListener(new WindowAdapter() {
                  public void windowClosing(WindowEvent e) {
                      close();
                  }
              });
      
              setLocationRelativeTo(null);
      
              retrieveLoggers();
      
              setVisible(true);
          }
      
          // logger from server
          private void retrieveLoggers() {
              // table model
              Object[][] loggerModels = logLevelPM.retrieveLoggers();
      
              if (loggerModels != null) {
                  String[] columnNames = new String[] {
                          "Logger Name", "Level", "Appender"
                  };
      
                  tblLoggers.setModel(new DefaultTableModel(loggerModels, columnNames) {          
                      /**
                       * 
                       */
                      private static final long serialVersionUID = 1L;
      
                      @Override
                      public java.lang.Class<?> getColumnClass(int columnIndex) {
                          switch (columnIndex) {
                          case 0:
                              return String.class;
                          case 1:
                              return String.class;
                          case 2:
                              return String.class;
                          default:
                              return Object.class;
                          }                   
                      };
      
                      @Override
                      public boolean isCellEditable(int row, int col)
                      {
                          if (dirty) {
                              if ((row+1) == this.getRowCount()) {
                                  return true;
                              }
                          } 
                          return (col==0)?false:true;
                      }
                  });
      
                  setUpLevelColumn(tblLoggers.getColumnModel().getColumn(1));
      
                  String[] appenderNames = logLevelPM.getAllAppenders();
                  setUpAppenderColumn(appenderNames, tblLoggers.getColumnModel().getColumn(2));
      
                  tblLoggers.getColumnModel().getColumn(0).setPreferredWidth(300);
                  tblLoggers.getColumnModel().getColumn(2).setPreferredWidth(200);
      
                  tblLoggers.getTableHeader().setReorderingAllowed(false);
      
                  tblLoggers.getModel().addTableModelListener(new TableModelListener() {
      
                      public void tableChanged(TableModelEvent e) {
                          int type = e.getType();
      
                          if (type != TableModelEvent.DELETE && type != TableModelEvent.INSERT) {
      
                              int row = e.getFirstRow();
                              int column = e.getColumn();
                              TableModel model = (TableModel)e.getSource();
      
                              String loggerName = (String) (model.getValueAt(row, 0));
                              String levelName = (String) (model.getValueAt(row, 1));
                              String appenderName = (String) model.getValueAt(row, 2);
      
                              if (dirty && (row+1) == model.getRowCount()) {
                                  // add
                                  if (loggerName != null 
                                          && !loggerName.isEmpty() 
                                          && levelName != null 
                                          && !levelName.isEmpty() 
                                          && appenderName != null 
                                          && !appenderName.isEmpty() 
                                          ) {
                                      logLevelPM.addLogger(loggerName, Level.getLevel(levelName), appenderName);
                                      dirty = false;
                                  }
                              } else {
                                  // update
                                  if (column == 1) {
                                      logLevelPM.changeLogLevel(loggerName, Level.getLevel(levelName));
                                  }
                                  if (column == 2) {
                                      logLevelPM.changeAppender(loggerName, Level.getLevel(levelName), appenderName);
                                  }
                              }
                          }
                      }
                  });
                  this.dirty = false;
              }
          }
      
          private void setUpAppenderColumn(String[] appenderNames, TableColumn column) {
              //Set up the editor for the sport cells.
              JComboBox<String> comboBox = new JComboBox<String>();
      
              for (int i = 0; i < appenderNames.length; i++) {
                  comboBox.addItem(appenderNames[i]);         
              }
              column.setCellEditor(new DefaultCellEditor(comboBox));
      
              //Set up tool tips for the sport cells.
              DefaultTableCellRenderer renderer =
                      new DefaultTableCellRenderer();
              renderer.setToolTipText("Click for appender change");
              column.setCellRenderer(renderer);
      
          }
      
          private void setUpLevelColumn(TableColumn column) {
              //Set up the editor for the sport cells.
              JComboBox<String> comboBox = new JComboBox<String>();
      //        for (Level level : Level.values()) {
      //          comboBox.addItem(level.toString());
      //      }
              comboBox.addItem(Level.ALL.name());
              comboBox.addItem(Level.TRACE.name());
              comboBox.addItem(Level.DEBUG.name());
              comboBox.addItem(Level.INFO.name());
              comboBox.addItem(Level.WARN.name());
              comboBox.addItem(Level.ERROR.name());
              comboBox.addItem(Level.FATAL.name());
              comboBox.addItem(Level.OFF.name());
              column.setCellEditor(new DefaultCellEditor(comboBox));
      
              //Set up tool tips for the sport cells.
              DefaultTableCellRenderer renderer =
                      new DefaultTableCellRenderer();
              renderer.setToolTipText("Click for level change");
              column.setCellRenderer(renderer);
      
          }
      
          private Object[][]  retrieveLoggersLocal() {
              Object[][] result = null;
      
              LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
              Configuration config = ctx.getConfiguration();
      
              Collection<LoggerConfig> loggerConfigs = config.getLoggers().values();
              result = new Object[loggerConfigs.size()][];
              result[0] = new Object[] {"ROOT", config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME).getLevel()};
      
              int i = 1;
              for (LoggerConfig loggerConfig : loggerConfigs) {
                  if (!loggerConfig.getName().isEmpty()) {
                      result[i++] = new Object[]{loggerConfig.getName(), loggerConfig.getLevel()};
                  }
              }
      
              return result;
          }
      
          private void close() {
              if (parent != null) {
                  parent.setEnabled(true);
                  ((JFrame)parent).toFront();
                  ((JFrame)parent).repaint();
              }
              dispose();
          }
      
          private void initUI() {
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              getContentPane().setLayout(new MigLayout("", "[grow][][]", "[][grow][grow]"));
      
              scrollPane_1 = new JScrollPane();
              getContentPane().add(scrollPane_1, "cell 0 2,grow");
      
              tblLoggers = new JTable();
              tblLoggers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
              tblLoggers.setModel(new DefaultTableModel(
                  new Object[][] {
                  },
                  new String[] {
                      "Logger Name", "Level", "Appender"
                  }
              ) {
                  private static final long serialVersionUID = 1L;
              });
              tblLoggers.getColumnModel().getColumn(0).setPreferredWidth(300);
              tblLoggers.getColumnModel().getColumn(2).setPreferredWidth(200);
              scrollPane_1.setViewportView(tblLoggers);
      
              panel = new JPanel();
              getContentPane().add(panel, "flowx,cell 1 2,grow");
              panel.setLayout(new MigLayout("", "[73px]", "[23px][][]"));
      
              btnRefresh = new JButton("Refresh");
              panel.add(btnRefresh, "cell 0 0,growx");
      
              btnNewButton = new JButton("Add");
              btnNewButton.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                      addLogger();
                  }
              });
              panel.add(btnNewButton, "cell 0 1,growx");
      
              btnDelete = new JButton("Delete");
              btnDelete.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                      deleteLogger();
                  }
              });
              panel.add(btnDelete, "cell 0 2,growx");
              btnRefresh.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                      retrieveLoggers();
                  }
              });
          }
      
          protected void deleteLogger() {
              int row = tblLoggers.getSelectedRow();
      
              if (row > 0) {
                  DefaultTableModel model = ((DefaultTableModel)tblLoggers.getModel());
                  String loggerName = (String) (model.getValueAt(row, 0));
      
                  logLevelPM.deleteLogger(loggerName);
      
                  model.removeRow(row);
                  tblLoggers.setRowSelectionInterval(row-1, row-1);
              }
          }
      
          protected void addLogger() {
              if (!dirty) {
                  DefaultTableModel model = ((DefaultTableModel)tblLoggers.getModel());
                  this.dirty = true;
                  model.addRow(new Object[]{"","",""});   
              }
          }
      
          protected void changeLogLevel(String loggerName, String level) {
              LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
              Configuration config = ctx.getConfiguration();
              LoggerConfig loggerConfig = null;
              if (loggerName.equals("ROOT")) {
                  loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);         
              } else {
                  loggerConfig = config.getLoggerConfig(loggerName);          
              }
              if (loggerConfig != null) {
                  loggerConfig.setLevel(Level.getLevel(level));
                  ctx.updateLoggers();            
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-04
        • 1970-01-01
        • 2017-01-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多