点击或拖拽改变大小

ILogNet 接口

一个通用的日志接口,支持5个等级的日志消息写入,支持设置当前的消息等级,定义一个消息存储前的触发事件。
A general-purpose log interface, supports the writing of 5 levels of log messages, supports setting the current message level, and defining a trigger event before a message is stored.

命名空间:  HslCommunication.LogNet
程序集:  HslCommunication (在 HslCommunication.dll 中) 版本:12.1.2.0 (12.1.2.0)
语法
public interface ILogNet : IDisposable

ILogNet 类型公开以下成员。

属性
  名称说明
公共属性ConsoleOutput
获取或设置当前的日志信息在存储的时候是否在控制台进行输出,默认不输出。
Gets or sets whether the current log information is output on the console when it is stored. It is not output by default.
公共属性HourDeviation
获取或设置当前日志时间的小时偏差信息,用来解决某些情况下时区设置异常导致记录时间一直不正确的问题,默认为 0,也就是不处理。可以为正数,也可以为负数。
Obtain or set the hourly deviation information of the current log time to solve the problem that the recording time has been incorrect due to abnormal time zone setting in some cases, and the default is 0, that is, it is not processed. Can be positive or negative.
公共属性LogNetStatistics
获取或设置当前的日志记录统计信息,如果你需要统计最近30天的日志,就需要对其实例化,详细参照LogStatistics
Get or set the current log record statistics. If you need to count the logs of the last 30 days, you need to instantiate it. For details, please refer to LogStatistics
公共属性LogSaveMode
日志存储模式,1:单文件,2:按大小存储,3:按时间存储
Log storage mode, 1: single file, 2: storage by size, 3: storage by time
公共属性LogStxAsciiCode
获取或设置在记录文件日志的时候,是否记录不可见字符STX(也即是ASCII字符集的0x02)。默认为 True, 也即是记录这个字符,在日志分析的时候,可以更加方便的分析。
Gets or sets whether to record the invisible character STX (that is, 0x02 of the ASCII character set) when recording the file log. The default is True, that is, this character is recorded, which can be analyzed more conveniently during log analysis.
公共属性LogThreadID
获取或设置是否记录线程ID的数据信息,默认为 True,表示记录,否则,需要设置为 False
Get or set whether to record the data information of the thread ID, the default is True, which means record, otherwise, it needs to be set to False
Top
方法
  名称说明
公共方法Dispose
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
(继承自 IDisposable。)
公共方法FiltrateKeyword
过滤掉指定的关键字的日志,该信息不存储,但仍然触发BeforeSaveToFile事件
Filter out the logs of the specified keywords, the information is not stored, but the BeforeSaveToFile event is still triggered
公共方法GetExistLogFileNames
获取已存在的日志文件名称
Get the name of an existing log file
公共方法RecordMessage
通过指定消息等级,关键字,日志信息进行消息记录
Record messages by specifying message level, keywords, and log information
公共方法RemoveFiltrate
移除过滤的关键字存储
Remove filtered keyword storage
公共方法SetMessageDegree
设置日志的存储等级,高于该等级的才会被存储
Set the storage level of the logs. Only the logs above this level will be stored.
公共方法WriteAnyString
写入任意字符串
Write arbitrary string
公共方法WriteDebug(String)
写入一条调试日志
Write a debug log
公共方法WriteDebug(String, String)
写入一条带关键字的调试日志
Write a debug log with keywords
公共方法WriteDescrition
写入一条解释性的信息,不属于消息等级控制的范畴
Write an explanatory message that is not part of message level control
公共方法WriteError(String)
写入一条错误日志
Write an error log
公共方法WriteError(String, String)
写入一条带关键字的错误日志
Write an error log with keywords
公共方法WriteException(String, Exception)
写入一条带关键字的异常信息
Write an exception log with keywords
公共方法WriteException(String, String, Exception)
写入一条带关键字和描述信息的异常信息
Write an exception log with keywords and text
公共方法WriteFatal(String)
写入一条致命日志
Write an fatal log
公共方法WriteFatal(String, String)
写入一条带关键字的致命日志
Write an fatal log with keywords
公共方法WriteInfo(String)
写入一条普通日志
Write an infomation log
公共方法WriteInfo(String, String)
写入一条带关键字的普通日志
Write an information log with keywords
公共方法WriteNewLine
写入一行换行符
Write a newline
公共方法WriteWarn(String)
写入一条警告日志
Write an warn log
公共方法WriteWarn(String, String)
写入一条带关键字的警告日志
Write an warn log with keywords
Top
事件
  名称说明
公共事件BeforeSaveToFile
存储之前引发的事件,允许额外的操作,比如打印控制台,存储数据库等等
Store previously raised events, allowing additional operations, such as print console, store database, etc.
Top
备注
本组件的日志核心机制,如果您使用了本组件却不想使用本组件的日志组件功能,可以自己实现新的日志组件,只要继承本接口接口。其他常用的日志组件如下:(都是可以实现的)
  1. Log4Net
  2. NLog
