JDBCAPPENDER.JAVA
Package com.benqguru.palau.log.jdbc.test;
Import java.sql. *; import java.util. *;
Import org.apache.log4j. *; import org.apache.log4j.spi. *;
/ ** This jdbcappender is used to write a message into the database.
JDBCAPPENDER is configured at runtime, by selecting: b> p> 1. Use profile b> p> to define an option in the file, and call 2. To complete b> p> call In JDBCAPPENDER, all useful variables are defined as static string constants and named xxx_option. p> The following is a description of all useful options: b> p> 1. Database options Connect to the Database (Database-Options) b> p> - URL_OPTION B>: A shape such as JDBC: Subprotocol: Subname Database URL P> - UserName_Option b>: Database User P> - Password_option b>: User Password P> 2. Specify your own JDBCConnectionHandler's connector option (connection) b> - Connector_Option b>: a class that implements the JDBCConnectionHandler interface p> This interface can be used to get custom connections. p> If the rest of the database option is given, these options will be used as the parameter to the JDBCConnectionHandler interface. p> < P> Additionally, if there is no reference option, the JDBCConnectionHandler interface will not take these parameters to be called p> additionally, JDBCappender requires the database option to open a connection p> 3. SQL option Specifies a static SQL statement, which will execute this statement b> p> - SQL_OPTION B>: A SQL statement used to write data to the database P> This SQL statement is used to use @msg @ << b> this variable, this variable must be replaced with message content p> If you give the entire option, table options, and column options will be ignored! p> 4. Table options to specify a table included in the database b> p> - Table_Option b>: Save Log Information Table P> 5. Column Options Use to describe important columns in the table (non-empty columns must be described!) b> p> - columns_option b>: column description A list of formatted list p> Each column description includes the following list p> - column name (Name) i> b> ( Must) p> - a static constant log type in the LogType class (logtype) i> b> (must) p> - dependent and logtype One value of the class i> b> (optional / must, dependency log type (logType) p> dir> this is { @Link LogType} b> The useful log type (logType) describing, and how to process the processing value (value) i> b>: p> O msg b> = a value that can be ignored, the column will get a message. (There is a column requires this type!) p> o static b> = This value can populate the column of each log message. (Ensure that the type of this value can be converted to the column SQL type!) P> o ID b> = value must be one Implement the class name of the JDBCIDHandler interface. P> o timestamp b> = A value that can be ignored, this column will be filled with the exact timestamp of each record log message. P> < P> O Empty b> = a value that can be ignored, when writing data to the database, this column will be ignored (guarantee the database trigger to fill the non-empty class!) p> dir > If there is a plurality of columns need to be described, the column must be tab divid-separated (Unicode0008)! P> column description must be separated by '~'! (instance: Name1 ~ logtype1 ~ value1 name2 ~ logtype2 ~ value2 ...) i> p> 6. The layout of the layout option is used to define the layout of the message (optional) b> p> - _ b>: The layout is not used as XXX_Option Set p> Refer to the following configuration file and code example ... p> The default layout is class {@link org.apache.log4j.patternLayout}, this layout is used only Message% M mode. P> 7. Buffer options are used to define a message event buffer (optional) b> p> - buffer_option < / b>: The definition will be cached until it is updated to the database. p> The default buffer size is 1, when the message event occurs, will be updated. p> 8. Submit options Used to define an automatic submission b> p> - commit_option b>: Defining Update Messages is (Y) No (n) Auto Submit Go to the database. P> When the default time commit = n. P> dir> This is important when the following options: b> p> 1. Connector Option (Connector-Option) OR / AND Database Option (Database- Options) b> p> Database connection! p> 2. (Table-Option) AND 列 c c 列Option (SQL-Option) b> p> The above is required! Where is written or write ...; -) p> 3. Other options can be set at any time ... Optional options, and there is a default value that can be customized. P> dir> This is a configuration file example as a PropertyConfigurator parameter b>: log4j.properties p> This is a code example for configuring the JDBCAPPENDER class with a configuration file b>: log4jtest.java . p> This is another code example for configuring a JDBCappender class in another configuration file b>: log4jtest2.java p> * title: log4j1.2.8 Source code analysis p> * Description: p> * Copyright: Copyright (c) 2004 p> * Company: BenQ is deducting P> * @Author Wang Jian * @version 1.0 * / public class jdbcappender Extends appenderskeleton {/ ** database option, setting settings database URL is jdbc: subsophocol: subname * / public static final string url_option = "url"; / * * Database option, the settings that can connect to this database * / public static final string username_option = "username"; / ** Database option, set user password * / public static factory string password_option = "password"; / ** Table option, specify a table in the database * / public static final string table_option = "table"; / ** Connector option, specify your own jdbcconnectionhandler * / public static final string connector_option = "connector"; / ** Column Options, Description Table Important Colum * / Public Static Final String Column_Option = "Columns"; / ** SQL option specifies a static SQL statement that executes when an event occurs * / public static final string SQL_OPTION = "SQL"; / ** Buffer option, define the size of the message event buffer * / public static final string buffer_option = "buffer"; / ** Submit an option to define an auto submission * / public static final string commit_option = "commit"; // save value may be variable alternative method of setting setOption () private String url = null; private String username = null; private String password = null; private String table = null; private String connection_class = null; private String sql = NULL; // If the database does not support the transaction, it is necessary to set to false, such as mysql private boolean docommit = false; private int buffer_size = 1; private jdbcconnectionhandler connectionhandler = null; // This buffer saves the message event. When the buffer reaches a certain size, the buffer will be refreshed and the information will be updated to the database. Private arraylist buffer = new arraylist (); // Database Connection Private connection con = NULL; // This class encapsulates the logical private jdbclogger jlogger = new jdbclogger (); // identifier: This is a logo that indicates whether a database connection has been established private boolean connect = false; // Indicates the identity boolean configured = false; // A indicating that all things are ready, you can use the identity boolean ready = false of Append (); // If the program ends, close the database and refresh the buffer public void finalize () {close (); super.finalize } / ** * Internal method. Returns a string array of useful options (option) that can be set on the method setOption (). * @Return String [] * / public string [] getOptionstrings () {// the sequence of options in this string is important, because setOption () is called this way ... return new String [] {CONNECTOR_OPTION, URL_OPTION, USERNAME_OPTION, PASSWORD_OPTION, SQL_OPTION, TABLE_OPTION, COLUMNS_OPTION, BUFFER_OPTION, COMMIT_OPTION};} / ** * Set all the necessary options * @Param _Option string * @Param _Value string * / public void setoption (string _option, string _value) {_Option = _Option.trim (); _Value = _Value.trim (); IF (_Option == null || _value == null) Return; if (_Option.Length () == 0 || _Value.length () == 0) Return; _Value = _Value.trim (); IF (_Option.equals (connector_option)) {// Connector if (! Connected) connection_class = _value;} else if (_Option.equals (url_option)) {// URL if (! connection) URL = _Value;} else (_OPTION.Equals (username_option) {// User Name If (! connection) username = _value;} else if (_Option.equals (password_option) {// Password If (! connection) password = _value;} else IF _OPTION.Equals (SQL_OPTION)) {// SQL statement SQL = _Value;} else if (_Option.equals (table_option)) {// Table IF (SQL! = null) return; // If the SQL statement is not null, then return Table = _Value;} else if (_Option.equals (colors_option)) {// column IF (SQL! = null) return; string name = null; int logType = -1; string value = null; string column = null; string Arg = null; int Num_args = 0; int num_columns = 0; StringTokenizer ST_COL; STRINGTOKENIZER ST_ARG; // columns are Tab-Separated St_col = New StringTokenizer (_Value, "); Num_columns = st_col.countToKens (); IF (Num_Columns <1) {ErrorHandler.Error ("JDBCAPPENDER :: SetOption (), Invalid Column_Option Value:" _Value "!"); Return;} For (int i = 1; i <= num_columns; i ) {column = ST_COL.NEXTTOKEN (); // arguments are ~ -separated st_arg = new stringTokenizer (column, "~"); Num_ARGS = ST_ARG.COUNTTOKENS (); IF (Num_Args <2) {ErrorHandler.Error ("JDBCAPPENDER :: SetOption (), Invalid Column_Option value:" _Value "!"); Return;} For (int J = 1; j <= num_args; j ) {arg = ST_ARG.NEXTTTOKEN (); if (j == 1) Name = arg; else if (j == 2) {Try {LogType = integer.parseint (arg);} catch (exception e) {logtype = logtype.parselogtype (arg);} IF (! logtype.islogtype ("jdbcappender :: setoption (), invalid column_option logtype:" arg "!"); return;}} else if (j == 3) value = arg; If (! setLogType (Name, LogType, Value) Return;}} else if (_Option.equals (buffer_option)) {// buffer try {buffer_size = integer.parseint (_Value);} catch (Exception E) {Errorhandler (), Invalid Buffer_Option value: " _Value "! "); return;}} else if (_Option.equals (commit_option)) {// Submit docommit = _Value.equals (" y "); IF (_OPTION.Equals (SQL_OPTION) || _Option.equals (Table_Option)) {if (! configured) configure ();}} / ** * Internal method, return true, you can define your own layout * @return boolean * / public boolean requireslayout () {Return True;} / ** * Internal method, close the database connection and flush (Flush) buffer * / public void close () {flush_buffer (); if (connection_class == null) {Try {Con. close ();} catch (Exception E ) {Errorhandler.Error ("JDBCAPPENDER :: Close ()," E);}} this.closed = true; / ** * All columns of log tables must call this method * @Param _name string * @Param _LogType int * @Param _Value Object * @Return Boolean * / public boolean setLogType (String _name, int _logtype, object _value) { IF (SQL! = null) Return True; if (! configured) {// Why? if (! ") Return False; Try {jlogger.setLogType (_Name, _LogType, _value);} catch (exception e) {ErrorHandler.Error ("JDBCAPPENDER :: setLogType ()," E); Return False;} Return True;} / ** * Internal method. Add message to database table * @Param Event loggingevent * / public void append (loggingEvent evenet) {if (! {I (@ ire "{ErrorHandler.Error (" JDBCAPPENDER :: Append (), NOTY TO APPEND! "); Return;}} Buffer.Add (Event); IF (buffer.size ()> = buffer_size) Flush_buffer (); / ** * internal method. Refresh buffer * / public void flush_buffer () {ion size = buffer.size (); IF (SIZE <1) return; For (int i = 0; i // INSERT Message Into Database Jlogger.Append (layout.format (event));} Buffer.clear (); IF (DOCOMMIT) Con.commit ();} catch (exception e) {Errorhandler.Error ("JDBCAPPENDER :: Flush_buffer ()," E ": Jlogger.Geterror (); try {con. rollback (}); (Exception ex) {} return;}} / ** * Internal method. When JDBCappender is ready to add a message to the database, return true; otherwise return false * @return boolean * / public boolean ready () {if (ready) return true; IF (! configured) returnaf false; Ready = jlogger.ready (); IF (! Ready) {ErrorHandler.Error (jlogger.geterror ());} Return Ready; / ** * Internal method, connection database * @throws exception * / protected void connect () throws exception {if (connect) return; Try {if (Connection_Class == Null) {if (URL == Null) Throw new Exception ("JDBCAPPENDER :: Connect (), no url defined."); IF (username == null) Throw new Exception ("JDBCAPPENDER :: Connect (), no username defined."); IF (Password == Null) Throw new Exception ("JDBCAPPENDER :: Connect (), no password defined."); ConnectionHandler = new defaultConnectionHandler ();} else {connectionhandler = (jdbcconnectionhandler) (CLASS.FORNAME (CONNECTION_CLASS) .newinstance ());} IF (URL! = NULL && Username! = null && password! = null) {con = ConnectionHandler.getConnection (URL, Username, Password);} else {con = ConnectionHandler.getConnection ();} if (con.isClosed ()) {throw new Exception ( "JDBCAppender :: connect (), JDBCConnectionHandler returns no connected Connection!");}} catch (Exception e) {throw new Exception ( "JDBCAppender :: connect (), " E);} // Set the connection ID to true connected = true; / ** * Internal method. Check if it is configured to add actions ... * @return boolean * / protected boolean configure () {if (configure) Return True; IF (! connection_class == null) && (URL == null || username == null || password == null)) {ErrorHandler.Error ("JDBCAPPENDER :: Configure (), missing database- Options or connector-option! "); return false;} Try {connect ();} catch (exception e) {connection_class = null; url = null; errorhandler.Error ("JDBCAPPENDER :: Configure ()," E); Return False;}}} (SQL == Null &&) Table == null) {ErrorHandler.Error ("JDBCAPPENDER :: Configure (), no sql_option or table_option given!"); return false;} IF (! jlogger.isconfigured ()) {Try {Jlogger.SetConnection (con); IF (SQL == null) {jlogger.configuretable (Table);} else jlogger.configureSQL (SQL);} catch (Exception E) {Errorhandler.Error ("JDBCAPPENDER :: Configure ()," E); Return False }} // default message-layout if (layout == null) {layout = new patternLayout ("% m");} / / Indicate that it is already configured! Configured = true; return true;} public String getUrl () {return url;} public void setUrl (String url) {this.url = url;} public String getUsername () {return username;} public void setUsername (String username) {this.username = username;} public String getPassword () {return password;} public void setPassword (String password) {this.password = password;} public String getConnection_class () {return connection_class;} public void setConnection_class (String connection_class) {this.connection_class = connection_class;} public String getSql () {return sql;} public void setSql (String sql) {this.sql = sql;} public String getTable () {return table;} public void setTable (String table) {this.table = table;} public int getBuffer_size () {return buffer_size;} public void setBuffer_size (int buffer_size) {this.buffer_size = buffer_size;} public String getDocommit () {if (docommit == true) {return "Y";} else { Return "N";}} public void setDocommit (string commit) {if (commit.equals ("n")) {this.docommit = false;} else {this.docommit = true;}}} / ** * This is a default JDBCConnectionHandler * Title: log4j1.2.8 source code for JDBCappender p> * description: p> * Copyright: CopyRight (C) 2004 P> * Company: BenQ Chart P> * @Author Wang Jian * @version 1.0 * / Class DefaultConnectionHandler Implements JDBCConnectionHandler {Connection Con = NULL; Public connection getConnection () {return con; public Connection getConnection (String _url, String _username, String _password) {try {if (con = null && con.isClosed ()!!) con.close (); con = DriverManager.getConnection (_url, _username, _password); con .Setautocommit (TRUE);} catch (exception e) {E.PrintStackTrace ();} returncon;}} 2.jdbcconnectionhandler.java Package com.benqguru.palau.log.jdbc.test; Import java.sql. *; / ** * Must implement this interface to process database connections, use this interface in the JDBCLogger class * Title: log4j1.2.8 source code analysis p> * Description: p> * Copyright: Copyright (C) 2004 P> * Company: BenQ Chart P> * @Author Wang Jian * @version 1.0 * / public interface jdbcconnectionhandler { / ** * Get a connection * @Return connect * / connection getConnection (); / ** * Get a custom connection * @Param _URL STRING * @Param _Username string * @Param _password string * @return connection * / connection getConnection (String _url, string _username, string _password);} 3.jdbcidhandler.java Package com.benqguru.palau.log.jdbc.test; / ** * Must implement this interface to provide ID-column with unique ID-Column, which uses this interface * Title: log4j1.2.8 source code in the JDBClogger class p> * Description: < / p> * Copyright: Copyright (c) 2004 p> * Company: BenQ competes to p> * @Author Wang Jian * @version 1.0 * / public interface jdbcidhandler { / ** * Get a unique ID * @return object * / Object getId (); 4.jdbclogger.java Package com.benqguru.palau.log.jdbc.test; Import java.sql. *; import java.util. *; / ** * This class package must record the logic in the table, JDBCappender uses this class * Title: log4j1.2.8 source code analysis p> * Description: p> * Copyright: Copyright (C) 2004 P> * Company: BenQ Chart P> * @Author Wang Jian * @Version 1.0 * / public class jdbclogger {// log table for all columns = NULL; // Columns supplied by log records, column_list = NULL; // Number of all columns Private int num = 0; // Represents the configure () method to perform success private boolean isconfigured = false; / / Means that you are ready to use append () to log Private boolean ready = false; // When the ready () method fails, the message will be filled with the error string, and this value can be used to return this value private string erroormsg = ""; Private connection con = NULL; Private Statement Stmt = NULL; Private ResultSet RS = NULL; private string table = null; // variables static SQL statements logging private String sql = null; private String new_sql = null; private String new_sql_part1 = null; private String new_sql_part2 = null; private static final String msg_wildcard = "@ MSG @"; private int msg_wildcard_pos = 0 ; / ** * Write a message into the database table, if a database error occurs, will throw an exception! * @Param _msg string * @throws exception * / public void append (string _msg) throws Exception {if (! Ready) IF (! Ready ()) Throw New Exception ("JDBCLogger :: append (), not ready to append!"); IF (SQL! = NULL) {appendsql (_msg); return;} Logcolumn logcol; rs.movetoinsertrow (); For (int i = 0; I if (logcol.logtype == LogType.MSG) {rs.updateObject (logcol.name, _msg);} else if (logcol.logtype == LogType.ID) {rs.updateObject (logcol.name, logcol.idhandler.getID ());} else if (logcol.logtype == LogType.STATIC) {rs.updateObject (logcol.name, logcol.value);} else if (logcol.logtype == LogType.TIMESTAMP) {rs.updateObject (logcol .name, new timestamp (NEW java.util.date ()). getTime ()));}}}}}}}}}}}}} / ** * Write a message into the database with a given SQL statement. If a database error occurs, it will throw an exception! * @Param _msg string * @throws exception * / public void appendsql (string _msg) throws exception {ix (! Ready) IF (! Ready ()) Throw new Exception ("JDBCLogger :: appendsql (), NOTY TO APPEND!"); IF (SQL == NULL) Throw new Exception ("JDBCLogger :: appendsql (), no sql-statement configured!"); IF (msg_wildcard_pos> 0) {new_sql = new_sql_part1 _msg new_sql_part2;} else new_sql = SQL; Try {stmt.executeUpdate (new_sql);} catch (exception e) {errormsg = new_sql; throw e;}} / ** * Configure this class by reading the structure of the log table. If a database error occurs, it will throw an exception! * @Param _table string * @throws exception * / public void configureTable (String _Table) THROWS Exception {if (iSconfigured Return; // with META-informations log table columns filled column stmt = con.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); rs = stmt.executeQuery ( "SELECT * FROM" _table "WHERE 1 = 2"); Logcolumn logcol; ResultSetmetaData RSMD = rs.getMetadata (); Num = rsmd.getcolumncount (); Logcols = new arraylist (num); for (int i = 1; i <= num; i ) {logcol = new logcolumn (); logcol.name = rsmd.getColumnname (i) .touppercase (); logcol.type = rsmd .getColumnTypeName (i); logcol.nullable = (rsmd.isNullable (i) == rsmd.columnNullable); logcol.isWritable = rsmd.isWritable (i); if logcol.ignore = true (logcol.isWritable!); logcols. Add (Logcol); Table = _Table; ISCONFIGURED = True;} / ** * Configure this class by saving the given SQL statement. If a database error occurs, an exception will be thrown! * @Param _sql string * @throws exception * / public void configuresql (string _sql) throws exception { ISCONFIGURED RETURN IF (! isconnected ()) Throw new Exception ("JDBCLogger :: Configuresql (), NOT Connected to Database!"); IF (_SQL == null || _sql.trim (). Equals (")) Throw new Exception (" JDBCLogger :: Configuresql (), Invalid SQL-Statement! "); SQL = _SQL.TRIM (); STMT = con.createstatement (); Msg_wildcard_pos = sql.indexof (msg_wildcard); if (msg_wildcard_pos> 0) {new_sql_part1 = sql.substring (0, msg_wildcard_pos - 1) " '"; // between the message ... new_sql_part2 = "'" sql.substring (msg_wildcard_pos msg_wildcard.length ()) } ISCONFIGURED = True;} / ** * Set a connection. If the connection is not open, you will throw an exception! * @Param _con connection * @throws exception * / public void setConnection (connection _con) throws exception {con = _con; IF (! isconnected ()) throw new exception ("JDBCLogger :: setConnection (), Given Connection isnt connection to database!"); / ** * Set a column log type (logtypes) and depend on the logType value. If a given parameter is incorrect, it will throw an exception! * @Param _name string * @Param _LogType int * @Param _Value Object * @Throws Exception (! isconfigured) * / public void setLogType (String _name, int _logtype, Object _value) throws Exception {if throw new Exception ( "JDBCLogger :: setLogType (), Not configured!"); // setLogType () makes only sense for Further Configuration of ConfigureTable () IF (SQL! = NULL) RETURN _name = _name.touppercase (); IF (_Name == Null ||! (_name.trim (). Length ()> 0)) Throw new Exception ("JDBCLogger :: setLogType (), missing argument name!"); if (! logtype.islogtype) )) throw new exception ("JDBCLogger :: setLogType (), invalid logtype '" _LogType ""); // In addition to message type and empty type, other types of values cannot be empty IF ((_LogType! = logtype .Msg && _logtype! = Logtype.empty) && _value == null) throw new exception ("JDBCLogger :: setLogType (), Missing Argument value!"); LogColumn logcol; // Set the source for the value of the column for (int i = 0; I IF (logcol.name.equals (_name)) {if (! logcol.iswritable "throw new exception (" JDBCLogger :: setLogTYPE (), column " _name " is not writeable! "); // Column gets the message if (_logtype == LogType.MSG) {logcol.logtype = _logtype; return;} // Column will be provided by JDBCIDHandler :: getID () else if (_logtype == LogType.ID) {logcol .logtype = _LogType; try {// Try to cast directly Object to JDBCIDHandler logcol.idhandler = (JDBCIDHandler) _value;} catch (Exception e) {try {// Assuming _value is of class string which contains the classname of a JDBCIDHandler logcol.idhandler = (JDBCIDHandler Class.Forname ((String) _Value) .newinstance ());} catch (Exception E2) {throw new exception ("JDBCLogger :: setLogType (), cannot cast value of class" _Value.getClass () " To class jdbcidhandler! ");}} Return; // Column Will Be staticly defined with object _value else ife = _ logcol.logtype = _LogType; logcol.value = _Value; return;} // Column Will Be supplied with a activity timestamp else if (_LogType == logtype.timestamp) {logcol.logtype = _LogType; Return; // Column will be fully ignored during process. // If this column is not nullable, the column has to be filled by a database trigger, // else a database error occurs! // Columns which are not nullable, but should be not filled, must be explicit assigned with LogType.EMPTY, // else a value is required else if (_logtype == LogType.EMPTY) {logcol.logtype = _logtype; logcol.ignore = true; return;}!}}} / ** * If this class's append () method is ready, return true, otherwise return false. * If it is not ready, a reason string will be saved in instance variable MSG * @return boolean * / public boilean Ready () {If (ready) return true; IF (! isconfigured) {error = "NOTY to append! call configure () first!"; return false;} // no need to doing the whole rest ... if (sql! = null) {ready = True; Return True;} Boolean msgcol_defined = false; Logcolumn logcol; For (int i = 0; I if (logcol.ignore || logcol.isWritable!) continue; (! logcol.nullable && logcol.logtype == LogType.EMPTY) if {errormsg = "Not ready to append Column!" logcol.name "is not nullable , and must be specified by setLogType ()! "; return false;} if (logcol.logtype == LogType.ID && logcol.idhandler == null) {errormsg =" Not ready to append Column " logcol.name ! "IS specified as an id-column, and a jdbcidhandler Has to be set!"; return false;} else if (logcol.logtype == logtype.static && logcol.value == null) {errormsg = "not Ready to append Column " logcol.name " IS specified as a static field, and a value has to be set! "; Return false;} else if (logcol.logtype == logtype.msg) msgcol_defined = true;} IF (! msgcol_defined) returnaf; // Create the column_list for (int i = 0; i IF (logcol.ignore ||! logcol.iswritable) Continue; if (logcol.logtype = LogType.EMPTY!) {if (column_list == null) {column_list = logcol.name;} else column_list = "," logcol.name;}} try {rs = stmt.executeQuery ( " SELECT " COLUMN_LIST " from " Table " Where 1 = 2 ");} Catch (Exception E) {ErrorMSG =" NOTY TO APPEND! CANNOT SELECT Column '" Column_List "' of Table " Table "!"; Returnaf Ready = True; Return True;} / ** * If this is already configured, return true, otherwise return false * @return boolean * / public boolean isconfigured () {returnfigured;} / ** * If this connection is open, return true, otherwise return false * @return boolean * / public boolean isconnected () {Try {Return (inc! = Null&&! Con.closed ());} catch (Exception e) {returnaf false;}} / ** * Returns internal error message stored in instance variable MSG * @return string * / public string getErrorMsg () {string r = new string (errormsg); erroormsg = null; return r;}} / ** * This class encapsulates the column related data required by the JDBClogger class * title: log4j1.2.8 source code analysis p> * description: p> * Copyright: Copyright (c) 2004 p> * Company: BenQ competes to p> * @Author Wang Jian * @version 1.0 * / class logcolumn { / ** Column name * / String name = null; / ** Column type * / string type = NULL; / ** NOT NULLABILTY means this column is a must * / boolean nullable = false; / ** iswritable means this column can be updated, or only read only. * / Boolean iswritable = false; / ** If ignore is TRUE, this column will ignore * / boolean ignore = false when compiling SQL statements; / ** must be filled with non-air column! Other situations are optional. * / Int logtype = logtype.empty; / ** corresponds to universal memory of wrapper, String, etc. * / Object value = null ; / ** JDBCIDHANDLER interface instance * / jdbcidhandler idhandler = null;} / ** * This class contains all constants, these constants are required to define a column log type. * Title: log4j1.2.8 Source quarter analysis p> * description: p> * Copyright: Copyright (C) 2004 P> * Company: BenQ Chart P> * @Author Wang Jian * @version 1.0 * / class logtype { / ** This type of column will accept the message * / public static final int msg = 1; / ** This type of column will be the unique identifier of the record line * / public static final int ID = 2; / ** This type of column will contain a statically defined value * / public static final int stat = 3; / ** This type of column will be filled with a timestamp, this timestamp relies on the start time of the log record * / public static final int todaystamp = 4; / ** This type of column will not contain a value and is not included in the insert statement in log record. This will be a column that does not need to be created, but in other places. * / Public static final int EMPTY = 5 ; / ** * Detection _LT is a log type * @Param _lt int * @return boolean * / public static boolean islogtype (int _lt) {if (_lt == msg || _lt == static || _lt == id | | _LT == TimeStamp || _lt == Empty) Return True; Return false;} / ** * Convert the string to log type * @Param _lt string * @return int * / public static int parselogtype (swright _lt) {if (_lt.equals ("msg")) Return Msg; if (_lt.equals ("ID")) RETURN ID; if (_lt.equals ("static")) Return Static; if (_Lt.Equals ("TimeStamp") Return TimeStamp; IF (_lt.equals ("empty")) Return Empty ; Return -1;}} 5.log4j.properties # This is a configuration file instance, and the PropertyConfigurator will use this file: # 声明 An appender variable named jdbclog4j.rootlogger = debug, JDBC #JDBC is a JDBCAPPENDER class, this class can write messages to database log4j.Appender.jdbc = com.benqguru.palau.log.jdbc.test.jdbcappender # 1. Connection database database option log4j.Appender.jdbc.url = jdbc : mysql: // localhost: 3306 / logtestlog4j.Appender.jdbc.userName = rootlog4j.Appender.jdbc.password = # 2. Specify your own JDBCConnectionHandler's connector option log4j.Appender.jdbc.connection_class = com.benqguru.palau.log.jdbc.test.myConnectionHandler # 3. Specify a SQL option for a static SQL statement, this statement will perform log4j.Appender.jdbc.sql = INSERT INTO LOGTEST (ID, MSG, CREATED_ON, CREATED_BY) VALUES (1, @ MSG @, sysdate, 'me') # 4. Specify the table options for a table in the database. Log4j.Appender.jdbc.table = logtest # 5. Column options for the description table (non-empty columns must be described) log4j.Appender.jdbc.columns = id_seq ~ empty ID ~ id ~ myidhandler msg ~ msg created_on ~ timestamp created_by ~ static ~ Thomas Fenner T.fenner@klopotek.de) # 6. Define the layout option of the message layout (optional) log4j.Appender.jdbc.Layout = org.apache.log4j.patternLayoutLog4j.Appender.jdbc.Layout.ConversionPattern =% M # 7. Define the size of the message event buffer (optional) log4j.Appender.jdbc.buffer_size = 1 # 8. Define the submission option (optional) log4j.Appender.jdbc.docommit = n ########## The following is English description ############# Date -% d {date} [SLF5s.date] #priority -% p [SLF5s.Priority] #Ndc -% x [slf5s.ndc] #thread -% T [SLF5s.thread] #category -% C [SLF5s.category] #Location -% L [SLF5s.Location] #MESSAGE -% M [SLF5s.MESSAGE] ## log4j.Appender.r.Layout.conversionPattern = [SLF5s.Start]% D {date} [SLF5s.date]% N / #% P [SLF5s.Priority]% N% x [SLF5s.NDC]% N% T [SLF5S.THREAD]% N / #% C [SLF5s.category]% N% L [SLF5S.LOCATION]% N% M [SLF5S.MESSAGE]% n% n ########## It is Chinese description ######################################################### Output the LOG information takes a few #% C to output the category belonging, which is usually the full name #% t output of the class generated to generate the thread name #% n output of the log event, and the Windows platform is "/ R / N ", the Unix platform is" / n "#% D output log time point date or time, the default format is ISO8601, or it can be specified in the format, # such as% D {YYY MMM DD HH: mm: SS, SSS}, Output Similar: October 18, 2002 22:10: 28,921 #% l Output log events, including category names, threads that occur, and number of rows in code. Example: Testlog4.main (Testlog4.java: 10) 6.log4jtest.java Package com.benqguru.palau.log.jdbc.test; Import java.sql. *; Import org.apache.log4j. *; / ** * This is an instance code for configuring JDBCappender with a configuration file * title: log4j1.2.8 Source code analysis p> * Description: p> * Copyright: CopyRight (C ) 2004 p> * Company: BenQ competes with p> * @Author Wang Jian * @version 1.0 * / public class log4jtest { / ** * root log logger * / static logger log = logger.getlogger (log4jtest.class.getname ()); Public static void main (string [] args) {Try {driver D = (DRIVER) ("org.gjt.mm.mysql.driver). NewInstance ()); DriverManager.RegisterDriver (d);} Catch (Exception E) {} // Configuration with configuration-file PropertyConfigurator.configure ( "E: /Log4j_src/classes/com/benqguru/palau/log/jdbc/test/log4j.properties"); // These messages with Priority> = setted priority will be logged To The Database. Log.debug ("Debug"); // this Not, Because Priority Debug is Less Than Info Log.Info ("Info"); Log.Error ("Error"); log.fatal ("Fatal" }} 7.log4jtest2.java Package com.benqguru.palau.log.jdbc.test; Import java.sql. *; Import org.apache.log4j. *; / ** * This is an instance code that does not use the configuration file to configure JDBCappender * Title: log4j1.2.8 Source code analysis p> * Description: p> * Copyright: CopyRight (C ) 2004 p> * Company: BenQ competes with p> * @Author Wang Jian * @version 1.0 * / public class log4jtest2 { / ** * root log logger * / static logger log = logger.getlogger (log4jtest2.class.getname ()); Public static void main (string [] args) {// Returns the serial number of transactions myidhandler idhandler = new myidhandler (); / / Make sure the required drive Try {Driver D = (DRIVER) is installed ("org.gjt.mm.mysql.driver). NewinStance ()); DriverManager.RegisterDriver (D);} catch (EXCEPTION E) {E.PrintStackTrace (); // Set the priority log.setlevel (Level.debug) that the message can be recorded; // Create a JDBCAPPENDER instance jdbcappender appender = new jdbcappender (); // Use the setoption () method to set the option appender.setoption (jdbcappender.connector_option, "com.benqguru.palau.log.jdbc.test.myconnectionhandler); appender.setoption (jdbcappender.url_option," jdbc: mysql: /////// Localhost: 3306 / logtest "); appender.setoption (jdbcappender.username_option," root "); appender.setoption (jdbcappender.password_option," "); // When this step is performed, JDBCappender calls the JDBCLogger connection database, lookup Information appender.setoption (jdbcappender.table_option, "logtest"); / * There are two ways to establish a column description: 1. Method setoption (jdbcappender.column_option, column-description) ja.setoption (jdbcappender.colump_option, "id_seq ~ EMPTY id ~ ID ~ MyIDHandler msg ~ MSG created_on ~ TIMESTAMP created_by ~ STATIC ~ :-) Thomas Fenner (t.fenner@klopotek.de)"); 2. with setLogType (String columnname, int LogType.xxx, Object XXX) is a better encoding method * / appender.setLogType ("id_seq", logtype.empty, ""); appender.setLogType ("ID", logtype.id, idhandler); appender.setLogType ("msg", LogType.msg, ""); appender.setlogtype ("created_on", logtype.t IMestamp, ""); appender.setLogType ("created_by", logtype.static, "fen"); / / If you want to execute a static SQL statement, forget the table and column option, use this method: // appender.setoption (jdbcappender.sql_option, "INSERT INTO LOGTEST (ID, MSG, CREATED_ON, CREATED_BY) VALUES (1, @ Msg @, sysdate, 'me') "); // Set the size of the database buffer option is 1 // appender.Setoption (JDBCAPPENDER.BUFFER_OPTION," 1 "); // If the database is used by mysql, it must be To set to "N", because MySQL does not support transaction // appender.setoption (JDBCAPPENDER.commit_option, "N"); / / Define a layout,% M represents the message specified in the output code // appender.setLayout ("% m")); / / Add an output source to the log logger log.addappender; // These tapes are greater than or equal to the set priority, will be recorded into the database log.debug ("debug"); LOG.INFO ("info"); log.error ("error"); log.fatal ("fatal");}} / ** * Implementation of the JDBCConnectionHandler interface address * Title: log4j1.2.8 Source code analysis p> * description: p> * Copyright: CopyRight (c) 2004 p> * Company: BenQ compete p> * @author Wang * @version 1.0 * / class MyConnectionHandler implements JDBCConnectionHandler {Connection con = null; // String url = "jdbc: oracle: thin: @ (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (protocol = tcp) (host = LENZI) (PORT = 1521)) (protocol = tcp.world) (host = lenzi) (port = 1526 )))) ""; String url = "jdbc: mysql: // localhost: 3306 / logtest"; string username = "root"; string password = " / ** * Get the default database connection * @return connection * / public connection getConnection () {system.out.println ("URL =" URL); System.out.Println ("UserName =" username); system. Out.println ("password =" password; return getConnection (URL, UserName, Password); / ** * The conditions for obtaining a given database connection * @param _url String * @param _username String * @param _password String * @return Connection * / public Connection getConnection (String _url, String _username, String _password) {try {if ( Con! = null &&! con?close (); con = drivermanager.getConnection (_URL, _USERNAME, _PASSWORD); con.setautocommit (TRUE);} catch (Exception E) {E.PrintStackTrace () Return con;}}}}} / ** * Implementation of the JDBCIDHANDLER interface * Title: log4j1.2.8 source code analysis p> * Description: p> * Copyright: CopyRight (c) 2004 p> * Company: BenQ competes to P> * @Author Wang Jian * @version 1.0 * / class myidhandler imports jdbcidhandler {private static long id = 0; / ** * Get a unique ID * @return object * / public synchronized Object getId () {return new long ( id);}} PropertyConfigurator.configure (filename) code> p> in your code
jdbcappender :: setoption (jdbcappender.xxx_option, string value) code> Things, in the case of useless files, p> dir>