Handle log rolling better by checking if filesize gets smaller or creation date is greater.
This commit is contained in:
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.3.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.3.5.0")]
|
||||
[assembly: AssemblyVersion("1.3.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.3.6.0")]
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using Interop.MSUtil;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
@@ -26,10 +26,17 @@ namespace TimberWinR.Inputs
|
||||
private int _pollingIntervalInSeconds;
|
||||
private TimberWinR.Parser.Log _arguments;
|
||||
private long _receivedMessages;
|
||||
|
||||
private Dictionary<string, Int64> _logFileMaxRecords;
|
||||
private Dictionary<string, DateTime> _logFileCreationTimes;
|
||||
private Dictionary<string, long> _logFileSizes;
|
||||
|
||||
public LogsListener(TimberWinR.Parser.Log arguments, CancellationToken cancelToken, int pollingIntervalInSeconds = 3)
|
||||
: base(cancelToken, "Win32-FileLog")
|
||||
{
|
||||
_logFileMaxRecords = new Dictionary<string, Int64>();
|
||||
_logFileCreationTimes = new Dictionary<string, DateTime>();
|
||||
_logFileSizes = new Dictionary<string, long>();
|
||||
|
||||
_receivedMessages = 0;
|
||||
_arguments = arguments;
|
||||
_pollingIntervalInSeconds = pollingIntervalInSeconds;
|
||||
@@ -38,7 +45,7 @@ namespace TimberWinR.Inputs
|
||||
{
|
||||
string file = srcFile.Trim();
|
||||
Task.Factory.StartNew(() => FileWatcher(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
@@ -54,24 +61,32 @@ namespace TimberWinR.Inputs
|
||||
new JProperty("messages", _receivedMessages),
|
||||
new JProperty("location", _arguments.Location),
|
||||
new JProperty("codepage", _arguments.CodePage),
|
||||
new JProperty("splitLongLines", _arguments.SplitLongLines),
|
||||
new JProperty("recurse", _arguments.Recurse)
|
||||
new JProperty("splitLongLines", _arguments.SplitLongLines),
|
||||
new JProperty("recurse", _arguments.Recurse),
|
||||
new JProperty("files",
|
||||
new JArray(from f in _logFileMaxRecords.Keys
|
||||
select new JValue(f))),
|
||||
new JProperty("fileIndices",
|
||||
new JArray(from f in _logFileMaxRecords.Values
|
||||
select new JValue(f))),
|
||||
new JProperty("fileCreationDates",
|
||||
new JArray(from f in _logFileCreationTimes.Values
|
||||
select new JValue(f)))
|
||||
)));
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
private void FileWatcher(string fileToWatch)
|
||||
{
|
||||
{
|
||||
var iFmt = new TextLineInputFormat()
|
||||
{
|
||||
iCodepage = _arguments.CodePage,
|
||||
splitLongLines = _arguments.SplitLongLines,
|
||||
splitLongLines = _arguments.SplitLongLines,
|
||||
recurse = _arguments.Recurse
|
||||
};
|
||||
|
||||
Dictionary<string, Int64> logFileMaxRecords = new Dictionary<string, Int64>();
|
||||
Dictionary<string, DateTime> logFileCreationTimes = new Dictionary<string, DateTime>();
|
||||
|
||||
|
||||
|
||||
// Execute the query
|
||||
while (!CancelToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -79,7 +94,7 @@ namespace TimberWinR.Inputs
|
||||
try
|
||||
{
|
||||
Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
|
||||
|
||||
|
||||
var qfiles = string.Format("SELECT Distinct [LogFilename] FROM {0}", fileToWatch);
|
||||
var rsfiles = oLogQuery.Execute(qfiles, iFmt);
|
||||
for (; !rsfiles.atEnd(); rsfiles.moveNext())
|
||||
@@ -87,39 +102,46 @@ namespace TimberWinR.Inputs
|
||||
var record = rsfiles.getRecord();
|
||||
string logName = record.getValue("LogFilename") as string;
|
||||
FileInfo fi = new FileInfo(logName);
|
||||
|
||||
|
||||
fi.Refresh();
|
||||
DateTime creationTime = fi.CreationTimeUtc;
|
||||
bool logHasRolled = logFileCreationTimes.ContainsKey(logName) && creationTime > logFileCreationTimes[logName];
|
||||
|
||||
if (!logFileMaxRecords.ContainsKey(logName) || logHasRolled)
|
||||
bool logHasRolled = (_logFileCreationTimes.ContainsKey(logName) &&
|
||||
creationTime > _logFileCreationTimes[logName]) ||
|
||||
(_logFileSizes.ContainsKey(logName) && fi.Length < _logFileSizes[logName]);
|
||||
|
||||
|
||||
if (!_logFileMaxRecords.ContainsKey(logName) || logHasRolled)
|
||||
{
|
||||
logFileCreationTimes[logName] = creationTime;
|
||||
_logFileCreationTimes[logName] = creationTime;
|
||||
_logFileSizes[logName] = fi.Length;
|
||||
var qcount = string.Format("SELECT max(Index) as MaxRecordNumber FROM {0}", logName);
|
||||
var rcount = oLogQuery.Execute(qcount, iFmt);
|
||||
var qr = rcount.getRecord();
|
||||
var lrn = (Int64)qr.getValueEx("MaxRecordNumber");
|
||||
if (logHasRolled)
|
||||
{
|
||||
LogManager.GetCurrentClassLogger().Info("Log {0} has rolled", logName);
|
||||
lrn = 0;
|
||||
logFileMaxRecords[logName] = lrn;
|
||||
}
|
||||
}
|
||||
_logFileMaxRecords[logName] = lrn;
|
||||
}
|
||||
}
|
||||
foreach (string fileName in logFileMaxRecords.Keys.ToList())
|
||||
foreach (string fileName in _logFileMaxRecords.Keys.ToList())
|
||||
{
|
||||
var lastRecordNumber = logFileMaxRecords[fileName];
|
||||
var lastRecordNumber = _logFileMaxRecords[fileName];
|
||||
var query = string.Format("SELECT * FROM {0} where Index > {1}", fileName, lastRecordNumber);
|
||||
|
||||
|
||||
var rs = oLogQuery.Execute(query, iFmt);
|
||||
Dictionary<string, int> colMap = new Dictionary<string, int>();
|
||||
for (int col = 0; col < rs.getColumnCount(); col++)
|
||||
{
|
||||
string colName = rs.getColumnName(col);
|
||||
string colName = rs.getColumnName(col);
|
||||
colMap[colName] = col;
|
||||
}
|
||||
|
||||
// Browse the recordset
|
||||
for (; !rs.atEnd(); rs.moveNext())
|
||||
{
|
||||
{
|
||||
var record = rs.getRecord();
|
||||
var json = new JObject();
|
||||
foreach (var field in _arguments.Fields)
|
||||
@@ -128,7 +150,7 @@ namespace TimberWinR.Inputs
|
||||
continue;
|
||||
|
||||
object v = record.getValue(field.Name);
|
||||
if (field.DataType == typeof (DateTime))
|
||||
if (field.DataType == typeof(DateTime))
|
||||
{
|
||||
DateTime dt = DateTime.Parse(v.ToString());
|
||||
json.Add(new JProperty(field.Name, dt));
|
||||
@@ -144,9 +166,9 @@ namespace TimberWinR.Inputs
|
||||
}
|
||||
|
||||
var lrn = (Int64)record.getValueEx("Index");
|
||||
logFileMaxRecords[fileName] = lrn;
|
||||
_logFileMaxRecords[fileName] = lrn;
|
||||
}
|
||||
|
||||
|
||||
// Close the recordset
|
||||
rs.close();
|
||||
rs = null;
|
||||
@@ -160,12 +182,12 @@ namespace TimberWinR.Inputs
|
||||
{
|
||||
oLogQuery = null;
|
||||
}
|
||||
|
||||
Thread.CurrentThread.Priority = ThreadPriority.Normal;
|
||||
|
||||
Thread.CurrentThread.Priority = ThreadPriority.Normal;
|
||||
System.Threading.Thread.Sleep(_pollingIntervalInSeconds * 1000);
|
||||
}
|
||||
|
||||
Finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user