Initial project's source code check-in.
This commit is contained in:
commit
b03b0b373f
4573 changed files with 981205 additions and 0 deletions
|
@ -0,0 +1,283 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Web;
|
||||
using WebsitePanel.Server.Utils;
|
||||
|
||||
namespace WebsitePanel.Providers.Utils.LogParser
|
||||
{
|
||||
public delegate void ProcessKeyFieldsEventHandler (string[] key_fields, string[] key_values, string[] log_fields, string[] log_values);
|
||||
public delegate void CalculateStatsLineEventHandler(StatsLine line, string[] fields, string[] values);
|
||||
/// <summary>
|
||||
/// Summary description for LogParser.
|
||||
/// </summary>
|
||||
public class LogParser
|
||||
{
|
||||
string serviceName;
|
||||
string logName;
|
||||
string logsPath;
|
||||
string[] keyFields;
|
||||
int keyFieldsLength;
|
||||
Regex re_clean = new Regex("\\W+", RegexOptions.Compiled);
|
||||
string[] _fields;
|
||||
|
||||
public event ProcessKeyFieldsEventHandler ProcessKeyFields;
|
||||
public event CalculateStatsLineEventHandler CalculateStatisticsLine;
|
||||
|
||||
public LogParser(string serviceName, string logName, string logsPath, params string[] keyFields)
|
||||
{
|
||||
this.serviceName = serviceName;
|
||||
this.logName = logName;
|
||||
this.logsPath = logsPath;
|
||||
this.keyFields = keyFields;
|
||||
this.keyFieldsLength = keyFields.Length;
|
||||
//
|
||||
List<string> fShadow = new List<string>(keyFields);
|
||||
fShadow.Add("sc-bytes");
|
||||
fShadow.Add("cs-bytes");
|
||||
fShadow.Add("date");
|
||||
//
|
||||
this._fields = fShadow.ToArray();
|
||||
}
|
||||
|
||||
public void ParseLogs()
|
||||
{
|
||||
ParseLogs<LogReader>();
|
||||
}
|
||||
|
||||
public void ParseLogs<T>() where T : LogReader
|
||||
{
|
||||
// ensure calculation logic has been initialized
|
||||
// with the default calculating routine
|
||||
if (CalculateStatisticsLine == null)
|
||||
CalculateStatisticsLine += new CalculateStatsLineEventHandler(Default_CalculateStatisticLine);
|
||||
//
|
||||
string statsDir = GetStatsFilePath();
|
||||
string statsName = null;
|
||||
// get site state
|
||||
LogState logState = new LogState(statsDir + logName + ".state");
|
||||
|
||||
LogReader reader = (LogReader)Activator.CreateInstance(typeof(T));
|
||||
reader.Open(logsPath, logState.LastAccessed, logState.Line);
|
||||
|
||||
Hashtable monthlyLogs = new Hashtable();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
try
|
||||
{
|
||||
// skip error and system lines
|
||||
if (reader.ErrorLine || reader.SystemLine)
|
||||
continue;
|
||||
// skip block with log data if fields aren't available
|
||||
if (!reader.CheckFieldsAvailable(_fields))
|
||||
continue;
|
||||
//
|
||||
string[] dateParts = reader["date"].Split('-'); // yyyy-mm-dd
|
||||
int day = Int32.Parse(dateParts[2]);
|
||||
|
||||
string[] keyValues = new string[keyFieldsLength];
|
||||
//
|
||||
for (int i = 0; i < keyFieldsLength; i++)
|
||||
keyValues[i] = reader[keyFields[i]];
|
||||
//
|
||||
if (ProcessKeyFields != null)
|
||||
ProcessKeyFields(keyFields, keyValues, reader.LineFields, reader.LineValues);
|
||||
// build stats file name
|
||||
statsName = GetMothlyStatsFileName(dateParts[0], dateParts[1], keyValues);
|
||||
//
|
||||
MonthlyStatistics monthlyStats = (MonthlyStatistics)monthlyLogs[statsName];
|
||||
if (monthlyStats == null)
|
||||
{
|
||||
// add new statistics
|
||||
try
|
||||
{
|
||||
monthlyStats = new MonthlyStatistics(Path.Combine(statsDir, statsName), true);
|
||||
monthlyLogs[statsName] = monthlyStats;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Handle an exception
|
||||
Log.WriteError(String.Format("LogParser: Failed to instantiate monthly stats file '{0}' at '{0}' path", statsName, statsDir), ex);
|
||||
// SKIP OVER THE NEXT ITERATION
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// get current day from statistic
|
||||
StatsLine dayStats = monthlyStats[day];
|
||||
if (dayStats == null)
|
||||
{
|
||||
dayStats = new StatsLine();
|
||||
monthlyStats[day] = dayStats;
|
||||
}
|
||||
// perform statistics line calculation
|
||||
// this workaround has been added due to avoid
|
||||
// IIS 6 vs. IIS 7 log files calculation logic discrepancies
|
||||
CalculateStatisticsLine(dayStats, reader.LineFields, reader.LineValues);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.WriteError(String.Format("Failed to process line {0}, statistics directory path {1}, statistics file name {2}", reader.LogLine, statsDir, reader.LogName), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// save all accumulated statistics
|
||||
foreach (MonthlyStatistics monthlyStats in monthlyLogs.Values)
|
||||
monthlyStats.Save(statsDir);
|
||||
|
||||
// save site state
|
||||
logState.LastAccessed = reader.LogDate;
|
||||
logState.Line = reader.LogLine;
|
||||
logState.Save();
|
||||
}
|
||||
|
||||
public MonthlyStatistics GetMonthlyStatistics(int year, int month, params string[] keyValues)
|
||||
{
|
||||
string statsName = GetMothlyStatsFileName(year.ToString(), month.ToString(), keyValues);
|
||||
return new MonthlyStatistics(Path.Combine(this.GetStatsFilePath(), statsName), true);
|
||||
}
|
||||
|
||||
public DailyStatistics[] GetDailyStatistics(DateTime since, params string[] keyValues)
|
||||
{
|
||||
ArrayList days = new ArrayList();
|
||||
|
||||
// read statistics
|
||||
DateTime now = DateTime.Now;
|
||||
DateTime date = since;
|
||||
|
||||
if (date == DateTime.MinValue)
|
||||
date = GetLogsBeginDate();
|
||||
|
||||
// iterate from since to now
|
||||
while (date < now)
|
||||
{
|
||||
// get monthly statistics
|
||||
MonthlyStatistics stats = GetMonthlyStatistics(date.Year, date.Month, keyValues);
|
||||
foreach (int day in stats.Days.Keys)
|
||||
{
|
||||
StatsLine line = stats[day];
|
||||
DailyStatistics dailyStats = new DailyStatistics();
|
||||
dailyStats.Year = date.Year;
|
||||
dailyStats.Month = date.Month;
|
||||
dailyStats.Day = day;
|
||||
dailyStats.BytesSent = line.BytesSent;
|
||||
dailyStats.BytesReceived = line.BytesReceived;
|
||||
|
||||
days.Add(dailyStats);
|
||||
}
|
||||
|
||||
// advance month
|
||||
date = date.AddMonths(1);
|
||||
}
|
||||
|
||||
return (DailyStatistics[])days.ToArray(typeof(DailyStatistics));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform default statistics line calculation.
|
||||
/// Suits for the following providers: IIS 6.0;
|
||||
/// </summary>
|
||||
/// <param name="line">Statistic line is being calculated</param>
|
||||
/// <param name="fields">Log file available fields</param>
|
||||
/// <param name="values">Log file available values for the line is being read</param>
|
||||
private void Default_CalculateStatisticLine(StatsLine line, string[] fields, string[] values)
|
||||
{
|
||||
int cs_bytes = Array.IndexOf(fields, "cs-bytes");
|
||||
int sc_bytes = Array.IndexOf(fields, "sc-bytes");
|
||||
// run default calculation logic
|
||||
if (cs_bytes > -1)
|
||||
line.BytesReceived += Int64.Parse(values[cs_bytes]);
|
||||
//
|
||||
if (sc_bytes > -1)
|
||||
line.BytesSent += Int64.Parse(values[sc_bytes]);
|
||||
}
|
||||
|
||||
private DateTime GetLogsBeginDate()
|
||||
{
|
||||
DirectoryInfo dir = new DirectoryInfo(logsPath);
|
||||
FileInfo[] files = dir.GetFiles();
|
||||
DateTime minDate = DateTime.Now;
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
if (file.CreationTime < minDate)
|
||||
minDate = file.CreationTime;
|
||||
}
|
||||
return minDate;
|
||||
}
|
||||
|
||||
private string GetMothlyStatsFileName(string year, string month, string[] keyValues)
|
||||
{
|
||||
// build statistics name
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int i = 0;
|
||||
try
|
||||
{
|
||||
// loop for key values
|
||||
for (i = 0; i < keyFieldsLength; i++)
|
||||
{
|
||||
if (keyValues[i] != null && keyValues[i] != "")
|
||||
sb.Append(re_clean.Replace(keyValues[i], "_")).Append("_");
|
||||
}
|
||||
// normalize year
|
||||
if (year.Length == 2)
|
||||
sb.Append("20");
|
||||
sb.Append(year);
|
||||
// normalize month
|
||||
if (month.Length == 1)
|
||||
sb.Append("0");
|
||||
sb.Append(month);
|
||||
// append log file extension
|
||||
sb.Append(".log");
|
||||
//
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.WriteError(String.Format("Monthly Statistics FileName: year - {0}, month - {1}, keyValue - {2}", year, month, keyValues[i]), ex);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private string GetStatsFilePath()
|
||||
{
|
||||
string homePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LogParser");
|
||||
homePath = Path.Combine(homePath, serviceName);
|
||||
//
|
||||
return homePath.EndsWith(@"\") ? homePath : homePath + @"\";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,367 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using WebsitePanel.Server.Utils;
|
||||
|
||||
namespace WebsitePanel.Providers.Utils.LogParser
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Summary description for LogReader.
|
||||
/// </summary>
|
||||
public class LogReader
|
||||
{
|
||||
public static long TotalBytesProcessed = 0;
|
||||
|
||||
public class FilesByCreationDateComparer : IComparer
|
||||
{
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
return DateTime.Compare(((FileInfo)x).CreationTime, ((FileInfo)y).CreationTime);
|
||||
}
|
||||
}
|
||||
|
||||
private const string FIELDS_LINE = "#Fields: ";
|
||||
private const int FIELDS_LINE_LENGTH = 9;
|
||||
protected const char FIELDS_SEPARATOR = ' ';
|
||||
protected static readonly char[] FIELDS_SPLITTER = new char[] { FIELDS_SEPARATOR };
|
||||
|
||||
protected int fieldsLength;
|
||||
|
||||
// initial log position
|
||||
private int fileIndex = -1;
|
||||
private long lineIndex = 0;
|
||||
private long lastLineIndex = 0;
|
||||
protected string line = null; // current log line
|
||||
protected bool errorLine = false;
|
||||
protected bool systemLine = false;
|
||||
private string logName = null;
|
||||
private long logDate = 0;
|
||||
private StreamReader reader;
|
||||
|
||||
// log files in the log directory
|
||||
protected ArrayList logFiles = new ArrayList();
|
||||
|
||||
// fields available in the current log file
|
||||
private string[] fields = new string[0];
|
||||
protected string[] fieldsValues = null;
|
||||
|
||||
// field values of the current log line
|
||||
protected Hashtable record = new Hashtable();
|
||||
|
||||
public LogReader()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
public void Open(string logsPath)
|
||||
{
|
||||
// use this
|
||||
this.Open(logsPath, 0, 0);
|
||||
}
|
||||
|
||||
public void Open(string logsPath, long lastAccessed, long line)
|
||||
{
|
||||
// save specified line
|
||||
lineIndex = line;
|
||||
|
||||
// get logs directory
|
||||
DirectoryInfo logsDir = new DirectoryInfo(FileUtils.EvaluateSystemVariables(logsPath));
|
||||
|
||||
// get the list of files
|
||||
if (logsDir.Exists)
|
||||
GetDirectoryFiles(logsDir, logFiles);
|
||||
|
||||
// sort files by date
|
||||
logFiles.Sort(new FilesByCreationDateComparer());
|
||||
|
||||
// try to find specified file
|
||||
if (lastAccessed != 0)
|
||||
{
|
||||
for (int i = 0; i < logFiles.Count; i++)
|
||||
{
|
||||
if (((FileInfo)logFiles[i]).CreationTime.Ticks == lastAccessed)
|
||||
{
|
||||
fileIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check whether specified file was found
|
||||
if (fileIndex == -1)
|
||||
{
|
||||
// no
|
||||
fileIndex = 0;
|
||||
lineIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether requested fields are available against currently reading block with log data
|
||||
/// </summary>
|
||||
/// <param name="keyFields">Fields names to be accessed</param>
|
||||
/// <returns>Returns true if all of requested fields are available. Otherwise returns false.</returns>
|
||||
public bool CheckFieldsAvailable(string[] keyFields)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (fields == null || fields.Length == 0)
|
||||
return false;
|
||||
//
|
||||
foreach (string keyField in keyFields)
|
||||
{
|
||||
//
|
||||
if (Array.IndexOf(fields, keyField) == -1)
|
||||
return false;
|
||||
}
|
||||
//
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.WriteError(ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Read()
|
||||
{
|
||||
// first of all try to open the "next" log file
|
||||
while (reader == null && fileIndex < logFiles.Count)
|
||||
{
|
||||
// open reader
|
||||
FileInfo file = (FileInfo)logFiles[fileIndex];
|
||||
logName = file.FullName;
|
||||
logDate = file.CreationTime.Ticks;
|
||||
|
||||
try
|
||||
{
|
||||
Stream logStream = new FileStream(logName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
reader = new StreamReader(logStream);
|
||||
|
||||
// update statistics counter
|
||||
TotalBytesProcessed += file.Length;
|
||||
|
||||
// position file to the specified line
|
||||
if (lineIndex > 0)
|
||||
{
|
||||
// skip lines up to required
|
||||
int seekLine = 0;
|
||||
while (((line = reader.ReadLine()) != null) && ++seekLine < lineIndex)
|
||||
{
|
||||
// try to get field names
|
||||
ParseFieldNames();
|
||||
}
|
||||
|
||||
lastLineIndex = lineIndex;
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
// can't open log file
|
||||
// skip it
|
||||
Log.WriteError(String.Format("An error occured while reading log file: {0}", logName), ex);
|
||||
}
|
||||
|
||||
fileIndex++; // increment files pointer
|
||||
}
|
||||
|
||||
// return if it was the last log file in the list
|
||||
if (reader == null)
|
||||
return false;
|
||||
|
||||
// assumed that log file is already opened
|
||||
// read next line
|
||||
line = reader.ReadLine();
|
||||
if (line == null)
|
||||
{
|
||||
// the most propbably current log file is finished
|
||||
// reset current reader
|
||||
reader.Close();
|
||||
reader = null;
|
||||
lineIndex = 0;
|
||||
|
||||
// try to open next reader and read the first line
|
||||
return Read();
|
||||
}
|
||||
|
||||
// increment line index
|
||||
lineIndex++;
|
||||
lastLineIndex = lineIndex;
|
||||
|
||||
// parse line
|
||||
if (!String.IsNullOrEmpty(line))
|
||||
{
|
||||
if (line[0] == '#')
|
||||
{
|
||||
ParseFieldNames();
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseFieldValues();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorLine = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void ParseFieldNames()
|
||||
{
|
||||
systemLine = true;
|
||||
|
||||
if (!line.StartsWith(FIELDS_LINE))
|
||||
return;
|
||||
|
||||
fields = line.Substring(FIELDS_LINE_LENGTH).Trim().Split(FIELDS_SPLITTER);
|
||||
fieldsLength = fields.Length;
|
||||
}
|
||||
|
||||
protected virtual void ParseFieldValues()
|
||||
{
|
||||
// clear state
|
||||
errorLine = systemLine = false;
|
||||
|
||||
// clear values hash
|
||||
// record.Clear();
|
||||
|
||||
/*if (line[0] == '#')
|
||||
{
|
||||
// it is a system line
|
||||
// skip it and go ahead
|
||||
systemLine = true;
|
||||
return;
|
||||
}*/
|
||||
//
|
||||
fieldsValues = line.Split(FIELDS_SPLITTER, StringSplitOptions.None);
|
||||
// error line
|
||||
if (fieldsValues.Length != fieldsLength)
|
||||
errorLine = true;
|
||||
}
|
||||
|
||||
private void GetDirectoryFiles(DirectoryInfo root, ArrayList files)
|
||||
{
|
||||
// get the files in the current directory
|
||||
files.AddRange(root.GetFiles());
|
||||
|
||||
// scan subdirectories
|
||||
DirectoryInfo[] dirs = root.GetDirectories();
|
||||
foreach (DirectoryInfo dir in dirs)
|
||||
GetDirectoryFiles(dir, files);
|
||||
}
|
||||
|
||||
// provide read-only access to the current log line fields
|
||||
public string this[string field]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!errorLine && !systemLine)
|
||||
{
|
||||
// get field index in fields array
|
||||
int indexOf = Array.IndexOf(fields, field);
|
||||
// ensure field exists
|
||||
if (indexOf > -1)
|
||||
return fieldsValues[indexOf]; ;
|
||||
}
|
||||
// field not found or line is either system or error
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ErrorLine
|
||||
{
|
||||
get
|
||||
{
|
||||
return errorLine;
|
||||
}
|
||||
set
|
||||
{
|
||||
errorLine = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SystemLine
|
||||
{
|
||||
get
|
||||
{
|
||||
return systemLine;
|
||||
}
|
||||
set
|
||||
{
|
||||
systemLine = value;
|
||||
}
|
||||
}
|
||||
|
||||
public long LogDate
|
||||
{
|
||||
get
|
||||
{
|
||||
return logDate;
|
||||
}
|
||||
}
|
||||
|
||||
public string LogName
|
||||
{
|
||||
get
|
||||
{
|
||||
return logName;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] LineFields
|
||||
{
|
||||
get { return fields; }
|
||||
}
|
||||
|
||||
public string[] LineValues
|
||||
{
|
||||
get { return fieldsValues; }
|
||||
}
|
||||
|
||||
public string CurrentLine
|
||||
{
|
||||
get { return line; }
|
||||
}
|
||||
|
||||
public long LogLine
|
||||
{
|
||||
get
|
||||
{
|
||||
return lastLineIndex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using WebsitePanel.Server.Utils;
|
||||
|
||||
namespace WebsitePanel.Providers.Utils.LogParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for WebSiteState.
|
||||
/// </summary>
|
||||
public class LogState
|
||||
{
|
||||
private long lastAccessed = 0;
|
||||
private long line = 0;
|
||||
private string siteFileName = null;
|
||||
|
||||
public LogState(string logName)
|
||||
{
|
||||
// make file name
|
||||
siteFileName = logName;
|
||||
|
||||
// open and parse site state file
|
||||
if(!File.Exists(siteFileName))
|
||||
return;
|
||||
|
||||
StreamReader reader = null;
|
||||
try
|
||||
{
|
||||
reader = new StreamReader(siteFileName);
|
||||
string s = null;
|
||||
|
||||
// last accesses time
|
||||
if((s = reader.ReadLine()) != null)
|
||||
lastAccessed = Int64.Parse(s.Trim());
|
||||
|
||||
// line
|
||||
if((s = reader.ReadLine()) != null)
|
||||
line = Int64.Parse(s.Trim());
|
||||
|
||||
reader.Close();
|
||||
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.WriteError(ex);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
// create directory if required
|
||||
string dir = Path.GetDirectoryName(siteFileName);
|
||||
if(!Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
StreamWriter writer = new StreamWriter(siteFileName);
|
||||
// last accesses time
|
||||
writer.WriteLine(lastAccessed.ToString());
|
||||
|
||||
// line
|
||||
writer.WriteLine(line);
|
||||
|
||||
// close writer
|
||||
writer.Close();
|
||||
}
|
||||
|
||||
public long LastAccessed
|
||||
{
|
||||
get { return lastAccessed; }
|
||||
set { lastAccessed = value; }
|
||||
}
|
||||
|
||||
public long Line
|
||||
{
|
||||
get { return line; }
|
||||
set { line = value; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
|
||||
namespace WebsitePanel.Providers.Utils.LogParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for WebSiteStatistics.
|
||||
/// </summary>
|
||||
public class MonthlyStatistics
|
||||
{
|
||||
private string statsFile = null;
|
||||
private Hashtable days = new Hashtable();
|
||||
|
||||
|
||||
public MonthlyStatistics(string statsFile)
|
||||
{
|
||||
// save file name
|
||||
this.statsFile = statsFile;
|
||||
}
|
||||
|
||||
public MonthlyStatistics(string statsFile, bool load)
|
||||
{
|
||||
// save file name
|
||||
this.statsFile = statsFile;
|
||||
//
|
||||
if (load)
|
||||
{
|
||||
if (File.Exists(statsFile))
|
||||
{
|
||||
Load();
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// throw new ArgumentException(String.Format("File with specified name doesn't exist: {0}", statsFile), "statsFile");
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
public StatsLine this[int day]
|
||||
{
|
||||
get { return (StatsLine)days[day]; }
|
||||
set { days[day] = value; }
|
||||
}
|
||||
|
||||
public Hashtable Days
|
||||
{
|
||||
get { return days; }
|
||||
}
|
||||
|
||||
private void Load()
|
||||
{
|
||||
//
|
||||
StreamReader reader = new StreamReader(statsFile);
|
||||
string line = null;
|
||||
while ((line = reader.ReadLine()) != null)
|
||||
{
|
||||
// parse line
|
||||
string[] columns = line.Split(new char[] { ' ' });
|
||||
int day = Int32.Parse(columns[0]);
|
||||
|
||||
// add new stats line to the hash
|
||||
StatsLine statsLine = new StatsLine();
|
||||
statsLine.BytesSent = Int64.Parse(columns[1]);
|
||||
statsLine.BytesReceived = Int64.Parse(columns[2]);
|
||||
|
||||
days.Add(day, statsLine);
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
Save(Path.GetDirectoryName(statsFile));
|
||||
}
|
||||
|
||||
public void Save(string dir)
|
||||
{
|
||||
// create directory if required
|
||||
//string dir = Path.GetDirectoryName(statsFile);
|
||||
if (!Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
StreamWriter writer = null;
|
||||
|
||||
try
|
||||
{
|
||||
writer = new StreamWriter(Path.Combine(dir, statsFile));
|
||||
|
||||
foreach (int day in days.Keys)
|
||||
{
|
||||
StatsLine statsLine = (StatsLine)days[day];
|
||||
|
||||
// write line
|
||||
writer.WriteLine("{0} {1} {2}", day, statsLine.BytesSent, statsLine.BytesReceived);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(String.Format("Can't open '{0}' log file", statsFile), ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (writer != null)
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WebsitePanel.Providers.Utils.LogParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for StatsLine.
|
||||
/// </summary>
|
||||
public class StatsLine
|
||||
{
|
||||
public long BytesReceived = 0;
|
||||
public long BytesSent = 0;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue