. Net log system parsing and. net log Parsing
I. Preface
The log system is essential for any project, whether for debugging, performance testing, execution time, Operation Records, online troubleshooting, and access records in the test phase, log systems play an important role. The purpose of this article is to help people who need it quickly build their own LogSystem. Let's start with the previous figure. I think the page is refreshing:
My LogSystem uses the Log4net warehouse receiving method. There are a lot of shares on the Internet, but there are very few that can be fully run. Therefore, we need to hurry up with our friends who will be useful in the future.
Ii. import custom Log4Net content to the database
The log storage method of Log4Net is not practical. Isn't IT automated? If you don't need to talk about it, first go to the code of the Log4net storage system.
LogSystem database structure. I suggest a project and a table.
In the Log component, you need these classes. The following code is provided:
LogContent. cs, which defines the Log entity. This object is created by passing parameters to the constructor when the entity is materialized. The comment is very detailed.
Using System; namespace LogComponent {public class LogContent {public LogContent (string logLevel, string logMsg, string logModule, string description, string userName) {LogLevel = logLevel; UserName = userName; description = description; LogMsg = logMsg; LogModule = logModule;} // <summary> // Log Level /// </summary> public string LogLevel {get; set ;} /// <summary> /// Log message // </summary> public string LogMsg {get; set ;} /// <summary> /// System Login User /// </summary> public string UserName {get; set ;} /// <summary> /// log Description /// </summary> public string Description {get; set ;} /// <summary> /// record time /// </summary> public DateTime LogDate {get; set ;} /// <summary> /// Module name /// </summary> public string LogModule {get; set ;}}}
LogHelper. cs, which defines the Log Level and Writing Method
[Assembly: log4net. config. xmlConfigurator (Watch = true, ConfigFile = "log4net. config ")] namespace LogComponent {public class LogHelper {static log4net. ILog log = log4net. logManager. getLogger ("myLogger "); /// <summary> /// exception log /// </summary> /// <param name = "logMsg"> log information </param> /// <param name = "logModule"> code module </param> /// <param name = "description"> other descriptions </param> /// <param name = "userName"> username </param> public static void LogError (string logMsg, string logModule, string description = "", string userName = "") {log. error (new LogContent ("Error", SubLogString (logMsg), logModule, SubLogString (description), userName);} public static void LogInfo (string logMsg, string logModule, string description = "", string userName = "") {log. info (new LogContent ("Info", SubLogString (logMsg), logModule, SubLogString (description), userName);} public static void LogWarn (string logMsg, string logModule, string description = "", string userName = "") {log. warn (new LogContent ("Warn", SubLogString (logMsg), logModule, SubLogString (description), userName);} public static void LogDebug (string logMsg, string logModule, string description = "", string userName = "") {log. debug (new LogContent ("Debug", SubLogString (logMsg), logModule, SubLogString (description), userName);} private static string SubLogString (string str) {if (str. length> 1500) {return str. substring (0, 1500) ;}return str ;}}}
MessagePartternConverter. cs
Using log4net. core; using log4net. layout. pattern; using System. IO; using System. reflection; namespace LogComponent {class MessagePatternConverter: PatternLayoutConverter {protected override void Convert (TextWriter writer, LoggingEvent loggingEvent) {if (Option! = Null) {// Write the value for the specified key WriteObject (writer, loggingEvent. repository, LookupProperty (Option, loggingEvent);} else {// Write all the key value pairs WriteDictionary (writer, loggingEvent. repository, loggingEvent. getProperties ());}} /// <summary> /// obtain the value of an attribute of the input log object through reflection /// </summary> /// <param name = "property"> </param> // <returns> </returns> private object LookupPrope Rty (string property, log4net. Core. LoggingEvent loggingEvent) {object propertyValue = string. Empty; PropertyInfo propertyInfo = loggingEvent. MessageObject. GetType (). GetProperty (property); if (propertyInfo! = Null) propertyValue = propertyInfo. GetValue (loggingEvent. MessageObject, null); return propertyValue ;}}}
MyLayout. cs
using log4net.Layout;namespace LogComponent{ class MyLayout : PatternLayout { public MyLayout() { this.AddConverter("property", typeof(MessagePatternConverter)); } }}
In fact, the most important part here is not the code. The core part of Log4net is all written for us. The key is your configuration. The following is the content of log4net. config. It is the same in your web project. But don't forget to reference nuget: log4net in your project.
Log4net. configThe following figure shows how to configure the parameters for logging to the database and SQL statements. Of course, there is an SQL connection. The annotations are already detailed.
<? Xml version = "1.0" encoding = "UTF-8"?> <Configuration> <configSections> <section name = "log4net" type = "log4net. config. log4NetConfigurationSectionHandler, log4net "/> </configSections> <log4net> <root> <level value =" Debug "/> <appender-ref =" ADONetAppender "/> </root> <logger name = "myLogger"> <level value = "Debug"/> <appender-ref = "ADONetAppender"/> </logger> <appender name = "ADONetAppender" type =" log4net. appender. ADONetAppender, log4net "> <! -- BufferSize indicates the buffer size. Only logs that exceed the value are written to the database. --> <bufferSize value = "1"/> <! -- Or <param name = "BufferSize" value = "1"/> --> <! -- Reference --> <connectionType value = "System. Data. SqlClient. SqlConnection, System. Data, Version = 1.0.3300.0, Culture = neutral, PublicKeyToken = b77a5c561934e089"/> <! -- Connect to the database string --> <connectionString value = "Data Source = 115.29.54.31; Initial Catalog = LogSystem; uid = sa; pwd = sa.; MultipleActiveResultSets = True"/> <! -- INSERT to table Log --> <commandText value = "insert into HdPubLog ([LogDate], [LogMsg], [UserName], [Description], [LogLevel], [LogModule]) VALUES (@ log_date, @ LogMsg, @ UserName, @ Description, @ LogLevel, @ LogModule) "/> <parameter> <parameterName value =" @ log_date "/> <dbType value =" DateTime "/> <layout type =" log4net. layout. rawTimeStampLayout "/> <! -- Obtain the default time output format of RawTimeStampLayout provided by log4net --> </parameter> <parameterName value = "@ LogMsg"/> <dbType value = "String & quot;/> <size value = "1510"/> <layout type = "LogComponent. myLayout, logComponent "> <param name =" ConversionPattern "value =" % property {LogMsg} "/> </layout> </parameter> <parameterName value =" @ UserName" /> <dbType value = "String"/> <size value = "50"/> <layout type = "LogComponent. myLayout, logComponent "> <param name =" ConversionPattern "value =" % property {UserName} "/> </layout> </parameter> <parameterName value =" @ Description" /> <dbType value = "String"/> <size value = "1510"/> <layout type = "LogComponent. myLayout, logComponent "> <param name =" ConversionPattern "value =" % property {Description} "/> </layout> </parameter> <parameterName value =" @ LogLevel" /> <dbType value = "String"/> <size value = "50"/> <layout type = "LogComponent. myLayout, logComponent "> <param name =" ConversionPattern "value =" % property {LogLevel} "/> </layout> </parameter> <parameterName value =" @ LogModule" /> <dbType value = "String"/> <size value = "50"/> <layout type = "LogComponent. myLayout, logComponent "> <param name =" ConversionPattern "value =" % property {LogModule} "/> </layout> </parameter> </appender> </log4net> </configuration>
In this way, your configuration is complete, and you can directly test the insertion:
3. Visualize Log information
My UI uses Datatables. js. the pop-up box is layer, the date component is layDate, and the drop-down box is select2 after the style is modified. The UI code is in my own framework and won't be posted if there is too much content. You just need to check the data from the library and bind it to any data table you like. Because the log system on a single page does not have any complicated operations, you can use sqlHelper to check it. The code and conditions are spliced as follows:
Public class xxxDal {private SqlHelper _ sqlHelper = new SqlHelper (); /// <summary> /// obtain xxx logs /// </summary> /// <param name = "model"> </param> /// <returns> </returns> public List <LogModel> GetxxxLog (SM_LogModel model) {StringBuilder SQL = new StringBuilder (); List <SqlParameter> sqlParameters = new List <SqlParameter> (); StringBuilder sqlWhere = new StringBuilder (); if (! String. isNullOrWhiteSpace (model. logStartTime) {sqlParameters. add (new SqlParameter ("@ LogStartTime", model. logStartTime); sqlWhere. append (@ "AND h. logDate> @ LogStartTime ");} if (! String. isNullOrWhiteSpace (model. logEndTime) {sqlParameters. add (new SqlParameter ("@ LogEndTime", model. logEndTime); sqlWhere. append (@ "AND h. logDate <@ LogEndTime ");} if (! String. isNullOrWhiteSpace (model. logLevel) {sqlParameters. add (new SqlParameter ("@ LogLevel", model. logLevel); sqlWhere. append (@ "AND h. logLevel = @ LogLevel ");} if (! String. isNullOrWhiteSpace (model. logModule) {sqlParameters. add (new SqlParameter ("@ LogModule", model. logModule); sqlWhere. append (@ "AND h. logModule = @ LogModule ");} SQL. appendFormat (@ "WITH t AS (SELECT ROW_NUMBER () OVER (order by id DESC) AS IndexNum, [Id], CONVERT (VARCHAR, [LogDate], 21) AS [LogDate], [UserName], SUBSTRING ([Description], 0,150) AS [Description], SUBSTRING ([LogMsg], 0, (200) AS [LogMsg], [LogLevel], [LogModule] FROM [LogSystem]. [dbo]. [xxxLog] h WHERE 1 = 1 {0}) SELECT * FROM t WHERE IndexNum> @ startIndex AND indexnum <@ endIndex ", sqlWhere); sqlParameters. add (new SqlParameter ("@ startIndex", model. start); sqlParameters. add (new SqlParameter ("@ endIndex", model. start + model. length); DataTable dt = _ sqlHelper. executeDataTable (SQL. toString (), sqlParameters. toArr Ay (); return DataTableTools <LogModel>. dataTableToList (dt);} public int GetxxxLogTotalCount (SM_LogModel model) {StringBuilder SQL = new StringBuilder (); List <SqlParameter> sqlParameters = new List <SqlParameter> (); SQL. append (@ "select count (*) FROM [HdPubLog] h where 1 = 1"); if (! String. isNullOrWhiteSpace (model. logStartTime) {sqlParameters. add (new SqlParameter ("@ LogStartTime", model. logStartTime); SQL. append (@ "AND h. logDate> @ LogStartTime ");} if (! String. isNullOrWhiteSpace (model. logEndTime) {sqlParameters. add (new SqlParameter ("@ LogEndTime", model. logEndTime); SQL. append (@ "AND h. logDate <@ LogEndTime ");} if (! String. isNullOrWhiteSpace (model. logLevel) {sqlParameters. add (new SqlParameter ("@ LogLevel", model. logLevel); SQL. append (@ "AND h. logLevel = @ LogLevel ");} if (! String. isNullOrWhiteSpace (model. logModule) {sqlParameters. add (new SqlParameter ("@ LogModule", model. logModule); SQL. append (@ "AND h. logModule = @ LogModule ");} return _ sqlHelper. executeScalar <int> (SQL. toString (), sqlParameters. toArray ();} [HttpPost] public LogModel GetxxxxSignelLog (int id) {string SQL = @ "SELECT [Id], CONVERT (VARCHAR (30), [LogDate], 21) AS [LogDate], [UserName], [Description], [LogMsg], [LogLevel], [LogModule], [Id] IndexNum FROM [LogSystem]. [dbo]. [xxxxLog] h WHERE h. id = @ Id "; var row = _ sqlHelper. executeDataRow (SQL, new SqlParameter ("@ Id", id); return DataTableTools <LogModel>. dataRowToModel (row );}}
The above is all the content of this article. I hope this article will help you in your study or work. I also hope to provide more support to the customer's home!