Asp.Net 应用 ;Oracle数据库
1. 新建数据库表Log
create table LOG
(
--默认信息
DATETIME DATE,
THREAD VARCHAR2(255),
LOG_LEVEL VARCHAR2(255),
LOGGER VARCHAR2(255),
MESSAGE VARCHAR2(4000),
--自定义信息
USERID VARCHAR2(50),
USERNAME VARCHAR2(20),
)
2. 新建Asp.Net网站 解决方案名:Log4net
(1) 添加引用
System.Data.OracleClient
log4net.dll
(2) 添加全局配置文件Global.asax
(3) 根目录添加文件夹Log用来存放日志输出的文本文件
到此项目结构如:
3. 配置文件web.config请看清楚位置,配置文件中的其它内容默认即可-数据库连接字符串一定要改正确
<?xml version="1.0"?>
<configuration>
<configSections>
<!-- log4net-->
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<log4net>
<!--
根节点<root>可以对日志级别进行控制<level value="INFO"/>
在这个根节点处可以设置appender列表如:
AdoNetAppender_Oracle 存入数据库
ColoredConsoleAppender 输出到控制台
RollingFileAppender 输出到文本文件
这里灵活定义,在这里选择INFO级别并且输入到Oracle数据库
-->
<root>
<level value="INFO"/>
<appender-ref ref="AdoNetAppender_Oracle"/>
</root>
<!--
这个logger可要可不要,如果不要会默认根节点执行
如果配置,会根据配置里面的<level value="INFO"/>
到根节点中找到相应级别然后调用appender输出
有这个节点的好处,可以程序中通过name="WebLogger"
得到用哪一个logger模式控制日志信息
-->
<logger name="WebLogger">
<level value="INFO"/>
</logger>
<logger name="开发用">
<level value="DEBUG"/>
<appender-ref ref="RollingFileAppender"/>
</logger>
<!--
输出到文本文件
网站根目录Log/log.txt
-->
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Log/log.txt"/>
<appendToFile value="true"/>
<maxSizeRollBackups value="20"/>
<maximumFileSize value="500"/>
<rollingStyle value="Date"/>
<datePattern value="yyyy-MM-dd"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<param name="Header" type="log4net.Util.PatternString" value="[%date]%newline"/>
<param name="Footer" value="
"/>
<conversionPattern value="%-5level %date %logger - %message%newline"/>
</layout>
</appender>
<!--Oracle数据库-->
<appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNetAppender">
<!-- Oracle数据源 ,本地安装Oracle客户端-->
<connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<!-- Oracle连接字符串-->
<connectionString value="data source=jdlcerp;User ID=jduser;Password=jduser"/>
<!--
Log4net默认数据表中有Datetime,Thread,Log_Level,Logger,Message这五个字段
数据库表名Log
我们创建数据表时,可以根据自已需求
在这里创建的Log表多加userid,username两个字段
数据表自已提前在数据库定义好
-->
<commandText value="INSERT INTO Log (Datetime,Thread,Log_Level,Logger,Message,userid,username) VALUES (:log_date, :thread, :log_level, :logger, :message,:userid,:username)"/>
<!--
设置缓存区大小
1表明有一条日志就要写入
如果10就表示日志到达10条时一起写入
-->
<bufferSize value="1"/>
<!--默认已有的成员 -->
<parameter>
<parameterName value=":log_date"/>
<dbType value="DateTime"/>
<layout type="log4net.Layout.RawTimeStampLayout"/>
</parameter>
<parameter>
<parameterName value=":thread"/>
<dbType value="String"/>
<size value="255"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread"/>
</layout>
</parameter>
<parameter>
<parameterName value=":log_level"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level"/>
</layout>
</parameter>
<parameter>
<parameterName value=":logger"/>
<dbType value="String"/>
<size value="255"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger"/>
</layout>
</parameter>
<parameter>
<parameterName value=":message"/>
<dbType value="String"/>
<size value="4000"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message"/>
</layout>
</parameter>
<!--自定义成员 -->
<parameter>
<parameterName value=":userid"/>
<dbType value="String"/>
<size value="50"/>
<!--
CustomLayout类的命名空间由自己定义
请注意否则这里找不到定义的字段
此例定义命名空间是:Log4Net
在这个命名空间下写了一个类CustomLayout
用来配置自定义的字段
-->
<layout type="Log4Net.CustomLayout">
<conversionPattern value="%userid"/>
</layout>
</parameter>
<parameter>
<parameterName value=":username"/>
<dbType value="String"/>
<size value="20"/>
<layout type="Log4Net.CustomLayout">
<conversionPattern value="%username"/>
</layout>
</parameter>
</appender>
</log4net>
</configuration>
4. App_Code中添加类文件,以实现自定义信息
(1)添加自字义字段类 ,创建一个新字段,添加这样一个类
1) UserIdPatternConverter.cs
using System;
using System.Collections.Generic;
using System.Text;
using log4net.Layout.Pattern;
using System.IO;
using log4net.Core;
namespace Log4net
{
internal sealed class UserIdPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogMessage logMessage = loggingEvent.MessageObject as LogMessage;
if (logMessage != null)
writer.Write(logMessage.Userid);
}
}
}
2) UserNamePatternConverter.cs
using System;
using System.Collections.Generic;
using System.Text;
using log4net.Layout.Pattern;
using System.IO;
using log4net.Core;
namespace Log4net
{
internal sealed class UserNamePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogMessage logMessage = loggingEvent.MessageObject as LogMessage;
if (logMessage != null)
writer.Write(logMessage.Username);
}
}
}
(2) 添加字段辅助类LogMessage.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.SessionState;
namespace Log4net
{
public class LogMessage:IRequiresSessionState
{
public LogMessage(){ }
public LogMessage(string userID,string UserName)
{
this.userid = userID;
this.username = UserName;
}
private string userid;
public string Userid
{
get { return userid; }
set { userid = value; }
}
private string username;
public string Username
{
get { return username; }
set { username = value; }
}
}
}
(3) 添加字段转换类CustomLayout.cs
using System;
using System.Collections;
using System.IO;
using log4net.Core;
using log4net.Layout.Pattern;
using log4net.Util;
using log4net.Layout;
using Log4net;
namespace Log4Net
{
public class CustomLayout : log4net.Layout.LayoutSkeleton
{
public const string DefaultConversionPattern ="%message%newline";
public const string DetailConversionPattern = "%timestamp [%thread] %level %logger %ndc - %message%newline";
private static Hashtable s_globalRulesRegistry;
private string m_pattern;
private PatternConverter m_head;
private Hashtable m_instanceRulesRegistry = new Hashtable();
//这里是重点-------------------------------------------------------
/// <summary>
/// 把自定义的字段放进Hashtable
/// 定义多少个写多少个
/// 注意这里有名称要和配置文件中的名称一致
/// 注意命名空间
/// 在配置文件中要用到命名空间
/// </summary>
static CustomLayout()
{
s_globalRulesRegistry = new Hashtable(2);
s_globalRulesRegistry.Add("username", typeof(UserNamePatternConverter));
s_globalRulesRegistry.Add("userid", typeof(UserIdPatternConverter));
}
//--------------------------------------------------------------------
public CustomLayout() : this(DefaultConversionPattern)
{}
public CustomLayout(string pattern)
{
IgnoresException = true;
m_pattern = pattern;
if (m_pattern == null)
{
m_pattern = DefaultConversionPattern;
}
ActivateOptions();
}
public string ConversionPattern
{
get { return m_pattern; }
set { m_pattern = value; }
}
/// <summary>
/// 对Hashtable中的值进行转换
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
virtual protected PatternParser CreatePatternParser(string pattern)
{
PatternParser patternParser = new PatternParser(pattern);
foreach(DictionaryEntry entry in s_globalRulesRegistry)
{
patternParser.PatternConverters[entry.Key] = entry.Value;
}
foreach(DictionaryEntry entry in m_instanceRulesRegistry)
{
patternParser.PatternConverters[entry.Key] = entry.Value;
}
return patternParser;
}
override public void ActivateOptions()
{
m_head = CreatePatternParser(m_pattern).Parse();
PatternConverter curConverter = m_head;
while(curConverter != null)
{
PatternLayoutConverter layoutConverter = curConverter as PatternLayoutConverter;
if (layoutConverter != null)
{
if (!layoutConverter.IgnoresException)
{
this.IgnoresException = false;
break;
}
}
curConverter = curConverter.Next;
}
}
override public void Format(TextWriter writer, LoggingEvent loggingEvent)
{
if (writer == null)
{
throw new ArgumentNullException("writer");
}
if (loggingEvent == null)
{
throw new ArgumentNullException("loggingEvent");
}
PatternConverter c = m_head;
while(c != null)
{
c.Format(writer, loggingEvent);
c = c.Next;
}
}
public void AddConverter(ConverterInfo converterInfo)
{
AddConverter(converterInfo.Name, converterInfo.Type);
}
public void AddConverter(string name, Type type)
{
if (name == null) throw new ArgumentNullException("name");
if (type == null) throw new ArgumentNullException("type");
if (!typeof(PatternConverter).IsAssignableFrom(type))
{
throw new ArgumentException("The converter type specified ["+type+"] must be a subclass of log4net.Util.PatternConverter", "type");
}
m_instanceRulesRegistry[name] = type;
}
public sealed class ConverterInfo
{
private string m_name;
private Type m_type;
public ConverterInfo()
{}
public string Name
{
get { return m_name; }
set { m_name = value; }
}
public Type Type
{
get { return m_type; }
set { m_type = value; }
}
}
}
}
(4) 输出日志的工具类LogUtil.cs
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using log4net;
public class LogUtil
{
public LogUtil()
{ }
private static Log4net.LogMessage message=null;
private static ILog _log;
public static ILog log
{
get
{
if (_log == null)
{
//从配置文件中读取Logger对象
_log = log4net.LogManager.GetLogger("WebLogger");
}
return _log;
}
}
public static void debug()
{
if (log.IsDebugEnabled)
{
log.Debug(message);
}
}
public static void error()
{
if (log.IsErrorEnabled)
{
log.Error(message);
}
}
public static void fatal()
{
if (log.IsFatalEnabled)
{
log.Fatal(message);
}
}
public static void info()
{
if (log.IsInfoEnabled)
{
log.Info(message);
}
}
public static void warn()
{
if (log.IsWarnEnabled)
{
log.Warn(message);
}
}
/// <summary>
/// 需要写日志的地方调用此方法
/// </summary>
/// <param name="userID">自定义字段</param>
/// <param name="UserName">自定义字段</param>
/// <param name="level">自定义级别</param>
public static void SaveMessage(string userID, string UserName, int level)
{
message = new Log4net.LogMessage(userID,UserName);//用到字段辅助类
switch (level){case 1: info(); break; case 2: warn(); break; case 3: error(); break; case 4: fatal(); break; default: break; }
}
}
5. 具体应用
(1) 在使用日志之前,必须监视Log4net配置;一种可以直接在类中,一种可以配置到全局配置文件中如全局配置
void Application_Start(object sender, EventArgs e)
{
//在应用程序启动时运行的代码
log4net.Config.XmlConfigurator.Configure();
}
(2) 示例Default.aspx页面,页面为空只是在Page_Load中调用输出日志如:
protected void Page_Load(object sender, EventArgs e)
{
//自定义信息
string userID="10000";
string userNmae="ajaxtop";
//级别:1[一般] 2[警告] 3[错误] 4[严重]
int level = 2;
LogUtil.SaveMessage(userID,userNmae,level);
}
6. 结果
7. 对提出问题的朋友表示感谢,但是没能及时回复又表示歉意,为此整理了一个事例,希望可以帮助到有需求的朋友