Added WindowsEvent log listener

This commit is contained in:
Eric Fontana
2014-07-17 10:37:16 -04:00
parent aa25a71f65
commit f1d186c280
27 changed files with 58348 additions and 19 deletions

View File

@@ -70,9 +70,12 @@ namespace TimberWinR.ServiceHost
_cancellationToken = _cancellationTokenSource.Token;
_serviceTask = new Task(RunService, _cancellationToken);
var elistner = new WindowsEvtInputListener(_cancellationToken);
_nlogListener = new TcpInputListener(_cancellationToken, 5140);
var outputRedis = new RedisOutput(new string[] { "tstlexiceapp006.vistaprint.svc", "tstlexiceapp007.vistaprint.svc" }, _cancellationToken);
outputRedis.Connect(_nlogListener);
outputRedis.Connect(_nlogListener);
outputRedis.Connect(elistner);
}
public void Start()
@@ -93,11 +96,10 @@ namespace TimberWinR.ServiceHost
{
TimberWinR.Manager manager = new TimberWinR.Manager();
while (!_cancellationTokenSource.IsCancellationRequested)
{
Console.WriteLine("I am working");
System.Threading.Thread.Sleep(1000);
}
//while (!_cancellationTokenSource.IsCancellationRequested)
//{
// System.Threading.Thread.Sleep(1000);
//}
}
}
}

View File

