Split database into separate file
This commit is contained in:
174
TimberWinR/Inputs/LogsFileDatabase.cs
Normal file
174
TimberWinR/Inputs/LogsFileDatabase.cs
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
using LogQuery = Interop.MSUtil.LogQueryClassClass;
|
||||||
|
using TextLineInputFormat = Interop.MSUtil.COMTextLineInputContextClass;
|
||||||
|
using LogRecordSet = Interop.MSUtil.ILogRecordset;
|
||||||
|
|
||||||
|
namespace TimberWinR.Inputs
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Maintain persistent state for Log files (to be used across restarts)
|
||||||
|
//
|
||||||
|
public class LogsFileDatabase
|
||||||
|
{
|
||||||
|
private static readonly object _locker = new object();
|
||||||
|
private List<LogsFileDatabaseEntry> Entries { get; set; }
|
||||||
|
private string DatabaseDirectory { get; set; }
|
||||||
|
public string DatabaseFileName
|
||||||
|
{
|
||||||
|
get { return Path.Combine(DatabaseDirectory, ".timberwinrdb"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Manager Manager { get; set; }
|
||||||
|
|
||||||
|
private static LogsFileDatabase instance;
|
||||||
|
|
||||||
|
private bool ExistingFile(string logName)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
return ExistingFileTest(logName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ExistingFileTest(string logName)
|
||||||
|
{
|
||||||
|
var existingEntry = (from e in Entries where e.FileName == logName select e).FirstOrDefault();
|
||||||
|
return existingEntry != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveFileEntry(string logName)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
var existingEntry = (from e in Entries where e.FileName == logName select e).FirstOrDefault();
|
||||||
|
if (existingEntry != null)
|
||||||
|
{
|
||||||
|
Entries.Remove(existingEntry);
|
||||||
|
WriteDatabaseFileNoLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LogsFileDatabaseEntry AddFileEntry(string logName, TextLineInputFormat fmt)
|
||||||
|
{
|
||||||
|
var de = new LogsFileDatabaseEntry();
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
var lq = new LogQuery();
|
||||||
|
var fi = new FileInfo(logName);
|
||||||
|
de.FileName = logName;
|
||||||
|
de.Size = fi.Length;
|
||||||
|
de.SampleTime = DateTime.UtcNow;
|
||||||
|
de.CreationTime = fi.CreationTimeUtc;
|
||||||
|
if (fi.Exists)
|
||||||
|
{
|
||||||
|
var qcount = string.Format("SELECT max(Index) as MaxRecordNumber FROM {0}", logName);
|
||||||
|
var rcount = lq.Execute(qcount, fmt);
|
||||||
|
var qr = rcount.getRecord();
|
||||||
|
var lrn = (Int64)qr.getValueEx("MaxRecordNumber");
|
||||||
|
de.MaxRecords = lrn;
|
||||||
|
}
|
||||||
|
Entries.Add(de);
|
||||||
|
WriteDatabaseFileNoLock();
|
||||||
|
}
|
||||||
|
return de;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogsFileDatabaseEntry AddLogFile(string logName, TextLineInputFormat fmt)
|
||||||
|
{
|
||||||
|
Instance.RemoveFileEntry(logName); // Remove if already exists, otherwise ignores.
|
||||||
|
return Instance.AddFileEntry(logName, fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogsFileDatabase Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
{
|
||||||
|
instance = new LogsFileDatabase(Manager.LogfileDir);
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(instance.DatabaseDirectory))
|
||||||
|
Directory.CreateDirectory(instance.DatabaseDirectory);
|
||||||
|
// If it exists, read the current state, otherwise create an empty database.
|
||||||
|
if (File.Exists(instance.DatabaseFileName))
|
||||||
|
instance.ReadDatabaseNoLock();
|
||||||
|
else
|
||||||
|
instance.WriteDatabaseFileNoLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReadDatabaseNoLock()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var serializer = new JsonSerializer();
|
||||||
|
if (File.Exists(DatabaseFileName))
|
||||||
|
Entries =
|
||||||
|
JsonConvert.DeserializeObject<List<LogsFileDatabaseEntry>>(File.ReadAllText(DatabaseFileName));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.GetCurrentClassLogger()
|
||||||
|
.Error("Error reading database '{0}': {1}", DatabaseFileName, ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void WriteDatabaseFileNoLock()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(DatabaseFileName, JsonConvert.SerializeObject(instance.Entries), Encoding.UTF8);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.GetCurrentClassLogger()
|
||||||
|
.Error("Error saving database '{0}': {1}", DatabaseFileName, ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ReadDatabaseLock()
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
ReadDatabaseNoLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private void WriteDatabaseLock()
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
WriteDatabaseFileNoLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LogsFileDatabase(string databaseDirectory)
|
||||||
|
{
|
||||||
|
DatabaseDirectory = databaseDirectory;
|
||||||
|
Entries = new List<LogsFileDatabaseEntry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LogsFileDatabaseEntry
|
||||||
|
{
|
||||||
|
public string FileName { get; set; }
|
||||||
|
public Int64 MaxRecords { get; set; }
|
||||||
|
public DateTime CreationTime { get; set; }
|
||||||
|
public DateTime SampleTime { get; set; }
|
||||||
|
public long Size { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ Version History
|
|||||||
|
|
||||||
### 1.3.19.0 - 01/12/2015
|
### 1.3.19.0 - 01/12/2015
|
||||||
|
|
||||||
1. Added support for Multiline codecs for Stdin and Logs listeners, addresses issue #23
|
1. Added support for Multiline codecs for Stdin and Logs listeners, closes issue [#23](https://github.com/Cimpress-MCP/TimberWinR/issues/23)
|
||||||
|
|
||||||
### 1.3.18.0 - 12/22/2014
|
### 1.3.18.0 - 12/22/2014
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user