示例
自己实例化操作,在HslCommunication里面,可选三种类型
单文件实例化
// 实例化一个日志后,就可以使用了
ILogNet logNet = new LogNetSingle( "D:\\123.txt" );
限制文件大小实例化
// 实例化一个日志后,路径是D的一个文件夹,大小为2M
ILogNet logNet = new LogNetFileSize( "D:\\Logs", 2 * 1024 * 1024 );
日期存储实例化
// 实例化一个日志后,路径是D的一个文件夹,按照每天的规律来存储
ILogNet logNet = new LogNetDateTime( "D:\\Logs", GenerateMode.ByEveryDay );
基本的使用
// 然后我们的代码就可以调用下面的方法来存储日志了,支持下面的5个等级的
logNet.WriteDebug( "Debug log test" );
logNet.WriteInfo( "Info log test" );
logNet.WriteWarn( "Warn log test" );
logNet.WriteError( "Error log test" );
logNet.WriteFatal( "Fatal log test" );

// 还有下面的几种额外的情况
logNet.WriteNewLine( );                       // 追加一行空行
logNet.WriteDescrition( "test" );             // 写入额外的注释的信息
logNet.WriteAnyString( "any string" );        // 写任意的数据,不受格式化影响

// 此处的5个等级有高低之分 debug < info < warn < error < fatal < all
// 如果我们需要屏蔽debug等级的话
logNet.SetMessageDegree( HslMessageDegree.INFO );

// 如果我们需要屏蔽debug及info等级的
logNet.SetMessageDegree( HslMessageDegree.WARN );

// 如果所有的日志在记录之前需要在控制台显示出来
logNet.BeforeSaveToFile += (object sender, HslEventArgs e) =>
{
    Console.WriteLine( e.HslMessage.ToString( ) );
};

// 带关键字的功能
logNet.WriteDebug( "A","Debug log test" );
logNet.WriteInfo( "B", "Info log test" );
logNet.WriteWarn( "C", "Warn log test" );
logNet.WriteError( "A", "Error log test" );
logNet.WriteFatal( "B", "Fatal log test" );

// 有了关键字之后,我们就可以根据关键字过滤了
logNet.FiltrateKeyword( "B" ); // 我们不需要B的关键字的日志
logNet.RemoveFiltrate( "B" );  // 重新需要B的关键字的日志

// 日志记录时默认获取当前系统的时间,如果需要在记录日志时,所有的时间往后加8小时,则可以这么设置(如果往前,就是负数)
logNet.HourDeviation = 8;
所有日志不存储
// 如果所有的日志在记录之前需要在控制台显示出来
logNet.BeforeSaveToFile += ( object sender, HslEventArgs e ) =>
{
    Console.WriteLine( e.HslMessage.ToString( ) );

    // 我们接下来举个例子,所有的日志都不存储文件
    e.HslMessage.Cancel = true;
};
仅存储ERROR等级
// 如果所有的日志在记录之前需要在控制台显示出来
logNet.BeforeSaveToFile += ( object sender, HslEventArgs e ) =>
{
    Console.WriteLine( e.HslMessage.ToString( ) );

    // 我们接下来举个例子,只有错误(ERROR)的等级才存储文件
    if (e.HslMessage.Degree != HslMessageDegree.ERROR)
    {
        // 这样的操作就导致,不是ERROR等级,全部不存储。但是不影响触发控制台输出
        e.HslMessage.Cancel = true;
    }
};
不指定路径
// 实例化一个日志后,如果不指定路径,那就不会存储文件,但仍然会触发BeforeSaveToFile事件
ILogNet logNet = new LogNetSingle( "" );

// 所有的日志在控制台显示出来
logNet.BeforeSaveToFile += ( object sender, HslEventArgs e ) =>
{
    Console.WriteLine( e.HslMessage.ToString( ) );
};
Form的示例,存储日志的使用都是一样的,就是实例化的时候不一致,以下示例代码以单文件日志为例
ILogNet示例
private void FormLogNet_Load( object sender, EventArgs e )
{
    logNet = new LogNetSingle( "log.txt" ); 
    // logNet = new LogNetDateTime( Path.Combine( AppDomain.CurrentDomain.BaseDirectory, "Logs" ), GenerateMode.ByEveryDay, 10 );
    comboBox1.DataSource = HslCommunication.BasicFramework.SoftBasic.GetEnumValues<HslMessageDegree>( );
    comboBox1.SelectedItem = HslMessageDegree.DEBUG;
    comboBox2.DataSource = HslCommunication.BasicFramework.SoftBasic.GetEnumValues<HslMessageDegree>( );
    comboBox2.SelectedItem = HslMessageDegree.DEBUG;
    comboBox2.SelectedIndexChanged += ComboBox2_SelectedIndexChanged;

    logNet.FiltrateKeyword( "123" );  // 过滤关键字123的存储
    logNet.BeforeSaveToFile += LogNet_BeforeSaveToFile;
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

    if (Program.Language == 2)
    {
        label1.Text = "Log Degree:";
        label6.Text = "Save Degree:";
        label2.Text = "Time Offset:";
        button_hour_offset.Text = "Set";
        label3.Text = "KeyWord:";
        checkBox1.Text = "Cancel Save?";
        label4.Text = "Message:";
        button3.Text = "Load File";
        button4.Text = "Clear File";
        button8.Text = "LogViewer";
        label5.Text = "Content:";
        label9.Text = "Code:";

        button1.Text = "w-Message";
        button5.Text = "w-NewLine";
        button6.Text = "w-Description";
        button7.Text = "w-Exception";
        button9.Text = "Raise Exception";
    }

    textBox_code.Text = $"ILogNet logNet = new LogNetSingle( \"log.txt\" );  // 如果传入 string.Empty 则不存文件";
}

