Some experiences on "logs"

Source: Internet
Author: User

The "Log" here refers to the applicationProgramEvent records during running.

In the process of interaction with users, the essence of an application is the process of completing an event operation according to the user's wishes, different Environments and other factors, the same event often has different execution results. In order to monitor the action process of a program and understand the user's operation behavior in case of problems found, we often design a "log" record function in the program, this method is used to record the action status of an application and the user's operation process. On the one hand, it helps the designer to handle program exceptions, and on the other hand, it helps the management staff of the software use unit to understand the operations of their operators, prevent adverse behavior...

In short, it is very useful and necessary to design the "log" function for the program.

Log category:

Logs are classified into system logs and operation logs. System logs are records of the events that occur during the application program running. The most common record is the system exceptions and the record status when the program runs on some key nodes. This type of log is mainly used by system designers to understand the program running status. Operation logs are records of user operations. For example, if a user logs on to the system, the user can modify or delete a row record. This type of log is mainly used for behavior management. Because the monitoring objects and monitoring purposes of these two types of logs are different, the log focus is also different. The former focuses on recording the system status when an event occurs, such as the values of some related variables, so that you can analyze the cause of the event in the future. The latter focuses on recording the specific content of user operations, such as the data values before and after a record change.

So what should a log record?

In my opinion, a log record is an event, so we should be able to clearly and accurately describe this event. Generally, an event includes the following elements: person, location, time, and content. For system logs, the character is the application name at the time, and the location is the specific eventCodeLocation, time is the system time at that time, the event content depends on the need, the key is to be able to fully provide designers with as much field information as possible. For the operation log, the character is the operator at that time, the location is the operation module where the event occurred, the time is the system time at that time, and the event content is the user's specific operation content, the key is to fully reflect the data changes before and after this operation.

Based on my understanding of "log", I am ready to do it myself and design a more suitable log function module for C.

Because the log is recorded at all times of the program running, the log-related code may be distributed in every corner of the software design, so this module should be easy to call.

First, you can use the EventLog class in the. NET Framework for system logs. This class can add Application log records to the Windows event viewer, which can easily meet the above system log Requirements, so I chose to use it to build my system log part.

Second, you can use files or database tables to record operation logs. The advantage of using a file record is that it is easy to view and transmit. The disadvantage is that it is not easy to manage, modify or delete, so it is not suitable for recording key logs. Database tables are safe, efficient, and easy to search and manage, but not to pass. The two methods have their own advantages and disadvantages. I plan to implement both methods at the same time and decide which method to use in actual calls.

it was officially designed: I defined the namespace as lucker. logmanager, which defines the class name as logmanager and separate it into a project. In the future, it can be compiled into a separate DLL file to facilitate reference to this DLL file in other projects. The logmanager class has three construction methods:
Public logmanager (string LOGNAME), which is used to record logs using files.
Public logmanager (string LOGNAME ), used to manage logs using Windows event viewer
Public logmanager (sqlconnection con, string user), used to record logs using database tables
when you decide to use a certain method, declare the corresponding constructor. For example:
logmanager lm1 = new logmanager ();
logmanager lm2 = new logmanager (application. productname);
logmanager lm3 = new logmanager (sqlcon, "admin");
the meanings of specific parameters are described below. The logmanager class exposes a logging method for each method, namely writefilelog, writewindowslog, and writedblog. Each method has several reload methods to call in different situations. In this way, you can easily call them for logging:
lm1.writefilelog ("log1");
lm1.writefilelog ("type1", "log2 ");
...
lm2.writewindowslog ("log3");
lm2.writewindowslog ("e", "log4");
lm2.writewindowslog ("Source", "log5", eventlogentrytype. error, 21, 10);
...
lm3.writedblog ("test1", "OBJ", "999", "99", "just a test! ");
lm3.writedblog (" Test2 "," OBJ "," just a test! ");

The following three methods are used to record logs:
Use Windows event viewer to manage logs:


Use NotePad to record logs:
 
Use the database log table to record logs:

It is time to design the specific implementation of the logmanager class:
Using system;
Using system. Data;
Using system. Data. sqlclient;
Using system. diagnostics;
Using system. IO;
Using system. text;

