Compare commits
43 Commits
test_fixtu
...
add_input_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90991a44d6 | ||
|
|
dcbb079101 | ||
|
|
091fe9e7e4 | ||
|
|
6db530b526 | ||
|
|
4ebe539ea8 | ||
|
|
75619a239a | ||
|
|
fd67c271b5 | ||
|
|
1f3aaf90fd | ||
|
|
dcfdf73842 | ||
|
|
dcd104e4f4 | ||
|
|
2377d4ebd2 | ||
|
|
64979df012 | ||
|
|
5eb75ab143 | ||
|
|
3e9ef6ae88 | ||
|
|
7df4dede90 | ||
|
|
d9509757e3 | ||
|
|
edcac22ea0 | ||
|
|
e98ef89fe2 | ||
|
|
6461369d39 | ||
|
|
f5b2858c1c | ||
|
|
3d0bfc248d | ||
|
|
dbaa52a12e | ||
|
|
7e69175f19 | ||
|
|
baa70eebbc | ||
|
|
29308446a9 | ||
|
|
a0cccc0b7f | ||
|
|
ec2ec66915 | ||
|
|
98ef675f9c | ||
|
|
1468a6d0e6 | ||
|
|
44104f1e59 | ||
|
|
22baef9838 | ||
|
|
1b51fcd989 | ||
|
|
0b3204efe8 | ||
|
|
80f8f9ee0c | ||
|
|
9d08fc2b28 | ||
|
|
349b0bf031 | ||
|
|
8b431f92eb | ||
|
|
770ac1b7b1 | ||
|
|
5d07acad5b | ||
|
|
e4bd5be8b1 | ||
|
|
786b6b4777 | ||
|
|
51dc9ee54c | ||
|
|
796ca51f31 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -155,3 +155,4 @@ $RECYCLE.BIN/
|
|||||||
# Mac desktop service store files
|
# Mac desktop service store files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
packages
|
packages
|
||||||
|
*.msi
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ https://groups.google.com/forum/#!forum/timberwinr
|
|||||||
|
|
||||||
Latest Build:
|
Latest Build:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Inputs
|
## Inputs
|
||||||
The current supported Input format sources are:
|
The current supported Input format sources are:
|
||||||
@@ -36,7 +37,8 @@ The current supported Input format sources are:
|
|||||||
5. [Stdin](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/StdinInput.md) (Standard Input for Debugging)
|
5. [Stdin](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/StdinInput.md) (Standard Input for Debugging)
|
||||||
6. [W3C](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/W3CInput.md)(Internet Information Services W3C Advanced/Custom Format)
|
6. [W3C](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/W3CInput.md)(Internet Information Services W3C Advanced/Custom Format)
|
||||||
7. [Udp](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/UdpInput.md) (listens for UDP on port for JSON messages)
|
7. [Udp](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/UdpInput.md) (listens for UDP on port for JSON messages)
|
||||||
8. [TailFiles](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/TailFiles.md) (Tails log files efficiently *New*)
|
8. [TailFiles](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/TailFiles.md) (Tails log files efficiently)
|
||||||
|
8. [Generator](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/Generator.md) (Generate logs for testing *New*)
|
||||||
|
|
||||||
## Codecs
|
## Codecs
|
||||||
The current list of supported codecs are:
|
The current list of supported codecs are:
|
||||||
@@ -167,7 +169,7 @@ following options:
|
|||||||
TimberWinR.ServiceHost.exe -configFile:myconfig.json -logLevel:Debug
|
TimberWinR.ServiceHost.exe -configFile:myconfig.json -logLevel:Debug
|
||||||
```
|
```
|
||||||
|
|
||||||
## Automatic Installation via Chocolatey
|
## Automatic Installation via Chocolatey (embedded)
|
||||||
|
|
||||||
[TimbeWinR Chocolatey](https://chocolatey.org/packages/TimberWinR)
|
[TimbeWinR Chocolatey](https://chocolatey.org/packages/TimberWinR)
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,6 @@ namespace TimberWinR.ServiceHost
|
|||||||
|
|
||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Arguments arguments = new Arguments();
|
Arguments arguments = new Arguments();
|
||||||
|
|
||||||
HostFactory.Run(hostConfigurator =>
|
HostFactory.Run(hostConfigurator =>
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.3.20.0")]
|
[assembly: AssemblyVersion("1.3.24.0")]
|
||||||
[assembly: AssemblyFileVersion("1.3.20.0")]
|
[assembly: AssemblyFileVersion("1.3.24.0")]
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ namespace TimberWinR.TestGenerator
|
|||||||
[Option("timberWinRConfig", DefaultValue = "default.json", HelpText = "Config file/directory to use")]
|
[Option("timberWinRConfig", DefaultValue = "default.json", HelpText = "Config file/directory to use")]
|
||||||
public string TimberWinRConfigFile { get; set; }
|
public string TimberWinRConfigFile { get; set; }
|
||||||
|
|
||||||
|
[Option("start", HelpText = "Start an instance of TimberWinR")]
|
||||||
|
public bool StartTimberWinR { get; set; }
|
||||||
|
|
||||||
[Option("testDir", DefaultValue = ".", HelpText = "Test directory to use (created if necessary)")]
|
[Option("testDir", DefaultValue = ".", HelpText = "Test directory to use (created if necessary)")]
|
||||||
public string TestDir { get; set; }
|
public string TestDir { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ namespace TimberWinR.TestGenerator
|
|||||||
// if it is not deleted.
|
// if it is not deleted.
|
||||||
using (StreamWriter sw = File.AppendText(logFilePath))
|
using (StreamWriter sw = File.AppendText(logFilePath))
|
||||||
{
|
{
|
||||||
sw.AutoFlush = true;
|
|
||||||
for (int i = 0; i < parms.NumMessages; i++)
|
for (int i = 0; i < parms.NumMessages; i++)
|
||||||
{
|
{
|
||||||
JObject o = new JObject
|
JObject o = new JObject
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ namespace TimberWinR.TestGenerator
|
|||||||
// if it is not deleted.
|
// if it is not deleted.
|
||||||
using (StreamWriter sw = File.AppendText(logFilePath))
|
using (StreamWriter sw = File.AppendText(logFilePath))
|
||||||
{
|
{
|
||||||
sw.AutoFlush = true;
|
|
||||||
for (int i = 0; i < parms.NumMessages; i++)
|
for (int i = 0; i < parms.NumMessages; i++)
|
||||||
{
|
{
|
||||||
JObject o = new JObject
|
JObject o = new JObject
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -86,7 +87,8 @@ namespace TimberWinR.TestGenerator
|
|||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
// Startup TimberWinR
|
// Startup TimberWinR
|
||||||
StartTimberWinR(Options.TimberWinRConfigFile, Options.LogLevel, ".", false);
|
if (Options.StartTimberWinR)
|
||||||
|
StartTimberWinR(Options.TimberWinRConfigFile, Options.LogLevel, ".", false);
|
||||||
|
|
||||||
// Run the Generators
|
// Run the Generators
|
||||||
var arrayOfTasks = RunGenerators(Options);
|
var arrayOfTasks = RunGenerators(Options);
|
||||||
@@ -114,7 +116,16 @@ namespace TimberWinR.TestGenerator
|
|||||||
sw.Start();
|
sw.Start();
|
||||||
|
|
||||||
// Get all the stats
|
// Get all the stats
|
||||||
var jsonTimberWinr = ShutdownTimberWinR();
|
JObject jsonTimberWinr;
|
||||||
|
|
||||||
|
if (Options.StartTimberWinR)
|
||||||
|
jsonTimberWinr = ShutdownTimberWinR();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jsonTimberWinr = GetDiagnosticsOutput();
|
||||||
|
if (jsonTimberWinr == null)
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
LogManager.GetCurrentClassLogger().Info("Finished Shutdown: " + sw.Elapsed);
|
LogManager.GetCurrentClassLogger().Info("Finished Shutdown: " + sw.Elapsed);
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
@@ -131,6 +142,30 @@ namespace TimberWinR.TestGenerator
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GET(string url)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
||||||
|
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
||||||
|
Stream stream = response.GetResponseStream();
|
||||||
|
StreamReader reader = new StreamReader(stream);
|
||||||
|
|
||||||
|
string data = reader.ReadToEnd();
|
||||||
|
|
||||||
|
reader.Close();
|
||||||
|
stream.Close();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LogManager.GetCurrentClassLogger().ErrorException("Error in GET", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static void CopySourceFile(string fileName, string outputDir)
|
private static void CopySourceFile(string fileName, string outputDir)
|
||||||
{
|
{
|
||||||
FileInfo fi = new FileInfo(fileName);
|
FileInfo fi = new FileInfo(fileName);
|
||||||
@@ -199,11 +234,18 @@ namespace TimberWinR.TestGenerator
|
|||||||
switch (inputProp.Name)
|
switch (inputProp.Name)
|
||||||
{
|
{
|
||||||
case "udp":
|
case "udp":
|
||||||
return VerifyConditions(json, new string[] { "udp" }, inputProp, jresult);
|
if (VerifyConditions(json, new string[] { "udp" }, inputProp, jresult) != 0)
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case "tcp":
|
||||||
|
if (VerifyConditions(json, new string[] { "tcp" }, inputProp, jresult) != 0)
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
case "log":
|
case "log":
|
||||||
case "taillog":
|
case "taillog":
|
||||||
return VerifyConditions(json, new string[] { "log", "taillog" }, inputProp, jresult);
|
if (VerifyConditions(json, new string[] { "log", "taillog" }, inputProp, jresult) != 0)
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,13 +304,32 @@ namespace TimberWinR.TestGenerator
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static JObject GetDiagnosticsOutput()
|
||||||
|
{
|
||||||
|
if (Diagnostics != null)
|
||||||
|
return Diagnostics.DiagnosticsOutput();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var jsonDiag = GET("http://localhost:5141");
|
||||||
|
if (jsonDiag == null)
|
||||||
|
{
|
||||||
|
LogManager.GetCurrentClassLogger().Error("TimberWinR diagnostics port not responding.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return JObject.Parse(jsonDiag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wait till all output has been transmitted.
|
// Wait till all output has been transmitted.
|
||||||
private static void WaitForOutputTransmission()
|
private static void WaitForOutputTransmission()
|
||||||
{
|
{
|
||||||
bool completed = false;
|
bool completed = false;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var json = Diagnostics.DiagnosticsOutput();
|
var json = GetDiagnosticsOutput();
|
||||||
|
if (json == null)
|
||||||
|
return;
|
||||||
|
|
||||||
//Console.WriteLine(json.ToString(Formatting.Indented));
|
//Console.WriteLine(json.ToString(Formatting.Indented));
|
||||||
|
|
||||||
@@ -330,21 +391,27 @@ namespace TimberWinR.TestGenerator
|
|||||||
|
|
||||||
private static JObject ShutdownTimberWinR()
|
private static JObject ShutdownTimberWinR()
|
||||||
{
|
{
|
||||||
_timberWinR.Shutdown();
|
if (_timberWinR != null)
|
||||||
|
{
|
||||||
|
// Cancel any/all other threads
|
||||||
|
_cancellationTokenSource.Cancel();
|
||||||
|
|
||||||
// Cancel any/all other threads
|
_timberWinR.Shutdown();
|
||||||
_cancellationTokenSource.Cancel();
|
|
||||||
|
|
||||||
var json = Diagnostics.DiagnosticsOutput();
|
var json = Diagnostics.DiagnosticsOutput();
|
||||||
|
|
||||||
LogManager.GetCurrentClassLogger()
|
LogManager.GetCurrentClassLogger()
|
||||||
.Info("Average CPU Usage: {0}%, Average RAM Usage: {1}MB, Max CPU: {2}%, Max Mem: {3}MB", _avgCpuUsage, _avgMemUsage, _maxCpuUsage, _maxMemUsage);
|
.Info("Average CPU Usage: {0}%, Average RAM Usage: {1}MB, Max CPU: {2}%, Max Mem: {3}MB",
|
||||||
|
_avgCpuUsage, _avgMemUsage, _maxCpuUsage, _maxMemUsage);
|
||||||
|
|
||||||
LogManager.GetCurrentClassLogger().Info(json.ToString());
|
LogManager.GetCurrentClassLogger().Info(json.ToString());
|
||||||
|
|
||||||
Diagnostics.Shutdown();
|
Diagnostics.Shutdown();
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StartTimberWinR(string configFile, string logLevel, string logFileDir, bool enableLiveMonitor)
|
static void StartTimberWinR(string configFile, string logLevel, string logFileDir, bool enableLiveMonitor)
|
||||||
@@ -357,8 +424,6 @@ namespace TimberWinR.TestGenerator
|
|||||||
|
|
||||||
private static void TimberWinROnOnConfigurationProcessed(Configuration configuration)
|
private static void TimberWinROnOnConfigurationProcessed(Configuration configuration)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Processed Config: {0}", configuration.GetHashCode());
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Options.RedisHost) && configuration.RedisOutputs != null && configuration.RedisOutputs.Count() > 0)
|
if (!string.IsNullOrEmpty(Options.RedisHost) && configuration.RedisOutputs != null && configuration.RedisOutputs.Count() > 0)
|
||||||
{
|
{
|
||||||
foreach (var ro in configuration.RedisOutputs)
|
foreach (var ro in configuration.RedisOutputs)
|
||||||
|
|||||||
@@ -99,6 +99,24 @@
|
|||||||
<Content Include="results2.json">
|
<Content Include="results2.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="test3.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="test3-tw.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="results3.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="test4-tw.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="results4.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="test4.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\TimberWinR\TimberWinR.csproj">
|
<ProjectReference Include="..\TimberWinR\TimberWinR.csproj">
|
||||||
|
|||||||
@@ -5,14 +5,14 @@
|
|||||||
"taillog": {
|
"taillog": {
|
||||||
"test1: message sent count": "[messages] == 7404",
|
"test1: message sent count": "[messages] == 7404",
|
||||||
"test2: average cpu": "[avgCpuUsage] <= 30",
|
"test2: average cpu": "[avgCpuUsage] <= 30",
|
||||||
"test3: maximum memory": "[maxMemUsage] <= 20"
|
"test3: maximum memory": "[maxMemUsage] <= 30"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"udp": {
|
"udp": {
|
||||||
"test1: message sent count": "[messages] == 1234",
|
"test1: message sent count": "[messages] == 1234",
|
||||||
"test2: average cpu": "[avgCpuUsage] <= 30",
|
"test2: average cpu": "[avgCpuUsage] <= 30",
|
||||||
"test3: maximum memory": "[maxMemUsage] <= 20"
|
"test3: maximum memory": "[maxMemUsage] <= 30"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,14 +5,14 @@
|
|||||||
"taillog": {
|
"taillog": {
|
||||||
"test1: message sent count": "[messages] == 7404",
|
"test1: message sent count": "[messages] == 7404",
|
||||||
"test2: average cpu": "[avgCpuUsage] <= 30",
|
"test2: average cpu": "[avgCpuUsage] <= 30",
|
||||||
"test3: maximum memory": "[maxMemUsage] <= 15"
|
"test3: maximum memory": "[maxMemUsage] <= 20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"udp": {
|
"udp": {
|
||||||
"test1: message sent count": "[messages] == 1234",
|
"test1: message sent count": "[messages] == 1234",
|
||||||
"test2: average cpu": "[avgCpuUsage] <= 30",
|
"test2: average cpu": "[avgCpuUsage] <= 30",
|
||||||
"test3: maximum memory": "[maxMemUsage] <= 15"
|
"test3: maximum memory": "[maxMemUsage] <= 20"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
20
TimberWinR.TestGenerator/results3.json
Normal file
20
TimberWinR.TestGenerator/results3.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"Results": {
|
||||||
|
"Inputs": [
|
||||||
|
{
|
||||||
|
"taillog": {
|
||||||
|
"test1: message sent count": "[messages] == 7404",
|
||||||
|
"test2: average cpu": "[avgCpuUsage] <= 30",
|
||||||
|
"test3: maximum memory": "[maxMemUsage] <= 15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tcp": {
|
||||||
|
"test4: message sent count": "[messages] == 1234",
|
||||||
|
"test5: average cpu": "[avgCpuUsage] <= 30",
|
||||||
|
"test6: maximum memory": "[maxMemUsage] <= 15"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
20
TimberWinR.TestGenerator/results4.json
Normal file
20
TimberWinR.TestGenerator/results4.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"Results": {
|
||||||
|
"Inputs": [
|
||||||
|
{
|
||||||
|
"taillog": {
|
||||||
|
"test1: message sent count": "[messages] == 7404",
|
||||||
|
"test2: average cpu": "[avgCpuUsage] <= 30",
|
||||||
|
"test3: maximum memory": "[maxMemUsage] <= 15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tcp": {
|
||||||
|
"test4: message sent count": "[messages] == 1234",
|
||||||
|
"test5: average cpu": "[avgCpuUsage] <= 30",
|
||||||
|
"test6: maximum memory": "[maxMemUsage] <= 15"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
"port": 5140
|
"port": 5140
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"TailFiles": [
|
"TailFiles": [
|
||||||
{
|
{
|
||||||
"interval": 5,
|
"interval": 5,
|
||||||
"logSource": "log files",
|
"logSource": "log files",
|
||||||
@@ -25,6 +25,11 @@
|
|||||||
""
|
""
|
||||||
],
|
],
|
||||||
"drop": "true"
|
"drop": "true"
|
||||||
|
},
|
||||||
|
"json": {
|
||||||
|
"type": "Win32-TailFile",
|
||||||
|
"source": "Text",
|
||||||
|
"promote": "Text"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -34,7 +39,7 @@
|
|||||||
"_comment": "Change the host to your Redis instance",
|
"_comment": "Change the host to your Redis instance",
|
||||||
"port": 6379,
|
"port": 6379,
|
||||||
"batch_count": 500,
|
"batch_count": 500,
|
||||||
"threads": 2,
|
"threads": 2,
|
||||||
"host": [
|
"host": [
|
||||||
"tstlexiceapp006.vistaprint.svc"
|
"tstlexiceapp006.vistaprint.svc"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"test": "Test 1",
|
"test": "Test 1",
|
||||||
"arguments": {
|
"arguments": {
|
||||||
|
"--start": "",
|
||||||
"--testFile": "test1.json",
|
"--testFile": "test1.json",
|
||||||
"--testDir": "test1",
|
"--testDir": "test1",
|
||||||
"--timberWinRConfig": "test1-twconfig.json",
|
"--timberWinRConfig": "test1-twconfig.json",
|
||||||
"--numMessages": 1234,
|
"--numMessages": 1234,
|
||||||
"--logLevel": "debug",
|
"--logLevel": "debug",
|
||||||
"--udp-host": "::1",
|
"--udp-host": "localhost",
|
||||||
"--udp": "5140",
|
"--udp": "5140",
|
||||||
"--jroll": ["r1.jlog", "r2.jlog"],
|
"--jroll": ["r1.jlog", "r2.jlog"],
|
||||||
"--json": ["1.jlog", "2.jlog", "3.jlog", "4.jlog"],
|
"--json": ["1.jlog", "2.jlog", "3.jlog", "4.jlog"],
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"--testDir": "test2",
|
"--testDir": "test2",
|
||||||
"--timberWinRConfig": "test2-tw.json",
|
"--timberWinRConfig": "test2-tw.json",
|
||||||
"--numMessages": 1234,
|
"--numMessages": 1234,
|
||||||
"--logLevel": "debug",
|
"--logLevel": "trace",
|
||||||
"--udp": "5140",
|
"--udp": "5140",
|
||||||
"--jroll": ["r1.jlog", "r2.jlog"],
|
"--jroll": ["r1.jlog", "r2.jlog"],
|
||||||
"--json": ["1.jlog", "2.jlog", "3.jlog", "4.jlog"],
|
"--json": ["1.jlog", "2.jlog", "3.jlog", "4.jlog"],
|
||||||
|
|||||||
50
TimberWinR.TestGenerator/test3-tw.json
Normal file
50
TimberWinR.TestGenerator/test3-tw.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"TimberWinR": {
|
||||||
|
"Inputs": {
|
||||||
|
"Udp": [
|
||||||
|
{
|
||||||
|
"_comment": "Output from NLog",
|
||||||
|
"port": 5140
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"TailFiles": [
|
||||||
|
{
|
||||||
|
"interval": 5,
|
||||||
|
"logSource": "log files",
|
||||||
|
"location": "d:\\logs\\sta\\sta.log",
|
||||||
|
"recurse": -1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Filters": [
|
||||||
|
{
|
||||||
|
"grok": {
|
||||||
|
"condition": "\"[EventTypeName]\" == \"Information Event\"",
|
||||||
|
"match": [
|
||||||
|
"Text",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"drop": "true"
|
||||||
|
},
|
||||||
|
"json": {
|
||||||
|
"type": "Win32-TailFile",
|
||||||
|
"source": "Text",
|
||||||
|
"promote": "Text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Outputs": {
|
||||||
|
"Redis": [
|
||||||
|
{
|
||||||
|
"_comment": "Change the host to your Redis instance",
|
||||||
|
"port": 6379,
|
||||||
|
"batch_count": 500,
|
||||||
|
"threads": 2,
|
||||||
|
"host": [
|
||||||
|
"tstlexiceapp006.vistaprint.svc"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
TimberWinR.TestGenerator/test3.json
Normal file
12
TimberWinR.TestGenerator/test3.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"test": "Test 3",
|
||||||
|
"arguments": {
|
||||||
|
"--start": "",
|
||||||
|
"--testFile": "test3.json",
|
||||||
|
"--testDir": "test3",
|
||||||
|
"--timberWinRConfig": "test3-tw.json",
|
||||||
|
"--numMessages": 1234,
|
||||||
|
"--logLevel": "debug",
|
||||||
|
"--resultsFile": "results3.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
50
TimberWinR.TestGenerator/test4-tw.json
Normal file
50
TimberWinR.TestGenerator/test4-tw.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"TimberWinR": {
|
||||||
|
"Inputs": {
|
||||||
|
"Udp": [
|
||||||
|
{
|
||||||
|
"_comment": "Output from NLog",
|
||||||
|
"port": 5140
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"TailFiles": [
|
||||||
|
{
|
||||||
|
"interval": 5,
|
||||||
|
"logSource": "log files",
|
||||||
|
"location": "d:\\logs\\sta\\sta.log",
|
||||||
|
"recurse": -1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Filters": [
|
||||||
|
{
|
||||||
|
"grok": {
|
||||||
|
"condition": "\"[EventTypeName]\" == \"Information Event\"",
|
||||||
|
"match": [
|
||||||
|
"Text",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"drop": "true"
|
||||||
|
},
|
||||||
|
"json": {
|
||||||
|
"type": "Win32-TailFile",
|
||||||
|
"source": "Text",
|
||||||
|
"promote": "Text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Outputs": {
|
||||||
|
"Redis": [
|
||||||
|
{
|
||||||
|
"_comment": "Change the host to your Redis instance",
|
||||||
|
"port": 6379,
|
||||||
|
"batch_count": 500,
|
||||||
|
"threads": 2,
|
||||||
|
"host": [
|
||||||
|
"tstlexiceapp006.vistaprint.svc"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
TimberWinR.TestGenerator/test4.json
Normal file
11
TimberWinR.TestGenerator/test4.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"test": "Test 4",
|
||||||
|
"arguments": {
|
||||||
|
"--testFile": "test4.json",
|
||||||
|
"--testDir": "test4",
|
||||||
|
"--timberWinRConfig": "test4-tw.json",
|
||||||
|
"--numMessages": 1234,
|
||||||
|
"--logLevel": "debug",
|
||||||
|
"--resultsFile": "results4.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
26
TimberWinR/Codecs/JsonCodec.cs
Normal file
26
TimberWinR/Codecs/JsonCodec.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using TimberWinR.Parser;
|
||||||
|
|
||||||
|
namespace TimberWinR.Codecs
|
||||||
|
{
|
||||||
|
class JsonCodec : ICodec
|
||||||
|
{
|
||||||
|
private CodecArguments _codecArguments;
|
||||||
|
|
||||||
|
public void Apply(string msg, Inputs.InputListener listener)
|
||||||
|
{
|
||||||
|
JObject jobject = JObject.Parse(msg);
|
||||||
|
listener.AddDefaultFields(jobject);
|
||||||
|
listener.ProcessJson(jobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonCodec(CodecArguments args)
|
||||||
|
{
|
||||||
|
_codecArguments = args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
TimberWinR/Codecs/PlainCodec.cs
Normal file
39
TimberWinR/Codecs/PlainCodec.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using TimberWinR.Parser;
|
||||||
|
|
||||||
|
namespace TimberWinR.Codecs
|
||||||
|
{
|
||||||
|
public class PlainCodec : ICodec
|
||||||
|
{
|
||||||
|
private CodecArguments _codecArguments;
|
||||||
|
|
||||||
|
public void Apply(string msg, Inputs.InputListener listener)
|
||||||
|
{
|
||||||
|
JObject json = new JObject();
|
||||||
|
listener.AddDefaultFields(json);
|
||||||
|
json["message"] = ExpandField(msg, json);
|
||||||
|
listener.ProcessJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string ExpandField(string fieldName, JObject json)
|
||||||
|
{
|
||||||
|
foreach (var token in json.Children())
|
||||||
|
{
|
||||||
|
string replaceString = "%{" + token.Path + "}";
|
||||||
|
fieldName = fieldName.Replace(replaceString, json[token.Path].ToString());
|
||||||
|
}
|
||||||
|
return fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public PlainCodec(CodecArguments args)
|
||||||
|
{
|
||||||
|
_codecArguments = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -102,6 +102,12 @@ namespace TimberWinR
|
|||||||
get { return _stdins; }
|
get { return _stdins; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<GeneratorParameters> _generators = new List<GeneratorParameters>();
|
||||||
|
public IEnumerable<GeneratorParameters> Generators
|
||||||
|
{
|
||||||
|
get { return _generators; }
|
||||||
|
}
|
||||||
|
|
||||||
private List<LogstashFilter> _filters = new List<LogstashFilter>();
|
private List<LogstashFilter> _filters = new List<LogstashFilter>();
|
||||||
|
|
||||||
public IEnumerable<LogstashFilter> Filters
|
public IEnumerable<LogstashFilter> Filters
|
||||||
@@ -239,6 +245,8 @@ namespace TimberWinR
|
|||||||
c._iisw3clogs.AddRange(x.TimberWinR.Inputs.IISW3CLogs.ToList());
|
c._iisw3clogs.AddRange(x.TimberWinR.Inputs.IISW3CLogs.ToList());
|
||||||
if (x.TimberWinR.Inputs.Stdins != null)
|
if (x.TimberWinR.Inputs.Stdins != null)
|
||||||
c._stdins.AddRange(x.TimberWinR.Inputs.Stdins.ToList());
|
c._stdins.AddRange(x.TimberWinR.Inputs.Stdins.ToList());
|
||||||
|
if (x.TimberWinR.Inputs.Generators != null)
|
||||||
|
c._generators.AddRange(x.TimberWinR.Inputs.Generators.ToList());
|
||||||
if (x.TimberWinR.Inputs.Logs != null)
|
if (x.TimberWinR.Inputs.Logs != null)
|
||||||
c._logs.AddRange(x.TimberWinR.Inputs.Logs.ToList());
|
c._logs.AddRange(x.TimberWinR.Inputs.Logs.ToList());
|
||||||
if (x.TimberWinR.Inputs.TailFilesArguments != null)
|
if (x.TimberWinR.Inputs.TailFilesArguments != null)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
@@ -12,6 +13,8 @@ namespace TimberWinR.Parser
|
|||||||
{
|
{
|
||||||
public partial class Json : LogstashFilter
|
public partial class Json : LogstashFilter
|
||||||
{
|
{
|
||||||
|
private long _errorCount;
|
||||||
|
|
||||||
public Json()
|
public Json()
|
||||||
{
|
{
|
||||||
RemoveSource = true;
|
RemoveSource = true;
|
||||||
@@ -22,6 +25,7 @@ namespace TimberWinR.Parser
|
|||||||
new JProperty("json",
|
new JProperty("json",
|
||||||
new JObject(
|
new JObject(
|
||||||
new JProperty("condition", Condition),
|
new JProperty("condition", Condition),
|
||||||
|
new JProperty("errors", _errorCount),
|
||||||
new JProperty("source", Source),
|
new JProperty("source", Source),
|
||||||
new JProperty("promote", Source),
|
new JProperty("promote", Source),
|
||||||
new JProperty("target", Target),
|
new JProperty("target", Target),
|
||||||
@@ -102,6 +106,7 @@ namespace TimberWinR.Parser
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogManager.GetCurrentClassLogger().Error(ex);
|
LogManager.GetCurrentClassLogger().Error(ex);
|
||||||
|
Interlocked.Increment(ref _errorCount);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
88
TimberWinR/Inputs/GeneratorInput.cs
Normal file
88
TimberWinR/Inputs/GeneratorInput.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using NLog;
|
||||||
|
using RestSharp.Extensions;
|
||||||
|
using TimberWinR.Codecs;
|
||||||
|
using TimberWinR.Parser;
|
||||||
|
|
||||||
|
|
||||||
|
namespace TimberWinR.Inputs
|
||||||
|
{
|
||||||
|
public class GeneratorInput : InputListener
|
||||||
|
{
|
||||||
|
public override JObject ToJson()
|
||||||
|
{
|
||||||
|
JObject json = new JObject(
|
||||||
|
new JProperty("message", _params.Message),
|
||||||
|
new JProperty("messages", _sentMessages),
|
||||||
|
new JProperty("generator", "enabled"));
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimberWinR.Parser.GeneratorParameters _params;
|
||||||
|
private Thread _listenThread;
|
||||||
|
private ICodec _codec;
|
||||||
|
private int _sentMessages;
|
||||||
|
|
||||||
|
public GeneratorInput(TimberWinR.Parser.GeneratorParameters parameters, CancellationToken cancelToken)
|
||||||
|
: base(cancelToken, "Win32-InputGen")
|
||||||
|
{
|
||||||
|
_params = parameters;
|
||||||
|
|
||||||
|
if (_params.CodecArguments != null)
|
||||||
|
{
|
||||||
|
switch (_params.CodecArguments.Type)
|
||||||
|
{
|
||||||
|
case CodecArguments.CodecType.json:
|
||||||
|
_codec = new JsonCodec(_params.CodecArguments);
|
||||||
|
break;
|
||||||
|
case CodecArguments.CodecType.multiline:
|
||||||
|
_codec = new Multiline(_params.CodecArguments);
|
||||||
|
break;
|
||||||
|
case CodecArguments.CodecType.plain:
|
||||||
|
_codec = new PlainCodec(_params.CodecArguments);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_listenThread = new Thread(new ThreadStart(GenerateData));
|
||||||
|
_listenThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateData()
|
||||||
|
{
|
||||||
|
LogManager.GetCurrentClassLogger().Info("Generator Creating {0} Lines", _params.Count);
|
||||||
|
|
||||||
|
int numMessages = _params.Count;
|
||||||
|
|
||||||
|
// Infinite or until done.
|
||||||
|
for (int i = 0; (_params.Count == 0 || i < numMessages); i++)
|
||||||
|
{
|
||||||
|
if (CancelToken.IsCancellationRequested)
|
||||||
|
break;
|
||||||
|
|
||||||
|
string msg = ToPrintable(_params.Message);
|
||||||
|
|
||||||
|
if (_codec != null)
|
||||||
|
_codec.Apply(msg, this);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JObject jo = new JObject();
|
||||||
|
jo["Message"] = msg;
|
||||||
|
AddDefaultFields(jo);
|
||||||
|
ProcessJson(jo);
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.Sleep(_params.Rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,18 +30,10 @@ namespace TimberWinR.Inputs
|
|||||||
|
|
||||||
private static LogsFileDatabase instance;
|
private static LogsFileDatabase instance;
|
||||||
|
|
||||||
private bool ExistingFile(string logName)
|
|
||||||
{
|
|
||||||
lock (_locker)
|
|
||||||
{
|
|
||||||
return ExistingFileTest(logName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Lookup the database entry for this log file, returns null if there isnt one.
|
// Lookup the database entry for this log file, returns null if there isnt one.
|
||||||
//
|
//
|
||||||
private LogsFileDatabaseEntry FindFile(string logName)
|
private LogsFileDatabaseEntry FindFileWithLock(string logName)
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
@@ -69,7 +61,7 @@ namespace TimberWinR.Inputs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LogsFileDatabaseEntry AddFileEntry(string logName)
|
private LogsFileDatabaseEntry AddFileEntryWithLock(string logName)
|
||||||
{
|
{
|
||||||
var de = new LogsFileDatabaseEntry();
|
var de = new LogsFileDatabaseEntry();
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
@@ -77,6 +69,7 @@ namespace TimberWinR.Inputs
|
|||||||
var fi = new FileInfo(logName);
|
var fi = new FileInfo(logName);
|
||||||
de.FileName = logName;
|
de.FileName = logName;
|
||||||
de.LogFileExists = fi.Exists;
|
de.LogFileExists = fi.Exists;
|
||||||
|
de.Previous = "";
|
||||||
de.NewFile = true;
|
de.NewFile = true;
|
||||||
de.ProcessedFile = false;
|
de.ProcessedFile = false;
|
||||||
de.LastPosition = fi.Length;
|
de.LastPosition = fi.Length;
|
||||||
@@ -91,9 +84,9 @@ namespace TimberWinR.Inputs
|
|||||||
|
|
||||||
public static LogsFileDatabaseEntry LookupLogFile(string logName)
|
public static LogsFileDatabaseEntry LookupLogFile(string logName)
|
||||||
{
|
{
|
||||||
LogsFileDatabaseEntry dbe = Instance.FindFile(logName);
|
LogsFileDatabaseEntry dbe = Instance.FindFileWithLock(logName);
|
||||||
if (dbe == null)
|
if (dbe == null)
|
||||||
dbe = Instance.AddFileEntry(logName);
|
dbe = Instance.AddFileEntryWithLock(logName);
|
||||||
|
|
||||||
FileInfo fi = new FileInfo(logName);
|
FileInfo fi = new FileInfo(logName);
|
||||||
|
|
||||||
@@ -101,21 +94,23 @@ namespace TimberWinR.Inputs
|
|||||||
var creationTime = fi.CreationTimeUtc;
|
var creationTime = fi.CreationTimeUtc;
|
||||||
|
|
||||||
if (dbe.LogFileExists && creationTime != dbe.CreationTimeUtc)
|
if (dbe.LogFileExists && creationTime != dbe.CreationTimeUtc)
|
||||||
|
{
|
||||||
dbe.NewFile = true;
|
dbe.NewFile = true;
|
||||||
|
dbe.Previous = "";
|
||||||
|
}
|
||||||
dbe.CreationTimeUtc = creationTime;
|
dbe.CreationTimeUtc = creationTime;
|
||||||
|
|
||||||
return dbe;
|
return dbe;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all the non-existent entries and remove them.
|
// Find all the non-existent entries and remove them.
|
||||||
private void PruneFiles()
|
private void PruneFilesWithLock()
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
foreach(var entry in Entries.ToList())
|
foreach (var entry in Entries.ToList())
|
||||||
{
|
{
|
||||||
FileInfo fi = new FileInfo(entry.FileName);
|
var fi = new FileInfo(entry.FileName);
|
||||||
if (!fi.Exists)
|
if (!fi.Exists)
|
||||||
Entries.Remove(entry);
|
Entries.Remove(entry);
|
||||||
}
|
}
|
||||||
@@ -127,18 +122,19 @@ namespace TimberWinR.Inputs
|
|||||||
{
|
{
|
||||||
dbe.ProcessedFile = processedFile;
|
dbe.ProcessedFile = processedFile;
|
||||||
dbe.LogFileExists = File.Exists(dbe.FileName);
|
dbe.LogFileExists = File.Exists(dbe.FileName);
|
||||||
Instance.UpdateEntry(dbe, lastOffset);
|
Instance.UpdateEntryWithLock(dbe, lastOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Roll(LogsFileDatabaseEntry dbe)
|
public static void Roll(LogsFileDatabaseEntry dbe)
|
||||||
{
|
{
|
||||||
dbe.ProcessedFile = false;
|
dbe.ProcessedFile = false;
|
||||||
dbe.LastPosition = 0;
|
dbe.LastPosition = 0;
|
||||||
Instance.UpdateEntry(dbe, 0);
|
dbe.Previous = "";
|
||||||
|
Instance.UpdateEntryWithLock(dbe, 0);
|
||||||
dbe.NewFile = true;
|
dbe.NewFile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateEntry(LogsFileDatabaseEntry dbe, long lastOffset)
|
private void UpdateEntryWithLock(LogsFileDatabaseEntry dbe, long lastOffset)
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
{
|
{
|
||||||
@@ -171,7 +167,7 @@ namespace TimberWinR.Inputs
|
|||||||
if (instance.Entries == null)
|
if (instance.Entries == null)
|
||||||
instance.Entries = new List<LogsFileDatabaseEntry>();
|
instance.Entries = new List<LogsFileDatabaseEntry>();
|
||||||
|
|
||||||
instance.PruneFiles();
|
instance.PruneFilesWithLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
@@ -191,18 +187,17 @@ namespace TimberWinR.Inputs
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogManager.GetCurrentClassLogger()
|
LogManager.GetCurrentClassLogger().Error("Error reading database '{0}': {1}", DatabaseFileName, ex.ToString());
|
||||||
.Error("Error reading database '{0}': {1}", DatabaseFileName, ex.ToString());
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (File.Exists(DatabaseFileName))
|
if (File.Exists(DatabaseFileName))
|
||||||
File.Delete(DatabaseFileName);
|
File.Delete(DatabaseFileName);
|
||||||
LogManager.GetCurrentClassLogger().Info("Creating New Database '{0}'", DatabaseFileName);
|
LogManager.GetCurrentClassLogger().Error("Creating New Database '{0}'", DatabaseFileName);
|
||||||
WriteDatabaseLock();
|
WriteDatabaseLock();
|
||||||
}
|
}
|
||||||
catch (Exception ex2)
|
catch (Exception ex2)
|
||||||
{
|
{
|
||||||
LogManager.GetCurrentClassLogger().Info("Error Creating New Database '{0}': {1}", DatabaseFileName, ex2.ToString());
|
LogManager.GetCurrentClassLogger().Error("Error Creating New Database '{0}': {1}", DatabaseFileName, ex2.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,6 +263,7 @@ namespace TimberWinR.Inputs
|
|||||||
{
|
{
|
||||||
Interlocked.Increment(ref _linesProcessed);
|
Interlocked.Increment(ref _linesProcessed);
|
||||||
}
|
}
|
||||||
|
public string Previous { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,14 @@ namespace TimberWinR.Inputs
|
|||||||
private int _pollingIntervalInSeconds;
|
private int _pollingIntervalInSeconds;
|
||||||
private TimberWinR.Parser.TailFileArguments _arguments;
|
private TimberWinR.Parser.TailFileArguments _arguments;
|
||||||
private long _receivedMessages;
|
private long _receivedMessages;
|
||||||
|
private long _errorCount;
|
||||||
private CodecArguments _codecArguments;
|
private CodecArguments _codecArguments;
|
||||||
private ICodec _codec;
|
private ICodec _codec;
|
||||||
|
|
||||||
public bool Stop { get; set; }
|
public bool Stop { get; set; }
|
||||||
|
|
||||||
public TailFileListener(TimberWinR.Parser.TailFileArguments arguments, CancellationToken cancelToken)
|
public TailFileListener(TimberWinR.Parser.TailFileArguments arguments,
|
||||||
|
CancellationToken cancelToken)
|
||||||
: base(cancelToken, "Win32-TailLog")
|
: base(cancelToken, "Win32-TailLog")
|
||||||
{
|
{
|
||||||
Stop = false;
|
Stop = false;
|
||||||
@@ -60,7 +61,9 @@ namespace TimberWinR.Inputs
|
|||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
{
|
{
|
||||||
LogManager.GetCurrentClassLogger().Info("{0}: Shutting Down {1} for {2}", Thread.CurrentThread.ManagedThreadId, InputType, _arguments.Location);
|
LogManager.GetCurrentClassLogger()
|
||||||
|
.Info("{0}: Shutting Down {1} for {2}", Thread.CurrentThread.ManagedThreadId, InputType,
|
||||||
|
_arguments.Location);
|
||||||
Stop = true;
|
Stop = true;
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
}
|
}
|
||||||
@@ -71,6 +74,7 @@ namespace TimberWinR.Inputs
|
|||||||
new JProperty("taillog",
|
new JProperty("taillog",
|
||||||
new JObject(
|
new JObject(
|
||||||
new JProperty("messages", _receivedMessages),
|
new JProperty("messages", _receivedMessages),
|
||||||
|
new JProperty("errors", _errorCount),
|
||||||
new JProperty("type", InputType),
|
new JProperty("type", InputType),
|
||||||
new JProperty("location", _arguments.Location),
|
new JProperty("location", _arguments.Location),
|
||||||
new JProperty("logSource", _arguments.LogSource),
|
new JProperty("logSource", _arguments.LogSource),
|
||||||
@@ -103,65 +107,99 @@ namespace TimberWinR.Inputs
|
|||||||
|
|
||||||
private void TailFileContents(string fileName, long offset, LogsFileDatabaseEntry dbe)
|
private void TailFileContents(string fileName, long offset, LogsFileDatabaseEntry dbe)
|
||||||
{
|
{
|
||||||
using (StreamReader reader = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
|
const int bufSize = 16535;
|
||||||
|
long prevLen = offset;
|
||||||
|
|
||||||
|
var fi = new FileInfo(fileName);
|
||||||
|
if (!fi.Exists)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LogManager.GetCurrentClassLogger().Trace(":{0} Tailing File: {1} as Pos: {2}", Thread.CurrentThread.ManagedThreadId, fileName, prevLen);
|
||||||
|
|
||||||
|
using (var stream = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite))
|
||||||
{
|
{
|
||||||
//start at the end of the file
|
stream.Seek(prevLen, SeekOrigin.Begin);
|
||||||
long lastMaxOffset = offset;
|
|
||||||
|
|
||||||
//if the file size has not changed, idle
|
var buffer = new char[bufSize];
|
||||||
if (reader.BaseStream.Length == lastMaxOffset)
|
var current = new StringBuilder();
|
||||||
return;
|
using (var sr = new StreamReader(stream))
|
||||||
|
|
||||||
//seek to the last max offset
|
|
||||||
LogManager.GetCurrentClassLogger().Trace("{0}: File: {1} Seek to: {2}", Thread.CurrentThread.ManagedThreadId, fileName, lastMaxOffset);
|
|
||||||
|
|
||||||
reader.BaseStream.Seek(lastMaxOffset, SeekOrigin.Begin);
|
|
||||||
|
|
||||||
//read out of the file until the EOF
|
|
||||||
string line = "";
|
|
||||||
long lineOffset = 0;
|
|
||||||
while ((line = reader.ReadLine()) != null)
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(line))
|
int nRead;
|
||||||
continue;
|
do
|
||||||
|
|
||||||
long index = lastMaxOffset + lineOffset;
|
|
||||||
string text = line;
|
|
||||||
string logFileName = fileName;
|
|
||||||
var json = new JObject();
|
|
||||||
|
|
||||||
if (json["logSource"] == null)
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_arguments.LogSource))
|
// Read a buffered amount
|
||||||
json.Add(new JProperty("logSource", fileName));
|
nRead = sr.ReadBlock(buffer, 0, bufSize);
|
||||||
else
|
for (int i = 0; i < nRead; ++i)
|
||||||
json.Add(new JProperty("logSource", _arguments.LogSource));
|
{
|
||||||
}
|
// We need the terminator!
|
||||||
|
if (buffer[i] == '\n' || buffer[i] == '\r')
|
||||||
|
{
|
||||||
|
if (current.Length > 0)
|
||||||
|
{
|
||||||
|
string line = string.Concat(dbe.Previous, current);
|
||||||
|
var json = new JObject();
|
||||||
|
|
||||||
json["Text"] = line;
|
if (json["logSource"] == null)
|
||||||
json["Index"] = index;
|
{
|
||||||
json["LogFileName"] = fileName;
|
if (string.IsNullOrEmpty(_arguments.LogSource))
|
||||||
|
json.Add(new JProperty("logSource", fileName));
|
||||||
|
else
|
||||||
|
json.Add(new JProperty("logSource", _arguments.LogSource));
|
||||||
|
}
|
||||||
|
|
||||||
|
//LogManager.GetCurrentClassLogger().Debug(":{0} File: {1}:{2} {3}", Thread.CurrentThread.ManagedThreadId, fileName, dbe.LinesProcessed, line);
|
||||||
|
|
||||||
if (_codecArguments != null && _codecArguments.Type == CodecArguments.CodecType.multiline)
|
// We've processed the partial input
|
||||||
|
dbe.Previous = "";
|
||||||
|
json["Text"] = line;
|
||||||
|
json["Index"] = dbe.LinesProcessed;
|
||||||
|
json["LogFileName"] = fileName;
|
||||||
|
if (_codecArguments != null && _codecArguments.Type == CodecArguments.CodecType.multiline)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_codec.Apply(line, this);
|
||||||
|
Interlocked.Increment(ref _receivedMessages);
|
||||||
|
dbe.IncrementLineCount();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Interlocked.Increment(ref _errorCount);
|
||||||
|
LogManager.GetCurrentClassLogger().ErrorException("Filter Error", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProcessJson(json);
|
||||||
|
dbe.IncrementLineCount();
|
||||||
|
Interlocked.Increment(ref _receivedMessages);
|
||||||
|
LogsFileDatabase.Update(dbe, true, sr.BaseStream.Position);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Interlocked.Increment(ref _errorCount);
|
||||||
|
LogManager.GetCurrentClassLogger().ErrorException("Process Error", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
current = new StringBuilder();
|
||||||
|
}
|
||||||
|
else // Copy character into the buffer
|
||||||
|
{
|
||||||
|
current.Append(buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (nRead > 0);
|
||||||
|
|
||||||
|
// We didn't encounter the newline, so save it.
|
||||||
|
if (current.Length > 0)
|
||||||
{
|
{
|
||||||
_codec.Apply(line, this);
|
dbe.Previous = current.ToString();
|
||||||
Interlocked.Increment(ref _receivedMessages);
|
|
||||||
dbe.IncrementLineCount();
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ProcessJson(json);
|
|
||||||
Interlocked.Increment(ref _receivedMessages);
|
|
||||||
dbe.IncrementLineCount();
|
|
||||||
//LogManager.GetCurrentClassLogger().Info("{0}: File: {1} {2} {3}", Thread.CurrentThread.ManagedThreadId, fileName, dbe.LinesProcessed, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
lineOffset += line.Length;
|
|
||||||
}
|
}
|
||||||
//update the last max offset
|
|
||||||
lastMaxOffset = reader.BaseStream.Position;
|
|
||||||
LogsFileDatabase.Update(dbe, true, lastMaxOffset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// One thread for each kind of file to watch, i.e. "*.log,*.txt" would be two separate
|
// One thread for each kind of file to watch, i.e. "*.log,*.txt" would be two separate
|
||||||
@@ -202,12 +240,13 @@ namespace TimberWinR.Inputs
|
|||||||
{
|
{
|
||||||
LogManager.GetCurrentClassLogger().Debug(":{0} Starting Thread Tailing File: {1}", Thread.CurrentThread.ManagedThreadId, dbe.FileName);
|
LogManager.GetCurrentClassLogger().Debug(":{0} Starting Thread Tailing File: {1}", Thread.CurrentThread.ManagedThreadId, dbe.FileName);
|
||||||
LogsFileDatabase.Update(dbe, false, dbe.LastPosition);
|
LogsFileDatabase.Update(dbe, false, dbe.LastPosition);
|
||||||
SaveVisitedFileName(fileName);
|
|
||||||
Task.Factory.StartNew(() => TailFileWatcher(fileName));
|
Task.Factory.StartNew(() => TailFileWatcher(fileName));
|
||||||
}
|
}
|
||||||
else if (!isWildcardPattern)
|
else if (!isWildcardPattern)
|
||||||
{
|
{
|
||||||
FileInfo fi = new FileInfo(dbe.FileName);
|
FileInfo fi = new FileInfo(dbe.FileName);
|
||||||
|
SaveVisitedFileName(fileName);
|
||||||
|
|
||||||
//LogManager.GetCurrentClassLogger().Info("Located File: {0}, New: {1}", dbe.FileName, dbe.NewFile);
|
//LogManager.GetCurrentClassLogger().Info("Located File: {0}, New: {1}", dbe.FileName, dbe.NewFile);
|
||||||
long length = fi.Length;
|
long length = fi.Length;
|
||||||
@@ -219,7 +258,7 @@ namespace TimberWinR.Inputs
|
|||||||
LogsFileDatabase.Roll(dbe);
|
LogsFileDatabase.Roll(dbe);
|
||||||
}
|
}
|
||||||
// Log has rolled or this is a file we are seeing for the first time.
|
// Log has rolled or this is a file we are seeing for the first time.
|
||||||
bool processWholeFile = logHasRolled || !dbe.ProcessedFile;
|
bool processWholeFile = logHasRolled || !dbe.ProcessedFile || dbe.NewFile;
|
||||||
if (processWholeFile)
|
if (processWholeFile)
|
||||||
{
|
{
|
||||||
LogsFileDatabase.Update(dbe, true, 0);
|
LogsFileDatabase.Update(dbe, true, 0);
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ namespace TimberWinR.Inputs
|
|||||||
private Thread _listenThreadV4;
|
private Thread _listenThreadV4;
|
||||||
private Thread _listenThreadV6;
|
private Thread _listenThreadV6;
|
||||||
private readonly int _port;
|
private readonly int _port;
|
||||||
|
|
||||||
private long _receivedMessages;
|
private long _receivedMessages;
|
||||||
|
private long _errorCount;
|
||||||
|
|
||||||
public override JObject ToJson()
|
public override JObject ToJson()
|
||||||
{
|
{
|
||||||
@@ -24,9 +26,9 @@ namespace TimberWinR.Inputs
|
|||||||
new JProperty("tcp",
|
new JProperty("tcp",
|
||||||
new JObject(
|
new JObject(
|
||||||
new JProperty("port", _port),
|
new JProperty("port", _port),
|
||||||
|
new JProperty("errors", _errorCount),
|
||||||
new JProperty("messages", _receivedMessages)
|
new JProperty("messages", _receivedMessages)
|
||||||
)));
|
)));
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +70,6 @@ namespace TimberWinR.Inputs
|
|||||||
|
|
||||||
listener.Start();
|
listener.Start();
|
||||||
|
|
||||||
|
|
||||||
while (!CancelToken.IsCancellationRequested)
|
while (!CancelToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -109,7 +110,7 @@ namespace TimberWinR.Inputs
|
|||||||
{
|
{
|
||||||
JObject json = JObject.Load(reader);
|
JObject json = JObject.Load(reader);
|
||||||
ProcessJson(json);
|
ProcessJson(json);
|
||||||
_receivedMessages++;
|
Interlocked.Increment(ref _receivedMessages);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -118,12 +119,16 @@ namespace TimberWinR.Inputs
|
|||||||
ProcessJson(jex1);
|
ProcessJson(jex1);
|
||||||
|
|
||||||
LogManager.GetCurrentClassLogger().Warn(ex);
|
LogManager.GetCurrentClassLogger().Warn(ex);
|
||||||
|
Interlocked.Increment(ref _errorCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(OperationCanceledException)
|
||||||
|
{
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogManager.GetCurrentClassLogger().Error(ex);
|
LogManager.GetCurrentClassLogger().Error(ex);
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.Collections.Concurrent;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
@@ -13,109 +11,160 @@ namespace TimberWinR.Inputs
|
|||||||
{
|
{
|
||||||
public class UdpInputListener : InputListener
|
public class UdpInputListener : InputListener
|
||||||
{
|
{
|
||||||
private UdpClient _udpListenerV6;
|
private UdpClient _udpListenerV4;
|
||||||
private readonly Thread _listenThreadV6;
|
private IPEndPoint _udpEndpointV4;
|
||||||
|
private readonly BlockingCollection<byte[]> _unprocessedRawData;
|
||||||
|
private readonly Thread _rawDataProcessingThread;
|
||||||
private readonly int _port;
|
private readonly int _port;
|
||||||
private long _receivedMessages;
|
private long _receivedMessages;
|
||||||
private long _parsedErrors;
|
private long _parseErrors;
|
||||||
|
private long _receiveErrors;
|
||||||
|
private long _parsedMessages;
|
||||||
|
|
||||||
public override JObject ToJson()
|
public override JObject ToJson()
|
||||||
{
|
{
|
||||||
JObject json = new JObject(
|
var json =
|
||||||
new JProperty("udp",
|
new JObject(new JProperty("udp",
|
||||||
new JObject(
|
new JObject(new JProperty("port", _port),
|
||||||
new JProperty("port", _port),
|
new JProperty("receive_errors", _receiveErrors),
|
||||||
new JProperty("errors", _parsedErrors),
|
new JProperty("parse_errors", _parseErrors),
|
||||||
new JProperty("messages", _receivedMessages)
|
new JProperty("messages", _receivedMessages),
|
||||||
)));
|
new JProperty("parsed_messages", _parsedMessages),
|
||||||
|
new JProperty("unprocessed_messages", _unprocessedRawData.Count))));
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UdpInputListener(CancellationToken cancelToken, int port = 5140)
|
public UdpInputListener(CancellationToken cancelToken, int port = 5140) : base(cancelToken, "Win32-Udp")
|
||||||
: base(cancelToken, "Win32-Udp")
|
|
||||||
{
|
{
|
||||||
_port = port;
|
_port = port;
|
||||||
|
|
||||||
|
|
||||||
_receivedMessages = 0;
|
_receivedMessages = 0;
|
||||||
|
|
||||||
_listenThreadV6 = new Thread(StartListener);
|
// setup raw data processor
|
||||||
_listenThreadV6.Start();
|
_unprocessedRawData = new BlockingCollection<byte[]>();
|
||||||
}
|
_rawDataProcessingThread = new Thread(ProcessDataLoop) { Name = "Win32-Udp-DataProcessor"};
|
||||||
|
_rawDataProcessingThread.Start();
|
||||||
|
|
||||||
|
// start listing to udp port
|
||||||
|
StartListener();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
{
|
{
|
||||||
LogManager.GetCurrentClassLogger().Info("Shutting Down {0}", InputType);
|
LogManager.GetCurrentClassLogger().Info("Shutting Down {0}", InputType);
|
||||||
|
|
||||||
// close UDP listeners, which will end the listener threads
|
// close UDP listeners, which will end the listener threads
|
||||||
_udpListenerV6.Close();
|
_udpListenerV4.Close();
|
||||||
|
|
||||||
// wait for completion of the threads
|
|
||||||
_listenThreadV6.Join();
|
|
||||||
|
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartListener()
|
private void StartListener()
|
||||||
{
|
{
|
||||||
var groupV6 = new IPEndPoint(IPAddress.IPv6Any, _port);
|
_udpEndpointV4 = new IPEndPoint(IPAddress.Any, _port);
|
||||||
// Create the socket as IPv6
|
|
||||||
var dualModeSocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
|
|
||||||
|
|
||||||
//
|
// setup listener
|
||||||
// Now, disable the IPV6only flag to make it compatable with both ipv4 and ipv6
|
_udpListenerV4 = new UdpClient(_port);
|
||||||
// See: http://blogs.msdn.com/b/malarch/archive/2005/11/18/494769.aspx
|
|
||||||
//
|
|
||||||
dualModeSocket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 0);
|
|
||||||
dualModeSocket.Bind(groupV6);
|
|
||||||
|
|
||||||
_udpListenerV6 = new UdpClient();
|
// start listening on UDP port
|
||||||
_udpListenerV6.Client = dualModeSocket;
|
StartReceiving();
|
||||||
|
|
||||||
LogManager.GetCurrentClassLogger().Info("Udp Input on Port {0} Ready", groupV6);
|
// all started; log details
|
||||||
|
LogManager.GetCurrentClassLogger().Info("Udp Input on Port {0} Ready", _udpEndpointV4);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartReceiving()
|
||||||
|
{
|
||||||
|
if (!CancelToken.IsCancellationRequested)
|
||||||
|
_udpListenerV4.BeginReceive(DataReceived, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DataReceived(IAsyncResult result)
|
||||||
|
{
|
||||||
|
if (CancelToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
_unprocessedRawData.CompleteAdding();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string lastMessage = "";
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (!CancelToken.IsCancellationRequested)
|
byte[] bytes = _udpListenerV4.EndReceive(result, ref _udpEndpointV4);
|
||||||
{
|
Interlocked.Increment(ref _receivedMessages);
|
||||||
try
|
StartReceiving();
|
||||||
{
|
_unprocessedRawData.Add(bytes);
|
||||||
byte[] bytes = _udpListenerV6.Receive(ref groupV6);
|
}
|
||||||
var data = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
|
catch (SocketException)
|
||||||
lastMessage = data;
|
{
|
||||||
var json = JObject.Parse(data);
|
LogManager.GetCurrentClassLogger().Info("Socked exception. Ending UDP Listener.");
|
||||||
ProcessJson(json);
|
_unprocessedRawData.CompleteAdding();
|
||||||
Interlocked.Increment(ref _receivedMessages);
|
}
|
||||||
}
|
catch (ObjectDisposedException)
|
||||||
catch(SocketException)
|
{
|
||||||
{
|
LogManager.GetCurrentClassLogger().Info("Object disposed. Ending UDP Listener");
|
||||||
break;
|
_unprocessedRawData.CompleteAdding();
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var jex1 = LogErrors.LogException(string.Format("Invalid JSON: {0}", lastMessage), ex);
|
|
||||||
if (jex1 != null)
|
|
||||||
ProcessJson(jex1);
|
|
||||||
|
|
||||||
LogManager.GetCurrentClassLogger().Warn("Bad JSON: {0}", lastMessage);
|
|
||||||
LogManager.GetCurrentClassLogger().Warn(ex);
|
|
||||||
|
|
||||||
Interlocked.Increment(ref _parsedErrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_udpListenerV6.Close();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (!CancelToken.IsCancellationRequested)
|
LogManager.GetCurrentClassLogger().Warn("Error while receiving data.", ex);
|
||||||
LogManager.GetCurrentClassLogger().Error(ex);
|
|
||||||
|
Interlocked.Increment(ref _receiveErrors);
|
||||||
|
StartReceiving();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessDataLoop()
|
||||||
|
{
|
||||||
|
while (!_unprocessedRawData.IsCompleted)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProcessData(_unprocessedRawData.Take());
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// we are shutting down.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
// when the collection is marked as completed
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.GetCurrentClassLogger().ErrorException("Error while processing data", ex);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Finished();
|
Finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ProcessData(byte[] bytes)
|
||||||
|
{
|
||||||
|
var data = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var json = JObject.Parse(data);
|
||||||
|
ProcessJson(json);
|
||||||
|
|
||||||
|
_parsedMessages++;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var jex1 = LogErrors.LogException(string.Format("Invalid JSON: {0}", data), ex);
|
||||||
|
if (jex1 != null)
|
||||||
|
{
|
||||||
|
ProcessJson(jex1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg = string.Format("Bad JSON: {0}", data);
|
||||||
|
LogManager.GetCurrentClassLogger().Warn(msg, ex);
|
||||||
|
|
||||||
|
_parseErrors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Security.AccessControl;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.IO;
|
|
||||||
using Interop.MSUtil;
|
|
||||||
|
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Newtonsoft.Json.Serialization;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using TimberWinR.Parser;
|
||||||
using LogQuery = Interop.MSUtil.LogQueryClassClass;
|
using LogQuery = Interop.MSUtil.LogQueryClassClass;
|
||||||
using EventLogInputFormat = Interop.MSUtil.COMEventLogInputContextClassClass;
|
using EventLogInputFormat = Interop.MSUtil.COMEventLogInputContextClassClass;
|
||||||
using LogRecordSet = Interop.MSUtil.ILogRecordset;
|
using LogRecordSet = Interop.MSUtil.ILogRecordset;
|
||||||
@@ -23,13 +16,13 @@ namespace TimberWinR.Inputs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class WindowsEvtInputListener : InputListener
|
public class WindowsEvtInputListener : InputListener
|
||||||
{
|
{
|
||||||
private int _pollingIntervalInSeconds = 1;
|
private readonly int _pollingIntervalInSeconds = 1;
|
||||||
private TimberWinR.Parser.WindowsEvent _arguments;
|
private readonly WindowsEvent _arguments;
|
||||||
private long _receivedMessages;
|
private long _receivedMessages;
|
||||||
private List<Thread> _tasks { get; set; }
|
private readonly List<Thread> _tasks;
|
||||||
public bool Stop { get; set; }
|
public bool Stop { get; set; }
|
||||||
|
|
||||||
public WindowsEvtInputListener(TimberWinR.Parser.WindowsEvent arguments, CancellationToken cancelToken)
|
public WindowsEvtInputListener(WindowsEvent arguments, CancellationToken cancelToken)
|
||||||
: base(cancelToken, "Win32-Eventlog")
|
: base(cancelToken, "Win32-Eventlog")
|
||||||
{
|
{
|
||||||
_arguments = arguments;
|
_arguments = arguments;
|
||||||
@@ -38,8 +31,7 @@ namespace TimberWinR.Inputs
|
|||||||
|
|
||||||
foreach (string eventHive in _arguments.Source.Split(','))
|
foreach (string eventHive in _arguments.Source.Split(','))
|
||||||
{
|
{
|
||||||
string hive = eventHive.Trim();
|
var thread = new Thread(EventWatcher) {Name = "Win32-Eventlog-" + eventHive};
|
||||||
var thread = new Thread(new ParameterizedThreadStart(EventWatcher));
|
|
||||||
_tasks.Add(thread);
|
_tasks.Add(thread);
|
||||||
thread.Start(eventHive);
|
thread.Start(eventHive);
|
||||||
}
|
}
|
||||||
@@ -49,6 +41,10 @@ namespace TimberWinR.Inputs
|
|||||||
{
|
{
|
||||||
Stop = true;
|
Stop = true;
|
||||||
LogManager.GetCurrentClassLogger().Info("Shutting Down {0}", InputType);
|
LogManager.GetCurrentClassLogger().Info("Shutting Down {0}", InputType);
|
||||||
|
foreach (var thread in _tasks)
|
||||||
|
{
|
||||||
|
thread.Join();
|
||||||
|
}
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,8 +72,6 @@ namespace TimberWinR.Inputs
|
|||||||
{
|
{
|
||||||
string location = ploc.ToString();
|
string location = ploc.ToString();
|
||||||
|
|
||||||
LogQuery oLogQuery = new LogQuery();
|
|
||||||
|
|
||||||
LogManager.GetCurrentClassLogger().Info("WindowsEvent Input Listener Ready");
|
LogManager.GetCurrentClassLogger().Info("WindowsEvent Input Listener Ready");
|
||||||
|
|
||||||
// Instantiate the Event Log Input Format object
|
// Instantiate the Event Log Input Format object
|
||||||
@@ -93,9 +87,7 @@ namespace TimberWinR.Inputs
|
|||||||
resolveSIDs = _arguments.ResolveSIDS
|
resolveSIDs = _arguments.ResolveSIDS
|
||||||
};
|
};
|
||||||
|
|
||||||
oLogQuery = null;
|
var logFileMaxRecords = new Dictionary<string, Int64>();
|
||||||
|
|
||||||
Dictionary<string, Int64> logFileMaxRecords = new Dictionary<string, Int64>();
|
|
||||||
|
|
||||||
using (var syncHandle = new ManualResetEventSlim())
|
using (var syncHandle = new ManualResetEventSlim())
|
||||||
{
|
{
|
||||||
@@ -107,7 +99,7 @@ namespace TimberWinR.Inputs
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
oLogQuery = new LogQuery();
|
var oLogQuery = new LogQuery();
|
||||||
|
|
||||||
var qfiles = string.Format("SELECT Distinct [EventLog] FROM {0}", location);
|
var qfiles = string.Format("SELECT Distinct [EventLog] FROM {0}", location);
|
||||||
var rsfiles = oLogQuery.Execute(qfiles, iFmt);
|
var rsfiles = oLogQuery.Execute(qfiles, iFmt);
|
||||||
@@ -145,21 +137,19 @@ namespace TimberWinR.Inputs
|
|||||||
object v = record.getValue(field.Name);
|
object v = record.getValue(field.Name);
|
||||||
if (field.Name == "Data")
|
if (field.Name == "Data")
|
||||||
v = ToPrintable(v.ToString());
|
v = ToPrintable(v.ToString());
|
||||||
|
if ((field.Name == "TimeGenerated" || field.Name == "TimeWritten") && field.DataType == typeof (DateTime))
|
||||||
|
v = ((DateTime) v).ToUniversalTime();
|
||||||
json.Add(new JProperty(field.Name, v));
|
json.Add(new JProperty(field.Name, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
var lrn = (Int64)record.getValueEx("RecordNumber");
|
var lrn = (Int64)record.getValueEx("RecordNumber");
|
||||||
logFileMaxRecords[fileName] = lrn;
|
logFileMaxRecords[fileName] = lrn;
|
||||||
|
|
||||||
record = null;
|
|
||||||
ProcessJson(json);
|
ProcessJson(json);
|
||||||
_receivedMessages++;
|
_receivedMessages++;
|
||||||
json = null;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// Close the recordset
|
// Close the recordset
|
||||||
rs.close();
|
rs.close();
|
||||||
rs = null;
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
if (!Stop)
|
if (!Stop)
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ namespace TimberWinR
|
|||||||
{
|
{
|
||||||
public Configuration Config { get; set; }
|
public Configuration Config { get; set; }
|
||||||
public List<OutputSender> Outputs { get; set; }
|
public List<OutputSender> Outputs { get; set; }
|
||||||
public List<TcpInputListener> Tcps { get; set; }
|
|
||||||
public List<TcpInputListener> Udps { get; set; }
|
|
||||||
public List<InputListener> Listeners { get; set; }
|
public List<InputListener> Listeners { get; set; }
|
||||||
public bool LiveMonitor { get; set; }
|
public bool LiveMonitor { get; set; }
|
||||||
|
|
||||||
@@ -119,17 +117,9 @@ namespace TimberWinR
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Is it a directory?
|
var fi = new FileInfo(jsonConfigFile);
|
||||||
if (Directory.Exists(jsonConfigFile))
|
if (fi.Exists)
|
||||||
{
|
{
|
||||||
DirectoryInfo di = new DirectoryInfo(jsonConfigFile);
|
|
||||||
LogManager.GetCurrentClassLogger().Info("Initialized, Reading Configurations From {0}", di.FullName);
|
|
||||||
Config = Configuration.FromDirectory(jsonConfigFile, cancelToken, this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var fi = new FileInfo(jsonConfigFile);
|
|
||||||
|
|
||||||
LogManager.GetCurrentClassLogger().Info("Initialized, Reading Configurations From File: {0}", fi.FullName);
|
LogManager.GetCurrentClassLogger().Info("Initialized, Reading Configurations From File: {0}", fi.FullName);
|
||||||
|
|
||||||
if (!fi.Exists)
|
if (!fi.Exists)
|
||||||
@@ -138,6 +128,12 @@ namespace TimberWinR
|
|||||||
LogManager.GetCurrentClassLogger().Info("Initialized, Reading Config: {0}", fi.FullName);
|
LogManager.GetCurrentClassLogger().Info("Initialized, Reading Config: {0}", fi.FullName);
|
||||||
Config = Configuration.FromFile(jsonConfigFile);
|
Config = Configuration.FromFile(jsonConfigFile);
|
||||||
}
|
}
|
||||||
|
else if (Directory.Exists(jsonConfigFile))
|
||||||
|
{
|
||||||
|
DirectoryInfo di = new DirectoryInfo(jsonConfigFile);
|
||||||
|
LogManager.GetCurrentClassLogger().Info("Initialized, Reading Configurations From {0}", di.FullName);
|
||||||
|
Config = Configuration.FromDirectory(jsonConfigFile, cancelToken, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (JsonSerializationException jse)
|
catch (JsonSerializationException jse)
|
||||||
{
|
{
|
||||||
@@ -163,7 +159,7 @@ namespace TimberWinR
|
|||||||
|
|
||||||
public void ProcessConfiguration(CancellationToken cancelToken, Configuration config)
|
public void ProcessConfiguration(CancellationToken cancelToken, Configuration config)
|
||||||
{
|
{
|
||||||
// Read the Configuration file
|
// Read the Configuration file
|
||||||
if (config != null)
|
if (config != null)
|
||||||
{
|
{
|
||||||
if (OnConfigurationProcessed != null)
|
if (OnConfigurationProcessed != null)
|
||||||
@@ -258,6 +254,15 @@ namespace TimberWinR
|
|||||||
output.Connect(elistner);
|
output.Connect(elistner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var stdin in config.Generators)
|
||||||
|
{
|
||||||
|
var elistner = new GeneratorInput(stdin, cancelToken);
|
||||||
|
Listeners.Add(elistner);
|
||||||
|
foreach (var output in Outputs)
|
||||||
|
output.Connect(elistner);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var computerName = System.Environment.MachineName + "." +
|
var computerName = System.Environment.MachineName + "." +
|
||||||
Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
|
Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
|
||||||
@"SYSTEM\CurrentControlSet\services\Tcpip\Parameters")
|
@"SYSTEM\CurrentControlSet\services\Tcpip\Parameters")
|
||||||
@@ -272,7 +277,7 @@ namespace TimberWinR
|
|||||||
new JObject(
|
new JObject(
|
||||||
new JProperty("version",
|
new JProperty("version",
|
||||||
Assembly.GetEntryAssembly().GetName().Version.ToString()),
|
Assembly.GetEntryAssembly().GetName().Version.ToString()),
|
||||||
//GetAssemblyByName("TimberWinR.ServiceHost").GetName().Version.ToString()),
|
//GetAssemblyByName("TimberWinR.ServiceHost").GetName().Version.ToString()),
|
||||||
new JProperty("host", computerName),
|
new JProperty("host", computerName),
|
||||||
new JProperty("output", output.Name),
|
new JProperty("output", output.Name),
|
||||||
new JProperty("initialized", DateTime.UtcNow)
|
new JProperty("initialized", DateTime.UtcNow)
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ namespace TimberWinR.Outputs
|
|||||||
private long _errorCount;
|
private long _errorCount;
|
||||||
private readonly int _maxQueueSize;
|
private readonly int _maxQueueSize;
|
||||||
private readonly bool _queueOverflowDiscardOldest;
|
private readonly bool _queueOverflowDiscardOldest;
|
||||||
|
private readonly bool _disablePing;
|
||||||
|
private readonly int _pingTimeout;
|
||||||
|
|
||||||
private Parser.ElasticsearchOutputParameters _parameters;
|
private Parser.ElasticsearchOutputParameters _parameters;
|
||||||
public bool Stop { get; set; }
|
public bool Stop { get; set; }
|
||||||
|
|
||||||
@@ -61,6 +64,11 @@ namespace TimberWinR.Outputs
|
|||||||
var settings = new ConnectionSettings(pool)
|
var settings = new ConnectionSettings(pool)
|
||||||
.ExposeRawResponse();
|
.ExposeRawResponse();
|
||||||
|
|
||||||
|
if (_disablePing)
|
||||||
|
settings.DisablePing();
|
||||||
|
else if (_pingTimeout != 0)
|
||||||
|
settings.SetPingTimeout(_pingTimeout);
|
||||||
|
|
||||||
var client = new ElasticClient(settings);
|
var client = new ElasticClient(settings);
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
@@ -84,7 +92,8 @@ namespace TimberWinR.Outputs
|
|||||||
_numThreads = parameters.NumThreads;
|
_numThreads = parameters.NumThreads;
|
||||||
_maxQueueSize = parameters.MaxQueueSize;
|
_maxQueueSize = parameters.MaxQueueSize;
|
||||||
_queueOverflowDiscardOldest = parameters.QueueOverflowDiscardOldest;
|
_queueOverflowDiscardOldest = parameters.QueueOverflowDiscardOldest;
|
||||||
|
_disablePing = !parameters.EnablePing;
|
||||||
|
_pingTimeout = parameters.PingTimeout;
|
||||||
|
|
||||||
for (int i = 0; i < parameters.NumThreads; i++)
|
for (int i = 0; i < parameters.NumThreads; i++)
|
||||||
{
|
{
|
||||||
@@ -99,7 +108,7 @@ namespace TimberWinR.Outputs
|
|||||||
new JObject(
|
new JObject(
|
||||||
new JProperty("host", string.Join(",", _hosts)),
|
new JProperty("host", string.Join(",", _hosts)),
|
||||||
new JProperty("errors", _errorCount),
|
new JProperty("errors", _errorCount),
|
||||||
new JProperty("sentMmessageCount", _sentMessages),
|
new JProperty("messages", _sentMessages),
|
||||||
new JProperty("queuedMessageCount", _jsonQueue.Count),
|
new JProperty("queuedMessageCount", _jsonQueue.Count),
|
||||||
new JProperty("port", _port),
|
new JProperty("port", _port),
|
||||||
new JProperty("flushSize", _flushSize),
|
new JProperty("flushSize", _flushSize),
|
||||||
@@ -123,6 +132,10 @@ namespace TimberWinR.Outputs
|
|||||||
// Force an inital flush
|
// Force an inital flush
|
||||||
DateTime lastFlushTime = DateTime.MinValue;
|
DateTime lastFlushTime = DateTime.MinValue;
|
||||||
|
|
||||||
|
LogManager.GetCurrentClassLogger()
|
||||||
|
.Info("{0}: Elasticsarch Output To {1} Ready", Thread.CurrentThread.ManagedThreadId, string.Join(",", _hosts));
|
||||||
|
|
||||||
|
|
||||||
using (var syncHandle = new ManualResetEventSlim())
|
using (var syncHandle = new ManualResetEventSlim())
|
||||||
{
|
{
|
||||||
// Execute the query
|
// Execute the query
|
||||||
@@ -203,6 +216,10 @@ namespace TimberWinR.Outputs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogManager.GetCurrentClassLogger()
|
||||||
|
.Info("{0}: Elasticsarch Output To {1} Terminated", Thread.CurrentThread.ManagedThreadId, string.Join(",", _hosts));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -151,11 +151,12 @@ namespace TimberWinR.Outputs
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
RedisClient client = new RedisClient(_redisHosts[_redisHostIndex], _port);
|
RedisClient client = new RedisClient(_redisHosts[_redisHostIndex], _port);
|
||||||
client.SendTimeout = _timeout;
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
LogManager.GetCurrentClassLogger().Error(ex);
|
||||||
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -263,12 +263,46 @@ namespace TimberWinR.Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class GeneratorParameters : IValidateSchema
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "type")]
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "codec")]
|
||||||
|
public CodecArguments CodecArguments { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "message")]
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "count")]
|
||||||
|
public int Count { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "rate")]
|
||||||
|
public int Rate { get; set; }
|
||||||
|
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeneratorParameters()
|
||||||
|
{
|
||||||
|
Count = 0; // Infinity messages
|
||||||
|
Rate = 10; // Milliseconds
|
||||||
|
Message = "Hello, world!";
|
||||||
|
CodecArguments = new CodecArguments();
|
||||||
|
CodecArguments.Type = CodecArguments.CodecType.plain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class CodecArguments
|
public class CodecArguments
|
||||||
{
|
{
|
||||||
public enum CodecType
|
public enum CodecType
|
||||||
{
|
{
|
||||||
singleline,
|
singleline,
|
||||||
multiline
|
multiline,
|
||||||
|
json,
|
||||||
|
plain
|
||||||
};
|
};
|
||||||
|
|
||||||
public enum WhatType
|
public enum WhatType
|
||||||
@@ -520,6 +554,10 @@ namespace TimberWinR.Parser
|
|||||||
public int MaxQueueSize { get; set; }
|
public int MaxQueueSize { get; set; }
|
||||||
[JsonProperty(PropertyName = "queue_overflow_discard_oldest")]
|
[JsonProperty(PropertyName = "queue_overflow_discard_oldest")]
|
||||||
public bool QueueOverflowDiscardOldest { get; set; }
|
public bool QueueOverflowDiscardOldest { get; set; }
|
||||||
|
[JsonProperty(PropertyName = "enable_ping")]
|
||||||
|
public bool EnablePing { get; set; }
|
||||||
|
[JsonProperty(PropertyName = "ping_timeout")]
|
||||||
|
public int PingTimeout { get; set; }
|
||||||
|
|
||||||
public ElasticsearchOutputParameters()
|
public ElasticsearchOutputParameters()
|
||||||
{
|
{
|
||||||
@@ -534,6 +572,8 @@ namespace TimberWinR.Parser
|
|||||||
Interval = 1000;
|
Interval = 1000;
|
||||||
QueueOverflowDiscardOldest = true;
|
QueueOverflowDiscardOldest = true;
|
||||||
MaxQueueSize = 50000;
|
MaxQueueSize = 50000;
|
||||||
|
EnablePing = false;
|
||||||
|
PingTimeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetIndexName(JObject json)
|
public string GetIndexName(JObject json)
|
||||||
@@ -605,7 +645,7 @@ namespace TimberWinR.Parser
|
|||||||
Index = "logstash";
|
Index = "logstash";
|
||||||
Host = new string[] { "localhost" };
|
Host = new string[] { "localhost" };
|
||||||
Timeout = 10000;
|
Timeout = 10000;
|
||||||
BatchCount = 50;
|
BatchCount = 200;
|
||||||
MaxBatchCount = BatchCount*10;
|
MaxBatchCount = BatchCount*10;
|
||||||
NumThreads = 1;
|
NumThreads = 1;
|
||||||
Interval = 5000;
|
Interval = 5000;
|
||||||
@@ -662,6 +702,9 @@ namespace TimberWinR.Parser
|
|||||||
|
|
||||||
[JsonProperty("Stdin")]
|
[JsonProperty("Stdin")]
|
||||||
public Stdin[] Stdins { get; set; }
|
public Stdin[] Stdins { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("Generator")]
|
||||||
|
public GeneratorParameters[] Generators { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class Grok : LogstashFilter, IValidateSchema
|
public partial class Grok : LogstashFilter, IValidateSchema
|
||||||
|
|||||||
@@ -3,8 +3,26 @@
|
|||||||
A Native Windows to Redis/Elasticsearch Logstash Agent which runs as a service.
|
A Native Windows to Redis/Elasticsearch Logstash Agent which runs as a service.
|
||||||
|
|
||||||
Version / Date
|
Version / Date
|
||||||
|
### 1.3.24.0 - 2015-04-29
|
||||||
|
1. Fixed potential bug in TailFiles when tailing log files which are partially flushed
|
||||||
|
to disk, it now will not process the line until the \r\n has been seen.
|
||||||
|
2. Added Generator input.
|
||||||
|
|
||||||
|
### 1.3.23.0 - 2015-04-23
|
||||||
|
1. Fixed bug with parsing a single json config file, rather than reading
|
||||||
|
JSON files from a directory.
|
||||||
|
2. Diabled elasticsearch outputter ping by default and parameterized the ping capability.
|
||||||
|
|
||||||
|
### 1.3.22.0 - 2015-04-14
|
||||||
|
1. Fixed minor bug with TailFiles and service re-starts not picking up
|
||||||
|
rolled files right away.
|
||||||
|
|
||||||
|
### 1.3.21.0 - 2015-04-13
|
||||||
|
1. Rolled Udp listener support to V4 only, too many issues with dual mode sockets
|
||||||
|
and hosts file. If we want to add this back, I will add a Udpv6 input.
|
||||||
|
|
||||||
|
### 1.3.20.0 - 2015-04-03
|
||||||
|
|
||||||
### 1.4.0.0 - 04/03/2015
|
|
||||||
1. A re-factoring of Logs and TailLogs to be more efficient and detect log rolling correctly,
|
1. A re-factoring of Logs and TailLogs to be more efficient and detect log rolling correctly,
|
||||||
this requires http://support.microsoft.com/en-us/kb/172190 which will be detected and
|
this requires http://support.microsoft.com/en-us/kb/172190 which will be detected and
|
||||||
set by TimberWinR, however, requires a reboot.
|
set by TimberWinR, however, requires a reboot.
|
||||||
@@ -12,11 +30,12 @@ Version / Date
|
|||||||
3. Created TimberWinR.TestGenerator for complete testing of TimberWinR
|
3. Created TimberWinR.TestGenerator for complete testing of TimberWinR
|
||||||
4. Fixed ipv4/ipv6 thread-safe issue with UdpInputListener which might lead to corrupted input data.
|
4. Fixed ipv4/ipv6 thread-safe issue with UdpInputListener which might lead to corrupted input data.
|
||||||
|
|
||||||
### 1.3.19.1 - 03/03/2015
|
### 1.3.19.1 - 2015-03-03
|
||||||
|
|
||||||
1. Added new Redis parameter _max\_batch\_count_ which increases the _batch\_count_ dynamically over time
|
1. Added new Redis parameter _max\_batch\_count_ which increases the _batch\_count_ dynamically over time
|
||||||
to handle input flooding. Default is _batch\_count_ * 10
|
to handle input flooding. Default is _batch\_count_ * 10
|
||||||
|
|
||||||
### 1.3.19.0 - 02/26/2015
|
### 1.3.19.0 - 2015-02-26
|
||||||
|
|
||||||
1. Added support for Multiline codecs for Stdin and Logs listeners, closes issue [#23](https://github.com/Cimpress-MCP/TimberWinR/issues/23)
|
1. Added support for Multiline codecs for Stdin and Logs listeners, closes issue [#23](https://github.com/Cimpress-MCP/TimberWinR/issues/23)
|
||||||
2. Added new TailFiles input type which uses a native implementation (more-efficient) than using LogParser's Log
|
2. Added new TailFiles input type which uses a native implementation (more-efficient) than using LogParser's Log
|
||||||
@@ -25,61 +44,60 @@ Version / Date
|
|||||||
5. Fixed bug when tailing non-existent log files which resulted in high cpu-usage.
|
5. Fixed bug when tailing non-existent log files which resulted in high cpu-usage.
|
||||||
6. Added feature to watch the configuration directory
|
6. Added feature to watch the configuration directory
|
||||||
|
|
||||||
### 1.3.18.0 - 12/22/2014
|
### 1.3.18.0 - 2014-12-22
|
||||||
|
|
||||||
1. Fixed bug introduced in 1.3.17.0 which changed the meaning of the delay for Elasticsearch, Redis and Stdout
|
1. Fixed bug introduced in 1.3.17.0 which changed the meaning of the delay for Elasticsearch, Redis and Stdout
|
||||||
intervals to be interpreted as seconds instead of milliseconds. 1.3.17.0 should not be used.
|
intervals to be interpreted as seconds instead of milliseconds. 1.3.17.0 should not be used.
|
||||||
2. Removed ability for installer to downgrade which was leading to leaving previous versions laying around (i.e. reverts 1.3.13.0 change)
|
2. Removed ability for installer to downgrade which was leading to leaving previous versions laying around (i.e. reverts 1.3.13.0 change)
|
||||||
|
|
||||||
### 1.3.17.0 - 12/19/2014
|
### 1.3.17.0 - 2014-12-19
|
||||||
|
|
||||||
1. Continued work improving shutdown time by using syncHandle.Wait instead of Thread.Sleep
|
1. Continued work improving shutdown time by using syncHandle.Wait instead of Thread.Sleep
|
||||||
|
|
||||||
### 1.3.16.0 - 12/19/2014
|
### 1.3.16.0 - 2014-12-19
|
||||||
|
|
||||||
1. Added logSource property to the Log input to facility the steering of log messages to different indices.
|
1. Added logSource property to the Log input to facility the steering of log messages to different indices.
|
||||||
|
|
||||||
### 1.3.15.0 - 12/12/2014
|
### 1.3.15.0 - 2014-12-12
|
||||||
|
|
||||||
1. Fixed bug whereby if the Udp or Tcp inputs receive an impropery formatted Json it caused the thread to terminate, and ignore
|
1. Fixed bug whereby if the Udp or Tcp inputs receive an impropery formatted Json it caused the thread to terminate, and ignore
|
||||||
future messages.
|
future messages.
|
||||||
|
|
||||||
### 1.3.14.0 - 12/11/2014
|
### 1.3.14.0 - 2014-12-11
|
||||||
|
|
||||||
1. Fixed bug with the Grok filter to match properly the value of the Text field against non-blank entries.
|
1. Fixed bug with the Grok filter to match properly the value of the Text field against non-blank entries.
|
||||||
|
|
||||||
### 1.3.13.0 - 12/02/2014
|
### 1.3.13.0 - 2014-12-02
|
||||||
|
|
||||||
1. Fixed MSI installer to allow downgrades.
|
1. Fixed MSI installer to allow downgrades.
|
||||||
|
|
||||||
### 1.3.12.0 - 11/25/2014
|
### 1.3.12.0 - 2014-11-25
|
||||||
|
|
||||||
1. Fixed all remaining memory leaks due to the COM Weak Surrogate which requires an explicit GC.Collect
|
1. Fixed all remaining memory leaks due to the COM Weak Surrogate which requires an explicit GC.Collect
|
||||||
|
|
||||||
### 1.3.11.0 - 11/21/2014
|
### 1.3.11.0 - 2014-11-21
|
||||||
|
|
||||||
1. Re-worked WindowsEvent listener to enable shutting down in a quicker fashion.
|
1. Re-worked WindowsEvent listener to enable shutting down in a quicker fashion.
|
||||||
|
|
||||||
### 1.3.10.0 - 11/18/2014
|
### 1.3.10.0 - 2014-11-18
|
||||||
|
|
||||||
1. Refactored Conditions handler to use non-leaking evaluator.
|
1. Refactored Conditions handler to use non-leaking evaluator.
|
||||||
|
|
||||||
### 1.3.9.0 - 11/11/2014
|
### 1.3.9.0 - 2014-11-11
|
||||||
|
|
||||||
1. Merged in pull request #9
|
1. Merged in pull request #9
|
||||||
2. Updated chocolately uninstall to preserve GUID
|
2. Updated chocolately uninstall to preserve GUID
|
||||||
|
|
||||||
### 1.3.8.0 - 11/06/2014
|
### 1.3.8.0 - 2014-11-06
|
||||||
|
|
||||||
1. Added interval parameter to WindowsEvent input listener
|
1. Added interval parameter to WindowsEvent input listener
|
||||||
2. Increased default value for interval to 60 seconds for polling WindowsEvents
|
2. Increased default value for interval to 60 seconds for polling WindowsEvents
|
||||||
|
|
||||||
### 1.3.7.0 - 10/21/2014
|
### 1.3.7.0 - 2014-10-21
|
||||||
|
|
||||||
1. Added additional information for diagnostics port
|
1. Added additional information for diagnostics port
|
||||||
2. Completed minor handling of Log rolling detection
|
2. Completed minor handling of Log rolling detection
|
||||||
|
|
||||||
### 1.3.6.0 - 10/16/2014
|
### 1.3.6.0 - 2014-10-16
|
||||||
|
|
||||||
1. Handle rolling of logs whereby the logfile remains the same, but the content resets back to 0 bytes.
|
1. Handle rolling of logs whereby the logfile remains the same, but the content resets back to 0 bytes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,9 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Codecs\JsonCodec.cs" />
|
||||||
<Compile Include="Codecs\Multiline.cs" />
|
<Compile Include="Codecs\Multiline.cs" />
|
||||||
|
<Compile Include="Codecs\PlainCodec.cs" />
|
||||||
<Compile Include="Configuration.cs" />
|
<Compile Include="Configuration.cs" />
|
||||||
<Compile Include="ConfigurationErrors.cs" />
|
<Compile Include="ConfigurationErrors.cs" />
|
||||||
<Compile Include="Diagnostics\Diagnostics.cs" />
|
<Compile Include="Diagnostics\Diagnostics.cs" />
|
||||||
@@ -94,6 +96,7 @@
|
|||||||
<Compile Include="Filters\MutateFilter.cs" />
|
<Compile Include="Filters\MutateFilter.cs" />
|
||||||
<Compile Include="ICodec.cs" />
|
<Compile Include="ICodec.cs" />
|
||||||
<Compile Include="Inputs\FieldDefinitions.cs" />
|
<Compile Include="Inputs\FieldDefinitions.cs" />
|
||||||
|
<Compile Include="Inputs\GeneratorInput.cs" />
|
||||||
<Compile Include="Inputs\IISW3CRowReader.cs" />
|
<Compile Include="Inputs\IISW3CRowReader.cs" />
|
||||||
<Compile Include="Inputs\LogsFileDatabase.cs" />
|
<Compile Include="Inputs\LogsFileDatabase.cs" />
|
||||||
<Compile Include="Inputs\TailFileListener.cs" />
|
<Compile Include="Inputs\TailFileListener.cs" />
|
||||||
@@ -137,6 +140,7 @@
|
|||||||
<None Include="mdocs\DateFilter.md" />
|
<None Include="mdocs\DateFilter.md" />
|
||||||
<None Include="mdocs\Filters.md" />
|
<None Include="mdocs\Filters.md" />
|
||||||
<None Include="mdocs\GeoIPFilter.md" />
|
<None Include="mdocs\GeoIPFilter.md" />
|
||||||
|
<None Include="mdocs\Generator.md" />
|
||||||
<None Include="mdocs\TailFiles.md" />
|
<None Include="mdocs\TailFiles.md" />
|
||||||
<None Include="mdocs\UdpInput.md" />
|
<None Include="mdocs\UdpInput.md" />
|
||||||
<None Include="mdocs\W3CInput.md" />
|
<None Include="mdocs\W3CInput.md" />
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ The following parameters are allowed when configuring the Redis output.
|
|||||||
| *port* | integer | Elasticsearch port number | This port must be open | 9200 |
|
| *port* | integer | Elasticsearch port number | This port must be open | 9200 |
|
||||||
| *queue_overflow_discard_oldest* | bool | If true, discard oldest messages when max_queue_size reached otherwise discard newest | | true |
|
| *queue_overflow_discard_oldest* | bool | If true, discard oldest messages when max_queue_size reached otherwise discard newest | | true |
|
||||||
| *threads* | [string] | Number of Threads | Number of worker threads processing messages | 1 |
|
| *threads* | [string] | Number of Threads | Number of worker threads processing messages | 1 |
|
||||||
|
| *enable_ping* | bool | If true, pings the server to test for keep alive | | false |
|
||||||
|
| *ping_timeout* | integer | Default ping timeout when enable_ping is true | milliseconds | 200 |
|
||||||
|
|
||||||
### Index parameter
|
### Index parameter
|
||||||
If you want to output your data everyday to a new index, use following index format: "index-%{yyyy.MM.dd}". Here date format could be any forwat which you need.
|
If you want to output your data everyday to a new index, use following index format: "index-%{yyyy.MM.dd}". Here date format could be any forwat which you need.
|
||||||
|
|||||||
37
TimberWinR/mdocs/Generator.md
Normal file
37
TimberWinR/mdocs/Generator.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Input: Generator
|
||||||
|
|
||||||
|
The Generator input can be used to Generate log files for test purposes.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
The following parameters are allowed when configuring the test log Generator.
|
||||||
|
|
||||||
|
| Parameter | Type | Description | Details | Default |
|
||||||
|
| :---------------- |:---------------| :----------------------------------------------------------------------- | :--------------------------- | :-- |
|
||||||
|
| *type* | string |Message type | | Win32-InputGen |
|
||||||
|
| *message* | string |Message format to send | | Hello, World! |
|
||||||
|
| *count* | integer |Number of messages to generate | 0 - Infinite, otherwise that number | 0 |
|
||||||
|
| *rate* | integer |Sleep time between generated messages | Milliseconds | 10 |
|
||||||
|
| [codec](https://github.com/Cimpress-MCP/TimberWinR/blob/master/TimberWinR/mdocs/Codec.md) | object | Codec to use |
|
||||||
|
|
||||||
|
Example: Generate 100000 "Hello Win32-InputGen" messages
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"TimberWinR": {
|
||||||
|
"Inputs": {
|
||||||
|
"Generator": [
|
||||||
|
{
|
||||||
|
"message": "Hello %{type}",
|
||||||
|
"count": 100000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## Fields
|
||||||
|
After a successful parse of the generated line, the following fields are added:
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| ---- |:-----| :-----------|
|
||||||
|
| Message | STRING | Text line content |
|
||||||
@@ -8,7 +8,7 @@ The following parameters are allowed when configuring the Redis output.
|
|||||||
| Parameter | Type | Description | Details | Default |
|
| Parameter | Type | Description | Details | Default |
|
||||||
| :-------------|:---------|:------------------------------------------------------------| :--------------------------- | :-- |
|
| :-------------|:---------|:------------------------------------------------------------| :--------------------------- | :-- |
|
||||||
| *threads* | string | Location of log files(s) to monitor | Number of worker theads to send messages | 1 |
|
| *threads* | string | Location of log files(s) to monitor | Number of worker theads to send messages | 1 |
|
||||||
| *batch_count* | integer | Sent as a single message | Number of messages to aggregate | 10 |
|
| *batch_count* | integer | Sent as a single message | Number of messages to aggregate | 200 |
|
||||||
| *max_batch_count* | integer | Dynamically adjusted count maximum | Increases over time | batch_count*10 |
|
| *max_batch_count* | integer | Dynamically adjusted count maximum | Increases over time | batch_count*10 |
|
||||||
| *interval* | integer | Interval in milliseconds to sleep during batch sends | Interval | 5000 |
|
| *interval* | integer | Interval in milliseconds to sleep during batch sends | Interval | 5000 |
|
||||||
| *index* | string | The name of the redis list | logstash index name | logstash |
|
| *index* | string | The name of the redis list | logstash index name | logstash |
|
||||||
|
|||||||
@@ -49,6 +49,8 @@
|
|||||||
<File Id="TimberWinR.ServiceHost.exe.config" Source="$(var.TimberWinR.ServiceHost.TargetDir)\TimberWinR.ServiceHost.exe.config" />
|
<File Id="TimberWinR.ServiceHost.exe.config" Source="$(var.TimberWinR.ServiceHost.TargetDir)\TimberWinR.ServiceHost.exe.config" />
|
||||||
<File Id="Interop.MSUtil.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Interop.MSUtil.dll" />
|
<File Id="Interop.MSUtil.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Interop.MSUtil.dll" />
|
||||||
<File Id="csredis.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\csredis.dll" />
|
<File Id="csredis.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\csredis.dll" />
|
||||||
|
<File Id="Nest.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Nest.dll" />
|
||||||
|
<File Id="Elasticsearch.Net.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Elasticsearch.Net.dll" />
|
||||||
<File Id="default.json" Source="$(var.TimberWinR.ServiceHost.TargetDir)\default.json" />
|
<File Id="default.json" Source="$(var.TimberWinR.ServiceHost.TargetDir)\default.json" />
|
||||||
<File Id="Newtonsoft.Json.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Newtonsoft.Json.dll" />
|
<File Id="Newtonsoft.Json.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Newtonsoft.Json.dll" />
|
||||||
<File Id="Nlog.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Nlog.dll" />
|
<File Id="Nlog.dll" Source="$(var.TimberWinR.ServiceHost.TargetDir)\Nlog.dll" />
|
||||||
|
|||||||
@@ -98,10 +98,12 @@
|
|||||||
</CreateProperty>
|
</CreateProperty>
|
||||||
</Target>
|
</Target>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>$(SolutionDir)\TimberWinR.ExtractID\$(OutDir)\TimberWinR.ExtractID.exe $(TargetDir) $(SolutionDir)chocolateyUninstall.ps1.guid $(SolutionDir)chocolateyUninstall.ps1.template</PostBuildEvent>
|
<PreBuildEvent>mkdir $(SolutionDir)tools
|
||||||
|
cmd.exe /c copy $(SolutionDir)chocolateyUninstall.ps1.template.orig $(SolutionDir)chocolateyUninstall.ps1.template</PreBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PreBuildEvent>cmd.exe /c copy $(SolutionDir)chocolateyUninstall.ps1.template.orig $(SolutionDir)chocolateyUninstall.ps1.template</PreBuildEvent>
|
<PostBuildEvent>$(SolutionDir)\TimberWinR.ExtractID\$(OutDir)\TimberWinR.ExtractID.exe $(TargetDir) $(SolutionDir)chocolateyUninstall.ps1.guid $(SolutionDir)chocolateyUninstall.ps1.template
|
||||||
|
cmd.exe /c copy "$(TargetDir)%2a.msi" "$(SolutionDir)tools"</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!--
|
<!--
|
||||||
To modify your build process, add your task inside one of the targets below and uncomment it.
|
To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
$packageName = 'TimberWinR-${version}'
|
$packageName = 'TimberWinR-${version}'
|
||||||
$installerType = 'msi'
|
$fileType = 'msi'
|
||||||
$url = 'http://www.ericfontana.com/TimberWinR/TimberWinR-${version}.0.msi'
|
|
||||||
$silentArgs = '/quiet'
|
$silentArgs = '/quiet'
|
||||||
$validExitCodes = @(0)
|
$scriptPath = $(Split-Path $MyInvocation.MyCommand.Path)
|
||||||
Install-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "$url" "$url64" -validExitCodes $validExitCodes
|
$fileFullPath = Join-Path $scriptPath 'TimberWinR-${version}.0.msi'
|
||||||
|
try {
|
||||||
|
Install-ChocolateyInstallPackage $packageName $fileType $silentArgs $fileFullPath
|
||||||
|
} catch {
|
||||||
|
Write-ChocolateyFailure $packageName $($_.Exception.Message)
|
||||||
|
throw
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
$packageName = 'TimberWinR-${version}' # arbitrary name for the package, used in messages
|
$packageName = 'TimberWinR-${version}' # arbitrary name for the package, used in messages
|
||||||
$installerType = 'msi' #only one of these: exe, msi, msu
|
$installerType = 'msi' #only one of these: exe, msi, msu
|
||||||
$url = 'http://www.ericfontana.com/TimberWinR/TimberWinR-${version}.0.msi' # download url
|
$scriptPath = $(Split-Path $MyInvocation.MyCommand.Path)
|
||||||
|
$fileFullPath = Join-Path $scriptPath 'TimberWinR-${version}.0.msi'
|
||||||
$silentArgs = '${PROJECTGUID} /quiet'
|
$silentArgs = '${PROJECTGUID} /quiet'
|
||||||
$validExitCodes = @(0) #please insert other valid exit codes here, exit codes for ms http://msdn.microsoft.com/en-us/library/aa368542(VS.85).aspx
|
$validExitCodes = @(0) #please insert other valid exit codes here, exit codes for ms http://msdn.microsoft.com/en-us/library/aa368542(VS.85).aspx
|
||||||
UnInstall-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "$url" -validExitCodes $validExitCodes
|
UnInstall-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "fileFullPath" -validExitCodes $validExitCodes
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
$packageName = 'TimberWinR-${version}' # arbitrary name for the package, used in messages
|
$packageName = 'TimberWinR-${version}' # arbitrary name for the package, used in messages
|
||||||
$installerType = 'msi' #only one of these: exe, msi, msu
|
$installerType = 'msi' #only one of these: exe, msi, msu
|
||||||
$url = 'http://www.ericfontana.com/TimberWinR/TimberWinR-${version}.0.msi' # download url
|
$scriptPath = $(Split-Path $MyInvocation.MyCommand.Path)
|
||||||
$silentArgs = '{D066A694-B9F7-4B35-BB7D-D34CB88CA89F} /quiet'
|
$fileFullPath = Join-Path $scriptPath 'TimberWinR-${version}.0.msi'
|
||||||
|
$silentArgs = '{CC4DF908-07C4-4BD8-A9FA-6E6AC315E30B} /quiet'
|
||||||
$validExitCodes = @(0) #please insert other valid exit codes here, exit codes for ms http://msdn.microsoft.com/en-us/library/aa368542(VS.85).aspx
|
$validExitCodes = @(0) #please insert other valid exit codes here, exit codes for ms http://msdn.microsoft.com/en-us/library/aa368542(VS.85).aspx
|
||||||
UnInstall-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "$url" -validExitCodes $validExitCodes
|
UnInstall-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "fileFullPath" -validExitCodes $validExitCodes
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
$packageName = 'TimberWinR-${version}' # arbitrary name for the package, used in messages
|
$packageName = 'TimberWinR-${version}' # arbitrary name for the package, used in messages
|
||||||
$installerType = 'msi' #only one of these: exe, msi, msu
|
$installerType = 'msi' #only one of these: exe, msi, msu
|
||||||
$url = 'http://www.ericfontana.com/TimberWinR/TimberWinR-${version}.0.msi' # download url
|
$scriptPath = $(Split-Path $MyInvocation.MyCommand.Path)
|
||||||
|
$fileFullPath = Join-Path $scriptPath 'TimberWinR-${version}.0.msi'
|
||||||
$silentArgs = '${PROJECTGUID} /quiet'
|
$silentArgs = '${PROJECTGUID} /quiet'
|
||||||
$validExitCodes = @(0) #please insert other valid exit codes here, exit codes for ms http://msdn.microsoft.com/en-us/library/aa368542(VS.85).aspx
|
$validExitCodes = @(0) #please insert other valid exit codes here, exit codes for ms http://msdn.microsoft.com/en-us/library/aa368542(VS.85).aspx
|
||||||
UnInstall-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "$url" -validExitCodes $validExitCodes
|
UnInstall-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "fileFullPath" -validExitCodes $validExitCodes
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user