Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d7d45d3
Broad strokes of a conversion - still needs query building, property …
MattMofDoom Oct 10, 2021
51acefb
TimedEventBag has proven useful so assume we still want it, but it ne…
MattMofDoom Oct 10, 2021
9c5baa6
Add parsing event XML and exposing as structured properties, logging …
MattMofDoom Oct 12, 2021
c2b713d
Reinstate & enhance remote log capability
MattMofDoom Oct 13, 2021
43d09c7
Code cleanup, add StoreLastEntry option
MattMofDoom Oct 13, 2021
e66db3c
Rename Summary and Description to avoid possible conflict with downst…
MattMofDoom Oct 13, 2021
526159b
Don't copy app.config - no longer required.
MattMofDoom Oct 14, 2021
b7064b0
Merge Seq.Client.WindowsLogins functionality
MattMofDoom Oct 18, 2021
1e05974
Version bump
MattMofDoom Oct 18, 2021
3971de0
Correct MachineName reference
MattMofDoom Dec 5, 2021
f4746de
Add icon
MattMofDoom Dec 5, 2021
85ab1c6
Correct Guid detection for Windows login functionality, reflect the G…
MattMofDoom Dec 5, 2021
c7b12ff
Periodically save bookmarks on heartbeat
MattMofDoom Dec 6, 2021
0f5493e
Load/Save listener config is now a debug log
MattMofDoom Dec 6, 2021
d3168bf
Dependency update, code cleanup
MattMofDoom Jan 24, 2022
2529ddd
Update Lurgle.Logging
MattMofDoom Feb 7, 2022
7260bc2
Update Lurgle.Logging to add Splunk support
MattMofDoom Feb 23, 2022
7832593
Add detection and recovery for no logs being seen for a configurable …
MattMofDoom Feb 27, 2022
6c5457b
HeartbeatsBeforeReset wasn't properly evaluating all events that wer…
MattMofDoom Mar 25, 2022
95a7f3f
Updated dependencies
MattMofDoom Aug 14, 2022
e5b1d38
Version bump
MattMofDoom Aug 14, 2022
2648209
correct copy/paste error in config: LogToFile
co-xpts Feb 24, 2023
a86618d
change Target .NET Framework to 4.7.2
co-xpts Feb 24, 2023
197bf1d
handle multiple xml node keys with same key value
co-xpts Feb 24, 2023
60b5838
handle null values of message in GetMessage
co-xpts Feb 24, 2023
658bf04
bump version
co-xpts Feb 28, 2023
c68f942
avoid keywordsdisplaynames exception
co-xpts Feb 28, 2023
b7aeb64
make pdb portable
co-xpts Feb 28, 2023
9ef8517
handle EventLogProviderDisabledException
co-xpts Feb 28, 2023
16a9fbc
handle exception for LevelDisplayName property
co-xpts Mar 1, 2023
b511450
improved handling of multi valued properties
co-xpts Mar 1, 2023
ad1e4b9
Merge pull request #1 from oleschri/dev-oleschri
MattMofDoom Jul 1, 2023
86906b4
Update dependencies
MattMofDoom Jul 1, 2023
587fae4
Update Lurgle.Logging
MattMofDoom Jul 4, 2023
5f53e9b
Version bump
MattMofDoom Jul 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Seq.Client.EventLog.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=appname/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=guids/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Logons/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TESTPC/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=uninstallation/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
39 changes: 20 additions & 19 deletions src/Seq.Client.EventLog/App.config
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>

<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Seq.Client.EventLog.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<applicationSettings>
<Seq.Client.EventLog.Properties.Settings>
<setting name="SeqUri" serializeAs="String">
<value>http://localhost:5341</value>
</setting>
<setting name="ApiKey" serializeAs="String">
<value />
</setting>
</Seq.Client.EventLog.Properties.Settings>
</applicationSettings>
<appSettings>
<!-- App name for logging purposes-->
<add key="AppName" value="Seq.Client.EventLog" />
<!-- Seq URL -->
<add key="LogSeqServer" value="https://Seq.domain.com" />
<!-- If empty, no API key will be used -->
<add key="LogSeqApiKey" value="" />
<!-- Log to file - defaults to true but can be disabled-->
<add key="LogToFile" value="true" />
<!-- Log folder for file logs ... if not specified, will attempt to log in a Logs folder under the exe location-->
<add key="LogFolder" value="" />
<!-- Heartbeat log entry interval in seconds, 0 disables heartbeat, default 600, maximum 86399 -->
<add key="HeartbeatInterval" value="600" />
<!-- If the Event Log service doesn't see any new log activity for the below number of heartbeats, it can restart the listener to recover-->
<add key="HeartbeatsBeforeReset" value="2"/>
<!-- Set IsDebug to true for additional heartbeat logging -->
<add key="IsDebug" value="false" />
</appSettings>
</configuration>
109 changes: 109 additions & 0 deletions src/Seq.Client.EventLog/Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System;
using System.Configuration;
using System.IO;
using System.Reflection;

