一个简单的封装 .net的日志功能

因为项目需要 ,经常自己写一点工具类

下面就是一个简单的日志类,支持多线程,不锁定文件,需要CLFS支持,性能非常好

0警告 0stylecop


ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Logger.cs" company="Clover">
// Copyright (c) Clover, All Rights Reserved.
// </copyright>
// <summary>
// Provides methods to write application logs based on a Common Log File System. This class cannot be inherited.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Clover
{
#region Using directives

using System;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.IO.Log;
using System.Text;

#endregion

/// <summary>
/// Encapsulates a type to write application logs based on a Common Log File System. This class cannot be inherited.
/// </summary>
public sealed class Logger : IDisposable
{
#region Constants and Fields

/// <summary>
/// The key of the configuration for base name.
/// </summary>
public const string BaseNameKey = " Clover.LogBaseName " ;

/// <summary>
/// The key of the configuration for base directory.
/// </summary>
public const string BasePathKey = " Clover.LogBasePath " ;

/// <summary>
/// The key of the configuration for extent size.
/// </summary>
public const string ExtentSizeKey = " Clover.ExtentSize " ;

/// <summary>
/// The default size for each log extent.
/// </summary>
private const int DefaultExtentSize = 10 * 1024 * 1024 ;

/// <summary>
/// The log record sequence object to write the log entries.
/// </summary>
private readonly LogRecordSequence _sequence;

/// <summary>
/// The log store to hold the log record sequence object.
/// </summary>
private readonly LogStore _store;

#endregion

#region Constructors and Destructors

/// <summary>
/// Initializes a new instance of the <see cref="Logger"/> class.
/// </summary>
/// <param name="basePath">
/// The base path where the log files are resided.
/// </param>
/// <param name="baseName">
/// The base name of the log files.
/// </param>
/// <param name="extentSize">
/// Size of each log extent in bytes.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="basePath"/> is null, or <paramref name="baseName"/> is null.
/// </exception>
public Logger( string basePath, string baseName, int extentSize)
{
if ( string .IsNullOrEmpty(basePath))
{
throw new ArgumentNullException( " basePath " );
}

if ( string .IsNullOrEmpty(baseName))
{
throw new ArgumentNullException( " baseName " );
}

// If the base path doesn't exist, create it.
if ( ! Directory.Exists(basePath))
{
Directory.CreateDirectory(basePath);
}

string fullPath = Path.Combine(basePath, baseName);
this ._store = new LogStore(fullPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
this ._sequence = new LogRecordSequence( this ._store);
this ._sequence.RetryAppend = true ;

if ( this ._store.Extents.Count == 0 )
{
this ._store.Extents.Add(fullPath, extentSize);
}
}

/// <summary>
/// Initializes a new instance of the <see cref="Logger"/> class.
/// </summary>
/// <param name="basePath">
/// The base path where the log files are resided.
/// </param>
/// <param name="baseName">
/// The base name of the log files.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="basePath"/> is null, or <paramref name="baseName"/> is null.
/// </exception>
public Logger( string basePath, string baseName)
:
this (basePath, baseName, Logger.DefaultExtentSize)
{

}

/// <summary>
/// Initializes a new instance of the <see cref="Logger"/> class by reading the arguments from the application
/// configuration file.
/// </summary>
/// <exception cref="ArgumentNullException">
/// One or more configuration values are not found in the application's configuration file.
/// </exception>
public Logger()
:
this (
ConfigurationManager.AppSettings[Logger.BasePathKey],
ConfigurationManager.AppSettings[Logger.BaseNameKey],
Convert.ToInt32(ConfigurationManager.AppSettings[Logger.DefaultExtentSize]))
{
}

#endregion

#region Public Methods

/// <summary>
/// Writes the specified entry to the log store with format arguments.
/// </summary>
/// <param name="entry">
/// The entry to write.
/// </param>
/// <param name="args">
/// The arguments to format the entry.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="entry"/> is null.
/// </exception>
public void WriteEntry( string entry, params object [] args)
{
if ( string .IsNullOrEmpty(entry))
{
throw new ArgumentNullException( " entry " );
}

entry
= string .Format(CultureInfo.CurrentCulture, entry, args);
this .WriteEntry(entry);
}

/// <summary>
/// Writes the specified entry to the log store with format arguments.
/// </summary>
/// <param name="entry">
/// The entry to write.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="entry"/> is null.
/// </exception>
public void WriteEntry( string entry)
{
if ( string .IsNullOrEmpty(entry))
{
throw new ArgumentNullException( " entry " );
}

byte [] bytes = Encoding.Unicode.GetBytes(entry);
this ._sequence.Append( new ArraySegment < byte > (bytes), SequenceNumber.Invalid, SequenceNumber.Invalid, RecordAppendOptions.None);
}

#endregion

#region Implemented Interfaces

#region IDisposable

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
this .Dispose( true );
GC.SuppressFinalize(
this );
}

#endregion

#endregion

#region Methods

/// <summary>
/// Releases unmanaged and - optionally - managed resources
/// </summary>
/// <param name="disposing">
/// <c> true </c> to release both managed and unmanaged resources; <c> false </c> to release only unmanaged resources.
/// </param>
private void Dispose( bool disposing)
{
if (disposing)
{
if ( this ._sequence != null )
{
this ._sequence.Dispose();
}

if ( this ._store != null )
{
this ._store.Dispose();
}
}
}

#endregion
}
}

 

以下是单元测试代码: 

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
#region Using directives

using System;

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading;

#endregion

/// <summary>
/// Contains tests for the Log class.
/// </summary>
[TestClass]
public class LoggerTest : UnitTestBase
{
/// <summary>
/// The base path for log test.
/// </summary>
private readonly string _basePath = Environment.ExpandEnvironmentVariables( @" %UserProfile%\Documents\LogTest " );

/// <summary>
/// The base name for log test.
/// </summary>
private const string BaseName = " MyLog " ;

#region Public Methods

/// <summary>
/// Tests the Constructor.
/// </summary>
[TestMethod]
public void ConstructorTest()
{
// Scenario 1: Create a normal Logger using parameterized constructor.
Logger logger = new Logger( this ._basePath, BaseName);
Assert.IsNotNull(logger);

// Scenario 2: Create a normal logger using default configuration.
try
{
new Logger();
Assert.Fail(
" Expect ArgumentNullException or ArgumentOutOfRangeException " );
}
catch (ArgumentOutOfRangeException)
{
Assert.IsTrue(
true );
}
catch (ArgumentNullException)
{
Assert.IsTrue(
true );
}
finally
{
logger.Dispose();
}
}

/// <summary>
/// Tests the WriteEntry method.
/// </summary>
[TestMethod]
public void WriteEntryTest()
{
// Scenario 1: Write one entry.
string content = " A quick brown fox jumps over the lazy dog " ;
using (Logger logger = new Logger( this ._basePath, BaseName))
{
logger.WriteEntry(content);
Assert.IsTrue(
true );

// Scenario 2: Write 1,000,000 entries at a time.
for ( int i = 0 ; i < 1000000 ; i ++ )
{
logger.WriteEntry(content);
}


// Scenario 3: Write one entry with format.
content = " {0} - {1}: {2} " ;
logger.WriteEntry(content,
1 , 2 , 3 );

}
}



#endregion
}

 

转载于:https://www.cnblogs.com/PurpleTide/archive/2011/01/19/1939189.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值