• System.IO.Log中的日志记录支持


    System.IO.Log命名空间定义用于登录到面向记录的顺序I/O系统的接口.
    可以实现自己的诊断日志记录系统或事务处理系统,以便实现事务持久性.

    system.io.log.dll 的默认位置为 %programfiles%\Reference Assemblies\Microsoft\Framework\v3.0\
    简单文件日志系统
    描述FileRecordSequence类型,该类型是基于文件系统中的单一日志文件的记录序列.它是在IRecordSequence接口在基于简单文件的日志上简单实现.
    public sealed class FileRecordSequence : IRecordSequence,IDisposable
    例子:

    代码
    public class MyLog
    {
          
    string logName = "test.log";
          FileRecordSequence sequence 
    = null;
          
    bool delete = true;
          
    public MyLog()
          {
                    sequence 
    = New FileRecordSequence(logName);
           }
          
          
    public void AppendRecords()
          {
                 SequenceNumber previous 
    = SequenceNumber.Invalid;
                 previous 
    = sequence.Append(CreateData("Hello Wordl!"), SequenceNumber.Invalid,SequenceNumber.Invalid,RecordAppendOption.ForceFlush);
          }

        
    public void ReadRecords()
        {
                 Encoding enc 
    = Encoding.Unicode;
                 
    foreach(LogRecord record in this.sequence.ReadLogRecords(this.sequence.BaseSequenceNumber,LogRecordEnumeratorType.Next)
                 {
                       
    byte[] data = new byte[record.Data.Length];
                       record.Data.Read(data, 
    0, (int)record.Data.Length);
                       
    string mystr = enc.GetString(data);
                 }
         }
         
    public void Cleanup()
         {
                sequence.Dispose();
                
    if(delete)
                {
                 
    try{  File.Delete(this.logName); }
                 
    catch(Exception e) {}
                }
         }
          
    //把str转成ArraySegment<byte>数组
          public static IList<ArraySegment<byte>> CreateData(string str)
          {
                 Encoding enc 
    = Encoding.Unicode;
                 
    byte[] array = enc.GetBytes(str);
                 ArraySegment
    <byte>[] segments = new ArraySegment<byte>[1];
                 segments[
    0= new ArraySegment<byte>(array);
                 
    return Array.AsReadOnly<ArraySegment<byte>>(segments);
          }
    }

    LogRecordSequence 类提供记录序列接口在公用日志文件系统 (CLFS) 日志之上的实现。除了标准的面向记录的功能,此类还提供一个策略模型,用于避免出现日志满的状况并允许多个客户端复用同一个物理文件。它与 LogStore 类一起使用,该类提供了直接操作和管理 CLFS 日志文件的接口。LogStore 类和 LogRecordSequence 类之间的关系类似于磁盘文件和 FileStream 对象之间的关系。磁盘文件提供实际存储区,并具有长度和上次访问时间等属性,而 FileStream 对象提供文件的视图,可用来在实际存储区中读取和写入数据。与之类似,LogStore 类具有策略和磁盘范围集合等属性;而 LogRecordSequence 类提供面向记录的数据读取和写入机制。

    代码
    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Text;
    using System.IO.Log;

    namespace MyLogRecordSequence
    {
        
    public class MyLog
        {
            
    string logName = "test.log";
            
    string logContainer = "MyExtent0";
            
    int containerSize = 32 * 1024;
            LogRecordSequence sequence 
    = null;
            
    bool delete = true;

            
    // These are used in the TailPinned event handler.
            public static LogRecordSequence MySequence = null;
            
    public static bool AdvanceBase = true;

            
    public MyLog()
            {
                
    // Create a LogRecordSequence.
                sequence = new LogRecordSequence(this.logName,
                                                  FileMode.CreateNew,
                                                  FileAccess.ReadWrite,
                                                  FileShare.None);

                
    // At least one container/extent must be added for Log Record Sequence.
                sequence.LogStore.Extents.Add(this.logContainer, this.containerSize);

                MySequence 
    = sequence;

            }

            
    public void AddExtents()
            {
                
    // Add two additional extents. The extents are 
                
    // of the same size as the first extent.
                sequence.LogStore.Extents.Add("MyExtent1");
                sequence.LogStore.Extents.Add(
    "MyExtent2");
            }

            
    public void EnumerateExtents()
            {
                LogStore store 
    = sequence.LogStore;

                Console.WriteLine(
    "Enumerating Log Extents...");
                Console.WriteLine(
    "    Extent Count: {0} extents", store.Extents.Count);
                Console.WriteLine(
    "    Extents Are...");
                
    foreach (LogExtent extent in store.Extents)
                {
                    Console.WriteLine(
    "      {0} ({1}, {2})",
                                      Path.GetFileName(extent.Path),
                                      extent.Size,
                                      extent.State);
                }
                Console.WriteLine(
    "    Free Extents: {0} Free", store.Extents.FreeCount);   
            }

            
    public void SetLogPolicy()
            {
                Console.WriteLine();
                Console.WriteLine(
    "Setting current log policy...");

                
    // SET LOG POLICY

                LogPolicy policy 
    = sequence.LogStore.Policy;

                
    // Set AutoGrow policy. This enables the log to automatically grow
                
    // when the existing extents are full. New extents are added until
                
    // we reach the MaximumExtentCount extents.
                
    // AutoGrow policy is supported only in Windows Vista and not available in R2.

                
    //policy.AutoGrow = true;

                
    // Set the Growth Rate in terms of extents. This policy specifies
                
    // "how much" the log should grow. 
                policy.GrowthRate = new PolicyUnit(2, PolicyUnitType.Extents);

                
    // Set the AutoShrink policy. This enables the log to automatically
                
    // shrink if the available free space exceeds the shrink percentage. 
                
    // AutoGrow/shrink policy is supported only in Windows Vista and not available in R2.

                
    //policy.AutoShrinkPercentage = new PolicyUnit(30, PolicyUnitType.Percentage);

                
    // Set the PinnedTailThreshold policy.
                
    // A tail pinned event is triggered when there is no
                
    // log space available and log space may be freed by advancing the base.
                
    // The user must handle the tail pinned event by advancing the base of the log. 
                
    // If the user is not able to move the base of the log, the user should report with exception in
                
    // the tail pinned handler.
                
    // PinnedTailThreashold policy dictates the amount of space that the TailPinned event requests 
                
    // for advancing the base of the log. The amount of space can be in percentage or in terms of bytes 
                
    // which is rounded off to the nearest containers in CLFS. The default is 35 percent.


                policy.PinnedTailThreshold 
    = new PolicyUnit(10, PolicyUnitType.Percentage);

                
    // Set the maximum extents the log can have.
                policy.MaximumExtentCount = 6;

                
    // Set the minimum extents the log can have.
                policy.MinimumExtentCount = 2;

                
    // Set the prefix for new containers that are added. 
                
    // when AutoGrow is enabled.
                
    //policy.NewExtentPrefix = "MyLogPrefix";

                
    // Set the suffix number for new containers that are added.
                
    // when AutoGrow is enabled. 
                policy.NextExtentSuffix = 3;

                
    // Commit the log policy.
                policy.Commit();

                
    // Refresh updates the IO.Log policy properties with current log policy 
                
    // set in the log. 
                policy.Refresh();

                
    // LOG POLICY END
                
    // 

                
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                
    // Setting up IO.Log provided capabilities...
                
    // 

                
    // SET RETRY APPEND

                
    // IO.Log provides a mechanism similar to AutoGrow.
                
    // If the existing log is full and an append fails, setting RetryAppend
                
    // invokes the CLFS policy engine to add new extents and re-tries
                
    // record appends. If MaximumExtent count has been reached, 
                
    // a SequenceFullException is thrown. 
                
    // 

                sequence.RetryAppend 
    = true;

                
    // RETRY APPEND END

                
    // REGISTER FOR TAILPINNED EVENT NOTIFICATIONS

                
    // Register for TailPinned Event by passing in an event handler.
                
    // An event is raised when the log full condition is reached.
                
    // The user should either advance the base sequence number to the 
                
    // nearest valid sequence number recommended in the tail pinned event or
                
    // report a failure that it is not able to advance the base sequence 
                
    // number. 
                
    //

                sequence.TailPinned 
    += new EventHandler<TailPinnedEventArgs>(HandleTailPinned);  

                Console.WriteLine(
    "Done...");
            }

            
    public void ShowLogPolicy()
            {
                Console.WriteLine();
                Console.WriteLine(
    "Showing current log policy...");

                LogPolicy policy 
    = sequence.LogStore.Policy;

                Console.WriteLine(
    "    Minimum extent count:  {0}", policy.MinimumExtentCount);
                Console.WriteLine(
    "    Maximum extent count:  {0}", policy.MaximumExtentCount);
                Console.WriteLine(
    "    Growth rate:           {0}", policy.GrowthRate);
                Console.WriteLine(
    "    Pinned tail threshold: {0}", policy.PinnedTailThreshold);
                Console.WriteLine(
    "    Auto shrink percent:   {0}", policy.AutoShrinkPercentage);
                Console.WriteLine(
    "    Auto grow enabled:     {0}", policy.AutoGrow);
                Console.WriteLine(
    "    New extent prefix:     {0}", policy.NewExtentPrefix);
                Console.WriteLine(
    "    Next extent suffix:    {0}", policy.NextExtentSuffix);

        }

            
    // Append records. Appending three records.  
            public void AppendRecords()
            {
                Console.WriteLine(
    "Appending Log Records...");
                SequenceNumber previous 
    = SequenceNumber.Invalid;

                previous 
    = sequence.Append(CreateData("Hello World!"), SequenceNumber.Invalid, SequenceNumber.Invalid, RecordAppendOptions.ForceFlush);
                previous 
    = sequence.Append(CreateData("This is my first Logging App"), SequenceNumber.Invalid, SequenceNumber.Invalid, RecordAppendOptions.ForceFlush);
                previous 
    = sequence.Append(CreateData("Using LogRecordSequence..."), SequenceNumber.Invalid, SequenceNumber.Invalid, RecordAppendOptions.ForceFlush);
            
                Console.WriteLine(
    "Done...");
            }


            
    // Read the records added to the log. 
            public void ReadRecords()
            {
                Encoding enc 
    = Encoding.Unicode;

                Console.WriteLine();

                Console.WriteLine(
    "Reading Log Records...");
                
    try
                {
                    
    foreach (LogRecord record in this.sequence.ReadLogRecords(this.sequence.BaseSequenceNumber, LogRecordEnumeratorType.Next))
                    {
                        
    byte[] data = new byte[record.Data.Length];
                        record.Data.Read(data, 
    0, (int)record.Data.Length);
                        
    string mystr = enc.GetString(data);
                        Console.WriteLine(
    "    {0}", mystr);
                    }
                }
                
    catch (Exception e)
                {
                    Console.WriteLine(
    "Exception {0} {1}", e.GetType(), e.Message);
                }

                Console.WriteLine();
            }

            
    public void FillLog()
            {
                
    bool append = true;

                
    while (append)
                {
                    
    try
                    {
                        sequence.Append(CreateData(
    16 * 1024), SequenceNumber.Invalid, SequenceNumber.Invalid, RecordAppendOptions.ForceFlush);
                    }

                    
    catch (SequenceFullException)
                    {
                        Console.WriteLine(
    "Log is Full...");
                        append 
    = false;
                    }
                }
            }

            
    // Dispose the record sequence and delete the log file. 
            public void Cleanup()
            {
                
    // Dispose the sequence
                sequence.Dispose();

                
    // Delete the log file.
                if (delete)
                {
                    
    try
                    {
                        
    // This deletes the base log file and all the extents associated with the log.
                        LogStore.Delete(this.logName);
                    }
                    
    catch (Exception e)
                    {
                        Console.WriteLine(
    "Exception {0} {1}", e.GetType(), e.Message);
                    }
                }
            }

            
    // Converts the given data to an Array of ArraySegment<byte> 
            public static IList<ArraySegment<byte>> CreateData(string str)
            {
                Encoding enc 
    = Encoding.Unicode;

                
    byte[] array = enc.GetBytes(str);

                ArraySegment
    <byte>[] segments = new ArraySegment<byte>[1];
                segments[
    0= new ArraySegment<byte>(array);

                
    return Array.AsReadOnly<ArraySegment<byte>>(segments);
            }

            
    public static IList<ArraySegment<byte>> CreateData(int size)
            {
                
    byte[] array = new byte[size];

                Random rand 
    = new Random();
                rand.NextBytes(array);

                ArraySegment
    <byte>[] segments = new ArraySegment<byte>[1];
                segments[
    0= new ArraySegment<byte>(array);

                
    return Array.AsReadOnly<ArraySegment<byte>>(segments);
            }

            
    public static SequenceNumber GetAdvanceBaseSeqNumber(SequenceNumber recTargetSeqNum)
            {
                SequenceNumber targetSequenceNumber 
    = SequenceNumber.Invalid;

                Console.WriteLine(
    "Getting actual target sequence number...");

                
    // 
                
    // Implement the logic for returning a valid sequence number closer to
                
    // recommended target sequence number. 
                
    //

                
    return targetSequenceNumber;
            }

            
    public static void HandleTailPinned(object arg, TailPinnedEventArgs tailPinnedEventArgs)
            {
                Console.WriteLine(
    "TailPinned has fired");

                
    // Based on the implementation of a logging application, the log base can be moved
                
    // to free up more log space and if it is not possible to move the 
                
    // base, the application should report by throwing an exception.

                
    if(MyLog.AdvanceBase)
                {
                    
    try
                    {
                        
    // TailPnnedEventArgs has the recommended sequence number and its generated 
                        
    // based on PinnedTailThreshold policy. 
                        
    // This does not map to an actual sequence number in the record sequence
                        
    // but an approximation and potentially frees up the threshold % log space
                        
    // when the log base is advanced to a valid sequence number closer to the 
                        
    // recommended sequence number. 
                        
    // The user should use this sequence number to locate a closest valid sequence
                        
    // number to advance the base of the log.

                        SequenceNumber recommendedTargetSeqNum 
    = tailPinnedEventArgs.TargetSequenceNumber; 

                        
    // Get the actual Target sequence number.
                        SequenceNumber actualTargetSeqNum = MyLog.GetAdvanceBaseSeqNumber(recommendedTargetSeqNum);

                        MySequence.AdvanceBaseSequenceNumber(actualTargetSeqNum);
                    }
                    
    catch (Exception e)
                    {
                        Console.WriteLine(
    "Exception thrown {0} {1}", e.GetType(), e.Message);
                    }
                }
                
    else
                {
                    
    // Report back Error if under some conditions the log cannot
                    
    // advance the base sequence number.

                    Console.WriteLine(
    "Reporting Error! Unable to move the base sequence number!");
                    
    throw new IOException();
                }
            }
        }

        
    class LogSample
        {
            
    static void Main(string[] args)
            {
                
    // Create log record sequence.
                MyLog log = new MyLog();

                
    // Add additional extents.
                log.AddExtents();

                
    // Enumerate the current log extents.
                log.EnumerateExtents();

                
    // Set log policies and register for TailPinned event notifications. 
                log.SetLogPolicy();

                log.ShowLogPolicy();

                
    // Append a few records and read the appended records. 
                log.AppendRecords();
                log.ReadRecords();

                
    // Fill the Log to trigger log growth...and subsequent TailPinned notifications.
                log.FillLog();

                log.EnumerateExtents();

                log.Cleanup();
            }
        }
    }
  • 相关阅读:
    在awk里引用shell变量(支持正则)
    python模块pyautogui
    一个完整的搜索系统
    信息检索笔记(9)再论文档评分
    信息检索导论学习笔记(8)向量空间模型
    搜索引擎查询扩展
    信息检索笔记(10)Lucene文档评分机制
    Lucene的分析过程
    信息检索导论学习笔记(7)文档评分、词项权重计算
    信息检索导论学习笔记(5)
  • 原文地址:https://www.cnblogs.com/chenqingwei/p/1658025.html
Copyright © 2020-2023  润新知