Save log4net logs to MongoDB database practice

Source: Internet
Author: User
Tags log log try catch log4net

Log4net's name has long been heard, has not really used, the development of the app project is ready to use the service side log4net. Log data volume is large, frequent write database is easy to affect the overall performance of the system, so it is a good choice to write logs to the MongoDB database independently. ---after 2 days of groping, summed up this document.  GitHub has an open source project, and another log4mongo-net author has modified http://skyd.sinaapp.com/archives/1282 based on the open source project. so use the code directly from the DIA.   1. Upgrade the log4net and MongoDB drivers to the latest version. log2net:1.2.15 MongoDB: 2.2.3.32, the new addition of a Loghelper class (single-piece mode), all the logs through the Loghelper static method to write.
public class Loghelper
{
private static readonly loghelper instance=new loghelper ();
private static ILog log = null;          Private Logger () {//Xmlconfigurator.configure ();                Loglog.internaldebugging = true; }public static Loghelper getinstance ()
{if (log = = null) {log = Logmanager.getlogger (System.Reflection.MethodBase.GetCurrentMethod ()). D      Eclaringtype);  } return instance; }
public void Debug (Object message, Exception Exception) {log. Debug (message);} public void Debug (Object message) {log. Debug (message);}
}
The result is that there is a problem, log4net could have logged the class name where the log occurred, and the exact line number. If a separate class is used to write logs, the recorded classes and line numbers are loghelper and cannot be located where the error occurred. The reason is that ilog is obtained by means of the Logmanger.getlogger (Type) method, and to get the wrong class and line number, you must call Logmanger.getlogger separately in each class ( System.Reflection.MethodBase.GetCurrentMethod (). DeclaringType). (self-understanding, not necessarily accurate) 3. Custom log content fields. There are a lot of ways to log4net add fields on the Web, but because I'm using a modified Log4mongo. and simplifies the configuration by default, all fields are displayed. So basically by changing the configuration is not applicable. start preparing to use logicalthreadcontext.properties["customcolumn"] = "Custom Value" to write more custom content to the log. performs a write log. Before Debug (object), set the various customizations through Logicalthreadcontext. And then execute log. Debug (object). Although this approach can achieve the goal, but it is not very convenient. Another problem is that after setting up Logicalthreadcontext, these values will persist and execute log again on the same line thread. Debug (object), you still record these custom attribute values, not very good control, easy to write the wrong content.  Another way is through log. The object in Debug (object) is implemented, in general it is a direct log. Debug ("This is Message") in this way to write the log, or you can pass an object to log. Debug. Before writing data to the database, you can read the passed object through Loggingevent.renderedmessage .Public class Loginfo    {Public string AppKey {set; get;} Public string UserID {set; get;}Public string HostName {set; get;}Public string IPAddress {set; get;}Public string Message {set; get;} Public override String ToString ()        {var bsondoc = this. Tobsondocument ();return bsondoc.tostring ();        }    }The default loggingevent.renderedmessage is to get the ToString () value of object, where you need to rewrite ToString () to convert the class to bsondocument. Loggingevent.renderedmessage Gets the bsondocument and then splits it into specific properties.  private static void Buildcustommessage (string message,ref log log)        {Try            {var Bson = bsondocument.parse (message);foreach (var item in Bson. Elements)                {String value = Item. Value.tostring ();if (item. Value.isbsonnull)                    {value = String. Empty;                    }log. Properties.add (item. Name, value);                }            }catch (Exception)            {log. renderedmessage = message;            }         }for convenience, use Bsondocument.parse (message) to determine whether it is a complex object or a string. Processing directly with a try catch can have a little effect on performance. The test did not require Buildcustommessage to pass the string directly, and the performance difference was about 6% when passing complex objects. This 6% is mainly the object ToString () converted to bsondocument, and buildcustommessage two parts.   4, a strange problem occurred in the test, a single statement log. Debug (string) can be output to the console, but it cannot write to the database. Instead, a loop is used to execute the log.  Debug (String), but can write to the database normally. Log4net has a hint of output shutdown called on hierarchy, but does not understand what it means and does not know whether it is relevant. The workaround is to change the write database operation from asynchronous to synchronous. Not found for specific reasons. Log4net own problems, mongodb drivers, log4net caches and so on can not be ruled out. //collection. Insertoneasync (Buildbsondocument (loggingevent));collection. Insertone (Buildbsondocument (loggingevent));  5, in order to facilitate future maintenance, set the database name and collection (table name) to the configuration file. <appender name= "Mongodbappender" type= "Log4mongo.mongodbappender, Log4mongo" ><connectionstring value= "mongodb://root:[email protected]: 27017"/><databasename value= "Log4mongo"/><collectionname value= "Yyyymm"/></appender>The configured values are obtained directly from the public class Mongodbappender:appenderskeleton and do not require additional processingPublic string connectionStringName {get; set;}Public string DatabaseName {get; set;}Public string CollectionName {get; set;}<collectionname value= "Yyyymm" The purpose of this writing is to have the logs automatically divided by date. By modifying the configuration, you can divide the table by day, by month, by year.  
Private imongocollection<log> GetCollection () {string tableName; TableName = CollectionName??            "Yyyymm"; TableName = "Log" + string.            Format ("{0:" + tableName + "}", DateTime.Now); Return Getdatabase (). Getcollection<log> (TableName); }
             

Save log4net logs to MongoDB database practice

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.