View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.appender.db.jdbc;
18  
19  import org.apache.logging.log4j.core.Filter;
20  import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender;
21  import org.apache.logging.log4j.core.config.plugins.Plugin;
22  import org.apache.logging.log4j.core.config.plugins.PluginAttr;
23  import org.apache.logging.log4j.core.config.plugins.PluginElement;
24  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
25  
26  /**
27   * This Appender writes logging events to a relational database using standard JDBC mechanisms. It takes a list of
28   * {@link ColumnConfig}s with which it determines how to save the event data into the appropriate columns in the table.
29   * A {@link ConnectionSource} plugin instance instructs the appender (and {@link JDBCDatabaseManager}) how to connect to
30   * the database. This appender can be reconfigured at run time.
31   * 
32   * @see ColumnConfig
33   * @see ConnectionSource
34   */
35  @Plugin(name = "Jdbc", category = "Core", elementType = "appender", printObject = true)
36  public final class JDBCAppender extends AbstractDatabaseAppender<JDBCDatabaseManager> {
37      private final String description;
38  
39      private JDBCAppender(final String name, final Filter filter, final boolean handleException,
40                           final JDBCDatabaseManager manager) {
41          super(name, filter, handleException, manager);
42          this.description = this.getName() + "{ manager=" + this.getManager() + " }";
43      }
44  
45      @Override
46      public String toString() {
47          return this.description;
48      }
49  
50      /**
51       * Factory method for creating a JDBC appender within the plugin manager.
52       *
53       * @param name The name of the appender.
54       * @param suppressExceptions {@code "true"} (default) if logging exceptions should be hidden from the application,
55       *                           {@code "false"} otherwise.
56       * @param filter The filter, if any, to use.
57       * @param connectionSource The connections source from which database connections should be retrieved.
58       * @param bufferSize If an integer greater than 0, this causes the appender to buffer log events and flush whenever
59       *                   the buffer reaches this size.
60       * @param tableName The name of the database table to insert log events into.
61       * @param columnConfigs Information about the columns that log event data should be inserted into and how to insert
62       *                      that data.
63       * @return a new JDBC appender.
64       */
65      @PluginFactory
66      public static JDBCAppender createAppender(@PluginAttr("name") final String name,
67                                                @PluginAttr("suppressExceptions") final String suppressExceptions,
68                                                @PluginElement("filter") final Filter filter,
69                                                @PluginElement("connectionSource") final ConnectionSource
70                                                        connectionSource,
71                                                @PluginAttr("bufferSize") final String bufferSize,
72                                                @PluginAttr("tableName") final String tableName,
73                                                @PluginElement("columnConfigs") final ColumnConfig[] columnConfigs) {
74          int bufferSizeInt;
75          try {
76              bufferSizeInt = bufferSize == null || bufferSize.length() == 0 ? 0 : Integer.parseInt(bufferSize);
77          } catch (final NumberFormatException e) {
78              LOGGER.warn("Buffer size [" + bufferSize + "] not an integer, using no buffer.");
79              bufferSizeInt = 0;
80          }
81  
82          final boolean handleExceptions = suppressExceptions == null || !Boolean.parseBoolean(suppressExceptions);
83  
84          final StringBuilder managerName = new StringBuilder("jdbcManager{ description=").append(name)
85                  .append(", bufferSize=").append(bufferSizeInt).append(", connectionSource=")
86                  .append(connectionSource.toString()).append(", tableName=").append(tableName).append(", columns=[ ");
87  
88          int i = 0;
89          for (final ColumnConfig column : columnConfigs) {
90              if (i++ > 0) {
91                  managerName.append(", ");
92              }
93              managerName.append(column.toString());
94          }
95  
96          managerName.append(" ] }");
97  
98          final JDBCDatabaseManager manager = JDBCDatabaseManager.getJDBCDatabaseManager(
99                  managerName.toString(), bufferSizeInt, connectionSource, tableName, columnConfigs
100         );
101         if (manager == null) {
102             return null;
103         }
104 
105         return new JDBCAppender(name, filter, handleExceptions, manager);
106     }
107 }