private void CurrentDomain_UnhandledException( object sender, UnhandledExceptionEventArgs e )
{
    if(e.ExceptionObject is Exception ex)
    {
        logNet?.WriteException( "UnhandledException", ex );
    }
}

private void LogNet_BeforeSaveToFile( object sender, HslEventArgs e )
{
    e.HslMessage.Cancel = checkBox1.Checked;
}

private void ComboBox2_SelectedIndexChanged( object sender, EventArgs e )
{
    HslMessageDegree degree = (HslMessageDegree)comboBox2.SelectedItem;
    logNet.SetMessageDegree( degree );
}

private ILogNet logNet;               // 日志

private void button1_Click( object sender, EventArgs e )
{
    // 写日志
    HslMessageDegree degree = (HslMessageDegree)comboBox1.SelectedItem;

    // 两种方法,第一种
    logNet.RecordMessage( degree, textBox1.Text, textBox2.Text );

    // 第二种
    //if(degree == HslMessageDegree.DEBUG)
    //{
    //    logNet.WriteDebug( textBox1.Text, textBox2.Text );
    //}
    //else if(degree == HslMessageDegree.INFO)
    //{
    //    logNet.WriteInfo( textBox1.Text, textBox2.Text );
    //}
    //else if(degree == HslMessageDegree.WARN)
    //{
    //    logNet.WriteWarn( textBox1.Text, textBox2.Text );
    //}
    //else if (degree == HslMessageDegree.ERROR)
    //{
    //    logNet.WriteError( textBox1.Text, textBox2.Text );
    //}
    //else if (degree == HslMessageDegree.FATAL)
    //{
    //    logNet.WriteFatal( textBox1.Text, textBox2.Text );
    //}

    textBox_code.Text = $"logNet.RecordMessage( HslMessageDegree.{degree}, \"{textBox1.Text}\", \"{textBox2.Text}\" );";
}

private void button5_Click( object sender, EventArgs e )
{
    logNet.WriteNewLine( );

    textBox_code.Text = "logNet.WriteNewLine( );";
}

private void button6_Click( object sender, EventArgs e )
{
    logNet.WriteDescrition( textBox2.Text );

    textBox_code.Text = $"logNet.WriteDescrition( \"{textBox2.Text}\" );";
}

private void button7_Click( object sender, EventArgs e )
{
    try
    {
        int i = 0;
        int j = 100 / i;
    }
    catch(Exception ex)
    {
        logNet.WriteException( textBox1.Text, ex );

        textBox_code.Text = $"logNet.WriteException( \"{textBox1.Text}\", ex );";
    }
}

private int threadCount = 3;
private void button2_Click( object sender, EventArgs e )
{
    threadCount = 3;
    // 100万条日志写入测试
    for (int i = 0; i < threadCount; i++)
    {
        new System.Threading.Thread( new System.Threading.ThreadStart( ThreadLogTest ) )
        {
            IsBackground = true,
        }.Start( );
    }

    button2.Enabled = false;
}

private void ThreadLogTest()
{
    DateTime start = DateTime.Now;
    for (int i = 0; i < 330000; i++)
    {
        logNet.WriteInfo( "key", "这是一条测试日志" );
    }

    TimeSpan ts = DateTime.Now - start;

    if (Interlocked.Decrement(ref threadCount) == 0)
    {
        Invoke( new Action( ( ) =>
        {
            MessageBox.Show( "完成!耗时:" + ts.TotalMilliseconds.ToString( "F3" ) + " 毫秒" );
            button2.Enabled = true;
        } ) );
    }
}

private void button3_Click( object sender, EventArgs e )
{
    if (System.IO.File.Exists( "log.txt" ))
    {
        // 显示日志信息
        using (System.IO.StreamReader sr = new System.IO.StreamReader( "log.txt", Encoding.UTF8 ))
        {
            textBox3.Text = sr.ReadToEnd( );
        }
    }
    else
    {
        MessageBox.Show( StringResources.Language.FileNotExist );
    }

    textBox_code.Text = $"string content = File.ReadAllText( \"log.txt\", Encoding.UTF8 );";
}
参见