MaoBisheng

Asp.Net(C#) & SQL & Oracle

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Most software is designed to accomplish a limited number of specific tasks. Log Parser is different... the number of ways it can be used is limited only by the needs and imagination of the user.——虽然有点夸张,但从这句话看,似乎就能感受到LogParser有多强大了。。。

LogParser功能非常的强大,可以分析IIS日志,系统事件日志,CSV,XML等格式日志,同时也支持接口编程——可用C#调用LogParser的Com,其效率非常之高,特别是对大的日志文件(几十M几百M甚至几G的文本日志文件),使用LogParser能够快速查出你所要的数据,一些常用的方法在LogParser的帮助文档中都有介绍,下面简单举两例子。

1.分析IIS日志
--统计iis日志404错误的页面
Logparser.exe "SELECT distinct count(*) as Times,cs-host as Host,cs-uri-stem as PageUrl into 'D:\Loginfo\IISLog\error\20100428.log.txt' FROM D:\Loginfo\IISLog\100428.log where sc-status=404 Group by Host,PageUrl order by Times desc" -o:tsv

2.分析自定义的日志
通常用程序定义的日志都设为tsv格式的,即列与列之间用 \t 隔开,或者用特殊的组合符号避免日志中本身就包含分隔符,如“\t|\t”,有利于后续的分析。
与系统日志相比,自定义的日志需要声明一个头文件,列名格式与日志内容的列一致,就像SQL表中的列名样。
LogParser.exe "select distinct Host, Uid,SessionId, CASE STRLEN(TRIM(AccountId)) WHEN NULL THEN 0 ELSE 1 END as IsLogin into C:\****.txt from 'D:\Loginfo\LogInfo_1004280930.log' where Host >''" -i:TSV -fixedSep:ON -iHeaderFile D:\Loginfo\PVLogHeadFile\PVLogHeadFile.txt -o:tsv -fileMode:0
-fileMode:0 为0表示追加,为1表示覆盖原文件。

3.用LogParser导数据到数据库中
(1)导入到远程数据库存在的表中
LogParser.exe "SELECT * FROM 'D:\LogInfo\LogInfo_1001032230.log' TO dbo.[table]" -o:SQL -server:[服务器IP] -driver:"SQL Server" -database:[数据库] -username:[用户名] -password:[密码] -i:tsv
(2)导入到本机数据库存在的表中
LogParser.exe "select * into [数据库].dbo.[table] from 'D:\LogInfo\LogInfo_1001032230.log'" -o:sql -database:[数据库]  -i:tsv -iCodepage:65001
(3)导入并创建表
LogParser.exe "SELECT * FROM 'D:\LogInfo\LogInfo_1001032230.log' TO dbo.[table]" -o:SQL -server:[服务器IP] -driver:"SQL Server" -database:[数据库] -username:[用户名] -password:[密码] -i:tsv -createtable:ON
说明:
(1)对于已存在的表,需要在前面预留两个字段,LogParser导入的时候,会把文件名和行号也导入到表中
(2)字段类型,对于已存在的表,里面设置的字段类型必须与要导入的日志文件的类型一一匹配,否则会导入失败,对于创建表的情况,如果需要导入的字段中包含长整型,则导入后的数据也是不对的,创建的表为int型,因此建议是手动建表。

4.C#调用LogParser Com
场景:某网站有一模块,被调用成功,失败都会记一笔日志到文本文件中,需要实时监控失败率。
说明:日志是以一定的格式记录的,第一列表示时间,第二列为描述,包含调用参数,调用是否成功等信息
添加引用:
using LogQuery = MSUtil.LogQueryClassClass;
using LogRecordSet = MSUtil.ILogRecordset;
using TsvInputFormat = MSUtil.COMTSVInputContextClassClass;

   1: /// <summary>
   2: /// 计算失败率
   3: /// </summary>
   4: public double GetFailureRate(string headerFile, string logPath)
   5: {
   6:     double failureRate = 1;
   7:     LogQuery oLogQuery = new LogQuery();
   8:     TsvInputFormat oTsvInputFormat = new TsvInputFormat();
   9:     oTsvInputFormat.iHeaderFile = headerFile;
  10:     LogRecordSet oRecordSet;
  11:     double totalQty = 0;
  12:     double successQty = 0;
  13:     string query = string.Empty;
  14:     try
  15:     {
  16:         #region 所有的条数--Log中包含“reccode=”的行数
  17:         query = @"select count(*) as qty from '" + logPath + "' where loginfo like '%reccode=%'";
  18:         oRecordSet = oLogQuery.Execute(query, oTsvInputFormat);
  19:         if (!oRecordSet.atEnd())
  20:         {
  21:             totalQty = (int)oRecordSet.getRecord().getValue("qty");
  22:         }
  23:         oRecordSet.close();
  24:         #endregion
  25:  
  26:         #region 成功的条数--Log中包含“reccode=0,”的行数
  27:         query = @"select count(*) as qty from '" + logPath) + "' where loginfo like '%reccode=0,%'";
  28:         oRecordSet = oLogQuery.Execute(query, oTsvInputFormat);
  29:         if (!oRecordSet.atEnd())
  30:         {
  31:             successQty = (int)oRecordSet.getRecord().getValue("qty");
  32:         }
  33:         oRecordSet.close();
  34:         #endregion
  35:  
  36:         if (totalQty > 0 && totalQty >= successQty)
  37:         {
  38:             failureRate = Math.Round((1 - successQty / totalQty) * 100, 2);
  39:         }
  40:     }
  41:     catch (Exception ex)
  42:     {
  43:         ReqLog.WriteLine(ex.ToString());
  44:     }
  45:  
  46:     return failureRate;
  47: }
  48:  
  49: /// <summary>
  50: /// 计算调用平均时间
  51: /// </summary>
  52: public double GetAvgLockSec(string headerFile, string logPath)
  53: {
  54:     double avgLockSec = 0;
  55:     LogQuery oLogQuery = new LogQuery();
  56:     TsvInputFormat oTsvInputFormat = new TsvInputFormat();
  57:     oTsvInputFormat.iHeaderFile = headerFile;
  58:     try
  59:     {
  60:         string query = "select AVG(TO_REAL(EXTRACT_VALUE(EXTRACT_TOKEN(SUBSTR(loginfo,INDEX_OF(loginfo,'locksec=')),0,' '),'locksec'))) as avglocksec from '" + logPath + "' where loginfo like '%locksec=%'";
  61:         LogRecordSet oRecordSet = oRecordSet = oLogQuery.Execute(query, oTsvInputFormat);
  62:         if (!oRecordSet.atEnd())
  63:         {
  64:             double item = 0;
  65:             if (!oRecordSet.getRecord().isNull(0))
  66:             {
  67:                 item = double.Parse(oRecordSet.getRecord().getValue(0).ToString());
  68:             }
  69:             avgLockSec = Math.Round(item, 2);
  70:         }
  71:         oRecordSet.close();
  72:     }
  73:     catch (Exception ex)
  74:     {
  75:         ReqLog.WriteLine(ex.ToString());
  76:     }
  77:     return avgLockSec;
  78: }
posted on 2010-05-16 10:15  MaoBisheng  阅读(9884)  评论(5编辑  收藏  举报