namespace Seq.Client.EventLog
{
public static class Config
{
static Config()
{
AppName = ConfigurationManager.AppSettings["AppName"];
SeqServer = ConfigurationManager.AppSettings["LogSeqServer"];
SeqApiKey = ConfigurationManager.AppSettings["LogSeqApiKey"];
LogToFile = GetBool(ConfigurationManager.AppSettings["LogToFile"], true);
LogFolder = ConfigurationManager.AppSettings["LogFolder"];
HeartbeatInterval = GetInt(ConfigurationManager.AppSettings["HeartbeatInterval"]);
HeartbeatsBeforeReset = GetInt(ConfigurationManager.AppSettings["HeartbeatsBeforeReset"]);

//Minimum is 0 (disabled)
if (HeartbeatInterval < 0)
HeartbeatInterval = 600;
//Maximum is 3600
if (HeartbeatInterval > 3600)
HeartbeatInterval = 3600;

if (HeartbeatsBeforeReset < 0)
HeartbeatsBeforeReset = 0;

IsDebug = GetBool(ConfigurationManager.AppSettings["IsDebug"]);

var isSuccess = true;
try
{
if (string.IsNullOrEmpty(AppName))
AppName = Assembly.GetEntryAssembly()?.GetName().Name;

AppVersion = Assembly.GetEntryAssembly()?.GetName().Version.ToString();
if (string.IsNullOrEmpty(LogFolder))
LogFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
}
catch
{
isSuccess = false;
}

if (isSuccess) return;
try
{
if (string.IsNullOrEmpty(AppName))
AppName = Assembly.GetExecutingAssembly().GetName().Name;

AppVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
if (string.IsNullOrEmpty(LogFolder))
LogFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
}
catch
{
//We surrender ...
AppVersion = string.Empty;
}
}

public static string AppName { get; }
public static string AppVersion { get; }
public static string SeqServer { get; }
public static string SeqApiKey { get; }
public static bool LogToFile { get; }
public static string LogFolder { get; }
public static int HeartbeatInterval { get; }
public static bool IsDebug { get; }
public static int HeartbeatsBeforeReset { get; }

/// <summary>
/// Convert the supplied <see cref="object" /> to an <see cref="int" />
/// <para />
/// This will filter out nulls that could otherwise cause exceptions
/// </summary>
/// <param name="sourceObject">An object that can be converted to an int</param>
/// <returns></returns>
public static int GetInt(object sourceObject)
{
var sourceString = string.Empty;

if (!Convert.IsDBNull(sourceObject)) sourceString = (string) sourceObject;

if (int.TryParse(sourceString, out var destInt)) return destInt;

return -1;
}

/// <summary>
/// Convert the supplied <see cref="object" /> to a <see cref="bool" />
/// <para />
/// This will filter out nulls that could otherwise cause exceptions
/// </summary>
/// <param name="sourceObject">An object that can be converted to a bool</param>
/// <param name="trueIfEmpty">Return true if the object is empty</param>
/// <returns></returns>
private static bool GetBool(object sourceObject, bool trueIfEmpty = false)
{
var sourceString = string.Empty;

if (!Convert.IsDBNull(sourceObject)) sourceString = (string) sourceObject;

return bool.TryParse(sourceString, out var destBool) ? destBool : trueIfEmpty;
}
}
}
Binary file added src/Seq.Client.EventLog/EventLog.ico
Binary file not shown.
Binary file added src/Seq.Client.EventLog/EventLog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 11 additions & 60 deletions src/Seq.Client.EventLog/EventLogClient.cs
Original file line number Diff line number Diff line change
@@ -1,68 +1,19 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Newtonsoft.Json;
using Serilog;

namespace Seq.Client.EventLog
namespace Seq.Client.EventLog
{
class EventLogClient
internal class EventLogClient
{
private List<EventLogListener> _eventLogListeners;

public void Start(string configuration = null)
{
LoadListeners(configuration);
ValidateListeners();
StartListeners();
}

public void Stop()
{
StopListeners();
}

private void LoadListeners(string configuration)
{
string filePath;
if (configuration == null)
{
var directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
filePath = Path.Combine(directory ?? ".", "EventLogListeners.json");
}
else
{
filePath = configuration;
}

Log.Information("Loading listener configuration from {ConfigurationFilePath}", filePath);
var file = File.ReadAllText(filePath);

_eventLogListeners = JsonConvert.DeserializeObject<List<EventLogListener>>(file);
}

private void ValidateListeners()
{
foreach (var listener in _eventLogListeners)
{
listener.Validate();
}
}

private void StartListeners()
public static void Start(bool isInteractive = false, string configuration = null)
{
foreach (var listener in _eventLogListeners)
{
listener.Start();
}
ServiceManager.LoadListeners(configuration);
ServiceManager.ValidateListeners();
ServiceManager.StartListeners(isInteractive);
}

private void StopListeners()
public static void Stop()
{
foreach (var listener in _eventLogListeners)
{
listener.Stop();
}
ServiceManager.StopListeners();
if (ServiceManager.SaveBookmarks)
ServiceManager.SaveListeners();
}
}
}
}
Loading