diff --git a/Fantail.SyslogServer/Fantail.SyslogServer.csproj b/Fantail.SyslogServer/Fantail.SyslogServer.csproj
new file mode 100644
index 0000000..e15bee7
--- /dev/null
+++ b/Fantail.SyslogServer/Fantail.SyslogServer.csproj
@@ -0,0 +1,71 @@
+
+
+ Debug
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {2276C92F-8444-47B4-B3C9-AF507C41BB98}
+ WinExe
+ Properties
+ Fantail.SyslogServer
+ Fantail.SyslogServer
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+ Component
+
+
+ ProjectInstaller.cs
+
+
+
+
+ Component
+
+
+ SyslogService.cs
+
+
+
+
+
+
+ Designer
+ ProjectInstaller.cs
+
+
+
+
+
\ No newline at end of file
diff --git a/Fantail.SyslogServer/LICENSE.TXT b/Fantail.SyslogServer/LICENSE.TXT
new file mode 100644
index 0000000..c40d87d
--- /dev/null
+++ b/Fantail.SyslogServer/LICENSE.TXT
@@ -0,0 +1,34 @@
+
+ Fantail.SyslogServer
+ ====================
+
+ Fantail Technology Ltd ( www.fantail.net.nz )
+
+ Designed by Chris Guthrey & David Husselmann
+ Developed by David Husselmann for Fantail Technology Ltd
+
+ chris@fantail.net.nz
+ david@tamix.com
+
+ Copyright (c) 2007, Fantail Technology Ltd
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+
diff --git a/Fantail.SyslogServer/MemoryBuffer.cs b/Fantail.SyslogServer/MemoryBuffer.cs
new file mode 100644
index 0000000..3b8142d
--- /dev/null
+++ b/Fantail.SyslogServer/MemoryBuffer.cs
@@ -0,0 +1,97 @@
+///
+/// Fantail.SyslogServer
+/// ====================
+///
+/// Fantail Technology Ltd ( www.fantail.net.nz )
+///
+/// Designed by Chris Guthrey & David Husselmann
+/// Developed by David Husselmann for Fantail Technology Ltd
+///
+/// chris@fantail.net.nz
+/// david@tamix.com
+///
+/// Copyright (c) 2007, Fantail Technology Ltd
+///
+/// All rights reserved.
+///
+/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+///
+/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+///
+/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+///
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Fantail.Libraries.Syslog;
+using System.Timers;
+using System.Threading;
+
+namespace Fantail.Libraries.Syslog {
+ ///
+ /// This class takes care of buffering incoming syslog messages in memory
+ /// and submitting them to the SqlUpdater in batches, rather than keeping the database
+ /// occupied with drip-fed messages.
+ ///
+ public class MemoryBuffer {
+ private List buffer = new List();
+ private TimeSpan commitInterval;
+ private System.Timers.Timer timer = new System.Timers.Timer();
+ private SqlUpdater sqlUpdater;
+ private Mutex bufferLock = new Mutex(false);
+
+ ///
+ /// Creates a new instance of the MemoryBuffer class.
+ ///
+ /// Specifies the interval at which message batches should be committed to the database.
+ /// The pre-initialised SqlUpdater to which messages should be submitted.
+ public MemoryBuffer(TimeSpan commitInterval, SqlUpdater sqlUpdater) {
+ this.commitInterval = commitInterval;
+ this.timer.Interval = commitInterval.TotalMilliseconds;
+ this.sqlUpdater = sqlUpdater;
+ this.timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
+ this.timer.Enabled = true;
+ }
+
+ void timer_Elapsed(object sender, ElapsedEventArgs e) {
+ Flush();
+ }
+
+ ///
+ /// Posts a new message to the buffer, for committing to the database when the internal timer elapses.
+ ///
+ /// The syslog message to be submitted.
+ public void PushMessage(SyslogMessage sm) {
+ bufferLock.WaitOne();
+ buffer.Add(sm);
+ bufferLock.ReleaseMutex();
+ }
+
+ ///
+ /// Flushes the buffer. This method can be called by the user to ensure that final in-memory entries are
+ /// written to the database.
+ ///
+ public void Flush() {
+ bufferLock.WaitOne();
+ try {
+ if (sqlUpdater.SaveMessage(buffer)) {
+ buffer.Clear();
+ }
+ } finally {
+ bufferLock.ReleaseMutex();
+ }
+ }
+ }
+}
diff --git a/Fantail.SyslogServer/Program.cs b/Fantail.SyslogServer/Program.cs
new file mode 100644
index 0000000..9657eab
--- /dev/null
+++ b/Fantail.SyslogServer/Program.cs
@@ -0,0 +1,49 @@
+///
+/// Fantail.SyslogServer
+/// ====================
+///
+/// Fantail Technology Ltd ( www.fantail.net.nz )
+///
+/// Designed by Chris Guthrey & David Husselmann
+/// Developed by David Husselmann for Fantail Technology Ltd
+///
+/// chris@fantail.net.nz
+/// david@tamix.com
+///
+/// Copyright (c) 2007, Fantail Technology Ltd
+///
+/// All rights reserved.
+///
+/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+///
+/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+///
+/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+///
+using System.Collections.Generic;
+using System.ServiceProcess;
+using System.Text;
+
+namespace Fantail.SyslogServer {
+ static class Program {
+ static void Main() {
+ ServiceBase[] ServicesToRun;
+
+ ServicesToRun = new ServiceBase[] { new SyslogService() };
+
+ ServiceBase.Run(ServicesToRun);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Fantail.SyslogServer/ProjectInstaller.Designer.cs b/Fantail.SyslogServer/ProjectInstaller.Designer.cs
new file mode 100644
index 0000000..4b800b0
--- /dev/null
+++ b/Fantail.SyslogServer/ProjectInstaller.Designer.cs
@@ -0,0 +1,91 @@
+///
+/// Fantail.SyslogServer
+/// ====================
+///
+/// Fantail Technology Ltd ( www.fantail.net.nz )
+///
+/// Designed by Chris Guthrey & David Husselmann
+/// Developed by David Husselmann for Fantail Technology Ltd
+///
+/// chris@fantail.net.nz
+/// david@tamix.com
+///
+/// Copyright (c) 2007, Fantail Technology Ltd
+///
+/// All rights reserved.
+///
+/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+///
+/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+///
+/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+///
+namespace Fantail.SyslogServer
+{
+ partial class ProjectInstaller {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if (disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent() {
+ this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
+ this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
+ //
+ // serviceProcessInstaller1
+ //
+ this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalService;
+ this.serviceProcessInstaller1.Password = null;
+ this.serviceProcessInstaller1.Username = null;
+ //
+ // serviceInstaller1
+ //
+ this.serviceInstaller1.Description = "SYSLOG server which saves log entries to an SQL database.";
+ this.serviceInstaller1.DisplayName = "Fantail Syslog Server";
+ this.serviceInstaller1.ServiceName = "Fantail.SyslogServer";
+ this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
+ this.serviceInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceInstaller1_AfterInstall);
+ //
+ // ProjectInstaller
+ //
+ this.Installers.AddRange(new System.Configuration.Install.Installer[] {
+ this.serviceProcessInstaller1,
+ this.serviceInstaller1});
+
+ }
+
+ #endregion
+
+ private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
+ private System.ServiceProcess.ServiceInstaller serviceInstaller1;
+ }
+}
\ No newline at end of file
diff --git a/Fantail.SyslogServer/ProjectInstaller.cs b/Fantail.SyslogServer/ProjectInstaller.cs
new file mode 100644
index 0000000..5c4194f
--- /dev/null
+++ b/Fantail.SyslogServer/ProjectInstaller.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Configuration.Install;
+
+namespace Fantail.SyslogServer {
+ [RunInstaller(true)]
+ public partial class ProjectInstaller : Installer {
+ public ProjectInstaller() {
+ InitializeComponent();
+ }
+
+ private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e) {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Fantail.SyslogServer/ProjectInstaller.resx b/Fantail.SyslogServer/ProjectInstaller.resx
new file mode 100644
index 0000000..5860189
--- /dev/null
+++ b/Fantail.SyslogServer/ProjectInstaller.resx
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 54
+
+
+ 187, 17
+
+
+ False
+
+
\ No newline at end of file
diff --git a/Fantail.SyslogServer/Properties/AssemblyInfo.cs b/Fantail.SyslogServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2078b9e
--- /dev/null
+++ b/Fantail.SyslogServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,67 @@
+///
+/// Fantail.SyslogServer
+/// ====================
+///
+/// Fantail Technology Ltd ( www.fantail.net.nz )
+///
+/// Designed by Chris Guthrey & David Husselmann
+/// Developed by David Husselmann for Fantail Technology Ltd
+///
+/// chris@fantail.net.nz
+/// david@tamix.com
+///
+/// Copyright (c) 2007, Fantail Technology Ltd
+///
+/// All rights reserved.
+///
+/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+///
+/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+///
+/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+///
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Fantail.SyslogServer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Fantail Technology Ltd")]
+[assembly: AssemblyProduct("Fantail.SyslogServer")]
+[assembly: AssemblyCopyright("Copyright © 2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("af346163-428b-4300-8572-0977d93cf5d2")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Fantail.SyslogServer/SqlUpdater.cs b/Fantail.SyslogServer/SqlUpdater.cs
new file mode 100644
index 0000000..fd84b65
--- /dev/null
+++ b/Fantail.SyslogServer/SqlUpdater.cs
@@ -0,0 +1,219 @@
+///
+/// Fantail.SyslogServer
+/// ====================
+///
+/// Fantail Technology Ltd ( www.fantail.net.nz )
+///
+/// Designed by Chris Guthrey & David Husselmann
+/// Developed by David Husselmann for Fantail Technology Ltd
+///
+/// chris@fantail.net.nz
+/// david@tamix.com
+///
+/// Copyright (c) 2007, Fantail Technology Ltd
+///
+/// All rights reserved.
+///
+/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+///
+/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+///
+/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+///
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Data.SqlClient;
+using Fantail.Libraries.Syslog;
+using System.Threading;
+
+namespace Fantail.Libraries.Syslog {
+ ///
+ /// Takes care of inserting SyslogMessage records into a database.
+ ///
+ public class SqlUpdater : IDisposable {
+ private const string CHECK_SCHEMA_SQL = @"
+declare @err varchar(2000)
+
+if not exists(select 1 from sysobjects where name=@TableName and xtype='U') begin
+ set @err = 'A table by the name '+isnull(@TableName,'NULL')+' does not exist in catalog '+DB_NAME()+''
+ raiserror(@err,16,1)
+ return
+end
+
+if exists(
+ select 1
+ from (
+ select 'Id' col, 'int' typ
+ union select 'Facility', 'int'
+ union select 'Severity', 'int'
+ union select 'Timestamp', 'datetime'
+ union select 'Hostname', 'varchar'
+ union select 'Message', 'varchar'
+ ) cols
+ left join information_schema.columns ic on cols.col=ic.column_name and cols.typ=ic.data_type and ic.table_name=@TableName
+ where ic.column_name is null
+) begin
+ set @err = 'The table schema does not conform to the recommended structure.
+The following SQL will create it for you:
+
+CREATE TABLE '+quotename(@TableName)+' (
+ Id int identity(1,1), Facility int, Severity int, Timestamp datetime,
+ Hostname varchar(255), Message varchar(1024)
+)
+'
+ raiserror(@err,16,2)
+end
+";
+
+ private SqlConnection conn;
+ private string tableName;
+
+ public SqlUpdater(string connectionString, string tableName) {
+ this.tableName = tableName;
+ conn = new SqlConnection(connectionString);
+
+ //try opening the connection a couple times, if we're in a boot process
+ int tries = 10;
+ do {
+ conn.Open();
+ if (tries != 10) Thread.Sleep(10000);
+ } while (tries-- > 0 && conn.State != System.Data.ConnectionState.Open);
+
+ using (SqlCommand cmd = new SqlCommand(CHECK_SCHEMA_SQL, conn)) {
+ try {
+ cmd.Parameters.AddWithValue("@TableName", tableName);
+ cmd.ExecuteNonQuery();
+ } catch (Exception ex) {
+ throw new Exception("Error checking the schema for the message table.", ex);
+ }
+ }
+ }
+
+ ///
+ /// Submits the given syslog message to the database table.
+ ///
+ /// The syslog message to save.
+ /// True if the operation was successful.
+ public bool SaveMessage(SyslogMessage sm) {
+ List l = new List();
+ l.Add(sm);
+ return SaveMessage(l);
+ }
+
+ ///
+ /// Submits the given syslog messages to the database table in a single transaction.
+ ///
+ /// The syslog messages to save.
+ /// True if the operation was successful.
+ public bool SaveMessage(List syslogMessages) {
+ //DFH Note that this method gets called a lot, so be careful about
+ //disposing of stuff properly.
+
+ if (syslogMessages.Count == 0) return true;
+
+ StringBuilder sb = new StringBuilder();
+ try {
+ //build the sql string
+ //Yep, it defies belief that using this rather than parameters is actually faster.
+ foreach (SyslogMessage sm in syslogMessages) {
+ sb.AppendFormat("INSERT INTO [" + tableName + "] (Facility, Severity, Timestamp, Hostname, Message) VALUES ({0},{1},'{2}','{3}','{4}')\n",
+ sm.Facility, sm.Severity, sm.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff"),
+ sm.Hostname.Replace("'", "''"),
+ sm.Message.Replace("'", "''")
+ );
+ }
+
+ //check the connection
+ if (!PrepareForCommand()) return false;
+
+ //submit the sql
+ using (SqlCommand cmd = new SqlCommand(sb.ToString(), conn)) {
+ try {
+ cmd.ExecuteNonQuery();
+ } catch (Exception ex) {
+ DoExceptionThrown(ex);
+ return false;
+ }
+ }
+
+ } finally {
+ sb = null;
+ }
+
+ //if we get here, everything worked.
+ return true;
+ }
+
+ private bool PrepareForCommand() {
+ if (conn.State != System.Data.ConnectionState.Open) {
+ //broken connection? try resetting it
+ try {
+ conn.Close();
+ } catch (Exception) {
+ }
+
+ try {
+ conn.Open();
+ } catch (Exception ex) {
+ //error trying to open the connection; we better terminate.
+ DoExceptionThrown(new Exception("Error trying to reopen a failed SQL connection.",ex));
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void DoExceptionThrown(Exception e) {
+ if (ExceptionThrown != null) {
+ ExceptionThrown(new ExceptionThrownEventArgs(e));
+ } else {
+ throw e;
+ }
+ }
+
+ ///
+ /// This event gets invoked if an exception is thrown while talking to the database.
+ ///
+ public event ExceptionThrownEventHandler ExceptionThrown;
+
+ ///
+ /// Called on disposing of this class. This will close the SqlConnection if it is still open.
+ ///
+ public void Dispose() {
+ if (conn.State != System.Data.ConnectionState.Closed) {
+ try {
+ conn.Close();
+ } catch (Exception) {
+ }
+ }
+ }
+ }
+
+ public delegate void ExceptionThrownEventHandler(ExceptionThrownEventArgs e);
+ ///
+ /// Encapsulates the exception thrown by internal code.
+ ///
+ public class ExceptionThrownEventArgs : EventArgs {
+ private Exception exception;
+
+ public Exception Exception {
+ get { return exception; }
+ }
+ public ExceptionThrownEventArgs(Exception exception) {
+ this.exception = exception;
+ }
+ }
+}
diff --git a/Fantail.SyslogServer/SyslogListener.cs b/Fantail.SyslogServer/SyslogListener.cs
new file mode 100644
index 0000000..1e5b7cf
--- /dev/null
+++ b/Fantail.SyslogServer/SyslogListener.cs
@@ -0,0 +1,357 @@
+///
+/// Fantail.SyslogServer
+/// ====================
+///
+/// Fantail Technology Ltd ( www.fantail.net.nz )
+///
+/// Designed by Chris Guthrey & David Husselmann
+/// Developed by David Husselmann for Fantail Technology Ltd
+///
+/// chris@fantail.net.nz
+/// david@tamix.com
+///
+/// Copyright (c) 2007, Fantail Technology Ltd
+///
+/// All rights reserved.
+///
+/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+///
+/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+///
+/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+///
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Net;
+using System.Net.Sockets;
+using System.Text.RegularExpressions;
+
+/*
+ * Syslog Listener library
+ * by David Husselmann
+ * for Fantail Technology Ltd
+ *
+ * Implements an RFC3164 compliant syslog listener which parses syslog messages
+ * sent to any interface the class is bound to. To use, instantiate the class:
+ *
+ * SyslogListener sl = new SyslogListener(IPAddress.Any);
+ *
+ * Attach a suitable event handler using the MessageReceived event:
+ *
+ * sl.MessageReceived += new MessageReceivedEventHandler(delegate(object sender, MessageReceivedEventArgs e) {
+ * Console.WriteLine("Got a message: ------------\n" + e.SyslogMessage.ToString());
+ * });
+ *
+ * And finally call the Start() and Stop() methods to control the class:
+ *
+ * sl.Start();
+ * Console.ReadLine();
+ * sl.Stop();
+ *
+ */
+
+/* CHANGELOG
+ * 20070813 DFH Initial version.
+ */
+
+namespace Fantail.Libraries.Syslog {
+
+ ///
+ /// Encapsulates a single syslog message, as received from a remote host.
+ ///
+ public struct SyslogMessage {
+ ///
+ /// Creates a new instance of the SyslogMessage class.
+ ///
+ /// Specifies the encoded PRI field, containing the facility and severity values.
+ /// Specifies the timestamp, if present in the packet.
+ /// Specifies the hostname, if present in the packet. The hostname can only be present if the timestamp is also present (RFC3164).
+ /// Specifies the textual content of the message.
+ public SyslogMessage(int? priority, DateTime timestamp, string hostname, string message) {
+ if (priority.HasValue) {
+ this.facility = (int)Math.Floor((double)priority.Value / 8);
+ this.severity = priority % 8;
+ } else {
+ this.facility = null;
+ this.severity = null;
+ }
+ this.timestamp = timestamp;
+ this.hostname = hostname;
+ this.message = message;
+ }
+
+ private int? facility;
+ ///
+ /// Returns an integer specifying the facility. The following are commonly used:
+ /// 0 kernel messages
+ /// 1 user-level messages
+ /// 2 mail system
+ /// 3 system daemons
+ /// 4 security/authorization messages (note 1)
+ /// 5 messages generated internally by syslogd
+ /// 6 line printer subsystem
+ /// 7 network news subsystem
+ /// 8 UUCP subsystem
+ /// 9 clock daemon (note 2)
+ /// 10 security/authorization messages (note 1)
+ /// 11 FTP daemon
+ /// 12 NTP subsystem
+ /// 13 log audit (note 1)
+ /// 14 log alert (note 1)
+ /// 15 clock daemon (note 2)
+ /// 16 local use 0 (local0)
+ /// 17 local use 1 (local1)
+ /// 18 local use 2 (local2)
+ /// 19 local use 3 (local3)
+ /// 20 local use 4 (local4)
+ /// 21 local use 5 (local5)
+ /// 22 local use 6 (local6)
+ /// 23 local use 7 (local7)
+ ///
+ public int? Facility {
+ get { return facility; }
+ }
+
+ private int? severity;
+ ///
+ /// Returns an integer number specifying the severity. The following values are commonly used:
+ /// 0 Emergency: system is unusable
+ /// 1 Alert: action must be taken immediately
+ /// 2 Critical: critical conditions
+ /// 3 Error: error conditions
+ /// 4 Warning: warning conditions
+ /// 5 Notice: normal but significant condition
+ /// 6 Informational: informational messages
+ /// 7 Debug: debug-level messages
+ ///
+ public int? Severity {
+ get { return severity; }
+ }
+
+ private DateTime timestamp;
+ ///
+ /// Returns a DateTime specifying the moment at which the event is known to have happened. As per RFC3164,
+ /// if the host does not send this value, it may be added by a relay.
+ ///
+ public DateTime Timestamp {
+ get { return timestamp; }
+ }
+
+ private string hostname;
+ ///
+ /// Returns the DNS hostname where the message originated, or the IP address if the hostname is unknown.
+ ///
+ public string Hostname {
+ get { return hostname; }
+ set { hostname = value; }
+ }
+
+ private string message;
+ ///
+ /// Returns a string indicating the textual content of the message.
+ ///
+ public string Message {
+ get { return message; }
+ set { message = value; }
+ }
+
+ ///
+ /// Returns a textual representation of the syslog message, for debugging purposes.
+ ///
+ ///
+ public override string ToString() {
+ return "Facility: " + this.facility + "\nSeverity: " + this.severity +
+ "\nTimestamp: "+this.timestamp+"\nHostname: "+this.hostname+"\nMessage: "+this.message;
+ }
+ }
+
+ public delegate void MessageReceivedEventHandler(MessageReceivedEventArgs e);
+
+ public class MessageReceivedEventArgs : EventArgs {
+ private SyslogMessage syslogMessage;
+ ///
+ /// Returns the syslog message as received from the remote host.
+ ///
+ public SyslogMessage SyslogMessage {
+ get { return syslogMessage; }
+ }
+
+ ///
+ /// Creates a new instance of the MessageReceivedEventArgs class.
+ ///
+ public MessageReceivedEventArgs(SyslogMessage sm) : base() {
+ this.syslogMessage = sm;
+ }
+ }
+
+ ///
+ /// Implements a syslog message listener which is RFC3164 compliant.
+ ///
+ public class SyslogListener {
+ private IPAddress listenAddress;
+ private Socket sock;
+ private const int SYSLOG_PORT = 514;
+ private const int RECEIVE_BUFFER_SIZE = 1024;
+
+ private byte[] receiveBuffer = new Byte[RECEIVE_BUFFER_SIZE];
+ private EndPoint remoteEndpoint = null;
+ private Regex msgRegex = new Regex(@"
+(\<(?\d{1,3})\>){0,1}
+(?
+ (?
+ (?Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s
+ (?[ 0-9][0-9])\s
+ (?[0-9]{2})\:(?[0-9]{2})\:(?[0-9]{2})
+ )\s
+ (?
+ [^ ]+?
+ )\s
+){0,1}
+(?.*)
+", RegexOptions.IgnorePatternWhitespace);
+
+ ///
+ /// Creates a new instance of the SyslogListener class.
+ ///
+ /// Specifies the address to listen on. IPAddress.Any will bind the listener to all available interfaces.
+ public SyslogListener(IPAddress listenAddress) {
+ this.listenAddress = listenAddress;
+ this.sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+ }
+
+ ///
+ /// Starts listening for syslog packets.
+ ///
+ public void Start() {
+ if (sock.IsBound) return;
+ sock.Bind(new IPEndPoint(listenAddress, SYSLOG_PORT));
+ SetupReceive();
+ }
+
+ private void SetupReceive() {
+ remoteEndpoint = new IPEndPoint(IPAddress.None, 0);
+ sock.BeginReceiveFrom(receiveBuffer, 0, RECEIVE_BUFFER_SIZE, SocketFlags.None, ref remoteEndpoint, new AsyncCallback(DoReceiveData), sock);
+ }
+
+ public event MessageReceivedEventHandler MessageReceived;
+
+ ///
+ /// This internal method processes an async receive as set up by SetupReceive()
+ ///
+ private void DoReceiveData(IAsyncResult r) {
+ Socket sock = (Socket)r.AsyncState;
+ //int count = sock.EndReceive(r, out errorCode);
+ EndPoint ep = new IPEndPoint(IPAddress.Any, 0);
+ int count = 0;
+ try {
+ count = sock.EndReceiveFrom(r, ref ep);
+ } catch (SocketException) {
+ //ignore buffer overruns; .NET handles them.
+ } catch (ObjectDisposedException) {
+ //if the socket is disposed, we're shutting down, so return
+ return;
+ }
+
+ string packet = System.Text.Encoding.ASCII.GetString(receiveBuffer, 0, count);
+
+ Match m = msgRegex.Match(packet);
+ //ignore invalid messages
+ if (m != null && !string.IsNullOrEmpty(packet)) {
+
+ //parse PRI section into priority
+ int pri;
+ int? priority = int.TryParse(m.Groups["PRI"].Value, out pri) ? new int?(pri) : null;
+
+ //parse the HEADER section - contains TIMESTAMP and HOSTNAME
+ string hostname = null;
+ Nullable timestamp = null;
+ if (!string.IsNullOrEmpty(m.Groups["HDR"].Value)) {
+ if (!string.IsNullOrEmpty(m.Groups["TIMESTAMP"].Value)) {
+ try {
+ timestamp = new DateTime(
+ DateTime.Now.Year,
+ MonthNumber(m.Groups["MMM"].Value),
+ int.Parse(m.Groups["DD"].Value),
+ int.Parse(m.Groups["HH"].Value),
+ int.Parse(m.Groups["MM"].Value),
+ int.Parse(m.Groups["SS"].Value)
+ );
+ } catch (ArgumentException) {
+ //ignore invalid timestamps
+ }
+ }
+
+ if (!string.IsNullOrEmpty(m.Groups["HOSTNAME"].Value)) {
+ hostname = m.Groups["HOSTNAME"].Value;
+ }
+ }
+
+ if (!timestamp.HasValue) {
+ //add timestamp as per RFC3164
+ timestamp = DateTime.Now;
+ }
+ if (string.IsNullOrEmpty(hostname)) {
+ IPEndPoint ipe = (IPEndPoint)ep;
+ IPHostEntry he = Dns.GetHostEntry(ipe.Address);
+ if (he != null && !string.IsNullOrEmpty(he.HostName))
+ hostname = he.HostName;
+ else
+ hostname = ep.ToString();
+ }
+
+ string message = m.Groups["MSG"].Value;
+
+ SyslogMessage sm = new SyslogMessage(priority, timestamp.Value, hostname, message);
+ if (MessageReceived != null) {
+ MessageReceived(new MessageReceivedEventArgs(sm));
+ }
+ }
+
+ //after we're done processing, ready the socket for another receive.
+ SetupReceive();
+ }
+
+ ///
+ /// Stops listening and reporting syslog message packets.
+ ///
+ public void Stop() {
+ if (sock.IsBound) {
+ try {
+ sock.Close();
+ } catch (Exception) { }
+ }
+ }
+
+ private static int MonthNumber(string monthName) {
+ switch (monthName.ToLower().Substring(0,3)) {
+ case "jan": return 1;
+ case "feb": return 2;
+ case "mar": return 3;
+ case "apr": return 4;
+ case "may": return 5;
+ case "jun": return 6;
+ case "jul": return 7;
+ case "aug": return 8;
+ case "sep": return 9;
+ case "oct": return 10;
+ case "nov": return 11;
+ case "dec": return 12;
+ default:
+ throw new Exception("Unrecognised month name: " + monthName);
+ }
+ }
+ }
+}
diff --git a/Fantail.SyslogServer/SyslogService.Designer.cs b/Fantail.SyslogServer/SyslogService.Designer.cs
new file mode 100644
index 0000000..094498f
--- /dev/null
+++ b/Fantail.SyslogServer/SyslogService.Designer.cs
@@ -0,0 +1,67 @@
+///
+/// Fantail.SyslogServer
+/// ====================
+///
+/// Fantail Technology Ltd ( www.fantail.net.nz )
+///
+/// Designed by Chris Guthrey & David Husselmann
+/// Developed by David Husselmann for Fantail Technology Ltd
+///
+/// chris@fantail.net.nz
+/// david@tamix.com
+///
+/// Copyright (c) 2007, Fantail Technology Ltd
+///
+/// All rights reserved.
+///
+/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+///
+/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+///
+/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+///
+namespace Fantail.SyslogServer
+{
+ partial class SyslogService {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if (disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent() {
+ components = new System.ComponentModel.Container();
+ this.ServiceName = "Service1";
+ }
+
+ #endregion
+ }
+}
diff --git a/Fantail.SyslogServer/SyslogService.cs b/Fantail.SyslogServer/SyslogService.cs
new file mode 100644
index 0000000..16b5481
--- /dev/null
+++ b/Fantail.SyslogServer/SyslogService.cs
@@ -0,0 +1,102 @@
+///
+/// Fantail.SyslogServer
+/// ====================
+///
+/// Fantail Technology Ltd ( www.fantail.net.nz )
+///
+/// Designed by Chris Guthrey & David Husselmann
+/// Developed by David Husselmann for Fantail Technology Ltd
+///
+/// chris@fantail.net.nz
+/// david@tamix.com
+///
+/// Copyright (c) 2007, Fantail Technology Ltd
+///
+/// All rights reserved.
+///
+/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+///
+/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+///
+/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+///
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.ServiceProcess;
+using System.Text;
+using Fantail.Libraries.Syslog;
+using System.Net;
+
+namespace Fantail.SyslogServer {
+ public partial class SyslogService : ServiceBase {
+
+ ///
+ /// This is where all the action really starts!
+ ///
+ /// The sequence of events is as follows:
+ ///
+ /// Create the SyslogListener object - this will listen on port 514 for syslog messages
+ /// Create the SqlUpdate object - this will save messages to your SQL database
+ ///
+ /// NOTE that you need to edit the new SqlUpdater for your database settings
+ ///
+ /// The MemoryBuffer holds the messages recieved by the listener and then calls the SQL update
+ /// in batches, so reduce load on the SQL server
+ ///
+ /// Setup event handlers for receiving new syslog messages and for handling SQL exceptions.
+ ///
+ /// and so on with starting the Fantail.SyslogServer service!
+ ///
+ ///
+ public SyslogService() {
+ InitializeComponent();
+ }
+
+ private SyslogListener syslogListener;
+ private SqlUpdater sqlUpdater;
+ private MemoryBuffer memoryBuffer;
+
+ protected override void OnStart(string[] args) {
+ syslogListener = new SyslogListener(IPAddress.Any);
+
+ ///
+ /// the next line needs to be edited. instead of hardcoding these details into the application
+ /// it would be better to store them in an XML config file or something...
+ ///
+ sqlUpdater = new SqlUpdater("server=;user=;password=;initial catalog=", "your-table-name");
+
+
+ memoryBuffer = new MemoryBuffer(TimeSpan.FromSeconds(30), sqlUpdater);
+
+ syslogListener.MessageReceived += new MessageReceivedEventHandler(delegate(MessageReceivedEventArgs e) {
+ memoryBuffer.PushMessage(e.SyslogMessage);
+ });
+
+ sqlUpdater.ExceptionThrown += new ExceptionThrownEventHandler(delegate(ExceptionThrownEventArgs e) {
+ EventLog.WriteEntry(EventLog.Source, e.Exception.ToString());
+ });
+
+ syslogListener.Start();
+ }
+
+ protected override void OnStop() {
+ syslogListener.Stop();
+ memoryBuffer.Flush();
+ }
+ }
+}
diff --git a/Fantail.SyslogServer/obj/Fantail.SyslogServer.csproj.FileList.txt b/Fantail.SyslogServer/obj/Fantail.SyslogServer.csproj.FileList.txt
new file mode 100644
index 0000000..ee6899d
--- /dev/null
+++ b/Fantail.SyslogServer/obj/Fantail.SyslogServer.csproj.FileList.txt
@@ -0,0 +1,14 @@
+bin\Debug\Fantail.SyslogServer.exe
+bin\Debug\Fantail.SyslogServer.pdb
+obj\Debug\ResolveAssemblyReference.cache
+obj\Debug\Fantail.SyslogServer.ProjectInstaller.resources
+obj\Debug\Fantail.SyslogServer.csproj.GenerateResource.Cache
+obj\Debug\Fantail.SyslogServer.exe
+obj\Debug\Fantail.SyslogServer.pdb
+bin\Release\Fantail.SyslogServer.exe
+bin\Release\Fantail.SyslogServer.pdb
+obj\Release\ResolveAssemblyReference.cache
+obj\Release\Fantail.SyslogServer.ProjectInstaller.resources
+obj\Release\Fantail.SyslogServer.csproj.GenerateResource.Cache
+obj\Release\Fantail.SyslogServer.exe
+obj\Release\Fantail.SyslogServer.pdb
diff --git a/Fantail.SyslogServer/readme.txt b/Fantail.SyslogServer/readme.txt
new file mode 100644
index 0000000..5518d37
--- /dev/null
+++ b/Fantail.SyslogServer/readme.txt
@@ -0,0 +1,152 @@
+Fantail.SyslogServer
+====================
+
+Fantail Technology Ltd ( www.fantail.net.nz )
+
+Designed by Chris Guthrey & David Husselmann
+Developed by David Husselmann for Fantail Technology Ltd
+
+chris@fantail.net.nz
+david@tamix.com
+
+Copyright (c) 2007, Fantail Technology Ltd
+
+
+This project is by no means fully complete. Fantail Technology Ltd has released this
+project as it is under a BSD-style license so that it may be of help or use to anyone
+else needing to build a C# Syslog to SQL service.
+
+The basic steps for building this project are:
+
+1) extract the ZIP file to :
+
+ C:\Projects\Fantail\SyslogServer\SyslogServer
+
+ If you want to stick it elsewhere, feel free to, but the solution files and such probably need to be updated.
+
+
+2) Setup an SQL database
+
+ 2a) If you don't already have a Microsoft SQL Server handy, you may want to download MSDE or SQLExpress
+
+ http://www.microsoft.com/sql/prodinfo/previousversions/msde/prodinfo.mspx
+ or
+ http://msdn2.microsoft.com/en-us/express/aa718378.aspx
+
+ Note that I haven't actually tested this code against SQLExpress, but since
+ it is all simple stuff, it should just work...
+
+
+ 2b) Create a database, if you can't think of a name for it, called it "FantailSysLog"
+
+
+ 2c) Create a table. Run the following SQL Statement to create the one table (just one!) that you need:
+
+ CREATE TABLE FantailSysLog (
+ Id int identity(1,1),
+ Facility int,
+ Severity int,
+ Timestamp datetime,
+ Hostname varchar(255),
+ Message varchar(1024)
+ )
+
+ (change "FantailSysLog" to a different table name if you wish)
+
+
+ 2d) Create a database user, and grant that user full permissions on your database and table
+
+
+3) edit the file
+
+ C:\Projects\Fantail\SyslogServer\SyslogServer\Fantail.SyslogServer\SyslogService.cs
+
+
+ and change the line:
+
+ sqlUpdater = new SqlUpdater("server=;user=;password=;initial catalog=", "");
+
+ as follows:
+ this should be the network name or IP address of the machine that hosts your MS SQL Server
+ (if you are going to install the Fantail.SyslogService on the same machine as the SQL Server
+ then you can simply set this to "." or "(local)"
+
+ this is the sql database user you created in step 2d) above
+
+ the password you assigned to above user
+
+ the database you created in step 2b)
+
+ the name of the table you created in step 2c) above
+
+
+4) build the project. This was written using Visual Studio 2005. If you don't have VS2005, you could probably
+ use SharpDevelop without a great deal of modification. I haven't tested this with SharpDevelop, but seeing that the
+ code is straightforward, it should just work...
+
+5) install the Service.
+ You will need a .NET 2 Utility called "InstallUtil".
+ Since the machine that you want to run this service on must already have the .NET2 framework installed, all you simply need do is
+
+ 5a) copy your newly built executable "Fantail.SyslogServer.exe" to a location where you want to run it from. I recommend you
+ create the folder: C:\Program Files\Fantail
+ and copy it there
+
+ 5b) open a Command Prompt (click Start menu, click on "Run...", then enter "CMD" and click the OK button)
+
+ 5c) change directory to the location where you copied your executable to, ie:
+
+ CD "\Program Files\Fantail"
+
+ 5d) use InstallUtil to install the executable as a Windows Service:
+
+ "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe" Fantail.SyslogServer.exe
+
+ you should get a message to the effect that the service has been installed successfully.
+
+ 5f) time to test it out! type:
+
+ NET START "Fantail Syslog Server"
+
+ 5g) if you get an error message, check the eventlog for clues as to what went wrong...
+
+ EVENTVWR
+
+
+Enjoy!
+
+If I get requested to, I will remove the ugly hard-coded SQL connection details, and move those settings into a Config File.
+This means that a generic EXE can be used to talk to any SQL server.
+
+Otherwise if anyone else cares to tidy up and finish off the rough edges, please send me a copy!
+
+Cheers!
+Chris Guthrey - chris@fantail.net.nz
+Fantail Technology Ltd
+www.fantail.net.nz
+
+===================================================================
+
+Copyright (c) 2007, Fantail Technology Ltd
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+
+===================================================================
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 0000000..c40d87d
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,34 @@
+
+ Fantail.SyslogServer
+ ====================
+
+ Fantail Technology Ltd ( www.fantail.net.nz )
+
+ Designed by Chris Guthrey & David Husselmann
+ Developed by David Husselmann for Fantail Technology Ltd
+
+ chris@fantail.net.nz
+ david@tamix.com
+
+ Copyright (c) 2007, Fantail Technology Ltd
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+
diff --git a/SyslogServer.sln b/SyslogServer.sln
new file mode 100644
index 0000000..a7889cf
--- /dev/null
+++ b/SyslogServer.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fantail.SyslogServer", "Fantail.SyslogServer\Fantail.SyslogServer.csproj", "{2276C92F-8444-47B4-B3C9-AF507C41BB98}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2276C92F-8444-47B4-B3C9-AF507C41BB98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2276C92F-8444-47B4-B3C9-AF507C41BB98}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2276C92F-8444-47B4-B3C9-AF507C41BB98}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2276C92F-8444-47B4-B3C9-AF507C41BB98}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/SyslogServer.suo b/SyslogServer.suo
new file mode 100644
index 0000000..8b5e3e5
Binary files /dev/null and b/SyslogServer.suo differ
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..5518d37
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,152 @@
+Fantail.SyslogServer
+====================
+
+Fantail Technology Ltd ( www.fantail.net.nz )
+
+Designed by Chris Guthrey & David Husselmann
+Developed by David Husselmann for Fantail Technology Ltd
+
+chris@fantail.net.nz
+david@tamix.com
+
+Copyright (c) 2007, Fantail Technology Ltd
+
+
+This project is by no means fully complete. Fantail Technology Ltd has released this
+project as it is under a BSD-style license so that it may be of help or use to anyone
+else needing to build a C# Syslog to SQL service.
+
+The basic steps for building this project are:
+
+1) extract the ZIP file to :
+
+ C:\Projects\Fantail\SyslogServer\SyslogServer
+
+ If you want to stick it elsewhere, feel free to, but the solution files and such probably need to be updated.
+
+
+2) Setup an SQL database
+
+ 2a) If you don't already have a Microsoft SQL Server handy, you may want to download MSDE or SQLExpress
+
+ http://www.microsoft.com/sql/prodinfo/previousversions/msde/prodinfo.mspx
+ or
+ http://msdn2.microsoft.com/en-us/express/aa718378.aspx
+
+ Note that I haven't actually tested this code against SQLExpress, but since
+ it is all simple stuff, it should just work...
+
+
+ 2b) Create a database, if you can't think of a name for it, called it "FantailSysLog"
+
+
+ 2c) Create a table. Run the following SQL Statement to create the one table (just one!) that you need:
+
+ CREATE TABLE FantailSysLog (
+ Id int identity(1,1),
+ Facility int,
+ Severity int,
+ Timestamp datetime,
+ Hostname varchar(255),
+ Message varchar(1024)
+ )
+
+ (change "FantailSysLog" to a different table name if you wish)
+
+
+ 2d) Create a database user, and grant that user full permissions on your database and table
+
+
+3) edit the file
+
+ C:\Projects\Fantail\SyslogServer\SyslogServer\Fantail.SyslogServer\SyslogService.cs
+
+
+ and change the line:
+
+ sqlUpdater = new SqlUpdater("server=;user=;password=;initial catalog=", "");
+
+ as follows:
+ this should be the network name or IP address of the machine that hosts your MS SQL Server
+ (if you are going to install the Fantail.SyslogService on the same machine as the SQL Server
+ then you can simply set this to "." or "(local)"
+
+ this is the sql database user you created in step 2d) above
+
+ the password you assigned to above user
+
+ the database you created in step 2b)
+
+ the name of the table you created in step 2c) above
+
+
+4) build the project. This was written using Visual Studio 2005. If you don't have VS2005, you could probably
+ use SharpDevelop without a great deal of modification. I haven't tested this with SharpDevelop, but seeing that the
+ code is straightforward, it should just work...
+
+5) install the Service.
+ You will need a .NET 2 Utility called "InstallUtil".
+ Since the machine that you want to run this service on must already have the .NET2 framework installed, all you simply need do is
+
+ 5a) copy your newly built executable "Fantail.SyslogServer.exe" to a location where you want to run it from. I recommend you
+ create the folder: C:\Program Files\Fantail
+ and copy it there
+
+ 5b) open a Command Prompt (click Start menu, click on "Run...", then enter "CMD" and click the OK button)
+
+ 5c) change directory to the location where you copied your executable to, ie:
+
+ CD "\Program Files\Fantail"
+
+ 5d) use InstallUtil to install the executable as a Windows Service:
+
+ "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe" Fantail.SyslogServer.exe
+
+ you should get a message to the effect that the service has been installed successfully.
+
+ 5f) time to test it out! type:
+
+ NET START "Fantail Syslog Server"
+
+ 5g) if you get an error message, check the eventlog for clues as to what went wrong...
+
+ EVENTVWR
+
+
+Enjoy!
+
+If I get requested to, I will remove the ugly hard-coded SQL connection details, and move those settings into a Config File.
+This means that a generic EXE can be used to talk to any SQL server.
+
+Otherwise if anyone else cares to tidy up and finish off the rough edges, please send me a copy!
+
+Cheers!
+Chris Guthrey - chris@fantail.net.nz
+Fantail Technology Ltd
+www.fantail.net.nz
+
+===================================================================
+
+Copyright (c) 2007, Fantail Technology Ltd
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+
+===================================================================