Namespace lucker. logmanager
{
Public class logmanager
{
Filestream FS; // log file object stream
String filepath = string. Empty; // file storage path
String file = string. Empty; // full file name (including path)

EventLog El; // EventLog object

Sqlconnection sqlcon; // The database connection object in which logs are stored
Sqlcommand sqlcom = new sqlcommand (); // command object for executing the log write operation
String machinename = environment. machinename; // the name of the client machine where the log occurs
String user = string. Empty; // operation Username
Const string createtable = @"
Create Table [DBO]. [log] (
[ID] [numeric] (10, 0) Identity (1, 1) not null,
[User] [nvarchar] (20) not null,
[Workstation] [nvarchar] (50) null,
[Datetime] [datetime] Null,
[Logtype] [nvarchar] (20) null,
[Object] [nvarchar] (20) null,
[Originalvalue] [nvarchar] (200) null,
[Newvalue] [nvarchar] (200) null,
[Remark] [nvarchar] (200) null,
Constraint [pk_log] primary key clustered
(
[ID] ASC
) On [primary]
"; // SQL statement used to create a log table

# Region three constructor Methods
Public logmanager (string LOGNAME)
{
El = new EventLog (LOGNAME, ".", "Default event"); // instantiate an EventLog object. The default source is "Default event"
}
Public logmanager ()
{
// Save the file to the logfiles folder in the application directory
Filepath = system. appdomain. currentdomain. setupinformation. applicationbase + "\ logfiles \\";
If (! Directory. exists (filepath ))
{
Directory. createdirectory (filepath );
}
// The file name is the current date. determine a date file every day to prevent a single file from being too large.
String filename = string. Format ("{0: 0000} {}. log", datetime. Now. Year, datetime. Now. Month, datetime. Now. Day );
File = filepath + filename;
}
Public logmanager (sqlconnection con, string user)
{
Sqlcon = con;
Sqlcom. Connection = sqlcon;
// Add and initialize parameters in the log table
Sqlcom. Parameters. Add ("user", sqldbtype. nvarchar, 20 );
Sqlcom. Parameters. Add ("workstation", sqldbtype. nvarchar, 50 );
Sqlcom. Parameters. Add ("datetime", sqldbtype. datetime );
Sqlcom. Parameters. Add ("logtype", sqldbtype. nvarchar, 20 );
Sqlcom. Parameters. Add ("object", sqldbtype. nvarchar, 20 );
Sqlcom. Parameters. Add ("originalvalue", sqldbtype. nvarchar, 200 );
Sqlcom. Parameters. Add ("newvalue", sqldbtype. nvarchar, 200 );
Sqlcom. Parameters. Add ("remark", sqldbtype. nvarchar, 200 );
User = user;
Iniparameters ();
}
# Endregion

# Region Windows Log
// When the specified log source does not exist, you need to create it
Private Static void createeventsource (string eventsourcename, string LOGNAME)
{
If (! EventLog. sourceexists (eventsourcename ))
{
Try
{
EventLog. createeventsource (eventsourcename, LOGNAME );
}
Catch (exception)
{
Throw new exception ("create event source failed:" + eventsourcename );
}
}
}
Public void close ()
{
El. Close (); // close the object when exiting the program
}
// The following are several methods for writing windows logs:
Public void writewindowslog (string logstring)
{
El. writeentry (logstring );
}
Public void writewindowslog (string eventsourcename, string logstring)
{
Createeventsource (eventsourcename, El. Log );
EventLog. writeentry (eventsourcename, logstring );
}
Public void writewindowslog (string eventsourcename, string logstring, eventlogentrytype logtype)
{
Createeventsource (eventsourcename, El. Log );
EventLog. writeentry (eventsourcename, logstring, logtype );
}
Public void writewindowslog (string logstring, eventlogentrytype logtype)
{
El. writeentry (logstring, logtype );
}
Public void writewindowslog (string logstring, eventlogentrytype logtype, int32 eventid)
{
El. writeentry (logstring, logtype, eventid );
}
Public void writewindowslog (string logstring, eventlogentrytype logtype, int eventid, short category)
{
El. writeentry (logstring, logtype, eventid, category );
}
Public void writewindowslog (string eventsourcename, string logstring, eventlogentrytype logtype, int eventid, short category)
{
Createeventsource (eventsourcename, El. Log );
EventLog. writeentry (eventsourcename, logstring, logtype, eventid, category );
}
# Endregion

# Region file log
// The following methods are used to write file logs:
Public void writefilelog (string MSG)
{
Try
{
FS = system. Io. file. Open (file, system. Io. filemode. append, system. Io. fileaccess. Write );
Byte [] info = new utf8encoding (true ). getbytes (string. format ("{0: yyyy-mm-dd hh: mm: SS}", datetime. now) + ": \ r \ n \ t" + MSG + "\ r \ n ");
FS. Write (Info, 0, info. Length );
FS. Close ();
}
Catch (exception E)
{
Throw new exception ("Write File log failed:" + E. Message );
}
}
Public void writefilelog (string logtype, string MSG)
{
Try
{
FS = system. Io. file. Open (file, system. Io. filemode. append, system. Io. fileaccess. Write );
Byte [] info = new utf8encoding (true ). getbytes (string. format ("{0: yyyy-mm-dd hh: mm: SS}", datetime. now) + ": \ t" + logtype + "\ r \ n \ t" + MSG + "\ r \ n ");
FS. Write (Info, 0, info. Length );
FS. Close ();
}
Catch (exception E)
{
Throw new exception ("Write File log failed:" + E. Message );
}
}
# Endregion

# Region Database Log
// There are several ways to write database logs:
Public void writedblog (string logtype, String object, string originalvalue, string newvalue, string remark)
{
Sqlcom. Parameters ["logtype"]. value = logtype;
Sqlcom. Parameters ["object"]. value = object;
Sqlcom. Parameters ["originalvalue"]. value = originalvalue;
Sqlcom. Parameters ["newvalue"]. value = newvalue;
Sqlcom. Parameters ["remark"]. value = remark;
Writedblog ();
}
// Modify data logs:
Public void writedblog (string logtype, String object, string originalvalue, string newvalue)
{
Sqlcom. Parameters ["logtype"]. value = logtype;
Sqlcom. Parameters ["object"]. value = object;
Sqlcom. Parameters ["originalvalue"]. value = originalvalue;
Sqlcom. Parameters ["newvalue"]. value = newvalue;
Writedblog ();
}
// Object operation log:
Public void writedblog (string logtype, String object, string remark)
{
Sqlcom. Parameters ["logtype"]. value = logtype;
Sqlcom. Parameters ["object"]. value = object;
Sqlcom. Parameters ["remark"]. value = remark;
Writedblog ();
}
// No object operation log:
Public void writedblog (string logtype, string remark)
{
Sqlcom. Parameters ["logtype"]. value = logtype;
Sqlcom. Parameters ["remark"]. value = remark;
Writedblog ();
}
// Initialize parameters in the log table
Private void iniparameters ()
{
Sqlcom. Parameters ["user"]. value = user;
Sqlcom. Parameters ["workstation"]. value = machinename;
Sqlcom. Parameters ["datetime"]. value = datetime. now;
Sqlcom. Parameters ["logtype"]. value = "unknow ";
Sqlcom. Parameters ["object"]. value = "unknow ";
Sqlcom. Parameters ["originalvalue"]. value = "unknow ";
Sqlcom. Parameters ["newvalue"]. value = "unknow ";
Sqlcom. Parameters ["remark"]. value = "NONE ";
}
Private void writedblog ()
{
Getconnection (); // check whether the database is connected. If the database is not connected, connect first.
Checktable (); // check whether the log table exists. If it does not exist, create it first.
Try
{
Sqlcom. commandtext = "insert into [log] ([user], [workstation], [datetime], [logtype], [object], [originalvalue], [newvalue], [Remark]) values (@ user, @ workstation, @ datetime, @ logtype, @ object, @ originalvalue, @ newvalue, @ remark )";
Sqlcom. executenonquery ();
Iniparameters (); // After writing data to the database, you must reset the parameters.
}
Catch (exception E)
{
Throw new exception ("Write database log failed:" + E. Message );
}
}
Private void getconnection ()
{
If (sqlcon = NULL)
Throw new exception ("there is no sqlconnection! ");
Try
{
If (sqlcon. State! = Connectionstate. open)
Sqlcon. open ();
}
Catch (sqlexception)
{
Throw new exception ("Open sqlconnection failed! ");
}
}
Private void checktable ()
{
Try
{
Sqlcommand cmd = new sqlcommand ();
Cmd. Connection = sqlcon;
Cmd. commandtext = "select count (*) from sysobjects where name = 'log '";
If (convert. toint32 (CMD. executescalar () = 1) // log table exists
Return;
Else // log table does not exist
{
Cmd. commandtext = createtable;
Cmd. executenonquery ();
}
}
Catch (exception ex)
{
Throw new exception ("Table log create failed:" + ex. Message );
}
}
# Endregion
}
}

This class takes into account the situation where the file path, log source, or database table does not exist and automatically processes them. Therefore, you do not need to set the task before calling.With this class, you only need to declare and instantiate a global logmanager object lm at the beginning of the program, and then you can call it around: LM. writer ** log (×× );It is easy to use. This class also implements three different logging methods to meet different needs.

Of course, the logmanager class can be further improved. For example, you can design a window for viewing and querying logs when using a database to record logs, use XML files instead of common files to record logs. I hope you will receive more comments.

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.