@@ -54,6 +54,9 @@
<Name>TimberWinR</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TimberWinR.Inputs
{
/// <summary>
/// Field Definition
/// </summary>
public class FieldDefinition
{
public string Name { get; set; }
public Type FieldType { get; set; }
public DateTime ToDateTime(object o)
{
return (DateTime) o;
}
public int ToInt(object o)
{
return (int) o;
}
public string ToString(object o)
{
return (string) o;
}
public float ToFloat(object o)
{
return (float)o;
}
public FieldDefinition(string fieldName, Type fieldType)
{
Name = fieldName;
FieldType = fieldType;
}
}
public class FieldDefinitions : IEnumerable<FieldDefinition>
{
private List<FieldDefinition> _fields;
public FieldDefinition this[int index]
{
get { return _fields[index]; }
set { _fields.Insert(index, value); }
}
public void Add(string fieldName, Type fieldType)
{
_fields.Add(new FieldDefinition(fieldName, fieldType));
}
public FieldDefinitions()
{
_fields = new List<FieldDefinition>();
}
public IEnumerator<FieldDefinition> GetEnumerator()
{
return _fields.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}

View File

@@ -11,12 +11,17 @@ namespace TimberWinR.Inputs
public CancellationToken CancelToken { get; set; }
public event Action<string> OnMessageRecieved;
public InputListener(CancellationToken token)
public FieldDefinitions Fields { get; set; }
public ParameterDefinitions Parameters { get; set; }
public InputListener(CancellationToken token, FieldDefinitions fields, ParameterDefinitions parms)
{
this.CancelToken = token;
Parameters = parms;
Fields = fields;
}
protected void ProcessMessage(string message)
protected void ProcessJson(string message)
{
if (OnMessageRecieved != null)
OnMessageRecieved(message);

View File

@@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace TimberWinR.Inputs
{
public class ParameterValue
{
public ParameterDefinition Parameter { get; private set; }
protected string CurrentValue { get; set; }
protected ParameterValue(ParameterDefinition paramDef)
{
Parameter = paramDef;
CurrentValue = Parameter.DefaultValue;
}
public override string ToString()
{
return string.Format("-{0}:{1}", Parameter.Name, CurrentValue);
}
}
public class BooleanParameterValue : ParameterValue
{
public BooleanParameterValue(ParameterDefinition paramDef)
: base(paramDef)
{
}
public bool Value
{
get
{
return CurrentValue.Equals(Parameter.LegalValues[Parameter.LegalValues.Count - 1],
StringComparison.OrdinalIgnoreCase);
}
set
{
string v = Parameter.LegalValues[0];
if (value)
v = Parameter.LegalValues[1];
CurrentValue = v;
}
}
}
public class EnumParameterValue : ParameterValue
{
public EnumParameterValue(ParameterDefinition paramDef)
: base(paramDef)
{
}
public string Value
{
get { return CurrentValue; }
set
{
if (Parameter.LegalValues.Contains(value))
CurrentValue = value;
else
throw new ArgumentException(string.Format("Illegal value: '{0}'", value), Parameter.Name);
}
}
}
public class TimestampParameterValue : ParameterValue
{
public TimestampParameterValue(ParameterDefinition paramDef)
: base(paramDef)
{
}
public DateTime Value
{
get { return DateTime.Parse(CurrentValue); }
set { CurrentValue = value.ToString(); }
}
}
public class ParameterDefinition
{
public string Name { get; set; }
public string DefaultValue { get; set; }
public List<string> LegalValues { get; set; }
public Type ParameterType { get; set; }
public ParameterDefinition(string name, string defaultValue, Type parameterType)
{
Name = name;
DefaultValue = defaultValue;
LegalValues = null;
ParameterType = parameterType;
}
public ParameterDefinition(string name, string defaultValue, Type parameterType, IEnumerable<string> legalValues)
{
Name = name;
DefaultValue = defaultValue;
LegalValues = legalValues.ToList();
ParameterType = parameterType;
}
}
public class ParameterDefinitions : IEnumerable<ParameterDefinition>
{
private readonly List<ParameterDefinition> _params;
public ParameterDefinition this[int index]
{
get { return _params[index]; }
set { _params.Insert(index, value); }
}
public void Add(string paramName, string defaultValue, Type parameterType)
{
_params.Add(new ParameterDefinition(paramName, defaultValue, parameterType));
}
public void Add(string paramName, string defaultValue, Type parameterType, IEnumerable<string> legalValues)
{
_params.Add(new ParameterDefinition(paramName, defaultValue, parameterType, legalValues));
}
public ParameterDefinitions()
{
_params = new List<ParameterDefinition>();
}
public IEnumerator<ParameterDefinition> GetEnumerator()
{
return _params.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}

View File

@@ -15,12 +15,12 @@ namespace TimberWinR.Inputs
private Thread _listenThread;
const int bufferSize = 16535;
public TcpInputListener(CancellationToken cancelToken, int port = 5140) : base(cancelToken)
public TcpInputListener(CancellationToken cancelToken, int port = 5140) : base(cancelToken, null, null)
{
_tcpListener = new System.Net.Sockets.TcpListener(IPAddress.Any, port);
_listenThread = new Thread(new ThreadStart(ListenForClients));
_listenThread.Start();
}
}
public void Shutdown()
{
@@ -82,7 +82,7 @@ namespace TimberWinR.Inputs
var encoder = new ASCIIEncoding();
var encodedMessage = encoder.GetString(message, 0, bytesRead);
ProcessMessage(encodedMessage);
ProcessJson(encodedMessage);
}
tcpClient.Close();
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using Interop.MSUtil;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using NLog;
using LogQuery = Interop.MSUtil.LogQueryClassClass;
using EventLogInputFormat = Interop.MSUtil.COMEventLogInputContextClassClass;
using LogRecordSet = Interop.MSUtil.ILogRecordset;
namespace TimberWinR.Inputs
{
/// <summary>
/// Listen to Windows Event Log
/// </summary>
public class WindowsEvtInputListener : InputListener
{
private int _pollingIntervalInSeconds = 1;
public WindowsEvtInputListener(CancellationToken cancelToken, int pollingIntervalInSeconds = 1)
: base(cancelToken, FieldDefinitions, ParameterDefinitions)
{
_pollingIntervalInSeconds = pollingIntervalInSeconds;
var task = new Task(EventWatcher, cancelToken);
task.Start();
}
private void EventWatcher()
{
var oLogQuery = new LogQuery();
var fileName = Path.Combine(System.IO.Path.GetTempPath(),
string.Format("{0}.lpc", Guid.NewGuid().ToString()));
// Instantiate the Event Log Input Format object
var iFmt = new EventLogInputFormat()
{
direction = "FW",
binaryFormat = "PRINT",
iCheckpoint = fileName,
resolveSIDs = true
};
// Create the query
var query = @"SELECT * FROM Application, System";
var firstQuery = true;
// Execute the query
while (!CancelToken.IsCancellationRequested)
{
try
{
var rs = oLogQuery.Execute(query, iFmt);
// Browse the recordset
for (; !rs.atEnd(); rs.moveNext())
{
// We want to "tail" the log, so skip the first query results.
if (!firstQuery)
{
var record = rs.getRecord();
var json = new JObject();
foreach (var field in Fields)
{
object v = record.getValue(field.Name);
if (field.FieldType == typeof(DateTime))
v = field.ToDateTime(v).ToUniversalTime();
json.Add(new JProperty(field.Name, v));
}
json.Add(new JProperty("type", "Win32-Eventlog"));
ProcessJson(json.ToString());
}
}
// Close the recordset
rs.close();
}
catch (Exception ex)
{
LogManager.GetCurrentClassLogger().Error(ex);
}
firstQuery = false;
System.Threading.Thread.Sleep(_pollingIntervalInSeconds * 1000);
}
}
public static ParameterDefinitions ParameterDefinitions
{
get
{
return new ParameterDefinitions()
{
{"fullText", "ON", typeof(bool), new string[] {"OFF", "ON"}},
{"resolveSIDs", "OFF", typeof(bool), new string[] {"OFF", "ON"}},
{"formatMsg", "ON", typeof(bool), new string[] {"OFF", "ON"}},
{"msgErrorMode", "MSG", typeof(string), new string[] {"NULL", "ERROR", "MSG"}},
{"fullEventCode", "OFF", typeof(bool), new string[] {"OFF", "ON"}},
{"direction", "FW", typeof(string), new string[] {"FW", "BW"}},
{"stringsSep", "|", typeof(string)},
{"binaryFormat", "HEX", typeof(string), new string[] {"ASC", "PRINT", "HEX"}},
};
}
}
public static FieldDefinitions FieldDefinitions
{
get
{
return new FieldDefinitions()
{
{"EventLog", typeof (string)},
{"RecordNumber", typeof (string)},
{"TimeGenerated", typeof (DateTime)},
{"TimeWritten", typeof (DateTime)},
{"EventID", typeof (int)},
{"EventType", typeof (int)},
{"EventTypeName", typeof (string)},
{"EventCategory", typeof (int)},
{"EventCategoryName", typeof (string)},
{"SourceName", typeof (string)},
{"Strings", typeof (string)},
{"ComputerName", typeof (string)},
{"SID", typeof (string)},
{"Message", typeof (string)},
{"Data", typeof (string)}
};
}
}
}
}

View File

@@ -19,7 +19,7 @@ namespace TimberWinR
public Manager(string configurationFile=null)
{
// Read the Configuration file
Config = new Configuration();
// Config = new Configuration();
var loggingConfiguration = new LoggingConfiguration();

View File

@@ -13,14 +13,13 @@ namespace TimberWinR.Outputs
{
public class RedisOutput : OutputSender
{
private readonly string _logstashIndexName;
private readonly string _hostname;
private readonly string _logstashIndexName;
private readonly int _port;
private readonly int _timeout;
private object _locker = new object();
private List<string> _jsonQueue;
private readonly object _locker = new object();
private readonly List<string> _jsonQueue;
readonly Task _consumerTask;
private string[] _redisHosts;
private readonly string[] _redisHosts;
private int _redisHostIndex;
/// <summary>
@@ -61,8 +60,8 @@ namespace TimberWinR.Outputs
_jsonQueue = new List<string>();
_port = port;
_timeout = timeout;
_logstashIndexName = logstashIndexName;
_consumerTask = new Task(RedisSender, CancellationToken.None);
_logstashIndexName = logstashIndexName;
_consumerTask = new Task(RedisSender, cancelToken);
_consumerTask.Start();
}

View File

@@ -39,6 +39,10 @@
<EmbedInteropTypes>False</EmbedInteropTypes>
<HintPath>lib\com-logparser\Interop.MSUtil.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.6.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog">
<HintPath>..\packages\NLog.3.1.0.0\lib\net40\NLog.dll</HintPath>
</Reference>
@@ -56,9 +60,12 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Configuration.cs" />
<Compile Include="Inputs\FieldDefinitions.cs" />
<Compile Include="Inputs\InputListener.cs" />
<Compile Include="Inputs\ParameterDefinitions.cs" />
<Compile Include="Inputs\TcpInputListener.cs" />
<Compile Include="Inputs\TextLine.cs" />
<Compile Include="Inputs\WindowsEvtInputListener.cs" />
<Compile Include="Manager.cs" />
<Compile Include="Outputs\OutputSender.cs" />
<Compile Include="Outputs\Redis.cs" />

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="csredis" version="1.4.7.1" targetFramework="net40" />
<package id="Newtonsoft.Json" version="6.0.3" targetFramework="net40" />
<package id="NLog" version="3.1.0.0" targetFramework="net40" />
</packages>

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,93 @@
param($installPath, $toolsPath, $package, $project)
# open json.net splash page on package install
# don't open if json.net is installed as a dependency
try
{
$url = "http://james.newtonking.com/json"
$dte2 = Get-Interface $dte ([EnvDTE80.DTE2])
if ($dte2.ActiveWindow.Caption -eq "Package Manager Console")
{
# user is installing from VS NuGet console
# get reference to the window, the console host and the input history
# show webpage if "install-package newtonsoft.json" was last input
$consoleWindow = $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow])
$props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor `
[System.Reflection.BindingFlags]::NonPublic)
$prop = $props | ? { $_.Name -eq "ActiveHostInfo" } | select -first 1
if ($prop -eq $null) { return }
$hostInfo = $prop.GetValue($consoleWindow)
if ($hostInfo -eq $null) { return }
$history = $hostInfo.WpfConsole.InputHistory.History
$lastCommand = $history | select -last 1
if ($lastCommand)
{
$lastCommand = $lastCommand.Trim().ToLower()
if ($lastCommand.StartsWith("install-package") -and $lastCommand.Contains("newtonsoft.json"))
{
$dte2.ItemOperations.Navigate($url) | Out-Null
}
}
}
else
{
# user is installing from VS NuGet dialog
# get reference to the window, then smart output console provider
# show webpage if messages in buffered console contains "installing...newtonsoft.json" in last operation
$instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor `
[System.Reflection.BindingFlags]::NonPublic)
$consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor `
[System.Reflection.BindingFlags]::NonPublic)
if ($instanceField -eq $null -or $consoleField -eq $null) { return }
$instance = $instanceField.GetValue($null)
if ($instance -eq $null) { return }
$consoleProvider = $consoleField.GetValue($instance)
if ($consoleProvider -eq $null) { return }
$console = $consoleProvider.CreateOutputConsole($false)
$messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor `
[System.Reflection.BindingFlags]::NonPublic)
if ($messagesField -eq $null) { return }
$messages = $messagesField.GetValue($console)
if ($messages -eq $null) { return }
$operations = $messages -split "=============================="
$lastOperation = $operations | select -last 1
if ($lastOperation)
{
$lastOperation = $lastOperation.ToLower()
$lines = $lastOperation -split "`r`n"
$installMatch = $lines | ? { $_.StartsWith("------- installing...newtonsoft.json ") } | select -first 1
if ($installMatch)
{
$dte2.ItemOperations.Navigate($url) | Out-Null
}
}
}
}
catch
{
# stop potential errors from bubbling up
# worst case the splash page won't open
}
# yolo